主要功能及实现:
1,使用命令行参数分析,暂时只支持 -l -a -n ,可混合使用或不使用
2,对于隐藏文件目前只考虑 . 和 ..
源代码如下:
/************************************************************** > File Name: myls.c > Author: LuoLiang > Mail: 1204553475@qq.com > Created Time: 2022年01月08日 星期六 13时09分11秒 **************************************************************/ #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <sys/types.h> #include <pwd.h> #include <grp.h> #include <glob.h> #include <time.h> #define SIZE 1024 /* 获取文件类型 */ static char getFileType(struct stat *statbuf) { switch (statbuf->st_mode & S_IFMT) { case S_IFREG: return '-'; case S_IFDIR: return 'd'; case S_IFSOCK: return 's'; case S_IFBLK: return 'b'; case S_IFIFO: return 'F'; default: return '?'; } } /* 获取权限信息 */ static char *getPermission(struct stat *statbuf) { char *buf; int i, k = 0; buf = calloc(9,sizeof(char)); if (buf == NULL) { fprintf(stderr,"calloc() fail\n"); exit(1); } for (i = 0; i < 9; i++) buf[i] = '-'; if (statbuf->st_mode & S_IRUSR) buf[k] = 'r'; if (statbuf->st_mode & S_IWUSR) buf[k+1] = 'w'; if (statbuf->st_mode & S_IXUSR) buf[k+2] = 'x'; if (statbuf->st_mode & S_IRGRP) buf[k+3] = 'r'; if (statbuf->st_mode & S_IWGRP) buf[k+4] = 'w'; if (statbuf->st_mode & S_IXGRP) buf[k+5] = 'x'; if (statbuf->st_mode & S_IROTH) buf[k+6] = 'r'; if (statbuf->st_mode & S_IWOTH) buf[k+7] = 'w'; if (statbuf->st_mode & S_IXOTH) buf[k+8] = 'x'; return buf; } /* 获取uname */ static char *getUsrname(int uid) { struct passwd *uid_line; uid_line = getpwuid(uid); if (uid_line == NULL) { perror("getpwuid()"); exit(1); } return uid_line->pw_name; } /* 获取gname */ static char *get_Gropname(int gid) { struct group *gid_line; gid_line = getgrgid(gid); if (gid_line == NULL) { perror("getpwuid()"); exit(1); } return gid_line->gr_name; } /* 获取文件去掉绝对路径的名字 */ static char *getRealName(char *pathname) { char *pos = NULL; pos = strrchr(pathname,'/'); if (pos) return pos+1; return pathname; } /* static int Judge_loop(char *pathname) { char *pos = NULL; pos = strrchr(pathname,'/'); if (strcmp(pos+1,".") == 0 || strcmp(pos+1,"..") == 0) return 0; return 1; } */ /* 根据参数打印文件属性 */ static void PrintFileNature(char *pathname,char *optbuf,struct stat *statbuf) { char *pms_ret = NULL; char *uid_ret = NULL; char *gid_ret = NULL; char *newname = NULL; char type; /* 将mtime改为本地时间 */ struct tm *t = localtime(&statbuf->st_mtime); pms_ret = getPermission(statbuf); newname = getRealName(pathname); type = getFileType(statbuf); if (optbuf[0] == 'l' && optbuf[2] != 'n') { uid_ret = getUsrname(statbuf->st_uid); gid_ret = get_Gropname(statbuf->st_gid); printf("%c%s %2ld %-4s %-4s %6ld %-2d月 %-2d %2d:%2d %-s\n",type,pms_ret,statbuf->st_nlink,uid_ret,gid_ret,\ statbuf->st_size,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,newname); } if (optbuf[1] == 'a' && optbuf[0] != 'l' && optbuf[2] != 'n') { puts(newname); } if (optbuf[2] == 'n') { printf("%c%s %2ld %-4d %-4d %-6ld %-2d月 %-2d %2d:%2d %-s\n",type,pms_ret,statbuf->st_nlink,statbuf->st_uid,\ statbuf->st_gid,statbuf->st_size,(t->tm_mon)+1,t->tm_mday,t->tm_hour,t->tm_min,newname); } if (optbuf[0] == 0 && optbuf[1] == 0 && optbuf[2] == 0) printf("%s\n",newname); } /* 获取文件夹里面文件的信息 */ static void getDirMsg(char *pathname,char *optbuf) { int l_ret; struct stat statbuf; l_ret = lstat(pathname,&statbuf); if (l_ret < 0) { perror("lstat()"); exit(1); } PrintFileNature(pathname,optbuf,&statbuf); } /* 通过文件类型进行对应操作 */ static void key_ls(char *pathname,char *optbuf) { int l_ret; struct stat statbuf; char pattern[SIZE] = {0}; glob_t line; l_ret = lstat(pathname,&statbuf); if (l_ret < 0) { perror("lstat()"); exit(1); } /* 如果是文件,直接打印属性信息 */ if (S_ISREG(statbuf.st_mode)) { PrintFileNature(pathname,optbuf,&statbuf); return ; } /* 如果是文件夹,获取文件夹下的文件 */ if(S_ISDIR(statbuf.st_mode)) { /* 文件隐藏文件匹配 */ if (optbuf[1] == 'a') { strncpy(pattern,pathname,SIZE); strncat(pattern,"/.",SIZE-1); glob(pattern,0,NULL,&line); strncpy(pattern,pathname,SIZE); strncat(pattern,"/..",SIZE-1); glob(pattern,GLOB_APPEND,NULL,&line); } strncpy(pattern,pathname,SIZE); strncat(pattern,"/*",SIZE-1); if (optbuf[1] == 'a') glob(pattern,GLOB_APPEND,NULL,&line); else glob(pattern,0,NULL,&line); for (int i = 0; i < line.gl_pathc; i++) { getDirMsg(line.gl_pathv[i],optbuf); } globfree(&line); } else return ; return ; } /* 根据文件名匹配 */ void func(char **pathname,char *optbuf) { int i, k = 0; if (pathname[0] == NULL) { pathname[0] = "./"; } for (i = 0; pathname[i]; i++) { if (k++) printf("\n"); key_ls(pathname[i],optbuf); } } int main(int argc,char **argv) { int opt; int flag = 1; int k = 0; char *pathname[SIZE]; char optbuf[3] = {0}; while ((opt = getopt(argc,argv,"-lan")) != -1) { flag = 0; switch (opt) { case 1: pathname[k++] = argv[optind-1]; break; //-l case 'l': optbuf[0] = 'l'; break; //-a case 'a': optbuf[1] = 'a'; break; //-n case 'n': optbuf[2] = 'n'; break; } } /* 未输入路径,默认为当前路径 */ if (flag) pathname[k++] = "./"; func(pathname,optbuf); exit(0); }