zoukankan      html  css  js  c++  java
  • 实现自己的ls命令

    实现自己的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("
    ");
                }
            }
            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(" 33[34m%-10s33[0m
    ",name);
                }
                else
                {
                    printf(" %-10s
    ",name);
                }
        }
        else
        {
            if(S_ISDIR(buf.st_mode))
            {
                printf(" 33[34m%-10s33[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 输出username
    {
        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
    "); //与以上不匹配,报错
        }
        return 0;
    }


  • 相关阅读:
    基于BGP/EVPN控制平面的VXLAN anycast-VTEP anycast-gateway基本配置
    NetworkManager配置VRF
    IBGP Segment Routing AIGP属性
    EBGP segment routing
    CentOS8创建网桥
    F5 HTTP response body rewrite
    OSPF Segment Routing和MPLS基本配置
    L2TP 和 IPsec over L2TP
    nmap
    LINUX DNS客户端 解析域名慢的问题。
  • 原文地址:https://www.cnblogs.com/brucemengbm/p/6770211.html
Copyright © 2011-2022 走看看