linux c類比ls命令

來源:互聯網
上載者:User
/* 類比ls命令,實現參數-tariRl.有些代碼重複出現,可改進 可以在該程式的基礎上增加參數,該程式思路清晰,容易擴充 */#include<stdio.h>#include<string.h>#include<stdlib.h>#include<sys/types.h>#include<unistd.h>#include<sys/stat.h>#include<dirent.h>#include<sys/ioctl.h>#include<pwd.h>#include<grp.h>#define LL (1<<0)  /*帶l參數標誌*/#define IL (1<<1)  /*帶i參數標誌*/#define RU (1<<2)  /*帶R參數標誌*/#define TL (1<<16) /*帶t參數標誌*/#define AL (1<<17) /*帶a參數標誌*/#define RL (1<<18) /*帶r參數標誌*/#define LENGTH 500 /*字串最大長度*/#define MAX_FILE_COUNT 500/*檔案清單最大長度*//*函式宣告*/void error(char* error_message,int line);void display(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode);int file_list(char* path,struct stat* stalist,char (*namelist)[LENGTH],int mode);void display_simply(char (*namelist)[LENGTH],int n);void display_LL(struct stat * stalist,char (*namelist)[LENGTH],int n);void display_IL(struct stat * stalist,char (*namelist)[LENGTH],int n);void display_LL_IL(struct stat * stalist,char (*namelist)[LENGTH],int n);void display_RU(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode);void display_RU_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode);void display_RU_IL(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode);void display_RU_IL_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode);/*主函數*/int main(int argc,char **argv){    int i,j;    /*mode的前16個位用來標誌那些能影響顯示的參數,16位之後的位用來標誌不影響輸出格式的參數。這個程式只用到了0-3位,16-18位,如果要在該程式的基礎上增加參數,可以用其他沒有使用的位。    mode的第0位為1表示帶l參數,mode的第1位為1表示帶i參數,mode的第2位為1表示帶R參數,mode的第16位為1表示帶t參數,mode的第17位為1表示帶a參數,mode的第18位為1表示帶r參數*/    int mode=0;    char error_message[LENGTH]={0};/*錯誤資訊*/    char path[LENGTH]={0};/*路徑*/    struct stat stalist[MAX_FILE_COUNT];/*檔案詳細資料數組*/    char  namelist[MAX_FILE_COUNT][LENGTH];/*檔案名稱數組*/    int flag=0;/*判斷是否指定了目錄*/    int count;/*檔案個數*/    /*解析參數*/    for(i=1;i<argc;i++){        if(argv[i][0]=='-'){/*如果是選項參數*/    for(j=1;j<strlen(argv[i]);j++){if(argv[i][j]=='l')    mode=mode|LL;else if(argv[i][j]=='i')    mode=mode|IL;else if(argv[i][j]=='R')    mode=mode|RU;else if(argv[i][j]=='r')    mode=mode|RL;else if(argv[i][j]=='a')    mode=mode|AL;else if(argv[i][j]=='t')    mode=mode|TL;else{    snprintf(error_message,LENGTH,"no option of %c",argv[i][j]);    error(error_message,__LINE__);}    }}else{/*參數為目錄或檔案*/    if(flag==1)error("can not specify more then two dir or file",__LINE__);    elseflag=1;            if(argv[i][0]!='/'){/*相對路徑*/strcat(path,get_current_dir_name());strcat(path,"/");strncat(path,argv[i],strlen(argv[i]));    }else/*絕對路徑*/strcpy(path,argv[i]);}    }    if(flag==0)/*未指定任何目錄或檔案,則使用預設目前的目錄*/strcat(path,get_current_dir_name());    /*根據mode擷取指定目錄下的檔案*/    count=file_list(path,stalist,namelist,mode);        /*根據mode顯示檔案*/    display(stalist,namelist,count,mode);    return 0;}/*擷取檔案清單*/int file_list(char* path,struct stat* stalist,char (*namelist)[LENGTH],int mode){    int i=0,index,j,k;    DIR *dir;    struct dirent *ptr;    char str[LENGTH];    char nametemp[LENGTH];    struct stat statemp;    if(stat(path,&stalist[0])<0){//puts(path);error("the specify file is not exist",__LINE__);    }    if(S_ISDIR(stalist[0].st_mode)){/*如果該路徑指向的是一個目錄*/        if((dir=opendir(path))==NULL){/*開啟目錄*/    sprintf(str,"can not open %s",path);    error(str,__LINE__);}        chdir(path);/*改變當前工作目錄到path*/        i=0;while((ptr=readdir(dir))!=NULL){/*依次讀取目錄下的所有檔案*/    if(ptr->d_name[0]=='.' && !(mode & AL))/*忽略隱藏檔案*/continue;    /*按字母順序插入到stalist數組及namelist數組*/    for(j=i;j>0;j--){if(strcmp(ptr->d_name,namelist[j-1])>0)    break;    }    for(k=i;k>j;k--){strcpy(namelist[k],namelist[k-1]);stalist[k]=stalist[k-1];    }            strcpy(namelist[j],ptr->d_name);            stat(ptr->d_name,&stalist[j]);    i++;    if(i==MAX_FILE_COUNT)error("file count beyond MAX_FILE_COUNT",__LINE__);}closedir(dir);    }else{j=strlen(path)-1;while(j>=0 && path[j]!='/'){    j--;}if(j<0)    error("path error",__LINE__);j++;k=0;        while(path[j]){    namelist[0][k]=path[j];            j++;     k++;}        namelist[0][k]=0;        return 1;    }    if(mode & TL){/*按檔案修改時間排序*/for(j=0;j<i;j++){    index=j;    for(k=j+1;k<i;k++)if(stalist[index].st_mtime<stalist[k].st_mtime){    index=k;}    statemp=stalist[j];    stalist[j]=stalist[index];    stalist[index]=statemp;    strcpy(nametemp,namelist[j]);    strcpy(namelist[j],namelist[index]);    strcpy(namelist[index],nametemp);}    }    if(mode & RL){/*反序排列*/for(j=0;j<i/2;j++){    strcpy(nametemp,namelist[j]);    strcpy(namelist[j],namelist[i-j-1]);    strcpy(namelist[i-j-1],nametemp);    statemp=stalist[j];    stalist[j]=stalist[i-j-1];    stalist[i-j-1]=statemp;}    }    return i;}/*根據mode選擇不同的函數進行顯示*/void display(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode){    /*使mode的高16位為0*/    int m = mode & ((1<<16)-1);    switch(m){case 0:    display_simply(namelist,n);    break;case 1:    display_LL(stalist,namelist,n);    break;case 2:    display_IL(stalist,namelist,n);    break;case 3:    display_LL_IL(stalist,namelist,n);    break;case 4:    display_RU(stalist,namelist,n,mode);    break;case 5:    display_RU_LL(stalist,namelist,n,mode);    break;        case 6:    display_RU_IL(stalist,namelist,n,mode);    break;case 7:    display_RU_IL_LL(stalist,namelist,n,mode);    break;    }}/*不帶顯示選項,簡單顯示檔案名稱*/void display_simply(char (*namelist)[LENGTH],int n){    int i,maxlength=0,cols;    struct winsize ts;    for(i=0;i<n;i++)if(strlen(namelist[i])>maxlength)    maxlength=strlen(namelist[i]);    /*擷取終端的大小*/    ioctl(STDIN_FILENO,TIOCGWINSZ,&ts);    cols=ts.ws_col;    cols/=(maxlength+1);    //lines=ts.ws_row;    for(i=0;i<n;i++){       if(i!=0 && i%cols==0)   puts("");       printf("%*s",-(maxlength+1),namelist[i]);    }    putchar('\n');}/*-l 參數,顯示詳細檔案資訊*/void display_LL(struct stat * stalist,char (*namelist)[LENGTH],int n){    int i,mode;    char* str;    for(i=0;i<n;i++){        mode=stalist[i].st_mode;        if(S_ISDIR(mode))    printf("d");else    printf("-");if(mode & (1<<8))    printf("r");else    printf("-");        if(mode & (1<<7))    printf("w");else    printf("-");        if(mode & (1<<6))    printf("x");else    printf("-");        if(mode & (1<<5))    printf("r");else    printf("-");        if(mode & (1<<4))    printf("w");else    printf("-");        if(mode & (1<<3))    printf("x");else    printf("-");        if(mode & (1<<2))    printf("r");else    printf("-");        if(mode & (1<<1))    printf("w");else    printf("-");        if(mode & (1<<0))    printf("x");else    printf("-");printf(" %-3d",stalist[i].st_nlink);printf(" %-6s",getpwuid(stalist[i].st_uid)->pw_name);printf(" %-6s",getgrgid(stalist[i].st_gid)->gr_name);printf(" %-10d",stalist[i].st_size);str=ctime(&stalist[i].st_mtime);str[strlen(str)-2]=0;printf(" %s",str);printf(" %s\n",namelist[i]);    }}/*-i 參數,顯示檔案名稱及節點號*/void display_IL(struct stat* stalist,char (*namelist)[LENGTH],int n){    int i,maxlength=0,cols;    struct winsize ts;    for(i=0;i<n;i++)if(strlen(namelist[i])>maxlength)    maxlength=strlen(namelist[i]);    /*擷取終端的大小*/    ioctl(STDIN_FILENO,TIOCGWINSZ,&ts);    cols=ts.ws_col;    cols/=(maxlength+9);    //lines=ts.ws_row;        for(i=0;i<n;i++){       if(i!=0 && i%cols==0)   puts("");       printf("%-8d ",stalist[i].st_ino);       printf("%*s",-(maxlength+1),namelist[i]);    }    putchar('\n');   }/*-li 參數,顯示詳細檔案資訊和節點號*/void display_LL_IL(struct stat * stalist,char (*namelist)[LENGTH],int n){    int i,mode;    char* str;    for(i=0;i<n;i++){        printf("%-8d ",stalist[i].st_ino);        mode=stalist[i].st_mode;        if(S_ISDIR(mode))    printf("d");else    printf("-");if(mode & (1<<8))    printf("r");else    printf("-");        if(mode & (1<<7))    printf("w");else    printf("-");        if(mode & (1<<6))    printf("x");else    printf("-");        if(mode & (1<<5))    printf("r");else    printf("-");        if(mode & (1<<4))    printf("w");else    printf("-");        if(mode & (1<<3))    printf("x");else    printf("-");        if(mode & (1<<2))    printf("r");else    printf("-");        if(mode & (1<<1))    printf("w");else    printf("-");        if(mode & (1<<0))    printf("x");else    printf("-");printf(" %-3d",stalist[i].st_nlink);printf(" %-6s",getpwuid(stalist[i].st_uid)->pw_name);printf(" %-6s",getgrgid(stalist[i].st_gid)->gr_name);printf(" %-10d",stalist[i].st_size);str=ctime(&stalist[i].st_mtime);str[strlen(str)-2]=0;printf(" %s",str);printf(" %s\n",namelist[i]);    }}/*-R 參數,簡單顯示所有檔案,包括目錄下面的子目錄*/void display_RU(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode){    int i,count;    char path[LENGTH]={0},temp[LENGTH]={0};    struct stat sta[MAX_FILE_COUNT];    char name[MAX_FILE_COUNT][LENGTH];    puts(get_current_dir_name());    display_simply(namelist,n);    putchar('\n');    strcpy(path,get_current_dir_name());        for(i=0;i<n;i++){        if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0)         continue;if(S_ISDIR(stalist[i].st_mode)){    strcpy(temp,path);    strcat(path,"/");    strcat(path,namelist[i]);    count=file_list(path,sta,name,mode);    display_RU(sta,name,count,mode);            strcpy(path,temp);}    }}/*-Rl 參數,顯示所有檔案,包括目錄下面的子目錄的詳細資料*/void display_RU_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode){    int i,count;    char path[LENGTH]={0},temp[LENGTH]={0};    struct stat sta[MAX_FILE_COUNT];    char name[MAX_FILE_COUNT][LENGTH];    puts(get_current_dir_name());    display_LL(stalist,namelist,n);    putchar('\n');    strcpy(path,get_current_dir_name());        for(i=0;i<n;i++){if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0)         continue;if(S_ISDIR(stalist[i].st_mode)){    strcpy(temp,path);    strcat(path,"/");    strcat(path,namelist[i]);    count=file_list(path,sta,name,mode);    display_RU_LL(sta,name,count,mode);    strcpy(path,temp);}    }}/*-Ri 參數,簡單顯示所有檔案,包括目錄下的子目錄,及節點號*/void display_RU_IL(struct stat* stalist,char (*namelist)[LENGTH],int n,int mode){    int i,count;    char path[LENGTH]={0},temp[LENGTH]={0};    struct stat sta[MAX_FILE_COUNT];    char name[MAX_FILE_COUNT][LENGTH];    puts(get_current_dir_name());    display_IL(stalist,namelist,n);    putchar('\n');    strcpy(path,get_current_dir_name());        for(i=0;i<n;i++){if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0)         continue;if(S_ISDIR(stalist[i].st_mode)){    strcpy(temp,path);    strcat(path,"/");    strcat(path,namelist[i]);    count=file_list(path,sta,name,mode);    display_RU_IL(sta,name,count,mode);    strcpy(path,temp);}    }}/*-Ril 參數,顯示所有檔案,包括目錄下面的子目錄的詳細資料,及節點號*/void display_RU_IL_LL(struct stat * stalist,char (*namelist)[LENGTH],int n,int mode){    int i,count;    char path[LENGTH]={0},temp[LENGTH]={0};    struct stat sta[MAX_FILE_COUNT];    char name[MAX_FILE_COUNT][LENGTH];    puts(get_current_dir_name());    display_LL_IL(stalist,namelist,n);    putchar('\n');    strcpy(path,get_current_dir_name());        for(i=0;i<n;i++){if(strcmp(namelist[i],".")==0 || strcmp(namelist[i],"..")==0)         continue;if(S_ISDIR(stalist[i].st_mode)){    strcpy(temp,path);    strcat(path,"/");    strcat(path,namelist[i]);    count=file_list(path,sta,name,mode);    display_RU_IL_LL(sta,name,count,mode);    strcpy(path,temp);}    }}//錯誤處理函數void error(char* error_message,int line){    char str[5];    sprintf(str,"%d:",line);    strcat(str,error_message);    perror(str);    exit(EXIT_FAILURE);}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.