实现ls-l功能

1、“ls -l”的意义

  以长格式显示目录下的内容列表。输出的信息从左到右依次包括文件名,文件类型、权限模式、硬连接数、所有者、组、文件大小和文件的最后修改时间等。

  例:-rw-rw-r-- 1 using using 3102 7月 22 17:06 test.c

    drwxrwxr-x 2 using using 4096 7月 22 18:39 testdir

    lrwxrwxrwx 1 using using 17 7月 22 18:43 shared -> /media/sf_shared/

  其中深蓝色为目录文件,天蓝色为软连接文件(具体颜色和vimrc配置有关)。

  第一字段:首字母代表的是文件类型 ,其中"-"为普通文件、"d"为目录文件、"c"为字符设备文件、"b"为块设备文件、"p"为管道文件、"l"为链接文件、"s"为socket文件。“rwx”分别代表拥有读、写和执行权限,“-”代表无对应权限。三个“rwx”依次代表文件所有者、文件所有者所在用户组、其它用户对文件拥有的权限。

  第二字段:文件硬连接数量

  第三字段:文件拥有者

  第四字段:文件拥有者所在组

  第五字段:文件大小(以字节为单位)

  第六字段:文件最后更改时间

扫描二维码关注公众号,回复: 3982837 查看本文章

  第七字段:文件名(若为链接文件则追加显示其链接的原文件的路径)

实现代码

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


#define ERR_EXIT(m) \
do\
{\
    perror(m);\
    exit(EXIT_FAILURE);\
}while(0)\

void lsdir(char *dirname);
void lsfile(char *filename);
void lsfile(char *filename);
char getFileType(struct stat *fstat);
void getFilePerm(struct stat *st, char *perm);

int main(int argc,char **argv)
{

if(argc != 2){
    fprintf(stderr,"usage:%s [filepath]\n",argv[0]);
    exit(EXIT_FAILURE);
}
struct stat fstat;
if(lstat(argv[1],&fstat) == -1)
    ERR_EXIT("STAT ERROR");

if(S_ISDIR(fstat.st_mode))
{
    lsdir(argv[1]);
}
else{
    lsfile(argv[1]);
}
return 0;
}

void lsdir(char *dirname)
{
DIR *dir;
char filename[100] = {0};
dir =opendir(dirname); 
if(dir == NULL)
    ERR_EXIT("opendir error");
struct dirent *dentry;
while((dentry = readdir(dir)) != NULL)
{
    
    char *fname;
    fname = dentry->d_name;
    if(strncmp(fname,".",1) == 0)
        continue;
    sprintf(filename,"%s/%s",dirname,fname);
    lsfile(filename);
}

closedir(dir);

}

//-rw-r--r--.   1            zxy        zxy        2586        Jul 10 17:00    ls.c
//类型及权限  硬链接数        拥有者    所属组    文件大小    创建时间        文件名
void lsfile(char *filename)
{
struct stat tmpstat;
if(lstat(filename,&tmpstat) == -1)
    ERR_EXIT("STAT ERROR");
char buf[11]= {0};
strcpy(buf,"----------");
char type;
type = getFileType(&tmpstat);
char *bname = basename(filename);
buf[0] = type;
if(type == 'l'){
    char content[1024];
    if(readlink(filename,content,1024) == -1)
        ERR_EXIT("readlink error");
    sprintf(bname,"%s -> %s",bname,content);

}
getFilePerm(&tmpstat,buf);
struct tm *ftime;
ftime = localtime(&tmpstat.st_mtime);

printf("%s %d %s %s %10ld %02d %02d %02d:%02d %s\n",
    buf,tmpstat.st_nlink,
    getpwuid(tmpstat.st_uid)->pw_name,
    getgrgid(tmpstat.st_gid)->gr_name,
    tmpstat.st_size,
    ftime->tm_mon+1,
    ftime->tm_mday,
    ftime->tm_hour,
    ftime->tm_min,
    bname);

}

//获得文件类型
char getFileType(struct stat *st)
{
char type = '-';
switch (st->st_mode  & S_IFMT)
{
    case S_IFSOCK:
    type = 's';
            break;
    case S_IFLNK:
    type = 'l';
            break;
    case S_IFREG:
    type = '-';
            break;
    case S_IFBLK:
    type = 'b';
            break;
    case S_IFDIR:
    type = 'd';
            break;
    case S_IFCHR:
    type = 'c';
            break;
    case S_IFIFO:
    type = 'p';
            break;
}
return type;
}

//获得文件访问权限
void getFilePerm(struct stat *st, char *perm)
{
mode_t mode = st->st_mode;
if (mode & S_IRUSR)
    perm[1] = 'r';
if (mode & S_IWUSR)
    perm[2] = 'w';
if (mode & S_IXUSR)
    perm[3] = 'x';
if (mode & S_IRGRP)
    perm[4] = 'r';
if (mode & S_IWGRP)
    perm[5] = 'w';
if (mode & S_IXGRP)
    perm[6] = 'x';
if (mode & S_IROTH)
    perm[7] = 'r';
if (mode & S_IWOTH)
    perm[8] = 'w';
if (mode & S_IXOTH)
    perm[9] = 'x';
}

猜你喜欢

转载自www.cnblogs.com/zl1998827/p/9928089.html