Linux---Ls命令 初级实现

By xxx0624
Done:
    ls
    ls -a
    ls -l
    ls /tmp
    ls -R
    ls -t
    FileName color
    FileName output

  1 /*
  2 By xxx0624
  3 Done:
  4     ls
  5     ls -a
  6     ls -l
  7     ls /tmp
  8     ls -R
  9     ls -t
 10     FileName color
 11     FileName output
 12 */
 13 
 14 #include<stdio.h>
 15 #include<string.h>
 16 #include<stdlib.h>
 17 #include<sys/types.h>
 18 #include<sys/stat.h>
 19 #include<sys/ioctl.h>
 20 #include<dirent.h>
 21 #include<pwd.h>
 22 #include<grp.h>
 23 #include<unistd.h>
 24 /*head file*/
 25 
 26 
 27 #define LenOfName 256
 28 #define maxN 1005
 29 #define maxM 505
 30 #define maxL 105
 31 #define LenOfPath 256<<4
 32 #define LS 0      //ls
 33 #define LS_A 1    //ls -a
 34 #define LS_L 2    //ls -l
 35 #define LS_TMP 3  //ls /tmp
 36 #define LS_R 4    //ls -R
 37 #define LS_T 5    //ls -t
 38 /*define file*/
 39 
 40 
 41 void do_ls( int,char [] );
 42 void dostat( char * );
 43 void show_file_info( char *,struct stat * );
 44 void mode_to_letters( int,char [] );
 45 char *uid_to_name( uid_t );
 46 char *gid_to_name( gid_t );
 47 void getcolor( char * );
 48 int get_file_type( char * );
 49 int get_modify_time( char * );
 50 void getWidth();
 51 void display_R( char * );
 52 int cmp1( const void * ,const void * );
 53 int cmp2( const void * ,const void * );
 54 int cmp3( const void * ,const void * );
 55 
 56  
 57 struct outputFile{
 58     char FileName[ LenOfName ];
 59     int modify_time ; 
 60     int file_type ;
 61 }Output[ maxN ],OutputPoint[ maxM ],Temp[ maxN+maxM ];
 62 int colormode,foreground,background;
 63 int terminalWidth ;
 64 
 65 
 66 void dostat( char *filename ){
 67     struct stat info;
 68     if( stat( filename,&info )==-1 ){
 69         perror( filename );
 70     }
 71     else{
 72         getcolor( filename );
 73         show_file_info( filename,&info );
 74     }
 75     return ;
 76 }
 77 /*get file info*/
 78 
 79 
 80 void mode_to_letters( int mode,char str[] ){
 81     strcpy( str,"----------" );
 82     
 83     if( S_ISDIR( mode ) ) str[0] = 'd';
 84     if( S_ISCHR( mode ) ) str[0] = 'c';
 85     if( S_ISBLK( mode ) ) str[0] = 'b';
 86     
 87     if( mode&S_IRUSR ) str[1] = 'r';
 88     if( mode&S_IWUSR ) str[2] = 'w';
 89     if( mode&S_IXUSR ) str[3] = 'x';
 90     
 91     if( mode&S_IRGRP ) str[4] = 'r';
 92     if( mode&S_IWGRP ) str[5] = 'w';
 93     if( mode&S_IXGRP ) str[6] = 'x';
 94     
 95     if( mode&S_IROTH ) str[7] = 'r';
 96     if( mode&S_IWOTH ) str[8] = 'w';
 97     if( mode&S_IXOTH ) str[9] = 'x';
 98     
 99     return ;
100 }
101 
102 
103 char *uid_to_name( uid_t uid ){
104     struct passwd  *pw_ptr;
105     static char numstr[ 10 ];
106     if( (pw_ptr = getpwuid( uid ) )==NULL ){
107         sprintf(numstr,"%d",uid);
108         return numstr;
109     }
110     else{
111         return pw_ptr->pw_name;
112     }
113 }
114 char *gid_to_name( gid_t gid ){
115     struct group  *grp_ptr;
116     static char numstr[ 10 ];
117     if( (grp_ptr = getgrgid( gid ) )==NULL ){
118         sprintf(numstr,"%d",gid);
119         return numstr;
120     }
121     else{
122         return grp_ptr->gr_name;
123     }
124 }
125 /*get userid & groupid*/
126 
127 
128 int get_file_type( char *filename ){
129     struct stat info;
130     stat( filename,&info );
131     int file_type = 0;
132     file_type = info.st_mode & S_IFMT;
133     return file_type;
134 }
135 /*get file type*/
136 
137 
138 int get_modify_time( char *filename ){
139     struct stat info;
140     stat( filename,&info );
141     int modify_time = 0;
142     modify_time = info.st_mtime;
143     return modify_time;
144 }
145 /*get file last modify time*/
146 
147 
148 int isadir(char *str)
149 {
150     struct stat info;
151 
152     return ( lstat(str,&info) != -1 && S_ISDIR(info.st_mode) );
153 }
154 /*judge the file is or not a dir*/
155 
156 
157 void display_R( char *filename ){
158     char fullpath[ LenOfPath ];
159     struct outputFile Output2[ maxN ];
160     getcolor( filename );
161     printf("33[%d;%d;%dm%s33[0m :
",colormode,foreground,background,filename);
162     DIR * dir_ptr ;
163     struct dirent *direntp;
164     int cntTemp = 0;
165     int i ;
166     if( (dir_ptr = opendir( filename ) )==NULL ){
167         fprintf( stderr,"myls:cannot open %s
",filename );
168         closedir( dir_ptr );
169         return ;
170     }
171     else {
172         while( (direntp = readdir( dir_ptr ))!=NULL ){
173             if( strcmp( direntp->d_name,"." )==0||strcmp( direntp->d_name,".." )==0 )
174                 continue;
175             strcpy( Output2[ cntTemp ].FileName,direntp->d_name );
176             strcpy( Output[ cntTemp ].FileName,direntp->d_name );
177             cntTemp ++ ;
178         }
179         closedir( dir_ptr );
180         if( cntTemp>1 ){
181             qsort( Output2,cntTemp,sizeof( Output2[0] ),cmp1 );
182             qsort( Output,cntTemp,sizeof( Output[0] ),cmp1 );
183         }
184         display_Ls( cntTemp );
185         for( i=0;i<cntTemp;i++ ){
186             memset( fullpath,'',sizeof( fullpath ) );
187             strcpy( fullpath,filename );
188             strcat( fullpath,"/" );
189             strcat( fullpath,Output2[ i ].FileName );
190             if( isadir( fullpath ) )
191                 display_R( fullpath );
192         }
193     }
194     return ;
195 } 
196 /*active ls -R && Output */
197 
198 
199 void getWidth(){
200     char *tp;
201     struct winsize wbuf;
202     terminalWidth = 80;
203     if( isatty(STDOUT_FILENO) ){  
204         if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &wbuf) == -1 || wbuf.ws_col == 0){
205             if( tp = getenv("COLUMNS") )
206                 terminalWidth = atoi( tp );
207         }
208         else
209             terminalWidth = wbuf.ws_col;
210     }
211     return ;
212 }
213 /******************************************************************
214     得出终端的宽度,默认宽度为80,如果获取失败,将激活-1选项
215 *******************************************************************/
216 
217 
218 
219 int cmp1( const void *p ,const void *q ){
220     char T1[ LenOfName ],T2[ LenOfName ];
221     strcpy( T1,(*(struct outputFile *)p).FileName );
222     strcpy( T2,(*(struct outputFile *)q).FileName );
223     int len1 = strlen( T1 );
224     int i ;
225     for( i=0;i<len1;i++ ){
226         if( T1[ i ]>='A' && T1[ i ]<='Z' ){
227             T1[ i ] = T1[ i ] - 'A' + 'a';
228         }
229     }
230     int len2 = strlen( T2 );
231     for( i=0;i<len2;i++ ){
232         if( T2[ i ]>='A' && T2[ i ]<='Z' ){
233             T2[ i ] = T2[ i ] - 'A' + 'a';
234         }
235     }
236     return strcmp( T1,T2 );
237 }
238 /********************************************************
239     文件名排序  cmp1
240 *********************************************************/
241 
242 
243 
244 int cmp2( const void *p,const void *q ){
245     return (*(struct outputFile *)p).file_type < (*(struct outputFile *)q).file_type ;
246 }
247 /********************************************************
248     文件类型排序  cmp2
249 *********************************************************/
250 
251 
252 
253 int cmp3( const void *p,const void *q ){
254     return (*(struct outputFile *)p).modify_time < (*(struct outputFile *)q).modify_time ;
255 }
256 /********************************************************
257     文件修改时间排序  cmp3
258 *********************************************************/
259 
260 
261 
262 void show_file_info( char *filename,struct stat * info_p ){
263     char modestr[ 12 ];
264     
265     mode_to_letters( info_p->st_mode,modestr );
266     
267     printf("%s",modestr);
268     printf("%4d ",(int)info_p->st_nlink);
269     printf("%-8s ",uid_to_name(info_p->st_uid));
270     printf("%-8s ",gid_to_name(info_p->st_gid));
271     printf("%8ld ",(long)info_p->st_size);
272     printf("%.12s ",4+ctime(&info_p->st_mtime));
273     printf("33[%d;%d;%dm%s33[0m
",colormode,foreground,background,filename);
274     return ;
275 }
276 /*******************************************************
277             ls -l 的输出
278 ********************************************************/
279 
280 
281 
282 void getcolor( char *filename ){
283     struct stat info;
284     stat( filename,&info );
285     foreground = 37;
286     background = 1;
287     colormode = 0;
288     switch ( (info.st_mode & S_IFMT) ){
289         case S_IFREG:               /*regular 普通文件 , 白色*/
290             foreground = 37;
291             break;
292         case S_IFLNK:               /*symbolic link 链接文件 , 青蓝色*/
293             foreground = 36;
294             colormode = 1;
295             break;
296         case S_IFSOCK:              /*紫红色*/  
297             foreground = 35;
298             colormode = 1;
299             break;
300         case S_IFDIR:               /*directory 目录文件 , 蓝色*/
301             foreground = 34;
302             break;
303         case S_IFBLK:               /*block special 块设备文件 , 黄色*/
304             foreground = 33;
305             colormode = 1;
306             break;
307         case S_IFCHR:               /*character special 字符设备文件 , 黄色*/
308             foreground = 33;
309             colormode = 1;
310             break;
311         case S_IFIFO:               /*fifo  绿色*/
312             foreground = 32;
313             colormode = 1;
314             break;
315     }
316 }
317 /*******************************************************
318             给文件添加颜色
319 ********************************************************/  
320 
321 
322   
323 void display_Ls( int cnt ){
324     int wordLenMax = 0;//the LenMax word
325     int wordRowNum = 0;//the amount of one row
326     int wordColNum = 0;//the amount of one col
327     int i , j;
328     for( i=0;i<cnt;i++ ){
329         if( i==0 ) wordLenMax = strlen( Output[ i ].FileName );
330         else wordLenMax = wordLenMax>strlen( Output[ i ].FileName )?wordLenMax:strlen( Output[ i ].FileName );
331     }
332     wordLenMax += 2;
333     wordRowNum = terminalWidth / wordLenMax;
334     if( cnt%wordRowNum==0 ) wordColNum = cnt / wordRowNum;
335     else wordColNum = cnt / wordRowNum + 1;
336     for( i=0;i<wordColNum;i++ ){
337         j = i;
338         while( j<cnt ){
339             getcolor( Output[ j ].FileName );
340             printf("33[%d;%d;%dm%-15s33[0m ",colormode,foreground,background,Output[ j ].FileName);
341             j += wordColNum;
342         }
343         printf("
");
344     }
345     return ;
346 }    
347 /**********************************************************
348             ls的分栏输出
349 ***********************************************************/
350 
351 
352 
353 void display_Ls_a( int cntPoint,int cnt ){
354     int CNT = 0;
355     int wordLenMax = 0;//the LenMax word
356     int wordRowNum = 0;//the amount of one row
357     int wordColNum = 0;//the amount of one col
358     int i , j;
359     for( i=0;i<cntPoint;i++ ){
360         strcpy( Temp[ CNT ].FileName,OutputPoint[ i ].FileName );
361         Temp[ CNT ].file_type = OutputPoint[ i ].file_type;
362         Temp[ CNT ].modify_time = OutputPoint[ i ].modify_time;
363         CNT ++;
364         wordLenMax = wordLenMax>strlen( OutputPoint[ i ].FileName )?wordLenMax:strlen( OutputPoint[ i ].FileName );
365     }
366     for( i=0;i<cnt;i++ ){
367         strcpy( Temp[ CNT ].FileName,Output[ i ].FileName );
368         Temp[ CNT ].file_type = Output[ i ].file_type;
369         Temp[ CNT ].modify_time = Output[ i ].modify_time;
370         CNT ++;
371         wordLenMax = wordLenMax>strlen( Output[ i ].FileName )?wordLenMax:strlen( Output[ i ].FileName );
372     }
373     wordLenMax += 2;
374     wordRowNum = terminalWidth / wordLenMax;
375     if( CNT%wordRowNum==0 ) wordColNum = CNT / wordRowNum;
376     else wordColNum = CNT / wordRowNum + 1;
377     for( i=0;i<wordColNum;i++ ){
378         j = i;
379         while( j<CNT ){
380             getcolor( Temp[ j ].FileName );
381             printf("33[%d;%d;%dm%-15s33[0m ",colormode,foreground,background,Temp[ j ].FileName);
382             j += wordColNum;
383         }
384         printf("
");
385     }
386     return ;
387 }
388 /**********************************************************
389             ls -a 的分栏输出
390 ***********************************************************/
391 
392 
393 
394 void display_Ls_tmp( int cnt ){
395     display_Ls( cnt );
396     return ;
397 }
398 /**********************************************************
399             ls /tmp 的分栏输出
400 ***********************************************************/
401 
402 
403 
404 void display_Ls_R( char *filename ){
405     char fullpath[ LenOfPath ];
406     strcpy( fullpath,get_current_dir_name() );
407     strcat( fullpath,"/" );
408     strcat( fullpath,filename );
409     display_R( fullpath );
410     return ;
411 }
412 /**********************************************************
413             ls -R 的分栏输出
414 ***********************************************************/   
415 
416 
417     
418 void do_ls( int myJudge,char myOrder[] ){
419     if( myJudge==LS_R ){
420         display_Ls_R( "." );
421         return ;
422     }
423     /**********************************************************
424             ls -R   
425     ***********************************************************/
426     char dirname[ maxL ];
427     if( myJudge!=LS_TMP ){
428         strcpy( dirname,"." );
429     }
430     else {
431         strcpy( dirname,myOrder );
432     }
433     DIR * dir_ptr;
434     struct dirent *direntp;
435     int cntOutput = 0;
436     int cntOutputPoint = 0;
437     if( ( dir_ptr = opendir( dirname ) )==NULL ){
438         fprintf( stderr,"myls:cannot open %s
",dirname );
439     }
440     else{
441         while( (direntp = readdir( dir_ptr ) )!=NULL ){
442             if( direntp->d_name[ 0 ]=='.' ) {
443                 strcpy( OutputPoint[ cntOutputPoint ].FileName,direntp->d_name );
444                 OutputPoint[ cntOutputPoint ].file_type = get_file_type( OutputPoint[ cntOutputPoint ].FileName );
445                 OutputPoint[ cntOutputPoint ].modify_time = get_modify_time( OutputPoint[ cntOutputPoint ].FileName );
446                 cntOutputPoint ++;
447             }
448             else {
449                 strcpy( Output[ cntOutput ].FileName,direntp->d_name );
450                 Output[ cntOutput ].file_type = get_file_type( Output[ cntOutput ].FileName );
451                 Output[ cntOutput ].modify_time = get_modify_time( Output[ cntOutput ].FileName );
452                 cntOutput ++;
453             }
454         }
455         
456         if( myJudge==LS_T ){
457             qsort( OutputPoint,cntOutputPoint,sizeof( OutputPoint[0] ),cmp3 );
458             qsort( Output,cntOutput,sizeof( Output[0] ),cmp3 );
459         }
460         else {
461             qsort( OutputPoint,cntOutputPoint,sizeof( OutputPoint[0] ),cmp1 );
462             qsort( Output,cntOutput,sizeof( Output[0] ),cmp1 );
463         }
464         /**********************************************************
465             预处理输出 
466         ***********************************************************/
467         if( myJudge==LS||myJudge==LS_T ){
468             display_Ls( cntOutput );
469             closedir( dir_ptr );
470         }
471         /**********************************************************
472             ls  && ls -t
473         ***********************************************************/
474         else if( myJudge==LS_A ){
475             display_Ls_a( cntOutputPoint,cntOutput );
476             closedir( dir_ptr );
477         }
478         /**********************************************************
479             ls -a  
480         ***********************************************************/
481         else if( myJudge==LS_L ){
482             int i;
483             for( i=0;i<cntOutput;i++ )
484                 dostat( Output[ i ].FileName );
485             closedir( dir_ptr );
486         }
487         /**********************************************************
488             ls -l  
489         ***********************************************************/
490         else {
491             display_Ls_tmp( cntOutput );
492             closedir( dir_ptr );
493         }
494         /**********************************************************
495             ls /tmp 
496         ***********************************************************/
497     }
498     return ;
499 }/*sovle*/
500 
501 
502 int main( int argc, char *argv[] ){
503     getWidth( );
504     int i ;
505     if( argc==1 ){
506         do_ls( LS,"ls" );
507     }
508     else{
509         int ord;
510         while( (ord = getopt(argc,argv,":laRt"))!=-1 ){
511             switch( ord ){
512                 case 'a':
513                     do_ls( LS_A,"ls-a" );
514                     break;
515                 case 'l':
516                     do_ls( LS_L,"ls-l" );
517                     break;
518                 case 'R':
519                     do_ls( LS_R,"ls-R" );
520                     break;
521                 case 't':
522                     do_ls( LS_T,"ls-t" );
523                     break;
524                 default :
525                     break;
526             }
527         }
528         for( i=1;i<argc;i++ ){
529             if( argv[ i ][ 0 ]=='-' ) continue;
530             printf("%s:
",argv[ i ]);
531             do_ls( LS_TMP,argv[ i ] );
532         }
533     }
534     return 0;
535 }
536 /*main*/
View Code
原文地址:https://www.cnblogs.com/xxx0624/p/3411841.html