linux c 模仿ls

/*
    ls -l -a -i -h
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <glob.h>
#include <dirent.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>

#define BUFSIZE 1024

void mystat(char *path);

//文件所有属性
void listl(char *path)
{        
    struct stat stat;
    char buf[BUFSIZE] = {};
    glob_t pglob;
    
    if(lstat(path, &stat) < 0)//失败返回-1
    {
        perror("lstat()");
        return;
    }
    if(!S_ISDIR(stat.st_mode))//判断是不是目录
    {
        mystat(path);
        return;
    }

    strcpy(buf, path);//复制字符串
    strcat(buf, "/*");//链接字符串
    glob(buf, 0, NULL, &pglob);//匹配路径

    for(int i = 0; i < pglob.gl_pathc; i++)
    {
        mystat(pglob.gl_pathv[i]);    
    }

    globfree(&pglob);
}

void mystat(char *path)
{
    struct stat mystat;
    
    if (lstat(path, &mystat) == -1) {
        perror("stat()");
        return ;
    }
        
    // 类型
    switch(mystat.st_mode & S_IFMT) {
        case S_IFREG:
            printf("-");
            break;
        case S_IFDIR:
            putchar('d');
            break;
        case S_IFSOCK:
            printf("s");
            break;
        case S_IFLNK:
            printf("l");
            break;
        case S_IFBLK:
            putchar('b');
            break;
        case S_IFCHR:
            printf("c");
            break;
        case S_IFIFO:
            printf("p");
            break;
        default:
            break;
    }
    
    // 权限
    if (mystat.st_mode & S_IRUSR)
        putchar('r');
    else
        putchar('-');
    if (mystat.st_mode & S_IWUSR)
        putchar('w');
    else
        putchar('-');
    if (mystat.st_mode & S_IXUSR) {
        if (mystat.st_mode & S_ISUID) {
            putchar('s');
        } else
            putchar('x');
    } else
        putchar('-');

    if (mystat.st_mode & S_IRGRP)
        putchar('r');
    else
        putchar('-');
    if (mystat.st_mode & S_IWGRP)
        putchar('w');
    else
        putchar('-');
    if (mystat.st_mode & S_IXGRP) {
        if (mystat.st_mode & S_ISGID) {
            putchar('s');
        } else
            putchar('x');
    } else
        putchar('-');
    if (mystat.st_mode & S_IROTH)
        putchar('r');
    else
        putchar('-');
    if (mystat.st_mode & S_IWOTH)
        putchar('w');
    else
        putchar('-');
    if (mystat.st_mode & S_IXOTH) {
        if (mystat.st_mode & S_ISVTX) {
            putchar('s');
        } else
            putchar('x');
    } else
        putchar('-');

    // 硬链接
    printf(" %ld ", mystat.st_nlink);

    // 文件拥有者名
    struct passwd *pwd = NULL;
    pwd = getpwuid(mystat.st_uid);
    printf("%s ", pwd->pw_name);

    // 文件所属组
    struct group *grp = NULL;
    grp = getgrgid(mystat.st_gid);
    printf("%s ", grp->gr_name);

    // 总字节个数 磁盘空间大小st_blocks/2 k
    printf("%ld ", mystat.st_size);

    // 获取文件时间 atime mtime ctime
    struct tm *tmp = NULL;
    tmp = localtime(&mystat.st_mtim.tv_sec);

    // if error
    char buf[BUFSIZE] = {};
    strftime(buf, BUFSIZE, "%m月  %d %H:%M", tmp);
    printf("%s ", buf);

    // 文件名
    char *p = strrchr(path,'/');
    printf("%s ", ++p);

    putchar('\n');

    return;
}

//文件名(包括隐含文件)
void lista(char *path)
{
    struct stat stat;
    char buf[BUFSIZE] = {};
    glob_t pglob;

    if(lstat(path, &stat) < 0)
    {
        perror("lstat()");
        return;
    }
    if(!S_ISDIR(stat.st_mode))
    {
        printf("%s \n",path);
        return;
    }

    strcpy(buf, path);
    strcat(buf, "/*");
    glob(buf, 0, NULL, &pglob);
    //隐藏文件
    memset(buf,'\0',BUFSIZE);
    strcpy(buf, path);
    strcat(buf, "/.*");
    glob(buf, GLOB_APPEND, NULL, &pglob);

    for(int i = 0; i < pglob.gl_pathc; i++)
    {
        if(lstat(((pglob.gl_pathv)[i]),&stat) < 0){
            perror("lstat()");    
            return;
        }
        char *p = strrchr((pglob.gl_pathv)[i],'/');
        printf("%s        \n",++p);
    }
    globfree(&pglob);
    
//    printf("文件名\n");    
}

//文件大小+文件名
void listi(char *path)
{
    struct stat stat;
    char buf[BUFSIZE] = {};
    glob_t pglob;

    if(lstat(path, &stat) < 0)
    {
        perror("lstat()");
        return;
    }
    if(!S_ISDIR(stat.st_mode))
    {
        printf("%ld %s \n",stat.st_ino,path);
        return;
    }

    strcpy(buf, path);
    strcat(buf, "/*");
    glob(buf, 0, NULL, &pglob);

    for(int i = 0; i < pglob.gl_pathc; i++)
    {
        if(lstat(((pglob.gl_pathv)[i]),&stat) < 0){
            perror("lstat()");    
            return;
        }
        char *p = strrchr((pglob.gl_pathv)[i],'/');
        printf("%ld %s     \n",stat.st_ino,++p);
    }

    globfree(&pglob);
//    printf("文件大小  文件名\n");    
}

//文件名(不包括隐含文件)
void listh(char *path)
{    
    struct stat stat;
    char buf[BUFSIZE] = {};
    glob_t pglob;

    if(lstat(path, &stat) < 0)
    {
        perror("lstat()");
        return;
    }
    if(!S_ISDIR(stat.st_mode))
    {
        printf("%ld %s \n",stat.st_size,path);
        return;
    }

    strcpy(buf, path);
    strcat(buf, "/*");
    glob(buf, 0, NULL, &pglob);

    for(int i = 0; i < pglob.gl_pathc; i++)
    {
        if(lstat(((pglob.gl_pathv)[i]),&stat) < 0){
            perror("lstat()");    
            return;
        }
        char *p = strrchr((pglob.gl_pathv)[i],'/');
        printf("%s    \n",++p);
    }

    globfree(&pglob);
//    printf("文件名\n");    

}
int main(int argc, char *argv[])
{
    char *optstring = "-l:a:h:i:";
    int c;

    while(1){
        c = getopt(argc, argv, optstring);    
        if(c == -1)
            break;
        switch(c){
            case 'l':
                listl(optarg);
                break;
            case 'a':
                lista(optarg);
                break;
            case 'i':
                listi(optarg);
                break;
            case 'h':
                listh(optarg);
                break;
            default:
                break;
        }
    }
    return 0;
}


posted @ 2019-03-16 17:01  乐小童  阅读(152)  评论(0)    收藏  举报