ls 实现-a,-l,-R参数

来源:互联网 发布:jpg转换矢量图软件 编辑:程序博客网 时间:2024/05/18 22:42

勉强完成了这周的小项目,经历了无数次的改buf,写的不是很好,但是还是完成了基本功能,还是很开心的,这次写项目也学到很多东西,再接再厉!!!

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<stdlib.h>#include<time.h>#include<sys/stat.h>#include<unistd.h>#include<sys/types.h>#include<limits.h>#include<dirent.h>#include<grp.h>#include<pwd.h>#include<errno.h>#define PARM_NONE 0#define PARM_A 1//将参数定义好#define PARM_L 2#define PARM_R 4#define MAXLEN 80#define BLACK  "\033[30m"#define ORANGE  "\033[31m"#define GREEN  "\033[32m"#define YELLOW  "\033[33m"#define BLUE  "\033[34m"#define PINK  "\033[35m"#define WHITE  "\033[37m"#define SKY "\033[36m"#define CANCEL "\033[0m"int maxfilename=0;int  filename=0;char arr[256][256];typedef struct tag{    char name[1000];    struct tag *next;}LINK;void swap(char *a, char *b);int PART(char (*arr)[256],int p,int q);void QUICK(char (*arr)[256],int p,int q);//快排!!!void my_err(char *err_string,int line);void display_attribute(struct stat buf,char *name,char*);void display(int flag_param,char *pathname);//传二维数组void color(char *name,char *pathname);int main(int argc,char *argv[]){    int i,j,k=0;    char param[10]={0};//存-a,-l    int flag_param=PARM_NONE;//默认是没有    struct stat buf;    char name[20]={0};    int count=0;//计数-    int flag = 1;    for(i=1;i<argc;i++)    {        if(argv[i][0]=='-')//证明有参数        {            for(j=1;j<strlen(argv[i]);j++)            {                param[k++]=argv[i][j];                count++;            }        }    }    for(i=0;i<count;i++)//权限问题    {        if(param[i]=='a')            flag_param|=PARM_A;        else if(param[i]=='l')            flag_param|=PARM_L;        else if(param[i]=='R')            flag_param|=PARM_R;        else            break;    }   for(i=1;i<argc;i++)    {        if(argv[i][0]!='-')            flag=0;//没有-的,证明就是有目录    }//判断后面有没有参数    if (flag==1)//有参数,没目录情况    {        strcpy(name,".");        display(flag_param,name);        return 0;    }     i=1;    while(i<argc)    {        if(argv[i][0]=='-')        {            i++;            continue;        }        else             strcpy(name,argv[i]);        if(stat(name,&buf)==-1)//获取属性            my_err("lstat",__LINE__);        display(flag_param,name);        i++;    }    return 0;}void swap(char *a, char *b){    char t[256];    strcpy(t,a);    strcpy(a,b);    strcpy(b,t);}int PART(char (*arr)[256],int p,int q){    int i,j;    j=p-1;    for(i=p;i<q;i++)    {        if(strcmp(arr[i], arr[q]) < 0)//if(arr[i][0]<arr[q][0])        {            j++;            swap(arr[i],arr[j]);        }    }    swap(arr[j+1],arr[q]);    return j+1;}void QUICK(char (*arr)[256],int p,int q)//快排!!!{    int r;    if(p<q)    {        r=PART(arr,p,q);        QUICK(arr,p,r-1);        QUICK(arr,r+1,q);    }}void my_err(char *err_string,int line){    fprintf(stderr,"line:%d ",line);    perror(err_string);    exit(1);}void display_attribute(struct stat buf,char *name,char *pathname){    struct passwd *user;    struct group *group;    struct stat bu;    char str[256];    sprintf(str,"%s/%s",pathname,name);//构建绝对路径    if(lstat(str,&bu)==-1)        {            my_err("stat",__LINE__);        }    if(S_ISLNK(bu.st_mode))//判断文件是什么类型        putchar('l');    else if(S_ISDIR(bu.st_mode))        putchar('d');    else if(S_ISCHR(bu.st_mode))        putchar('c');    else if(S_ISBLK(bu.st_mode))        putchar('b');    else if(S_ISFIFO(bu.st_mode))        putchar('f');    else if(S_ISSOCK(bu.st_mode))        putchar('s');    else        putchar('-');    //判断user权限    if(bu.st_mode & S_IREAD)        putchar('r');    else         putchar('-');    if(bu.st_mode & S_IWRITE)        putchar('w');    else        putchar('-');    if(bu.st_mode & S_IEXEC)        putchar('x');    else         putchar('-');    //判断group权限    if(bu.st_mode & S_IRGRP)        putchar('r');    else        putchar('-');     if(bu.st_mode & S_IWGRP)        putchar('w');    else        putchar('-');     if(bu.st_mode & S_IXGRP)        putchar('x');    else         putchar('-');    //判断others权限    if(bu.st_mode & S_IROTH)        putchar('r');    else        putchar('-');    if(bu.st_mode & S_IWOTH)        putchar('w');    else        putchar('-');     if(bu.st_mode & S_IXOTH)        putchar('x');    else        putchar('-');    user=getpwuid(bu.st_uid);//获取userID    group=getgrgid(bu.st_gid);//获取groupID    printf("  %-4d",bu.st_nlink);//链接数    printf("%-5s",user->pw_name);//user;    printf("%-5s",group->gr_name);//group;    printf("%-8d",bu.st_size);//文件大小    char time_buf[255];    strcpy(time_buf, ctime(&bu.st_atime));    time_buf[strlen(time_buf)-1] = '\0';//ctime会有一个换行    printf("%  s  ",time_buf);//文件时间    if(name[0]!='\0')        {            color(name,pathname);            putchar('\n');        }}void display(int flag_param,char *pathname)//传二维数组,pahtname全路径{    DIR *dir;    struct dirent *ptr;    int count=0;    struct stat buf;    int i,j=0;    char alldir[800][1000];    char t[200];    char *pwd;    int k;    if(lstat(pathname,&buf)==-1)    {        my_err("lstat",__LINE__);    }    switch(flag_param)    {        case PARM_NONE:        {                    if(S_ISDIR(buf.st_mode))                    {                         count=0;                        if((dir=opendir(pathname))==NULL)                            my_err("opendir",__LINE__);                        while((ptr=readdir(dir))!=NULL)////要排序                        {                            if(ptr->d_name[0]!='.')                                strcpy(arr[count++],ptr->d_name);                        }                        QUICK(arr,0,count-1);                        int k=0;                        for(i=0;i<count;i++)                        {                            color(arr[i],pathname);                            printf("  ");                            k++;                            if(k%5==0)                                putchar('\n');                        }                        if(k%5!=0)                            putchar('\n');                        closedir(dir);                  }                else                      //color(pathname);                    printf(SKY "%s" CANCEL,pathname);//文件        }        break;        case PARM_A:         {                count=0;                if((dir=opendir(pathname))==NULL)                    my_err("opendir",__LINE__);                while((ptr=readdir(dir))!=NULL)////要排序                        strcpy(arr[count++],ptr->d_name);                    QUICK(arr,0,count-1);                    int k=0;                    for(i=0;i<count;i++)                    {                        color(arr[i],pathname);//arr[i]);                        printf("  ");                        k++;                        if(k%5==0)                            putchar('\n');                    }                    if(k%5!=0)                        putchar('\n');            closedir(dir);        }            break;        case PARM_L:            {                count=0;                    if(S_ISDIR(buf.st_mode))                    {                        if((dir=opendir(pathname))==NULL)                            my_err("opendir",__LINE__);                        while((ptr=readdir(dir))!=NULL)////要排序                            strcpy(arr[count++],ptr->d_name);                        QUICK(arr,0,count-1);                        for(i=0;i<count;i++)                        {                            if(arr[i][0]!='.')                                display_attribute(buf,arr[i],pathname);                        }                         closedir(dir);                    }                    else                        display_attribute(buf,".",pathname);            }        break;    case PARM_L+PARM_A:    {                 count=0;               if(S_ISDIR(buf.st_mode))               {                if((dir=opendir(pathname))==NULL)                    my_err("opendir",__LINE__);                while((ptr=readdir(dir))!=NULL)////要排序                        strcpy(arr[count++],ptr->d_name);                QUICK(arr,0,count-1);                    for(i=0;i<count;i++)                        display_attribute(buf,arr[i],pathname);               }               else                     display_attribute(buf,".",pathname);                closedir(dir);    }        break;    case PARM_A+PARM_R:    {            LINK *p1,*q1,*head1;            LINK *p2,*q2,*head2;            if(S_ISDIR(buf.st_mode))            {                q1 = head1 = (LINK*)malloc(sizeof(LINK));                strcpy(head1->name, pathname);                q1->next=NULL;                while (head1 != NULL)                {                    char thisname[256];                    strcpy(thisname, head1->name);                    printf(BLUE "%s"CANCEL,thisname);//目录                   // color(thisname);                    printf(":\n");                    head2=NULL;                    if ((dir = opendir(thisname)) == NULL)                     {                        perror("opendir");                        p1 = head1;                        head1 = head1->next;                        free(p1);                        continue;                    }                    count=0;                    while((ptr=readdir(dir))!=NULL)//创建文件链表                    {                        p2=(LINK*)malloc(sizeof(LINK));                        strcpy(p2->name,ptr->d_name);                        count++;                        p2->next=NULL;                        if(head2==NULL)                            head2=p2;                        else                             q2->next=p2;                        q2=p2;                    }                    closedir(dir);                    for(i=1;i<=count;i++)                    {                        p2=head2;                        for(j=1;j<=count-i;j++)                        {                            if(strcmp(p2->name,p2->next->name)>0)                                swap(p2->name,p2->next->name);                            p2=p2->next;                        }                    }                    int k=0;                    for (p2=head2; p2!=NULL; p2=p2->next)                    {                        char full_dir[256];                        sprintf(full_dir,"%s/%s",thisname,p2->name);                        if(lstat(full_dir,&buf)==-1)                         {                            perror("\nlstat");                        }                        else                        {                            if(S_ISDIR(buf.st_mode))                            {                                p1=(LINK*)malloc(sizeof(LINK));                                strcpy(p1->name,full_dir);                                p1->next=NULL;                                q1->next=p1;                                q1=p1;                            }                        }                        color(p2->name,thisname);                        printf("  ");                        k++;                        if(k%5==0)                            putchar('\n');                    }                    putchar('\n');                    p2=head2;                    while(p2!=NULL)                    {                        q2=p2->next;                        free(p2);                        p2=q2;                    }                    p1 = head1;                    head1 = head1->next;                    free(p1);                }            }            else                 {                    //color(pathname);                    printf(SKY "%s" CANCEL,pathname);//文件                    putchar('\n');                }    }break;    case PARM_L+PARM_R:    {             LINK *p1,*q1,*head1;            LINK *p2,*q2,*head2;            if(S_ISDIR(buf.st_mode))            {                q1 = head1 = (LINK*)malloc(sizeof(LINK));                strcpy(head1->name, pathname);                q1->next=NULL;                while (head1 != NULL)                {                    char thisname[256];                    strcpy(thisname, head1->name);                    //color(thisname);                     printf(BLUE "%s"CANCEL,thisname);//目录                    printf(":\n");                    head2=NULL;                    if ((dir = opendir(thisname)) == NULL)                     {                        perror("opendir");                        p1 = head1;                        head1 = head1->next;                        free(p1);                        continue;                    }                    count=0;                    while((ptr=readdir(dir))!=NULL)//创建文件链表                    {                        p2=(LINK*)malloc(sizeof(LINK));                        if(ptr->d_name[0]=='.')                            continue;                        strcpy(p2->name,ptr->d_name);                        count++;                        p2->next=NULL;                        if(head2==NULL)                            head2=p2;                        else                             q2->next=p2;                        q2=p2;                    }                    closedir(dir);                    for(i=1;i<=count;i++)                    {                        p2=head2;                        for(j=1;j<=count-i;j++)                        {                            if(strcmp(p2->name,p2->next->name)>0)                                swap(p2->name,p2->next->name);                            p2=p2->next;                        }                    }                    int k=0;                    for (p2=head2; p2!=NULL; p2=p2->next)                    {                        char full_dir[256];                        sprintf(full_dir,"%s/%s",thisname,p2->name);                        if(lstat(full_dir,&buf)==-1)                         {                            perror("\nlstat");                        }                        else                        {                            if(S_ISDIR(buf.st_mode))                            {                                p1=(LINK*)malloc(sizeof(LINK));                                strcpy(p1->name,full_dir);                                p1->next=NULL;                                q1->next=p1;                                q1=p1;                            }                        }                    display_attribute(buf,p2->name,thisname);                    }                    putchar('\n');                    p2=head2;                    while(p2!=NULL)                    {                        q2=p2->next;                        free(p2);                        p2=q2;                    }                    p1 = head1;                    head1 = head1->next;                    free(p1);                }            }            else            {                printf(BLUE "%s"CANCEL,pathname);//目录                printf("\n");            }    }    break;    case PARM_L+PARM_R+PARM_A:    {        LINK *p1,*q1,*head1;        LINK *p2,*q2,*head2;            if(S_ISDIR(buf.st_mode))            {                q1 = head1 = (LINK*)malloc(sizeof(LINK));                strcpy(head1->name, pathname);                q1->next=NULL;                while (head1 != NULL)                {                    char thisname[256];                    strcpy(thisname, head1->name);                    printf(BLUE "%s"CANCEL,thisname);//目录                    printf(":\n");                    head2=NULL;                    if ((dir = opendir(thisname)) == NULL)                     {                        perror("opendir");                        p1 = head1;                        head1 = head1->next;                        free(p1);                        continue;                    }                    count=0;                    while((ptr=readdir(dir))!=NULL)//创建文件链表                    {                        p2=(LINK*)malloc(sizeof(LINK));                        strcpy(p2->name,ptr->d_name);                        count++;                        p2->next=NULL;                        if(head2==NULL)                            head2=p2;                        else                             q2->next=p2;                        q2=p2;                    }                    closedir(dir);                    for(i=1;i<=count;i++)                    {                        p2=head2;                        for(j=1;j<=count-i;j++)                        {                            if(strcmp(p2->name,p2->next->name)>0)                                swap(p2->name,p2->next->name);                            p2=p2->next;                        }                    }                    int k=0;                    for (p2=head2; p2!=NULL; p2=p2->next)//存放目录文件                    {                        char full_dir[256];                        sprintf(full_dir,"%s/%s",thisname,p2->name);                        if(lstat(full_dir,&buf)==-1)                         {                            perror("\nlstat");                        }                        else                        {                            if(S_ISDIR(buf.st_mode)&&strcmp(p2->name,".")!=0&&strcmp(p2->name,"..")!=0)                            {                                p1=(LINK*)malloc(sizeof(LINK));                                strcpy(p1->name,full_dir);                                p1->next=NULL;                                q1->next=p1;                                q1=p1;                            }                        }                    display_attribute(buf,p2->name,thisname);                    }                    putchar('\n');                    p2=head2;                    while(p2!=NULL)                    {                        q2=p2->next;                        free(p2);                        p2=q2;                    }                    p1 = head1;                    head1 = head1->next;                    free(p1);                }            }            else             {                printf(BLUE "%s"CANCEL,pathname);//目录                printf("\n");            }    }    break;    case PARM_R:    {            LINK *p1,*q1,*head1;            LINK *p2,*q2,*head2;            if(S_ISDIR(buf.st_mode))            {                q1 = head1 = (LINK*)malloc(sizeof(LINK));                strcpy(head1->name, pathname);                q1->next=NULL;                while (head1 != NULL)                {                    char thisname[256];                    strcpy(thisname, head1->name);                     printf(BLUE "%s"CANCEL,thisname);//目录                    printf(":\n");                    head2=NULL;                    if ((dir = opendir(thisname)) == NULL)                     {                        perror("opendir");                        p1 = head1;                        head1 = head1->next;                        free(p1);                        continue;                    }                    count=0;                    while((ptr=readdir(dir))!=NULL)//创建文件链表                    {                        p2=(LINK*)malloc(sizeof(LINK));                        if(ptr->d_name[0]=='.')                            continue;                        strcpy(p2->name,ptr->d_name);                        count++;                        p2->next=NULL;                        if(head2==NULL)                            head2=p2;                        else                             q2->next=p2;                        q2=p2;                    }                    closedir(dir);                    for(i=1;i<=count;i++)                    {                        p2=head2;                        for(j=1;j<=count-i;j++)                        {                            if(strcmp(p2->name,p2->next->name)>0)                                swap(p2->name,p2->next->name);                            p2=p2->next;                        }                    }                    int k=0;                    for (p2=head2; p2!=NULL; p2=p2->next)                    {                        char full_dir[256];                        sprintf(full_dir,"%s/%s",thisname,p2->name);                        if(lstat(full_dir,&buf)==-1)                         {                            perror("\nlstat");                        }                        else                        {                            if(S_ISDIR(buf.st_mode))                            {                                p1=(LINK*)malloc(sizeof(LINK));                                strcpy(p1->name,full_dir);                                p1->next=NULL;                                q1->next=p1;                                q1=p1;                            }                        }                        color(p2->name,thisname);                        printf("  ");                        k++;                        if(k%5==0)                            putchar('\n');                    }                    putchar('\n');                    p2=head2;                    while(p2!=NULL)                    {                        q2=p2->next;                        free(p2);                        p2=q2;                    }                    p1 = head1;                    head1 = head1->next;                    free(p1);                }            }            else             {                 printf(BLUE "%s"CANCEL,pathname);//目录                printf("\n");            }    }    break;           default:        break;    }}void color(char *name,char *pathname )//颜色函数{    struct stat bu;    char buf[256];    int flag=0;    if(pathname[strlen(pathname)-2]!='/'&&name[0]!='/')        sprintf(buf,"%s/%s",pathname,name);    else if(pathname[strlen(pathname)-2]!='/'&&name[0]=='/')        sprintf(buf,"%s%s",pathname,name);    else         sprintf(buf,"%s%s",pathname,name);    if(lstat(buf,&bu)==-1)    {        flag=1;        //printf(",权限不足!\n");    }    if(S_ISLNK(bu.st_mode))//判断文件是什么类型     printf(BLUE "%s"CANCEL,name);//目录    else if(S_ISDIR(bu.st_mode))        printf(ORANGE "%s" CANCEL,name);//链接    else if(S_ISCHR(bu.st_mode))    printf(GREEN "%s"CANCEL,name);//字符    else if(S_ISBLK(bu.st_mode))      printf(PINK "%s"CANCEL,name);//块    else if(S_ISFIFO(bu.st_mode))    printf(WHITE "%s"CANCEL,name);//FIFO    else if(S_ISSOCK(bu.st_mode))     printf(BLACK"%s"CANCEL,name);//socket    else        printf(SKY "%s" CANCEL,name);//文件    if(flag)        printf("权限不足!\n");}