實現ls-l功能
阿新 • • 發佈:2018-11-08
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”依次代表檔案所有者、檔案所有者所在使用者組、其它使用者對檔案擁有的許可權。
第二欄位:檔案硬連線數量
第三欄位:檔案擁有者
第四欄位:檔案擁有者所在組
第五欄位:檔案大小(以位元組為單位)
第六欄位:檔案最後更改時間
第七欄位:檔名(若為連結檔案則追加顯示其連結的原檔案的路徑)
實現程式碼
#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'; }