• 2017-2018-1 20155330 《信息安全系统设计基础》加分项目--实现mypwd


    2017-2018-1 20155330 《信息安全系统设计基础》加分项目--实现mypwd

    pwd命令

    • 命令功能:查看”当前工作目录“的完整路径。
    • 通过man命令查看pwd的相关信息

    mypwd的实现

    研究pwd实现需要的系统调用(man -k; grep),写出伪代码

    • 通过man -k directory | grep 2查看相关系统调用。可以发现getcwd()函数是实现该功能的相关函数。
    • 通过man 2 getcwd查看函数结构。
    • 利用getcwd()函数简单实现的伪代码
    设置一个char型数组(或指针)用于保存当前绝对路径内容;
    调用系统函数`getcwd()`获取当前路径并保存在之前的数组中;
    if(返回指针==NULL)
    	错误;
    else
    	打印当前路径;
    
    
    • 代码
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #define MAX 2048
    
    int main()
    {
    	char buf[MAX],*a=getcwd(buf,sizeof(buf));
    	if(a==NULL)
    		printf("Error!");
    	else
    		printf("%s
    ",a);
    	return 0;
    }
    

    运行结果:

    • 通过man -k directory | grep 3查看相关库函数。
    • 通过之前查看的getcwd函数可知getcwd函数与getwd函数基本相同。现在查看opendir()函数和readdir()函数。
      • opendir()函数
      • readdir()函数
    • readdir()函数中的结构体
    struct dirent {
               ino_t          d_ino;       /* inode number */
               off_t          d_off;       /* not an offset; see NOTES */
               unsigned short d_reclen;    /* length of this record */
               unsigned char  d_type;      /* type of file; not supported
                                              by all filesystem types */
               char           d_name[256]; /* filename */
           };
    

    可以知道显示文件名需要与之对应的i-node

    • 获得i-node可用stat函数,需要注意的是,在使用帮助文档查看stat函数时,应使用命令man 2 stat
    • 代码实现查看inode功能
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <time.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[])
           {
               struct stat sb;
    
               if (argc != 2) {
                   fprintf(stderr, "Usage: %s <pathname>
    ", argv[0]);
                   exit(EXIT_FAILURE);
               }
    
               if (stat(argv[1], &sb) == -1) {
                   perror("stat");
                   exit(EXIT_FAILURE);
               }
    
               printf("File type:                ");
    
               switch (sb.st_mode & S_IFMT) {
               case S_IFBLK:  printf("block device
    ");            break;
               case S_IFCHR:  printf("character device
    ");        break;
               case S_IFDIR:  printf("directory
    ");               break;
               case S_IFIFO:  printf("FIFO/pipe
    ");               break;
               case S_IFLNK:  printf("symlink
    ");                 break;
               case S_IFREG:  printf("regular file
    ");            break;
               case S_IFSOCK: printf("socket
    ");                  break;
               default:       printf("unknown?
    ");                break;
               }
    
               printf("I-node number:            %ld
    ", (long) sb.st_ino);
    
               printf("Mode:                     %lo (octal)
    ",
                       (unsigned long) sb.st_mode);
    
               printf("Link count:               %ld
    ", (long) sb.st_nlink);
               printf("Ownership:                UID=%ld   GID=%ld
    ",
                       (long) sb.st_uid, (long) sb.st_gid);
    
               printf("Preferred I/O block size: %ld bytes
    ",
                       (long) sb.st_blksize);
               printf("File size:                %lld bytes
    ",
                       (long long) sb.st_size);
               printf("Blocks allocated:         %lld
    ",
                       (long long) sb.st_blocks);
    
               printf("Last status change:       %s", ctime(&sb.st_ctime));
               printf("Last file access:         %s", ctime(&sb.st_atime));
               printf("Last file modification:   %s", ctime(&sb.st_mtime));
    
               exit(EXIT_SUCCESS);
           }
    
    • 运行结果
    • 综合以上信息得到伪代码
    设置一个char型数组(或指针)用于保存当前绝对路径内容,无符号数用于记录绝对路径的深度;
    while(1)
    {
    	分别获取"."(当前目录)和".."(当前目录的上一级目录)i-node;
    	if("."i-node==".."i-noode)
    		输出目录信息;
    	else
    	{
    		切换至父级目录获取i-node
            在父级目录中搜索对应的文件名并记录下来
    	}
    }
    
    
    • 完整代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <dirent.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <string.h>
    #include <unistd.h>
    
    //获取文件的inode-number
    ino_t get_ino_byname(char *filename)
    {
    	struct stat file_stat;
    	if(0 != stat(filename, &file_stat)) //stat()通过文件名filename获取文件信息,并保存在buf所指的结构体stat中
    	{
    		perror("stat");
    		exit(-1);
    	}
    
    	return file_stat.st_ino;
    }
    
    //根据inode-number, 在当前目录中查找对应文件名
    char *find_name_byino(ino_t ino)
    {
    	DIR *dp = NULL;
    	struct dirent *dptr = NULL;
    	char *filename = NULL;
    	
    	if(NULL == (dp = opendir("."))) //opendir()打开一个目录,在失败的时候返回一个空的指针,成返回DIR结构体
    	{
    		fprintf(stderr, "Can not open Current Directory
    ");
    		exit(-1);
    	}
    	else
    	{
    		while(NULL != (dptr = readdir(dp))) //readdir()用来读取目录。返回是dirent结构体指针
    		{
    			if(dptr->d_ino == ino)
    			{
    				filename = strdup(dptr->d_name); //strdup()将串拷贝到新建的位置处,返回一个指针,指向为复制字符串分配的空间;如果分配空间失败,则返回NULL值.
    				break;
    			}
    		}
    
    		closedir(dp);
    	}
    
    	return filename;
    }
    
    int main(int argc, char *argv[])
    {
    	//记录目名的栈
    	char *dir_stack[256];
    	unsigned current_depth = 0;
    
    	while(1)
    	{
    		ino_t current_ino = get_ino_byname("."); //通过"."获取当期目录inode
    		ino_t parent_ino = get_ino_byname(".."); //通过".."获取当前目录的父目录的inode
    		if(current_ino == parent_ino)
    			break;				 //达到根目录,推出循环
    
    		/*若两个inode不一样*/
    		chdir(".."); //更改当前工作目录,变为当前目录的父目录
    		dir_stack[current_depth++] = find_name_byino(current_ino); //"文件名"地址存放
    	}
    
    	int i = current_depth - 1;
    	for(i = current_depth - 1; i >= 0; i--) //打印路径
    	{
    		fprintf(stdout, "/%s", dir_stack[i]);
    	}
    	fprintf(stdout, "%s
    ", current_depth == 0 ? "/" : "");
    
    	return 0;
    }
    

    运行结果:

  • 相关阅读:
    【转载】浏览器兼容性测试
    【转载】移动端
    【转载】Postman学习之【压力测试】
    【转载】如何进行bug总结
    【转载】按键精灵对安卓APP进行自动化界面点击测试
    【转载】Selenium+Python自动化测试环境搭建和搭建过程遇到的问题解决
    【转载】fiddler软件测试——Fiddler抓取https设置详解(图文)
    【转载】服务器性能测试工具 ---- nmon
    python中的一些好用的库
    python操作excel表格相关的库
  • 原文地址:https://www.cnblogs.com/ashin-kl/p/7860382.html
Copyright © 2020-2023  润新知