#include <stdio.h>
#include <getopt.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <time.h>
#include <grp.h>
#include <pwd.h>
#include <dirent.h>
#include <glob.h>
#include <string.h>

#define BUFSIZE 1024
/*
1.尝试实现ls命令的功能 加选项-l -a -i -h
*/

int stat_show(struct stat file_st,char flg);
int l_show(char *file_name, struct stat File_st,char flg);
int _show(char *file_name, struct stat File_st,char flg);


int main(int argc, char **argv)
{
    struct option opts[2] = {{"ls", no_argument, NULL, 'A'}, {0, 0, 0, 0}};
    struct stat file_st;
    glob_t glober;
    int c = 0;
    char *f_name = NULL;
    char buf[BUFSIZE] = {};

    if (argc < 2)
    {
        printf("argv<\n");
        return -1;
    }

    while (1)
    {   // ‘-’ 开头识别非选项参数
        c = getopt_long(argc, argv, "-l::a::i::h::", opts, NULL);
        if (c == -1)
            break;
        //获取文件信息
        if (stat(argv[2], &file_st) == -1)
        {
            perror("stat()");
            return -1;
        }
        switch (c)
        {
        case 'l':
             //-l后不带其他选项
             if (optarg == NULL)
            {
                _show(argv[2], file_st,c);
                break;
            }
            //-l后带其他选项
            else
            {
                switch (*optarg)
                {
                //选项为 a
                case 'a':
                    l_show(argv[2], file_st,'a');
                    break;

                //选项为 i
                case 'i':
                    l_show(argv[2], file_st,'i');
                    break;
               
                //选项为 h
                case 'h':
                    l_show(argv[2], file_st,'h');
                    break;
                
                default:
                    break;
                }
            }
            break;
 
        case 'i':
            _show(argv[2], file_st,c);
            break;

        case 'h':
            _show(argv[2], file_st,c);
            break;

        case 'a':
            _show(argv[2], file_st,c);        
            break;
        default:
            break;
        }
    }
}

/*-l显示*/
int stat_show(struct stat file_st,char flg)
{
    struct passwd *pwd = NULL;
    struct group *grp = NULL;
    struct tm *time = NULL;
    char buf[100] = {};

    if(flg=='i')
        printf("%ld ",file_st.st_ino);

    //文件类型
    switch (file_st.st_mode & __S_IFMT)
    {
    case S_IFREG:
        printf("-");
        break;
    case S_IFDIR:
        printf("d");
        break;
    case S_IFBLK:
        printf("b");
        break;
    case S_IFIFO:
        printf("p");
        break;
    case S_IFCHR:
        printf("c");
        break;
    case S_IFLNK:
        printf("l");
        break;
    case S_IFSOCK:
        printf("s");
        break;

    default:
        break;
    }

    //文件权限
    //拥有者
    if (file_st.st_mode & S_IRUSR)
        putchar('r');
    else
        putchar('-');
    if (file_st.st_mode & S_IWUSR)
        putchar('w');
    else
        putchar('-');
    if (file_st.st_mode & S_IXUSR)
    {
        if (file_st.st_mode & S_ISUID)
            putchar('s');
        else
            putchar('x');
        if (file_st.st_mode & S_ISGID)
            putchar('g');
    }
    else
        putchar('-');
    //所属组
    if (file_st.st_mode & S_IRGRP)
        putchar('r');
    else
        putchar('-');
    if (file_st.st_mode & S_IWGRP)
        putchar('w');
    else
        putchar('-');
    if (file_st.st_mode & S_IXGRP)
    {
        if (file_st.st_mode & S_ISUID)
            putchar('s');
        else
            putchar('x');
        if (file_st.st_mode & S_ISGID)
            putchar('g');
    }
    else
        putchar('-');

    //其他组
    if (file_st.st_mode & S_IROTH)
        putchar('r');
    else
        putchar('-');
    if (file_st.st_mode & S_IWOTH)
        putchar('w');
    else
        putchar('-');
    if (file_st.st_mode & S_IXOTH)
    {
        if (file_st.st_mode & S_ISUID)
            putchar('s');
        else
            putchar('x');
        if (file_st.st_mode & S_ISGID)
            putchar('g');
    }
    else
        putchar('-');
    putchar(' ');

    //文件硬链接数
    printf("%ld ", file_st.st_nlink);

    //文件名拥有者名
    pwd = getpwuid(file_st.st_uid);
    printf("%s ", pwd->pw_name);

    //文件所属组名
    grp = getgrgid(file_st.st_gid);
    printf("%s ", grp->gr_name);

   //文件大小获取
    if(flg=='h')
        printf("%ldk ", (file_st.st_size)/1024);
    else
        printf("%ld ", file_st.st_size);

    //时间获取
    time = localtime(&file_st.st_mtim.tv_sec);
    strftime(buf, 100, "%m月  %d %H:%M:%S", time);
    printf("%s ", buf);

    return 0;
}
/*-l后有其他选项*/ 
int l_show(char *file_name, struct stat File_st,char flg)
{
    glob_t glober;
    struct stat file_st;
    int c = 0;
    char *f_name = NULL;   //去掉 ‘/’ 的文件名
    char buf[BUFSIZE] = {};

    //非目录文件
    if (!S_ISDIR(File_st.st_mode))
    {
        stat_show(File_st, 'a');
        printf("%s \n", file_name);
    }
    //目录文件
    memset(buf, '\0', BUFSIZE);
    strcpy(buf, file_name);
    strcat(buf, "/*"); //尾追加 “/*” 因glob()
    glob(buf, 0, NULL, &glober);
    
    //追加隐藏文件
    if(flg=='a')
    {
        memset(buf, '\0', BUFSIZE);
        strcpy(buf, file_name);
        strcat(buf, "/.*"); //尾追加 “/.” 因glob() 不记录隐藏文件
        glob(buf, GLOB_APPEND, NULL, &glober);
    }
    for (int i = 0; i < glober.gl_pathc; i++)
    {
        stat((glober.gl_pathv)[i], &file_st);
        stat_show(file_st, flg);
        f_name = strrchr((glober.gl_pathv)[i], '/');
        printf("%s \n", f_name + 1);
    }
    globfree(&glober);
    return 0;
}

/*一个选项*/
int _show(char *file_name, struct stat File_st,char flg)
{
    struct stat file_st;
    glob_t glober;
    int c = 0;
    char buf[BUFSIZE] = {};

    //非目录文件
    if (!S_ISDIR(File_st.st_mode))
    {
        stat_show(File_st, flg);
        printf("%s \n", file_name);
        return 0;
    }
    //目录文件
    memset(buf, '\0', BUFSIZE);
    strcpy(buf, file_name);
    strcat(buf, "/*"); //尾追加 “/*” 因glob()
    glob(buf, 0, NULL, &glober);
    // -a
    if (flg == 'a')
    {
        //追加隐藏文件
        memset(buf, '\0', BUFSIZE);
        strcpy(buf, file_name);
        strcat(buf, "/.*"); //尾追加 “/.” 因glob() 不记录隐藏文件
        glob(buf, GLOB_APPEND, NULL, &glober);
    }

    for (int i = 0; i < glober.gl_pathc; i++)
    {
        if (flg == 'l')
        {
            stat((glober.gl_pathv)[i], &file_st);
            stat_show(file_st, flg);
        }
        if (flg == 'i')
        {
            printf("%ld ", File_st.st_ino); /* code */
        }
        printf("%s \n", (glober.gl_pathv)[i] + 2);
    }
    globfree(&glober);
}

#include <stdio.h> #include <getopt.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <time.h> #include <grp.h> #include <pwd.h> #include <dirent.h> #include <glob.h> #include <string.h>
#define BUFSIZE 1024 /* 1.尝试实现ls命令的功能 加选项-l -a -i -h */
int stat_show(struct stat file_st,char flg); int l_show(char *file_name, struct stat File_st,char flg); int _show(char *file_name, struct stat File_st,char flg);

int main(int argc, char **argv) { struct option opts[2] = {{"ls", no_argument, NULL, 'A'}, {0, 0, 0, 0}}; struct stat file_st; glob_t glober; int c = 0; char *f_name = NULL; char buf[BUFSIZE] = {};
if (argc < 2) { printf("argv<\n"); return -1; }
while (1) { // ‘-’ 开头识别非选项参数 c = getopt_long(argc, argv, "-l::a::i::h::", opts, NULL); if (c == -1) break; //获取文件信息 if (stat(argv[2], &file_st) == -1) { perror("stat()"); return -1; } switch (c) { case 'l': //-l后不带其他选项 if (optarg == NULL) { _show(argv[2], file_st,c); break; } //-l后带其他选项 else { switch (*optarg) { //选项为 a case 'a': l_show(argv[2], file_st,'a'); break;
//选项为 i case 'i': l_show(argv[2], file_st,'i'); break; //选项为 h case 'h': l_show(argv[2], file_st,'h'); break; default: break; } } break; case 'i': _show(argv[2], file_st,c); break;
case 'h': _show(argv[2], file_st,c); break;
case 'a': _show(argv[2], file_st,c); break; default: break; } } }
/*-l显示*/ int stat_show(struct stat file_st,char flg) { struct passwd *pwd = NULL; struct group *grp = NULL; struct tm *time = NULL; char buf[100] = {};
if(flg=='i') printf("%ld ",file_st.st_ino);
//文件类型 switch (file_st.st_mode & __S_IFMT) { case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; case S_IFBLK: printf("b"); break; case S_IFIFO: printf("p"); break; case S_IFCHR: printf("c"); break; case S_IFLNK: printf("l"); break; case S_IFSOCK: printf("s"); break;
default: break; }
//文件权限 //拥有者 if (file_st.st_mode & S_IRUSR) putchar('r'); else putchar('-'); if (file_st.st_mode & S_IWUSR) putchar('w'); else putchar('-'); if (file_st.st_mode & S_IXUSR) { if (file_st.st_mode & S_ISUID) putchar('s'); else putchar('x'); if (file_st.st_mode & S_ISGID) putchar('g'); } else putchar('-'); //所属组 if (file_st.st_mode & S_IRGRP) putchar('r'); else putchar('-'); if (file_st.st_mode & S_IWGRP) putchar('w'); else putchar('-'); if (file_st.st_mode & S_IXGRP) { if (file_st.st_mode & S_ISUID) putchar('s'); else putchar('x'); if (file_st.st_mode & S_ISGID) putchar('g'); } else putchar('-');
//其他组 if (file_st.st_mode & S_IROTH) putchar('r'); else putchar('-'); if (file_st.st_mode & S_IWOTH) putchar('w'); else putchar('-'); if (file_st.st_mode & S_IXOTH) { if (file_st.st_mode & S_ISUID) putchar('s'); else putchar('x'); if (file_st.st_mode & S_ISGID) putchar('g'); } else putchar('-'); putchar(' ');
//文件硬链接数 printf("%ld ", file_st.st_nlink);
//文件名拥有者名 pwd = getpwuid(file_st.st_uid); printf("%s ", pwd->pw_name);
//文件所属组名 grp = getgrgid(file_st.st_gid); printf("%s ", grp->gr_name);
//文件大小获取 if(flg=='h') printf("%ldk ", (file_st.st_size)/1024); else printf("%ld ", file_st.st_size);
//时间获取 time = localtime(&file_st.st_mtim.tv_sec); strftime(buf, 100, "%m月 %d %H:%M:%S", time); printf("%s ", buf);
return 0; } /*-l后有其他选项*/ int l_show(char *file_name, struct stat File_st,char flg) { glob_t glober; struct stat file_st; int c = 0; char *f_name = NULL; //去掉 ‘/’ 的文件名 char buf[BUFSIZE] = {};
//非目录文件 if (!S_ISDIR(File_st.st_mode)) { stat_show(File_st, 'a'); printf("%s \n", file_name); } //目录文件 memset(buf, '\0', BUFSIZE); strcpy(buf, file_name); strcat(buf, "/*"); //尾追加 “/*” 因glob() glob(buf, 0, NULL, &glober); //追加隐藏文件 if(flg=='a') { memset(buf, '\0', BUFSIZE); strcpy(buf, file_name); strcat(buf, "/.*"); //尾追加 “/.” 因glob() 不记录隐藏文件 glob(buf, GLOB_APPEND, NULL, &glober); } for (int i = 0; i < glober.gl_pathc; i++) { stat((glober.gl_pathv)[i], &file_st); stat_show(file_st, flg); f_name = strrchr((glober.gl_pathv)[i], '/'); printf("%s \n", f_name + 1); } return 0; }
/*一个选项*/ int _show(char *file_name, struct stat File_st,char flg) { struct stat file_st; glob_t glober; int c = 0; char *f_name = NULL; char buf[BUFSIZE] = {};
//非目录文件 if (!S_ISDIR(File_st.st_mode)) { stat_show(File_st, flg); printf("%s \n", file_name); return 0; } //目录文件 memset(buf, '\0', BUFSIZE); strcpy(buf, file_name); strcat(buf, "/*"); //尾追加 “/*” 因glob() glob(buf, 0, NULL, &glober); // -a if (flg == 'a') { //追加隐藏文件 memset(buf, '\0', BUFSIZE); strcpy(buf, file_name); strcat(buf, "/.*"); //尾追加 “/.” 因glob() 不记录隐藏文件 glob(buf, GLOB_APPEND, NULL, &glober); }
for (int i = 0; i < glober.gl_pathc; i++) { if (flg == 'l') { stat((glober.gl_pathv)[i], &file_st); stat_show(file_st, flg); } if (flg == 'i') { printf("%ld ", File_st.st_ino); /* code */ } printf("%s \n", (glober.gl_pathv)[i] + 2); } } 优质内容筛选与推荐>>
1、Linq To SQL分页失败后引发的思考
2、【codecs】音视频编解码开源项目大汇总
3、c#中常用集合类和集合接口之集合类系列【转】
4、系统分析员考试试题结构分析
5、Error:java: 无效的源发行版: 11


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn