linux c编程实现ls -l递归调用子目录并缩进显示文件信息
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<string.h>
#include<pwd.h>
#include<grp.h>
#include<time.h>
#include<dirent.h>
#define N_BITS 3
char file_type(int mode){
if(S_ISDIR(mode)){
return 'd';
}
if(S_ISREG(mode)){
return '-';
}
if(S_ISFIFO(mode)){
return 'p';
}
if(S_ISLNK(mode)){
return 'l';
}
if(S_ISBLK(mode)){
return 'b';
}
if(S_ISSOCK(mode)){
return 's';
}
if(S_ISCHR(mode)){
return 'c';
}
return '0';
}
int print_perm(int st_mode){
int i;
unsigned int mask = 0700;
static char *perm[] = {"---","--x","-w-","-wx","r--","r-x","rw-","rwx"};
for(i = 3; i; --i){
printf("%3s",perm[(st_mode & mask) >> (i-1) * N_BITS]);
mask >>= N_BITS;
}
return 0;
}
int print_filename(struct stat file,char *filename) {
char filename_ink[128] = {};
memset(filename_ink,'\0',128);
if(S_ISDIR(file.st_mode)){
printf("\033[34m%s\033[0m\n",filename);
return 0;
}
if(S_ISLNK(file.st_mode)){
readlink(filename,filename_ink,128);
printf("\033[36m%s\033[0m -> %s\n",filename,filename_ink);
return 0;
}
if(S_IXUSR & file.st_mode || S_IXGRP & file.st_mode || S_IXOTH & file.st_mode){
printf("\033[32m%s\033[0m\n",filename);
return 0;
}
printf("\033[30m%s\033[0m\n",filename);
return 0;
}
int list_file(struct stat file,char * filename,int deep){
struct passwd *p_passwd;
struct group *p_group;
struct tm *t;
t = localtime(&file.st_mtime);
p_passwd = getpwuid(file.st_uid);
p_group = getgrgid(file.st_gid);
printf("%*s%c",deep,"",file_type(file.st_mode));
print_perm(file.st_mode);
printf("%5d%5s%8s%14d",file.st_nlink,p_passwd->pw_name,p_group->gr_name,file.st_size);
printf("%3d%5d%3d:%2d ",t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min);
print_filename(file,filename);
return 0;
}
int list_dir(char *dirname,int deep){
DIR *dirp;
struct dirent *dir;
struct stat file;
if((dirp = opendir(dirname)) == NULL){
perror(dirname);
exit(1);
}
chdir(dirname);
while((dir = readdir(dirp)) != NULL){
if(lstat(dir->d_name,&file) != 0){
perror(dir->d_name);
continue;
}
if(S_ISDIR(file.st_mode)){
if(dir->d_name[0] == '.'){
continue;
}
list_file(file,dir->d_name,deep);
list_dir(dir->d_name,deep + 4);
chdir("..");
}else {
list_file(file,dir->d_name,deep);
}
}
return 0;
}
int main(int argc, char *argv[]) {
char path[1024] = {};
struct stat filePath;
if(argc < 2){
printf("loss argument\n");
exit(1);
}
if((argc == 2 ) && !(strcmp(argv[1],"-l"))){
strcpy(path,".");
list_dir(path,0);
return 0;
}
if(argc == 3 && !strcmp(argv[1], "-l")){
if(lstat(argv[2],&filePath) == -1) {
perror(argv[2]);
exit(1);
}
if(S_ISDIR(filePath.st_mode)){
list_dir(argv[2],0);
}else {
list_file(filePath,argv[2],0);
}
return 0;
}else {
printf("input error.\n");
return 0;
}
}