使用linux c 实现linux控制台 ls 命令

来源:互联网 发布:婚纱照软件哪个好 编辑:程序博客网 时间:2024/06/05 20:22
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <error.h>#include <time.h>// ctime()函数#include <dirent.h>//操作目录#include <sys/stat.h>//操作文件#include <pwd.h>// 获取文件所有者#include <grp.h>//InfoModeAll -a        InfoModeDetail -l//显示信息模式typedef enum _InfoMode { InfoModeBothNo,InfoModeAll,InfoModeDetail,InfoModeBoth} InfoMode;//目录元素种类(文件、目录)enum ItemCategory { ItemCategoryDir, ItemCategoryFile };//显示目录中元素列表void display_dirItemList(char *path, int isAll);//显示目录中元素信息void display_dirItemInfo(char *path, int isAll);//显示目录信息void display_singleDirInfo(char *path);//显示文件信息void display_singleFileInfo(char *path);//显示文件名,根据文件路径void display_fileName(char *path);//显示文件信息void display_fileInfo(char *path, InfoMode mode);//显示目录信息void display_dirInfo(char *path, InfoMode mode);//解析命令行参数,返回,显示信息模式InfoMode AnalyticalParm(int argc, char **arg);//获取完整路径void getAbsolutePath(char *path);//检查path是否为绝对路径,0 不是,是相对路径  1 是绝对路径int checkPathIsAbsolutePath(char *path);//获取目录下的文件/目录名称,返回char **(这个变量需要动态释放),以及fileNameCountvoid getFileNameListFormDir(char *path,int isAll,char fileNameList[][10],int *fileNameCount);//打印目录元素的属性void Demonstrate_attribute(struct stat buf);//判断元素是文件还是目录int checkPathIsFile(char *path);int main(int argc, char **arg) {    /*    argc = 3;    arg[0] = "./my_ls";    arg[1] = "-a";    arg[1] = "-l";    arg[2] = "/home/pengjing/文档/10-文件读写/my_ls/bin/Debug/test/";    //int i;    //for(i=0; i<argc; i++) {        //printf("%s\t",arg[i]);    //}    //printf("\n");    */    InfoMode mode = AnalyticalParm(argc, arg);    char *path = arg[argc-1];    //判断是否为文件名,还是目录名,当res_index为0时,是目录名,当res_index为.所在的索引时为文件名    getAbsolutePath(path);    //过滤最后一个"/"    if(path[strlen(path)-1] == '/'){        path[strlen(path)-1] = '\0';    }    int isFile = checkPathIsFile(path);    if(isFile == 1) {        display_fileInfo(path,mode);    } else {        display_dirInfo(path,mode);    }    return 0;}void display_dirItemList(char *path, int isAll) {    int fileNameCount = 0;    char fileNames[30][10];    getFileNameListFormDir(path,isAll,fileNames,&fileNameCount);    int i;    for(i=0;i<fileNameCount;i++){        printf("%-s\t",fileNames[i]);    }    printf("\n");}void display_dirItemInfo(char *path, int isAll) {    int fileNameCount = 0;    char fileNameList[30][10];    char filePathList[30][100];    int i,j;    getFileNameListFormDir(path,isAll,fileNameList,&fileNameCount);    for(i=0; i<fileNameCount; ++i) {        char filePath[90] = {'\0'};        strcpy(filePath,path);        strcat(filePath,"/");        strcat(filePath,fileNameList[i]);        strcpy(filePathList[i],filePath);    }    struct stat _stat;    for(i=0; i<fileNameCount; i++) {        //bzero(_stat,sizeof(struct stat));        //printf("%s\n",filePathList[i]);        // /home/pengjing/document/10-文件读写/my_ls/bin/Debug/test/file1        // char *myPath = "/home/pengjing/document/10-文件读写/my_ls/bin/Debug/test/file1";        int res_lstat = lstat(filePathList[i],&_stat);        if(res_lstat == -1) {            perror("lstat");            exit(0);        }        Demonstrate_attribute(_stat);    }}void getFileNameListFormDir(char *path,int isAll,char fileNameList[][10],int *fileNameCount) {    struct dirent *diren;    DIR *dir;    *fileNameCount = 0;    //printf("fileNameList size :%ld\n",sizeof(fileNameList));    if((dir = opendir(path)) == NULL) {        perror("opendir");    }    while((diren = readdir(dir)) != NULL) {        char *name = diren->d_name;        if(isAll == 0 && name[0] == '.') {            continue;        }        strcpy(fileNameList[*fileNameCount],name);        (*fileNameCount)++;    }    closedir(dir);}//显示文件信息void display_singleFileInfo(char *path) {    //printf("显示单个文件信息\n");    struct stat _stat;    int res_lstat = lstat(path,&_stat);    if(res_lstat == -1) {        perror("lstat");        exit(0);    }    Demonstrate_attribute(_stat);}void display_fileName(char *path){    //printf("显示文件名");    char res[10],*a;    a = rindex(path,'/');    strcpy(res,a);    int i;    for(i=1;i<strlen(res);i++){        res[i-1] = res[i];    }    res[i-1] = '\0';    printf("%s\n",res);}//显示文件信息void display_fileInfo(char *path, InfoMode mode) {    //printf("显示文件的详细信息 mode:%d\n",mode);    //根据显示模式显示内容    switch(mode) {        case InfoModeBothNo: {            //显示目录中元素的名称            display_fileName(path);            break;        }        case InfoModeAll: {            //显示目录中所有元素的名称            display_fileName(path);            break;        }        case InfoModeDetail: {            //显示目录下元素的信息            display_singleFileInfo(path);            break;        }        case InfoModeBoth: {            //显示目录下所有元素的信息            display_singleFileInfo(path);            break;        }        default : {            //mode 错误            printf("mode 错误");            exit(0);            break;        }    }}//显示目录信息void display_dirInfo(char *path, InfoMode mode) {    //printf("显示目录的详细信息 mode:%d\n",mode);    //根据显示模式显示内容    switch(mode) {        case InfoModeBothNo: {            //显示目录中元素的名称            display_dirItemList(path,0);            break;        }        case InfoModeAll: {            //显示目录中所有元素的名称            display_dirItemList(path,1);            break;        }        case InfoModeDetail: {            //显示目录下元素的信息            display_dirItemInfo(path,0);            break;        }        case InfoModeBoth: {            //显示目录下所有元素的信息            display_dirItemInfo(path,1);            break;        }        default : {            //mode 错误            printf("mode 错误");            exit(0);            break;        }    }}//解析命令行参数,返回parmCount(参数个数),显示信息模式InfoMode AnalyticalParm(int argc, char **arg) {    int i;    InfoMode mode = InfoModeBothNo;    for(i = 1 ; i < argc; i++) {        if(arg[i][0] == '-') {            if(arg[i][1] == 'a') {                if(mode == InfoModeDetail) {                    mode = InfoModeBoth;                    break;                }                mode = InfoModeAll;            } else if(arg[i][1] == 'l') {                if(mode == InfoModeAll) {                    mode = InfoModeBoth;                    break;                }                mode = InfoModeDetail;            }        }    }    return mode;}int checkPathIsAbsolutePath(char *path) {    int res = 0;    if(path[0] == '/' || path[0] == '~') {        res = 1;    }    return res;}//获取文件属性并打印void Demonstrate_attribute(struct stat buf){    char buf_time[32]; //存放时间    struct passwd *psd; //从该结构体中获取文件所有者的用户名    struct group *grp; //从该结构体中获取文件所有者所属组的组名/*    我们使用最多的属性是st_mode.通过着属性我们可以判断给定的文件是一个普通文件还是一个目录,连接等等.可以使用下面几个宏来判断.    S_ISLNK(st_mode):是否是一个连接    S_ISREG是否是一个常规文件    S_ISDIR是否是一个目录    S_ISCHR是否是一个字符设备    S_ISBLK是否是一个块设备    S_ISFIFO是否是一个FIFO文件    S_ISSOCK是否是一个SOCKET文件    S_IFMT      0170000     文件类型的位遮罩    S_IFSOCK    0140000     socket    S_IFLNK     0120000     符号链接(symbolic link)    S_IFREG     0100000     一般文件    S_IFBLK     0060000     区块装置(block device)    S_IFDIR     0040000     目录    S_IFCHR     0020000     字符装置(character device)    S_IFIFO     0010000     先进先出(fifo)    S_ISUID     0004000     文件的(set user-id on execution)位    S_ISGID     0002000     文件的(set group-id on execution)位    S_ISVTX     0001000     文件的sticky位    S_IRWXU     00700       文件所有者的遮罩值(即所有权限值)    S_IRUSR     00400       文件所有者具可读取权限    S_IWUSR     00200       文件所有者具可写入权限    S_IXUSR     00100       文件所有者具可执行权限    S_IRWXG     00070       用户组的遮罩值(即所有权限值)    S_IRGRP     00040       用户组具可读取权限    S_IWGRP     00020       用户组具可写入权限    S_IXGRP     00010       用户组具可执行权限    S_IRWXO     00007       其他用户的遮罩值(即所有权限值)    S_IROTH     00004       其他用户具可读取权限    S_IWOTH     00002       其他用户具可写入权限    S_IXOTH     00001       其他用户具可执行权限*/    //获取并打印文件类型    if (S_ISLNK(buf.st_mode)){ //判断是否为符号链接        printf("l");    }else if (S_ISREG(buf.st_mode)){ //判断是否为文件        printf("-");    }else if (S_ISDIR(buf.st_mode)){ //判断是否为目录        printf("d");    }else if (S_ISCHR(buf.st_mode)){ //判断是否为字符设备文件        printf("c");    }else if (S_ISBLK(buf.st_mode)){ //判断是否为块设备文件        printf("b");    }else if (S_ISFIFO(buf.st_mode)){ //判断是否为先进先出的FIFO        printf("f");    }else if (S_ISSOCK(buf.st_mode)){ //判断是否为socket        printf("s");    }    //获取并打印文件所有者的权限    //按位与结果作为条件判断,应当判断其与结果为0还是非0数值  当前比较的是buf.st_mode在用户读权限的位与S_IRUSR是否相等    if (buf.st_mode & S_IRUSR){        printf("r");    }else{        printf("-");    }    if (buf.st_mode & S_IWUSR){        printf("w");    }else{        printf("-");    }    if (buf.st_mode & S_IXUSR){        printf("x");    }else{        printf("-");    }    //获取并打印与文件所有者同组的用户对该文件的操作权限    if(buf.st_mode & S_IRGRP){        printf("r");    }else{        printf("-");    }    if(buf.st_mode & S_IWGRP){        printf("w");    }else{        printf("-");    }    if(buf.st_mode & S_IXGRP){        printf("x");    }else{        printf("-");    }    //获取并打印其它用户的对该文件的操作权限    if (buf.st_mode & S_IROTH){        printf("r");    }else{        printf("-");    }    if (buf.st_mode & S_IWOTH){        printf("w");    }else{        printf("-");    }    if (buf.st_mode & S_IXOTH){        printf("x");    }else{        printf("-");    }    printf(" ");    //根据uid与gid获取文件所有者的用户名与组名    psd = getpwuid(buf.st_uid);    grp = getgrgid(buf.st_gid);    printf("%4d ",buf.st_nlink); //打印文件的链接数(该文件硬链接数目)    printf("%-9s", psd->pw_name); //打印文件拥有者    printf("%-8s", grp->gr_name); //打印文件所属用户组    printf("%6d",(int)buf.st_size); // 打印文件的大小    char *wo = ctime(&buf.st_mtime);    strcpy(buf_time, ctime(&buf.st_mtime));    buf_time[strlen(buf_time) - 1] = '\0'; // 去掉换行符    printf(" %s\n", buf_time); // 打印文件的时间信息}int checkPathIsFile(char *path){    int res = 0;    struct stat _stat;    int res_lstat = lstat(path,&_stat);    if(res_lstat == -1){        perror("lstat");        exit(0);    }    if(S_ISREG(_stat.st_mode)){ //判断是否为文件        res = 1;    }    return res;}void getAbsolutePath(char *path){    //组建绝对路径    char absPath[100];    int isAbsolutePath = checkPathIsAbsolutePath(path);    if(isAbsolutePath == 1) {        //absPath = (char *)malloc(sizeof(char) * strlen(path));        strcpy(absPath,path);    } else {        if(getcwd(absPath,200) == NULL) {            perror("获取当前工作目录失败");        }        strcat(absPath,"/");        strcat(absPath,path);        //printf("absPath:%s\n",absPath);    }    path = absPath;}


0 0
原创粉丝点击