系统编程之模拟ls -l命令

如果是做作业的孩子找到了这里,希望不要直接copy,供参考,其实我做的也不一定好嘻嘻。

其实这里,我考虑了输出的排序问题, 所以用了数组保存,可能感觉挺繁琐的 = =。一般情况下大家都是直接while输出。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<dirent.h>
#include<sys/types.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<pwd.h>
#include<grp.h>
#include<time.h>
#define BUFFERSIZE 512
char* info[200][7];
int num;
int allSize;
int n_year;
int isDir;
void getCode(int mode,char *code){
    switch(mode){
        case 7: code[0] = 'r';
            code[1] = 'w';
            code[2] = 'x';
            break;
        case 6: code[0] = 'r';
                        code[1] = 'w';
                        code[2] = '-';
                        break;
        case 5: code[0] = 'r';
                        code[1] = '-';
                        code[2] = 'x';
                        break;
        case 4: code[0] = 'r';
                        code[1] = '-';
                        code[2] = '-';
                        break;
        case 3: code[0] = '-';
                        code[1] = 'w';
                        code[2] = 'x';
                        break;
        case 2: code[0] = '-';
                        code[1] = 'w';
                        code[2] = '-';
                        break;
        case 1: code[0] = '-';
                        code[1] = '-';
                        code[2] = 'x';
                        break;
        default: code[0] = '-';
                         code[1] = '-';
                         code[2] = '-';
                         break;
    };
    code[3]='';
}

void getType(int i,mode_t mode){
        if (S_ISREG(mode)){  
            info[i][0][0] = '-';
        }else if(S_ISDIR(mode)){  
            info[i][0][0] = 'd'; 
        }else if(S_ISBLK(mode)){  
            info[i][0][0] = 'b'; 
        }else if(S_ISCHR(mode)){  
            info[i][0][0] = 'c';
        }else if(S_ISFIFO(mode)){  
        info[i][0][0] = 'p';
        }else if(S_ISLNK(mode)){  
            info[i][0][0] = 'l';  
        }else if(S_ISSOCK(mode)){  
            info[i][0][0] = 's';
        }else{
        info[i][0][0] = '-';
    }     
}

void getNumber(int num,char *nlink){
    int i=0;
    int cur=num;
    while(cur > 0){
        cur = cur/10;
        i++;
    }
    cur = i;
    if(num == 0){
        nlink[0] = '0';
        nlink[1] = '';
        return;
    }
    while(num > 0){
        nlink[i-1] = (num%10)+'0';
        num = num / 10;
        i--;
    }
    nlink[cur]='';
}
void getOwner(int id,char *owner){
    struct passwd *data;
    data = getpwuid(id);
    strcpy(owner,data->pw_name);
}
void getGroup(int id,char *grp){
        struct group *data;
        data = getgrgid(id);
        strcpy(grp,data->gr_name);
}
void getTime(time_t btime,char *atime){
    char *mon[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
    struct tm *p;
    char clock[5];
    atime[0]='';
    p=localtime(&btime);
    if(n_year == p->tm_year){
        strcat(atime,mon[p->tm_mon]);
                strcat(atime," ");
                getNumber(p->tm_mday,clock);
                strcat(atime,clock);
        strcat(atime," ");

        getNumber(p->tm_hour,clock);
        if(p->tm_hour < 10){
            strcat(atime,"0");
        }
        strcat(atime,clock);
        strcat(atime,":");
        if(p->tm_min < 10){
            strcat(atime,"0");
        }
        getNumber(p->tm_min,clock);
        strcat(atime,clock);
    } else {    
        strcat(atime,mon[p->tm_mon]);
        strcat(atime," ");
        getNumber(p->tm_mday,clock);
        strcat(atime,clock);
        
        strcat(atime," ");
        getNumber(p->tm_year+1900,clock);
        strcat(atime,clock);
    }
}

void calBlock(int size,mode_t mode){
    if(S_ISLNK(mode)){
            return;
        }
    int blocks = size / 4096;
    if(size % 4096 > 0){
        blocks++;
    }
    blocks*=4;
    allSize+=blocks;
}
int addInfo(int x,char *path,char *name){
    int i;
    struct stat buf;
    char code[12],code1[5];
    char nlink[12],owner[80],group[80];
    char time[30],fullpath[100],linkname[100];
    linkname[0]='';
    fullpath[0]='';
    
    if(isDir==0){
        strcpy(fullpath,path);
        name = (char*)malloc(100*sizeof(char));
        strcpy(name,strrchr(path,'/')+1);
    } else {
        strcat(fullpath,path);
        strcat(fullpath,"/");
        strcat(fullpath,name);
    }
    
    //get code of power    
    code[1]='';
    for(i=0;i<=6;i++){
        info[x][i] = (char*)malloc(100*sizeof(char));
    }
            
    lstat(fullpath,&buf);
    getCode((buf.st_mode>>6)&7,code1);
    strcat(code,code1);

    getCode((buf.st_mode>>3)&7,code1);
    strcat(code,code1);

    getCode(buf.st_mode&7,code1);
    strcat(code,code1);
    
    code[10]='.';
    code[11]='';
    strcpy(info[x][0],code);
    
    getType(x,buf.st_mode);
    
    //get num of number
    getNumber(buf.st_nlink,nlink);
    strcpy(info[x][1],nlink);
    
    //get owner
    getOwner(buf.st_uid,owner);
    strcpy(info[x][2],owner);    

    //get group
    getGroup(buf.st_gid,group);
    strcpy(info[x][3],group);
    
    //get size
    calBlock(buf.st_size,buf.st_mode);
    getNumber(buf.st_size,nlink);
    strcpy(info[x][4],nlink);
    
    //get time
    getTime(buf.st_mtime,time);
    strcpy(info[x][5],time);
    
    //get name of file
    if(S_ISLNK(buf.st_mode)){
        strcpy(info[x][6],name);
        strcat(info[x][6]," -> ");
        readlink(fullpath,linkname,100);
        strcat(info[x][6],linkname);
        
    }else{
        strcpy(info[x][6],name);
    }
}

int readList(char *path){
    DIR *dir;
    struct dirent *p;
    struct stat buf;
    time_t now=time(NULL);
    struct tm *n = localtime(&now);
    n_year = n->tm_year;
    num=0;
    allSize=0;
    if((dir=opendir(path)) == NULL && access(path,F_OK)!=0){
        return -1;
    } else if(dir==NULL && access(path,F_OK) == 0){
        addInfo(num,path,NULL);
        isDir=0;
        num++;
        return;
    }
    isDir=1;
    while((p=readdir(dir)) != NULL){
            if(strcmp(p->d_name,".")==0 || strcmp(p->d_name,"..")==0 || p->d_name[0]=='.')
                        continue;
                   addInfo(num,path,p->d_name);        
                num++;
    }
}

void sort(){
    int i,j,k,t;
    char temp[7][200];
    for(i=num-1;i>1;i--){
        for(j=0;j<=i-1;j++){
            t = strcmp(info[j][6],info[j+1][6]);
            if(t >= 1){
                for(k=0;k<=6;k++){
                    strcpy(temp[k],info[j][k]);
                }
                
                for(k=0;k<=6;k++){
                    strcpy(info[j][k],info[j+1][k]);
                }

                for(k=0;k<=6;k++){
                    strcpy(info[j+1][k],temp[k]);
                }
            }
        }
    }
}

void displayList(){
    int i,j;    
    sort();
    if(isDir==1)
        printf("Total:%d
",allSize);
    for(i=0;i<num;i++){
        for(j=0;j<=6;j++){
            if(j==0)
            printf("%10s",info[i][j]);
            else if(j==1 || j==2 || j==3 || j==4)
            printf("%8s",info[i][j]);
            else
            printf("%15s",info[i][j]);
        }
        printf("
");
    }
}
int main(int argc,char **arvg){
    char path[1026];
    if(argc == 1){
        getcwd(path,1024);
    }else if(argc == 2){
        strcpy(path,arvg[1]);
    }
    if(readList(path)==-1){
        printf("Directory/File not exists.
");
        return;
    }
    displayList();
    return 0;
}
原文地址:https://www.cnblogs.com/rimochiko/p/8168630.html