码迷,mamicode.com
首页 > 编程语言 > 详细

高仿linux下的ls -l命令——C语言实现

时间:2019-07-27 13:12:41      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:nta   help   col   and   http   大小   show   sizeof   扩展   

主要用到的函数可以参考头文件,仅仅支持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语言实现

标签:nta   help   col   and   http   大小   show   sizeof   扩展   

原文地址:https://www.cnblogs.com/ikaros-521/p/11254332.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!