狂自私

导航

简洁的实现ls-l命令

现在我们来简洁的实现命令:了解一下相关知识:

我们使用掩码可以很明确的得出文件的每一种信息。关于掩码,上图中的S_IRUSR等均为掩码。我们来看看函数getpwuid,原型:struct passwd *getpwuid(uid_t uid);头文件:#include <pwd.h>。
getpwuid()用来逐一搜索参数uid 指定的用户识别码, 找到时便将该用户的数据以结构体的形式返回。该函数的返回值是一个结构体passwd 。我们来看看这个结构体:

struct passwd {

    char *pw_name; /* username */

    char *pw_passwd; /* user password */

    uid_t pw_uid; /* user ID */

    gid_t pw_gid; /* group ID */

    char *pw_gecos; /* user information */

    char *pw_dir; /* home directory */

    char *pw_shell; /* shell program */

};

结构体已经很清楚明了了。所以我们很容易可以得到用户名。我们再来看另一个函数:getgrgid(),函数原型:struct group *getgrgid(gid_t gid);头文件:#include <grp.h>。和getpwuid类似。结构体group:

struct group {

    char *gr_name; /* group name */

    char *gr_passwd; /* group password */

    gid_t gr_gid; /* group ID */

    char **gr_mem; /* NULL-terminated array of pointers

                            to names of group members */

};

所以文件所属组也很容易得到。

所以整体上很容易了:

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <stdlib.h>

#include <time.h>

#include <pwd.h>

#include <grp.h>

 

 

int main(int argc, char* argv[])

{

    if (argc < 2)

    {

        printf(". / a.out filename\n");

        exit(1);

    }

 

    struct stat st;

    int ret = stat(argv[1], &st);

    if (ret == -1)

    {

        perror("stat");

        exit(1);

    }

 

    // 存储文件类型和访问权限

    char perms[11] = { 0 };

    // 判断文件类型

    switch (st.st_mode & S_IFMT)

    {

    case S_IFLNK:

        perms[0] = 'l';

        break;

    case S_IFDIR:

        perms[0] = 'd';

        break;

    case S_IFREG:

        perms[0] = ' - ';

        break;

    case S_IFBLK:

        perms[0] = 'b';

        break;

    case S_IFCHR:

        perms[0] = 'c';

        break;

    case S_IFSOCK:

        perms[0] = 's';

        break;

    case S_IFIFO:

        perms[0] = 'p';

        break;

    default:

        perms[0] = ' ? ';

        break;

    }

    // 判断文件的访问权限

    // 文件所有者

    perms[1] = (st.st_mode & S_IRUSR) ? 'r' : ' - ';

    perms[2] = (st.st_mode & S_IWUSR) ? 'w' : ' - ';

    perms[3] = (st.st_mode & S_IXUSR) ? 'x' : ' - ';

    // 文件所属组

    perms[4] = (st.st_mode & S_IRGRP) ? 'r' : ' - ';

    perms[5] = (st.st_mode & S_IWGRP) ? 'w' : ' - ';

    perms[6] = (st.st_mode & S_IXGRP) ? 'x' : ' - ';

    // 其他人

    perms[7] = (st.st_mode & S_IROTH) ? 'r' : ' - ';

    perms[8] = (st.st_mode & S_IWOTH) ? 'w' : ' - ';

    perms[9] = (st.st_mode & S_IXOTH) ? 'x' : ' - ';

 

    // 硬链接计数

    int linkNum = st.st_nlink;

    // 文件所有者

    char* fileUser = getpwuid(st.st_uid)->pw_name;

    // 文件所属组

    char* fileGrp = getgrgid(st.st_gid)->gr_name;

    // 文件大小

    int fileSize = (int)st.st_size;

    // 修改时间

    char* time = ctime(&st.st_mtime);

    char mtime[512] = { 0 };

    strncpy(mtime, time, strlen(time) - 1);

 

    char buf[1024];

    sprintf(buf, "%s %d %s %s %d %s %s", perms, linkNum, fileUser, fileGrp, fileSize, mtime, argv[1]);

 

    printf("%s\n", buf);

 

    return 0;

}

posted on 2018-04-05 20:46  狂自私  阅读(510)  评论(0编辑  收藏  举报