- 姓名
- 学号
- 班级
1. 编写程序
在服务器上用Vim编写一个程序:实现Linux系统命令ls -lai
的功能,给出源代码。
1 #include <stdio.h> 2 #include <dirent.h> 3 #include <string.h> 4 #include <sys/stat.h> 5 #include <unistd.h> 6 #include <sys/types.h> 7 #include <pwd.h> 8 #include <grp.h> 9 #include <time.h> 10 #include <stdlib.h> 11 12 int ls(char *str); 13 int ls_long(char *str, char *argv); 14 char getFileType(int st_mode); 15 char* getPower(int st_mode); 16 char* getUsername(int uid); 17 char* getGroupname(int gid); 18 19 int main(int argc, char *argv[]){ 20 if (argc == 1){ 21 int status; 22 status = ls("."); 23 if (status == -1) 24 printf("Error: file can't open\n"); 25 return 0; 26 } 27 if (argc == 2){ 28 if (argv[1][0] == '-'){ 29 int status; 30 status = ls_long(".", argv[1]); 31 if (status == -1) 32 printf("Error: file can't open\n"); 33 if (status == 0){ 34 printf("Error: input parameter error\n"); 35 } 36 }else{ 37 printf("apponit dir\n"); 38 int status; 39 status = ls(argv[1]); 40 if (status == -1){ 41 printf("Error: file can't open\n"); 42 } 43 } 44 return 0; 45 } 46 if (argc >= 3){ 47 int status; 48 status = ls_long(argv[1], argv[2]); 49 if (status == -1) 50 printf("Error: file can't open\n"); 51 if (status == 0) 52 printf("Error: input parameter error\n"); 53 return 0; 54 } 55 return 0; 56 } 57 int ls(char *str){ 58 DIR *dirp; 59 struct dirent *dp; 60 dirp = opendir(str); 61 if (readdir(dirp) == NULL){ 62 return -1; 63 } 64 while ((dp = readdir(dirp)) != NULL){ 65 printf("%s\n", dp -> d_name); 66 } 67 closedir(dirp); 68 return 1; 69 } 70 int ls_long(char *str, char *argv){ 71 DIR *dirp; 72 struct dirent *dp; 73 dirp = opendir(str); 74 if (readdir(dirp) == NULL){ 75 return -1; 76 } 77 int len; 78 len = strlen(argv); 79 int i; 80 int flag = 0; 81 for(i = 1; i < len; i++){ 82 if (argv[i] == 'l') 83 flag = 1; 84 } 85 if (flag == 0) 86 return 0; 87 chdir(str); 88 while ((dp = readdir(dirp)) != NULL){ 89 struct stat buf; 90 int st; 91 st = stat(dp -> d_name, &buf); 92 if (st == -1) 93 return -1; 94 char type; 95 type = getFileType(buf.st_mode); 96 char power[9]; 97 int j; 98 char* p = getPower(buf.st_mode); 99 for (j = 0; j < 9; j++){ 100 power[j] = *(p + j); 101 } 102 char* username = getUsername(buf.st_uid); 103 char* groupname = getGroupname(buf.st_gid); 104 struct tm* t; 105 t = localtime(&buf.st_mtime); 106 printf("%c%s\t%ld\t%s\t%s\t%ld\t%02d.%02d %02d:%02d\t%s\n",type,power, buf.st_nlink, username, groupname, buf.st_size, t -> tm_mon + 1, t -> tm_mday, t -> tm_hour, t -> tm_min, dp -> d_name ); 107 } 108 closedir(dirp); 109 return 1; 110 } 111 char getFileType(int st_mode){ 112 if ((st_mode & S_IFREG) == S_IFREG){ 113 return '-'; 114 }else if ((st_mode & S_IFDIR) == S_IFDIR){ 115 return 'd'; 116 } 117 else if ((st_mode & S_IFLNK) == S_IFLNK){ 118 return 'l'; 119 }else if ((st_mode & S_IFSOCK) == S_IFSOCK){ 120 return 's'; 121 }else if ((st_mode & S_IFBLK) == S_IFBLK){ 122 return 'b'; 123 }else { 124 return 'c'; 125 } 126 } 127 char* getPower(int st_mode){ 128 char *power = (char*)malloc(10); 129 if ((st_mode & S_IRUSR) == S_IRUSR){ 130 power[0] = 'r'; 131 }else{ 132 power[0] = '-'; 133 } 134 if ((st_mode & S_IWUSR) == S_IWUSR){ 135 power[1] = 'w'; 136 }else{ 137 power[1] = '-'; 138 } 139 if ((st_mode & S_IXUSR) == S_IXUSR){ 140 power[2] = 'x'; 141 }else{ 142 power[2] = '-'; 143 } 144 if ((st_mode & S_IRGRP) == S_IRGRP){ 145 power[3] = 'r'; 146 }else{ 147 power[3] = '-'; 148 } 149 if ((st_mode & S_IWGRP) == S_IWGRP){ 150 power[4] = 'w'; 151 }else{ 152 power[4] = '-'; 153 } 154 if ((st_mode & S_IXGRP) == S_IXGRP){ 155 power[5] = 'x'; 156 }else{ 157 power[5] = '-'; 158 } 159 if ((st_mode & S_IROTH) == S_IROTH){ 160 power[6] = 'r'; 161 }else{ 162 power[6] = '-'; 163 } 164 if ((st_mode & S_IWOTH) == S_IWOTH){ 165 power[7] = 'w'; 166 }else{ 167 power[7] = '-'; 168 } 169 if((st_mode & S_IXOTH) == S_IXOTH){ 170 power[8] = 'x'; 171 }else{ 172 power[8] = '-'; 173 } 174 power[9] = '\0'; 175 return power; 176 } 177 char* getUsername(int uid){ 178 struct passwd *my_info; 179 my_info = getpwuid(uid); 180 return (my_info -> pw_name); 181 } 182 char* getGroupname(int gid){ 183 struct group *group_info; 184 group_info = getgrgid(gid); 185 return (group_info -> gr_name); 186 }
2. 分析运行结果
给出运行结果截图,对于每一列是如何获取的,结合源代码做解释
第一列表示该文件或目录的权限位
r表示拥有读的权限 w表示写入权限 、x表示执行权限
其中第0位是类型,1~3位表示文件拥有者的权限,4~6位表示文件所属组拥有的权限,7~9位表示其他用户拥有的权限。
127 char* getPower(int st_mode){ 128 char *power = (char*)malloc(10); 129 if ((st_mode & S_IRUSR) == S_IRUSR){//文件拥有者 130 power[0] = 'r'; 131 }else{ 132 power[0] = '-'; 133 } 134 if ((st_mode & S_IWUSR) == S_IWUSR){ 135 power[1] = 'w'; 136 }else{ 137 power[1] = '-'; 138 } 139 if ((st_mode & S_IXUSR) == S_IXUSR){ 140 power[2] = 'x'; 141 }else{ 142 power[2] = '-'; 143 } 144 if ((st_mode & S_IRGRP) == S_IRGRP){//用户组 145 power[3] = 'r'; 146 }else{ 147 power[3] = '-'; 148 } 149 if ((st_mode & S_IWGRP) == S_IWGRP){ 150 power[4] = 'w'; 151 }else{ 152 power[4] = '-'; 153 } 154 if ((st_mode & S_IXGRP) == S_IXGRP){ 155 power[5] = 'x'; 156 }else{ 157 power[5] = '-'; 158 } 159 if ((st_mode & S_IROTH) == S_IROTH){//其他人 160 power[6] = 'r'; 161 }else{ 162 power[6] = '-'; 163 } 164 if ((st_mode & S_IWOTH) == S_IWOTH){ 165 power[7] = 'w'; 166 }else{ 167 power[7] = '-'; 168 } 169 if((st_mode & S_IXOTH) == S_IXOTH){ 170 power[8] = 'x'; 171 }else{ 172 power[8] = '-'; 173 } 174 power[9] = '\0'; 175 return power; 176 }
第三列用户ID号
printf("%c%s\t%ld\t%s\t%s\t%ld\t%02d.%02d %02d:%02d\t%s\n",type,power, buf.st_nlink, username, groupname, buf.st_size, t -> tm_mon + 1, t -> tm_mday, t -> tm_hour, t -> tm_min, dp -> d_name );
第四列用户名字
char* username = getUsername(buf.st_uid);
第五列用户所在的组群
char* groupname = getGroupname(buf.st_gid);
第六列该文件所占用的空间
printf("%c%s\t%ld\t%s\t%s\t%ld\t%02d.%02d %02d:%02d\t%s\n",type,power, buf.st_nlink, username, groupname, buf.st_size, t -> tm_mon + 1, t -> tm_mday, t -> tm_hour, t -> tm_min, dp -> d_name);
第七列文件(目录)最近访问(修改)时间
printf("%c%s\t%ld\t%s\t%s\t%ld\t%02d.%02d %02d:%02d\t%s\n",type,power, buf.st_nlink, username, groupname, buf.st_size, t->tm_mon+1, t ->tm_mday, t->tm_hour, t -> tm_min, dp -> d_name);
第八列文件名字
直接运行程序给出文件名。
57 int ls(char *str){ 58 DIR *dirp; 59 struct dirent *dp; 60 dirp = opendir(str); 61 if (readdir(dirp) == NULL){ 62 return -1; 63 } 64 while ((dp = readdir(dirp)) != NULL){ 65 printf("%s\n", dp -> d_name); 66 } 67 closedir(dirp); 68 return 1; 69 }
3. 通过该实验产生新的疑问及解答
通过该实验如果有产生新的疑问,可以写出来,并尝试自己解决问题。