/*
*只支持当前目录下的-a, -l, -al的显示。希望对初学者有所帮助。
*/
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include <sys/stat.h> #include <unistd.h> #include <sys/types.h> #include <linux/limits.h> #include <dirent.h> #include <grp.h> #include <pwd.h> #include <error.h> #define NONE 0 //没有参数 #define HAVE_A 1 //参数是-a #define HAVE_L 2 //参数是-l #define HAVE_AL 3 #define HANGMAX 123 //一行最多打印的字符数 #define FILEMAX 256 int leave_max = HANGMAX; //记录一行剩余的字符数 int len_max; //目录下最长的文件 int count = 0; typedef struct file{ //记录当前目录下的所用文件名和文件长度 char filename[FILEMAX][30]; int filelen[FILEMAX]; }filelan; /* *函数名称:filelan copy_file(char *pathname) *函数功能:将当前目录下的所用文件拷贝到结构体filelan里 *传递参数:pathname:当前的目录 *返回类型:将拷贝完的文件返回给filelan F */ filelan copy_file(char *pathname) { DIR *dp; struct dirent *dirp; filelan F; int i; if((dp = opendir(pathname)) == NULL) printf("Cannot open %s\n", pathname); len_max = 0; i = 0; while((dirp = readdir(dp)) != NULL){ if(len_max < (strlen(dirp->d_name))) len_max = strlen(dirp->d_name); F.filelen[i] = strlen(dirp->d_name); strcpy(F.filename[i], dirp->d_name); i++; count++; } if(count > FILEMAX){ printf("Too Many Files!\n"); exit(0); } // printf("i = %d\n", i); // printf("count = %d\n", count); // printf("len_max = %d\n", len_max); closedir(dp); return F; } /* *函数名称:int part_parameter(int argc, char **argv) *函数功能:分离主函数传入的参数 *传递参数:argc:主函数参数个数,argv:主函数参数本身 *返回类型:flag:参数分离的结果 */ int part_parameter(int argc, char **argv) { int flag; if(argc == 1) flag = NONE; else if(argc == 2){ if((strcmp(argv[1], "-a")) == 0) flag = HAVE_A; else if((strcmp(argv[1], "-l")) == 0) flag = HAVE_L; else if((strcmp(argv[1], "-al")) == 0 ||(strcmp(argv[1], "-la")) == 0) flag = HAVE_AL; else{ perror("ERROR: <1>can shu\n"); exit(0); } } else if(argc == 3){ if(((strcmp(argv[1], "-a")) == 0) && ((strcmp(argv[2], "-l"))) == 0) flag = HAVE_AL; else if(((strcmp(argv[1], "-l")) == 0) && ((strcmp(argv[2], "-a"))) == 0) flag = HAVE_AL; else{ perror("ERROR: <2>cna shu\n"); exit(0); } } return flag; } /* *函数名称:show_file(int flag, filelan F) *函数功能:显示当前目录下的文件。 *传递参数:flag:判断是否为-a的参数。F:将拷贝好的结构体传入此函数。 *返回类型:无 */ void show_file(int flag, filelan F) { int i, j; int len; for(i = 0; i < count; i++) { if(len_max > leave_max){ printf("\n"); leave_max = HANGMAX; } if(flag == NONE) if(F.filename[i][0] == '.') continue; len = F.filelen[i]; len = len_max - len; printf("%s", F.filename[i]); for(j = 0; j < len; j++) printf(" "); printf(" "); leave_max = leave_max - (len_max+2); } printf("\n"); } /* *函数名称:void show_file_l(char *filename) *函数功能:主要显示有-l参数的文件 *传递参数:filename:要显示的文件名 *返回类型:无 */ void show_file_l(char *filename) { char file_time[32]; struct stat file_stat; struct passwd *psd; //获得文件所有者的用户名 struct group *grp; //获取文件所有者的所属组的组名 if(lstat(filename, &file_stat) == -1){ perror("Cannot get the information of the file!\n"); exit(0); } //获取并打印文件类型 if(S_ISREG(file_stat.st_mode)) printf("-"); else if(S_ISDIR(file_stat.st_mode)) printf("d"); else if(S_ISCHR(file_stat.st_mode)) printf("c"); else if(S_ISBLK(file_stat.st_mode)) printf("b"); else if(S_ISFIFO(file_stat.st_mode)) printf("f"); else if(S_ISLNK(file_stat.st_mode)) printf("l"); else if(S_ISSOCK(file_stat.st_mode)) printf("s"); //获取并打印文件所有者的权限 if(file_stat.st_mode & S_IRUSR) printf("r"); else printf("-"); if(file_stat.st_mode & S_IWUSR) printf("w"); else printf("-"); if(file_stat.st_mode & S_IXUSR) printf("x"); else printf("-"); //获取并打印文件所有者同组成员的权限 if(file_stat.st_mode & S_IRGRP) printf("r"); else printf("-"); if(file_stat.st_mode & S_IWGRP) printf("w"); else printf("-"); if(file_stat.st_mode & S_IXGRP) printf("x"); else printf("-"); //获取并打印其他用户的权限 if(file_stat.st_mode & S_IROTH) printf("r"); else printf("-"); if(file_stat.st_mode & S_IWOTH) printf("w"); else printf("-"); if(file_stat.st_mode & S_IXOTH) printf("x"); else printf("-"); printf(" "); psd = getpwuid(file_stat.st_uid); grp = getgrgid(file_stat.st_gid); printf("%4d ", file_stat.st_nlink); printf("%-8s", psd->pw_name); printf("%-8s", grp->gr_name); printf("%6d ", file_stat.st_size); strcpy(file_time, ctime(&file_stat.st_mtime)); file_time[strlen(file_time) - 1] = '\0'; printf(" %s", file_time); printf(" %s\n", filename); } //主函数:分离参数并且调用以上函数实现功能 int main(int argc, char **argv) { int flag,i; filelan F; F = copy_file("./"); flag = part_parameter(argc, argv); // printf("flag = %d\n", flag); switch(flag){ case NONE: show_file(NONE, F); break; case HAVE_A: show_file(HAVE_A, F); break; case HAVE_L: for(i = 0; i < count; i++){ if(F.filename[i][0] == '.') continue; show_file_l(F.filename[i]); } break; case HAVE_AL: for(i = 0; i < count; i++){ show_file_l(F.filename[i]); } break; } return 0; }
|