osvimer
2/20/2016 - 8:22 AM

my_ls.c

/*=========================================================
* Author         : Junjie Huang
* Email          : acmhjj@gmail.com
* Last modified  : 2016-02-20 16:21
* Filename       : my_ls.c
* Description    : 遍历并打印指定目录下文件信息
=========================================================*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>

char file[256];

int my_ls(char *);
int my_dir_scan(char *);

int main (int argc, char const* argv[])
{
    if(argc < 2){
        printf("Arguments Error!\n");
        return -1;
    }
    struct stat buf;
    bzero(file, sizeof(file));
    strcpy(file, argv[1]);
    stat(file, &buf);
    if (S_ISDIR(buf.st_mode)){
        my_dir_scan(file);
    }else{
        my_ls(file);
    }
    return 0;
}
//遍历当前目录
int my_dir_scan(char * file){
    DIR * dir;
    dir = opendir(file);
    if(NULL == dir){
        perror("opendir");
        return -1;
    }
    struct dirent * pdi;
    while(pdi=readdir(dir)){
        if(strcmp(".", pdi->d_name) != 0 && strcmp("..", pdi->d_name) != 0){
            my_ls(pdi->d_name);
        }
    }
    closedir(dir);
    return 0;
}
//文件状态显示
int my_ls(char * file_name){
    int i;
    struct stat buf;
    char file_mode[11];
    char file_time[25];
    char file_path[256];
    bzero(file_mode, sizeof(file_mode));
    bzero(file_time, sizeof(file_time));
    bzero(file_path, sizeof(file_path));
    sprintf(file_path, "%s%s%s", file, "/", file_name);
    if(stat(file_path, &buf) == -1){
        perror("stat");
        return -1;
    }
    unsigned short pfm = buf.st_mode;
    //文件类型
    if (S_ISREG(buf.st_mode)){
        file_mode[0] = '-';
    }else if (S_ISDIR(buf.st_mode)){
        file_mode[0] = 'd';
    }else if (S_ISCHR(buf.st_mode)){
        file_mode[0] = 'c';
    }else if(S_ISBLK(buf.st_mode)){
        file_mode[0] = 'b';
    }else if(S_ISFIFO(buf.st_mode)){
        file_mode[0] = 'p';
    }else if(S_ISLNK(buf.st_mode)){
        file_mode[0] = 'l';
    }else if(S_ISSOCK(buf.st_mode)){
        file_mode[0] = 's';
    }
    //文件权限
    for(i = 0; i < 9; i++){
        if(pfm % 2 == 0){
            file_mode[9 - i] = '-';
        }else if(i % 3 == 0){
            file_mode[9 - i] = 'x';
        }else if(i % 3 == 1){
            file_mode[9 - i] = 'w';
        }else if(i % 3 == 2){
            file_mode[9 - i] = 'r';
        }
        pfm >>= 1;
    }
    //时间格式
    strcpy(file_time, ctime(&buf.st_mtime));
    char * pt = file_time + 4;
    *(pt + 12) = 0;
    printf("%10s%2lu%8s%8s%6ld%13s %-20s\n", file_mode, buf.st_nlink, getpwuid(buf.st_uid)->pw_name, getgrgid(buf.st_gid)->gr_name, buf.st_size, pt, file_name);
    return 0;
}

/*
   st_mode 中文件类型宏定义
   宏定义      类型
   --------------------------------
   S_ISREG()   普通文件
   S_ISDIR()   目录文件
   S_ISCHR()   字符设备文件
   S_ISBLK()   块设备文件
   S_ISFIFO()  有名管道文件
   S_ISLNK()   软连接(符号链接)文件
   S_ISSOCK()  套接字文件
*/