ls命令的實現,ls命令實現

來源:互聯網
上載者:User

ls命令的實現,ls命令實現

實現linux下的ls命令,網上的代碼總是不是太完善。主要實現ls, ls -l兩個功能。分欄排序不是很滿意,linux原版分欄簡直贊,對齊的十分完美。這個代碼是在網上的基礎上改bug和修改完成。代碼更新在 https://github.com/ljfly/ls


主要函數void do_ls( int,char [] );

void dostat( char * ); /*get file info*/

void show_file_info( char *,struct stat * ); //ls -l 的輸出

void display_Ls( int cnt ) // ls 的分欄輸出

void mode_to_letters( int,char [] ); //檔案屬性: drwxr-xr-x

char *uid_to_name( uid_t ); /* 通過 uid 獲得對應的使用者名稱 */

char *gid_to_name( gid_t ); /* 通過 gid 獲得對應的組名 */

void getcolor( char * ); //擷取壓縮顏色

int get_file_type( char * ); /*get file type*/

int get_modify_time( char * ); /*get file last modify time*/

void getWidth(); //擷取螢幕寬度

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<sys/types.h>#include<sys/stat.h>#include<sys/ioctl.h>#include<dirent.h>#include<pwd.h>#include<grp.h>#include<unistd.h>/*head file*/#define LenOfName 256#define maxN 1005#define maxM 505#define maxL 105#define LenOfPath 256<<4#define LS 0      //ls#define LS_A 1    //ls -a#define LS_L 2    //ls -l#define LS_TMP 3  //ls /tmp#define LS_T 5    //ls -t/*define file*/void do_ls( int,char [] );void dostat( char * );                                      /*get file info*/void show_file_info( char *,struct stat * );  //ls -l 的輸出void mode_to_letters( int,char [] );            //檔案屬性:drwxr-xr-xchar *uid_to_name( uid_t );               /* 通過uid獲得對應的使用者名稱 */char *gid_to_name( gid_t );              /* 通過gid獲得對應的組名 */void getcolor( char * );                     int get_file_type( char * );             /*get file type*/int get_modify_time( char * );         /*get file last modify time*/void getWidth();int cmp1( const void * ,const void * );   //檔案名稱排序 int cmp2( const void * ,const void * );   //檔案修改時間排序 struct outputFile{    char FileName[ LenOfName ];    int modify_time ;     int file_type ;}Output[ maxN ],OutputPoint[ maxM ],Temp[ maxN+maxM ];int colormode,foreground,background;int terminalWidth ;void dostat( char *filename ){    struct stat info;    if( stat( filename,&info )==-1 ){        perror( filename );        printf("filename:%s\n", filename);    }    else{        char *pname = strrchr(filename, '/');        getcolor(filename );        show_file_info( pname+1,&info );    }    return ;}/*get file info*/void mode_to_letters( int mode,char str[] ){    strcpy( str,"----------" );        if( S_ISDIR( mode ) ) str[0] = 'd';    if( S_ISCHR( mode ) ) str[0] = 'c';    if( S_ISBLK( mode ) ) str[0] = 'b';        if( mode&S_IRUSR ) str[1] = 'r';    if( mode&S_IWUSR ) str[2] = 'w';    if( mode&S_IXUSR ) str[3] = 'x';        if( mode&S_IRGRP ) str[4] = 'r';    if( mode&S_IWGRP ) str[5] = 'w';    if( mode&S_IXGRP ) str[6] = 'x';        if( mode&S_IROTH ) str[7] = 'r';    if( mode&S_IWOTH ) str[8] = 'w';    if( mode&S_IXOTH ) str[9] = 'x';        return ;}char *uid_to_name( uid_t uid ){    struct passwd  *pw_ptr;    static char numstr[ 10 ];    if( (pw_ptr = getpwuid( uid ) )==NULL ){        sprintf(numstr,"%d",uid);        return numstr;    }    else{        return pw_ptr->pw_name;    }}/* 通過uid獲得對應的使用者名稱 */char *gid_to_name( gid_t gid ){    struct group  *grp_ptr;    static char numstr[ 10 ];    if( (grp_ptr = getgrgid( gid ) )==NULL ){        sprintf(numstr,"%d",gid);        return numstr;    }    else{        return grp_ptr->gr_name;    }}/* 通過gid獲得對應的組名 */int get_file_type( char *filename ){    struct stat info;    stat( filename,&info );    int file_type = 0;    file_type = info.st_mode & S_IFMT;    return file_type;}/*get file type*/int get_modify_time( char *filename ){    struct stat info;    stat( filename,&info );    int modify_time = 0;    modify_time = info.st_mtime;    return modify_time;}/*get file last modify time*/int isadir(char *str){    struct stat info;    return ( lstat(str,&info) != -1 && S_ISDIR(info.st_mode) );}/*判斷某檔案是否為目錄檔案*/void getWidth(){    char *tp;    struct winsize wbuf;    terminalWidth = 80;    if( isatty(STDOUT_FILENO) ){          if(ioctl(STDOUT_FILENO, TIOCGWINSZ, &wbuf) == -1 || wbuf.ws_col == 0){            if( tp = getenv("COLUMNS") )                terminalWidth = atoi( tp );        }        else            terminalWidth = wbuf.ws_col;    }    return ;}/******************************************************************    得出終端的寬度,預設寬度為80,如果擷取失敗,將啟用-1選項*******************************************************************/int cmp1( const void *p ,const void *q ){    char T1[ LenOfName ],T2[ LenOfName ];    strcpy( T1,(*(struct outputFile *)p).FileName );    strcpy( T2,(*(struct outputFile *)q).FileName );    int len1 = strlen( T1 );    int i ;    for( i=0;i<len1;i++ ){        if( T1[ i ]>='A' && T1[ i ]<='Z' ){            T1[ i ] = T1[ i ] - 'A' + 'a';        }    }    int len2 = strlen( T2 );    for( i=0;i<len2;i++ ){        if( T2[ i ]>='A' && T2[ i ]<='Z' ){            T2[ i ] = T2[ i ] - 'A' + 'a';        }    }    return strcmp( T1,T2 );}/********************************************************    檔案名稱排序  cmp1*********************************************************/int cmp2( const void *p,const void *q ){    return (*(struct outputFile *)p).modify_time < (*(struct outputFile *)q).modify_time ;}/********************************************************    檔案修改時間排序  cmp2*********************************************************/void show_file_info( char *filename,struct stat * info_p ){    char modestr[ 12 ];        mode_to_letters( info_p->st_mode,modestr );        printf("%s",modestr);    printf("%3d ",(int)info_p->st_nlink);    printf("%-2s ",uid_to_name(info_p->st_uid));    printf("%-1s ",gid_to_name(info_p->st_gid));    printf("%7ld ",(long)info_p->st_size);    printf("%.12s ",4+ctime(&info_p->st_mtime));    printf("\033[%d;%d;%dm%s\033[0m\n",colormode,foreground,background,filename);    return ;}/*******************************************************            ls -l 的輸出********************************************************/void getcolor( char *filename ){    struct stat info;    stat( filename,&info );    foreground = 30;    background = 1;    colormode = 0;    switch ( (info.st_mode & S_IFMT) ){        case S_IFREG:               /*regular 普通檔案 , 色*/            foreground = 30;            colormode = 1;            break;        case S_IFLNK:               /*symbolic link 連結檔案 , 青藍色*/            foreground = 36;            colormode = 1;            break;        case S_IFSOCK:              /*紫紅色*/              foreground = 35;            colormode = 1;            break;        case S_IFDIR:               /*directory 目錄檔案 , 藍色*/            foreground = 34;            break;        case S_IFBLK:               /*block special 塊裝置檔案 , 黃色*/            foreground = 33;            colormode = 1;            break;        case S_IFCHR:               /*character special 字元裝置檔案 , 黃色*/            foreground = 33;            colormode = 1;            break;        case S_IFIFO:               /*fifo  綠色*/            foreground = 32;            colormode = 1;            break;    }}/*******************************************************            給檔案添加顏色********************************************************/    void display_Ls( int cnt ){    int wordLenMax = 0;//the LenMax word    int wordRowNum = 0;//the amount of one row    int wordColNum = 0;//the amount of one col    int i , j;    for( i=0;i<cnt;i++ ){        if( i==0 ) wordLenMax = strlen( Output[ i ].FileName );        else wordLenMax = wordLenMax>strlen( Output[ i ].FileName )?wordLenMax:strlen( Output[ i ].FileName );    }    wordLenMax +=2;    wordRowNum = terminalWidth / wordLenMax;    if( cnt%wordRowNum==0 ) wordColNum = cnt / wordRowNum;    else wordColNum = cnt / wordRowNum + 1;    for( i=0;i<wordColNum;i++ ){        j = i;        while( j<cnt ){            getcolor( Output[ j ].FileName );            printf("\033[%d;%d;%dm%-15s\033[0m ",colormode,foreground,background,Output[ j ].FileName);            j += wordColNum;        }        printf("\n");    }    return ;}    /**********************************************************            ls的分欄輸出***********************************************************/void display_Ls_a( int cntPoint,int cnt ){    int CNT = 0;    int wordLenMax = 0;//the LenMax word    int wordRowNum = 0;//the amount of one row    int wordColNum = 0;//the amount of one col    int i , j;    for( i=0;i<cntPoint;i++ ){        strcpy( Temp[ CNT ].FileName,OutputPoint[ i ].FileName );        Temp[ CNT ].file_type = OutputPoint[ i ].file_type;        Temp[ CNT ].modify_time = OutputPoint[ i ].modify_time;        CNT ++;        wordLenMax = wordLenMax>strlen( OutputPoint[ i ].FileName )?wordLenMax:strlen( OutputPoint[ i ].FileName );    }    for( i=0;i<cnt;i++ ){        strcpy( Temp[ CNT ].FileName,Output[ i ].FileName );        Temp[ CNT ].file_type = Output[ i ].file_type;        Temp[ CNT ].modify_time = Output[ i ].modify_time;        CNT ++;        wordLenMax = wordLenMax>strlen( Output[ i ].FileName )?wordLenMax:strlen( Output[ i ].FileName );    }    wordLenMax += 2;    wordRowNum = terminalWidth / wordLenMax;    if( CNT%wordRowNum==0 ) wordColNum = CNT / wordRowNum;    else wordColNum = CNT / wordRowNum + 1;    for( i=0;i<wordColNum;i++ ){        j = i;        while( j<CNT ){            getcolor( Temp[ j ].FileName );            printf("\033[%d;%d;%dm%-15s\033[0m ",colormode,foreground,background,Temp[ j ].FileName);            j += wordColNum;        }        printf("\n");    }    return ;}/**********************************************************            ls -a 的分欄輸出***********************************************************/void display_Ls_tmp( int cnt ){    display_Ls( cnt );    return ;}/**********************************************************            ls /tmp 的分欄輸出***********************************************************/    void do_ls( int myJudge,char myOrder[] ){    char dirname[ maxL ];    if( myJudge!=LS_TMP   && myJudge!=LS_L){        strcpy( dirname,"." );    }    else {        strcpy( dirname,myOrder );    }    DIR * dir_ptr;    struct dirent *direntp;    int cntOutput = 0;    int cntOutputPoint = 0;    char full_path[256];    if( ( dir_ptr = opendir( dirname ) )==NULL ){        fprintf( stderr,"my god, i cannot open %s\n",dirname );    }    else{        if(myJudge!=LS_L ) {                while( (direntp = readdir( dir_ptr ) )!=NULL ){            if( direntp->d_name[ 0 ]=='.' ) {                strcpy( OutputPoint[ cntOutputPoint ].FileName,direntp->d_name );                OutputPoint[ cntOutputPoint ].file_type = get_file_type( OutputPoint[ cntOutputPoint ].FileName );                OutputPoint[ cntOutputPoint ].modify_time = get_modify_time( OutputPoint[ cntOutputPoint ].FileName );                cntOutputPoint ++;            }            else {                strcpy( Output[ cntOutput ].FileName,direntp->d_name );                Output[ cntOutput ].file_type = get_file_type( Output[ cntOutput ].FileName );                Output[ cntOutput ].modify_time = get_modify_time( Output[ cntOutput ].FileName );                cntOutput ++;            }        }     }           if( myJudge==LS_T ){            qsort( OutputPoint,cntOutputPoint,sizeof( OutputPoint[0] ),cmp2 );            qsort( Output,cntOutput,sizeof( Output[0] ),cmp2 );        }        else {            qsort( OutputPoint,cntOutputPoint,sizeof( OutputPoint[0] ),cmp1 );            qsort( Output,cntOutput,sizeof( Output[0] ),cmp1 );        }        /**********************************************************            預先處理輸出         ***********************************************************/        if( myJudge==LS||myJudge==LS_T ){            display_Ls( cntOutput );            closedir( dir_ptr );        }        /**********************************************************            ls  && ls -t        ***********************************************************/        else if( myJudge==LS_A ){            display_Ls_a( cntOutputPoint,cntOutput );            closedir( dir_ptr );        }        /**********************************************************            ls -a          ***********************************************************/        else if( myJudge==LS_L ){                    while( (direntp = readdir( dir_ptr ) )!=NULL ){            if( direntp->d_name[ 0 ]=='.' ) {                strcpy( OutputPoint[ cntOutputPoint ].FileName,direntp->d_name );                OutputPoint[ cntOutputPoint ].file_type = get_file_type( OutputPoint[ cntOutputPoint ].FileName );                OutputPoint[ cntOutputPoint ].modify_time = get_modify_time( OutputPoint[ cntOutputPoint ].FileName );                cntOutputPoint ++;            }            else {                strcpy(full_path, dirname);                int dir_len = strlen(dirname);                 strcpy(full_path + dir_len, direntp->d_name);                strcpy( Output[ cntOutput ].FileName,full_path );                Output[ cntOutput ].file_type = get_file_type( Output[ cntOutput ].FileName );                Output[ cntOutput ].modify_time = get_modify_time( Output[ cntOutput ].FileName );                cntOutput ++;            }        }            int i;            for( i=0;i<cntOutput;i++ )                dostat( Output[ i ].FileName );            closedir( dir_ptr );        }        /**********************************************************            ls -l          ***********************************************************/        else {            display_Ls_tmp( cntOutput );            closedir( dir_ptr );        }        /**********************************************************            ls /tmp         ***********************************************************/    }    return ;}/*sovle*/int main( int argc, char *argv[] ){    getWidth( );    int i ;    if( argc==1 ){        do_ls( LS,"ls" );    }    else{        int ord;        while( (ord = getopt(argc,argv,":lat"))!=-1 ){            switch( ord ){                case 'a':                    do_ls( LS_A,"ls-a" );                    break;                case 'l':{                        if(argc == 2)  do_ls( LS_L,"/" );                        else  {                         for( i= 2;i<argc;i++ ){                        if( argv[ i ][ 0 ]=='-' ) continue;                       printf("%s:\n",argv[ i ]);                       do_ls( LS_L,argv[ i ] );                       }                   }                    return;                }                    break;                case 't':                    do_ls( LS_T,"ls-t" );                    break;                default :                    break;            }        }        for( i=1;i<argc;i++ ){            if( argv[ i ][ 0 ]=='-' ) continue;            printf("%s:\n",argv[ i ]);            do_ls( LS_TMP,argv[ i ] );        }    }    return 0;}/*main*/



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.