高仿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。

linux:基本指令

linux:基本指令

Linux / MacOS 修改 ls 显示年月日的时间格式

Linux / MacOS 修改 ls 显示年月日的时间格式