高仿linux下的ls -l命令——C语言实现
Posted ikaros-521
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高仿linux下的ls -l命令——C语言实现相关的知识,希望对你有一定的参考价值。
主要用到的函数可以参考头文件,仅仅支持ls -l这功能,扩展就交给大家了0.0
相关测试图片:
话不多说,直接上码
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <sys/stat.h> 5 #include <sys/types.h> 6 #include <string.h> 7 #include <time.h> 8 #include <pwd.h> 9 #include <grp.h> 10 #include <time.h> 11 #include <dirent.h> 12 13 #define MAX_FILE_NUM 200 14 15 16 //可能还有一些小问题没有解决,功能基本已经实现,如有建议,望大佬赐教 17 18 typedef struct LS 19 20 char mode[15]; // 文件的模式 21 int dir_num; // 是否目录或目录中包含目录的数量 22 char user[20]; // 文件的用户名 23 char group[20]; // 文件的组名 24 long size; // 文件的字节数 25 char time[30]; // 文件的最后修改时间 26 char year[5]; // 拓展用,年份 27 char mon[5]; // 月份 28 char hour[5]; // 时 29 char min[5]; // 分 30 int st_mode; // 文件类型和权限 31 char name[20]; // 文件名 32 LS; 33 34 // 获取文件的模式 35 char* file_mode(mode_t m,char* str) 36 37 if(S_ISREG(m)) 38 str[0] = ‘-‘; 39 else if(S_ISDIR(m)) 40 str[0] = ‘d‘; 41 else if(S_ISCHR(m)) 42 str[0] = ‘c‘; 43 else if(S_ISBLK(m)) 44 str[0] = ‘b‘; 45 else if(S_ISFIFO(m)) 46 str[0] = ‘q‘; 47 else if(S_ISLNK(m)) 48 str[0] = ‘l‘; 49 // else if(S_ISSOCK(m)) 50 // str[0] = ‘s‘; 51 else 52 str[0] = ‘?‘; 53 54 str[1] = ‘\0‘; 55 56 strcat(str,S_IRUSR&m?"r":"-"); 57 strcat(str,S_IWUSR&m?"w":"-"); 58 strcat(str,S_IXUSR&m?"x":"-"); 59 60 strcat(str,S_IRGRP&m?"r":"-"); 61 strcat(str,S_IWGRP&m?"w":"-"); 62 strcat(str,S_IXGRP&m?"x":"-"); 63 64 strcat(str,S_IROTH&m?"r":"-"); 65 strcat(str,S_IWOTH&m?"w":"-"); 66 strcat(str,S_IXOTH&m?"x":"-"); 67 68 return str; 69 70 71 // 获取目录的数量 72 int dir_count(char* path) 73 74 DIR *dir; 75 dir = opendir(path); 76 struct dirent *dirent; 77 int count = 0; 78 while((dirent = readdir(dir)) != NULL) 79 80 if(dirent->d_type == 4) 81 count++; 82 83 closedir(dir); 84 return count; 85 86 87 // 是否是目录或目录下有目录 88 int is_dir(struct dirent *dirent) 89 90 char* a = dirent->d_name; 91 if(dirent->d_type == 8) 92 return 1; 93 if(dirent->d_type == 4) 94 95 if(dir_count(a) == 0) 96 return 2; 97 else 98 return dir_count(a); 99 100 101 102 // 获取用户名 103 char* file_user(uid_t st_uid,char* str) 104 105 struct passwd *user; 106 user = getpwuid(st_uid); 107 sprintf(str,"%s",user->pw_name); 108 return str; 109 110 111 // 获取组名 112 char* file_group(uid_t st_uid,char* str) 113 114 struct passwd *user; 115 user = getpwuid(st_uid); 116 struct group *grp; 117 grp = getgrgid(user->pw_gid); 118 sprintf(str,"%s",grp->gr_name); 119 return str; 120 121 122 // 获取文件大小 123 off_t file_size(struct stat buf) 124 125 off_t size = buf.st_size; 126 return size; 127 128 129 // 获取最后修改时间 130 char* file_time(time_t mt,char* str) 131 132 struct tm* t = localtime(&mt); 133 sprintf(str,"%d月 %02d %02d:%02d",t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min); 134 return str; 135 136 137 // 获取文件的数量 138 int file_count(char* path) 139 140 DIR *dir; 141 dir = opendir(path); 142 struct dirent *dirent; 143 int count = 0; 144 while((dirent = readdir(dir)) != NULL) 145 146 count++; 147 148 closedir(dir); 149 return count; 150 151 152 // 交换 153 void equal(LS *a,LS *b) 154 155 strcpy(a->mode,b->mode); 156 a->dir_num = b->dir_num; 157 strcpy(a->user,b->user); 158 strcpy(a->group,b->group); 159 a->size = b->size; 160 strcpy(a->time,b->time); 161 a->st_mode = b->st_mode; 162 strcpy(a->name,b->name); 163 164 165 // 排序 166 void sort(LS *info,int index) 167 168 LS *temp = (LS*)malloc(sizeof(LS)); 169 for(int i=index-1; i>0; i--) 170 171 for(int j=0; j<i; j++) 172 173 if(strcmp(info[i].name,info[j].name)<0) 174 175 equal(temp,&info[i]); 176 equal(&info[i],&info[j]); 177 equal(&info[j],temp); 178 179 180 181 182 183 // 输出结构体 184 void show_ls(LS *info,int index) 185 186 for(int i=0; i<index; i++) 187 188 //printf("%d: ",i); 189 printf("%s \033[0m",info[i].mode); 190 printf("%d ",info[i].dir_num); 191 printf("%s ",info[i].user); 192 printf("%s ",info[i].group); 193 printf("%5ld ",info[i].size); 194 printf(" %s ",info[i].time); 195 //printf("%d ",info[i].st_mode); 196 if(16893 == info[i].st_mode) 197 198 // 颜色 199 printf("\033[34m\033[1m%s\033[0m",info[i].name); 200 201 else if(33277 == info[i].st_mode) 202 203 printf("\033[32m\033[1m%s\033[0m",info[i].name); 204 205 else 206 207 printf("%s",info[i].name); 208 209 if(i < index) 210 printf("\n"); 211 212 //printf("循环结束\n"); 213 214 215 // 创建结构体,赋值 216 LS *create(struct stat buf,struct dirent *dirent) 217 218 LS* info = (LS*)malloc(sizeof(LS)); 219 char str[50] = ; 220 //puts(file_mode(buf.st_mode,str)); 221 strcpy(info->mode,file_mode(buf.st_mode,str)); 222 //puts(info->mode); 223 info->dir_num = is_dir(dirent); 224 strcpy(info->user,file_user(buf.st_uid,str)); 225 strcpy(info->group,file_group(buf.st_uid,str)); 226 info->size = file_size(buf); 227 strcpy(info->time,file_time(buf.st_mtime,str)); 228 info->st_mode = buf.st_mode; 229 strcpy(info->name,dirent->d_name); 230 231 return info; 232 233 234 int main(int argc,char* argv[]) 235 236 LS info[MAX_FILE_NUM]; 237 char* l = "-l"; 238 if(strcmp(argv[1],l) != 0) 239 240 printf("\"ls:无法识别的选项\"%s\"\n",argv[1]); 241 printf("请尝试执行\"ls --help\"来获取更多信息。\n"); 242 return 0; 243 244 char* a = "."; 245 char* b = ".."; 246 char* path = malloc(10000); 247 strcpy(path,"./"); // 只支持当前路径 248 int count = file_count(path); 249 250 DIR *dir; 251 dir = opendir(path); 252 struct dirent *dirent; 253 int index = 0; // 结构体下标 254 int blocks = 0; 255 for(int i=0; i<count; i++) 256 257 dirent = readdir(dir); 258 struct stat buf = ; 259 if(stat(dirent->d_name,&buf)) 260 261 perror("stat"); 262 return -1; 263 264 265 // 跳过特殊情况 266 if(strcmp(dirent->d_name,a)==0 || strcmp(dirent->d_name,b)==0) 267 continue; 268 blocks += buf.st_blocks; 269 //printf("%d\n",blocks); 270 info[index++] = *create(buf,dirent); 271 272 closedir(dir); 273 //printf("文件总数:%d\n",index); 274 //show_ls(info,index); 275 276 printf("总用量 %d\n",blocks/2); 277 sort(info,index); 278 show_ls(info,index); 279 return 0; 280
以上是关于高仿linux下的ls -l命令——C语言实现的主要内容,如果未能解决你的问题,请参考以下文章
Windows下的通用进程守护程序(持续更新中),高仿supervisor。
Windows下的通用进程守护程序(持续更新中),高仿supervisor。