实现自己的ls命令

来源:互联网 发布:c语言pow函数 编辑:程序博客网 时间:2024/05/16 03:01

实现自己的ls命令

估计每个使用过linux系统的人都知道ls是啥吧。也相信大家都对ls的简单命令烂熟于心了吧,这里就不想再赘述了,直接进入正题吧。代码里面会有许多注释,相信的家一定能看懂的。说明:此代码我在kail linux下编译无任何错误,运行也基本无bug,相信大家在一般linux下运行也无问题。
代码:
#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <dirent.h>#include <string.h>#include <linux/limits.h>#include <pwd.h>#include <grp.h>#include <time.h>#define MAX_STRING 255   /*最长文件名,linux系统下规定文件名不允许超过255个字符,当然文件夹也是,因为文件夹就是特殊的文件。*///链表头插法初始化,这里使用的是宏定义来进行链表操作的,很高端,come on ,你也可以的#define List_Init(list,list_node_t){                     \    list=(list_node_t *)malloc(sizeof(list_node_t));    \    list->next=NULL;                                    \}//链表头插法宏定义#define List_AddHead(list,newNode){      \    newNode->next=list->next;           \    list->next=newNode;                 \}typedef struct str_sort  //结构体,里面仅保存问价名{    char str[256];    struct str_sort *next;}str_node_t;//函数声明部分void my_stat(int flag,char *name);void my_err(const char *err_string,int line);char *analy_filetype(struct stat *buf);void print_filemode_usr(struct stat *buf);void print_filemode_gro(struct stat *buf);void print_filemode_oth(struct stat *buf);void print_usr_name(struct stat *buf);void print_gro_name(struct stat *buf);void print_time(time_t st_time);int display(int flag,char *path);void sort(int count,str_node_t *head);int print_info_srv(int count,int flag,str_node_t *head);int display(int flag,char *path)  //文件目录解析函数,获取当前目录所有文件{    int i=0,j,count=0;    DIR *dir;    struct dirent *ptr;    char cwd[256];    getcwd(cwd,256);   //记录当前的目录     chdir(path);             //转到path所代表的目录下    str_node_t *newNode,*head;    List_Init(head,str_node_t);    if((dir=opendir(path))==NULL)    {        perror("opendir");        return -1;    }    while((ptr=readdir(dir))!=NULL)    {        i++;        newNode=(str_node_t *)malloc(sizeof(str_node_t));        strcpy(newNode->str,ptr->d_name);        List_AddHead(head,newNode); //头插法建立新链表    }    count=i;    print_info_srv(count,flag,head);    closedir(dir);    chdir(cwd);  //转到先前的目录}int print_info_srv(int count,int flag,str_node_t *head)     //打印文件信息服务函数{    int i;    str_node_t *p;    sort(count,head);      //对文件名进行排序    p=head;    for(i=0;i<count;i++)    {        p=p->next;        if(flag==-1 || flag==0)        {            if(!strcmp(p->str,".")||!strcmp(p->str,"..")||p->str[0]=='.')/*排除掉点和点点目录,以及以点开头的隐藏目录*/            {                continue;            }            my_stat(flag,p->str);            if(i==count-1)            {                printf("\n");            }        }        else        {           my_stat(flag,p->str);        }    }}void sort(int count,str_node_t *head) //文件名排序函数,使用的是冒牌排序法{    int i,j;    char temp[256];    str_node_t *p;    for(i=1;i<=count;i++)    {        p=head->next;        for(j=1;j<count;j++)        {            if(strcmp(p->str,p->next->str)>0)            {                strcpy(temp,p->str);                strcpy(p->str,p->next->str);                strcpy(p->next->str,temp);            }            p=p->next;        }    }}void my_stat(int flag,char *name)  //打印文件相关信息{    struct stat buf;    lstat(name,&buf);    if(flag==0 || flag==2)    {            printf("%s",analy_filetype(&buf));            print_filemode_usr(&buf);            print_filemode_gro(&buf);            print_filemode_oth(&buf);            printf("%3d",buf.st_nlink);            print_usr_name(&buf);            print_gro_name(&buf);            printf("%6d",buf.st_size);            print_time(buf.st_mtime);            if(S_ISDIR(buf.st_mode))           {                printf(" \033[34m%-10s\033[0m\n",name);            }            else            {                printf(" %-10s\n",name);            }    }    else    {        if(S_ISDIR(buf.st_mode))        {            printf(" \033[34m%-10s\033[0m",name);        }        else        {           printf("%-14s",name);        }    }}char *month_analy(int month)     //月份解析函数,linux底层是以0开始的,相信大家也并不意外{    switch(month)    {        case 0:            return "Jan";        case 1:            return "Feb";        case 2:            return "Mar";        case 3:            return "Apr";        case 4:            return "May";        case 5:            return "Jun";        case 6:            return "Jul";        case 7:            return "Aug";        case 8:            return "Sep";        case 9:            return "Oct";        case 10:            return "Nov";        case 11:            return "Dec";    }}void print_time(time_t st_time) //日期解析函数{    struct tm p;    gmtime_r(&st_time,&p);    printf(" %3s",month_analy(p.tm_mon));    if(p.tm_mday<10) //小于十的前面补零    {        printf(" 0%d",p.tm_mday); //小于十的前面补零    }    else    {        printf(" %2d",p.tm_mday);    }    if(p.tm_hour<2 || p.tm_hour>=23)    {        printf(" 0%d:",(p.tm_hour+8));  /*此处系统使用的是国际标准时间,中国位于东八区,比标准时间早8个小时,故要加上八*/    }    else    {        printf(" %2d:",p.tm_hour+8);    }    if(p.tm_min<10)    {        printf("0%d",p.tm_min);    }    else    {        printf("%2d",p.tm_min);    }}void my_err(const char *err_string ,int line){    fprintf(stderr,"line:%d",line);    perror(err_string);    exit(1);}char *analy_filetype(struct stat *buf)  //文件类型解析函数{    if(S_ISLNK(buf->st_mode))    {        return "l";    //符号链接    }    else if(S_ISREG(buf->st_mode))    {        return "-";   //普通文件    }    else if(S_ISDIR(buf->st_mode))    {        return "d";   //目录文件    }    else if(S_ISCHR(buf->st_mode))    {        return "c";  //字符特殊文件    }    else if(S_ISBLK(buf->st_mode))    {        return "b";  //块特殊文件    }    else if(S_ISFIFO(buf->st_mode))    {        return "f";  //命名管道    }    else if(S_ISSOCK(buf->st_mode))    {        return "s";   //套接字    }}void print_filemode_usr(struct stat *buf)   //文件所有者{    //文件所有者权限    if(buf->st_mode & S_IRUSR)        printf("r");    else        printf("-");    if(buf->st_mode & S_IWUSR)        printf("w");    else        printf("-");    if(buf->st_mode & S_IXUSR)        printf("x");    else        printf("-");}void print_filemode_gro(struct stat *buf)  //文件所数组{    //文件用户组权限    if(buf->st_mode & S_IRGRP)        printf("r");    else        printf("-");    if(buf->st_mode & S_IWGRP)        printf("w");    else        printf("-");    if(buf->st_mode & S_IXGRP)        printf("x");    else        printf("-");}void print_filemode_oth(struct stat *buf)  //其他用户{    //其他用户权限    if(buf->st_mode & S_IROTH)        printf("r");    else        printf("-");    if(buf->st_mode & S_IWOTH)        printf("w");    else        printf("-");    if(buf->st_mode & S_IXOTH)        printf("x ");    else        printf("- ");}void print_usr_name(struct stat *buf) //通过uid 输出用户名{    struct passwd *pwd;    pwd=getpwuid(buf->st_uid);    printf(" %s",pwd->pw_name);}void print_gro_name(struct stat *buf) //通过gid输出用户组名a{    struct group *gup;    gup=getgrgid(buf->st_gid);    printf(" %s",gup->gr_name);}int main(int argc,char **argv){    int flag;           //flag=-1 [ls] flag=0 [ls -l]     flag=1 [ls -a]  flag=2  [ls -al/-la]    if(1==argc)         //analysis: ls    {        flag=-1;        display(flag,".");        return 0;    }    else if(argc==2 && !strcmp("-l",argv[1]))  //analysis: ls -l    {        flag=0;        display(flag,".");    }    else if(argc==2 && !strcmp("-a",argv[1]))  //analysis: ls -a    {        flag=1;        display(flag,".");    }    else if(argc==2 && !strcmp("-al",argv[1])) //analysis: ls -al    {        flag=2;        display(flag,".");    }    else if(argc==2 && !strcmp("-la",argv[1])) //analysis : ls -la    {        flag=2;        display(flag,".");    }    else if(argc==2) //analysis: ls file    {        flag=-1;        display(flag,argv[1]);    }    else if(argc==3 && !strcmp("-l",argv[1]))  //analysis: ls -l file    {        flag=0;        display(flag,argv[2]);    }    else if(argc==3 && !strcmp("-a",argv[1]))  //analysis : ls -a file    {        flag=1;        display(flag,argv[2]);    }    else if(argc==3 && !strcmp("-al",argv[1])) //analysis :ls -al file    {        flag=2;        display(flag,argv[2]);    }    else if(argc==3 && !strcmp("-la",argv[1])) //analysis :ls -la file    {        flag=2;        display(flag,argv[2]);    }    else    {        printf("Not Support This Commond\n"); //与以上不匹配,报错    }    return 0;}


0 0
原创粉丝点击