刘赤-ls

#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);
}
}

猜你喜欢

转载自www.cnblogs.com/LC18330852893/p/10541040.html
ls