#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <time.h>
#include <errno.h>
#include <pwd.h>
#define len 32
int main(int argc, char const *argv[]) {
if(argc != 2) {
printf("Usage: %s [OPTION]\n", argv[0]);
goto err;
}
time_t t;
time(&t);
char uid_n[10];
char gid[10];
uid_t uid;
char level[9];
struct passwd *pwd;
unsigned char symbol;
int total = 0;
DIR *file = NULL;
struct dirent *dir = NULL;
struct stat st;
file = opendir(argv[1]);
if(file == NULL) {
printf("Line %d occurs %d error\n", __LINE__,errno);
goto err;
}
/*this step is needed,it'll fail on function stat as its path is not clear*/
if(-1 == chdir(argv[1])) {
printf("Line %d occurs %d error\n", __LINE__,errno);
goto err;
}
while ((dir = readdir(file)) != NULL) {
if(-1 == (stat(dir->d_name, &st))) {
printf("Line %d occurs %d error\n", __LINE__,errno);
goto err;
}
#if 0 /*another way to check the file type*/
if(S_ISDIR(st.st_mode))
printf("d");
else if(S_ISREG(st.st_mode))
printf("-");
else if(S_ISCHR(st.st_mode))
printf("c");
else if(S_ISBLK(st.st_mode))
printf("b");
else if(S_ISFIFO(st.st_mode))
printf("p");
else if(S_ISLNK(st.st_mode))
printf("l");
else if(S_ISSOCK(st.st_mode))
printf("s");
else
printf("?");
/*also can be written like this*/
switch(st.st_mode & S_IFMT)
{
case S_IFDIR:
printf("d");
break;
case S_IFREG:
printf("-");
break;
case S_IFCHR:
printf("c");
break;
case S_IFBLK:
printf("b");
break;
case S_IFIFO:
printf("p");
break;
case S_IFLNK:
printf("l");
break;
case S_IFSOCK:
printf("s");
break;
default:
printf("?");
break;
#endif
total += st.st_blocks;
switch (dir->d_type) {
case DT_DIR: symbol = 'd'; break;
case DT_REG: symbol = '-'; break;
case DT_BLK: symbol = 'b'; break;
case DT_LNK: symbol = 'l'; break;
case DT_FIFO: symbol = 'p'; break;
case DT_SOCK: symbol = 's'; break;
case DT_UNKNOWN: symbol = '?'; break;
default: printf("error happens\n");break;
}
uid = getuid();
pwd = getpwuid(uid);
if( NULL == pwd ) {
printf("Line %d:%d\n",__LINE__,errno);
goto err;
}
if(st.st_uid == getuid() || st.st_gid == getgid()) {
strcpy(uid_n,pwd->pw_name);
strcpy(gid,uid_n);
}
else{
strcpy(uid_n,"root");
strcpy(gid,uid_n);
}
/*文件所有者权限*/
if(st.st_mode & S_IRUSR)
level[0] = 'r';
else
level[0] = '-';
if(st.st_mode & S_IWUSR)
level[1] = 'w';
else
level[1] = '-';
if(st.st_mode & S_IXUSR)
level[2] = 'x';
else
level[2] = '-';
/*用户组权限*/
if(st.st_mode & S_IRGRP)
level[3] = 'r';
else
level[3] = '-';
if(st.st_mode & S_IWGRP)
level[4] = 'w';
else
level[4] = '-';
if(st.st_mode & S_IXGRP)
level[5] = 'x';
else
level[5] = '-';
/*其他用户权限*/
if(st.st_mode & S_IROTH)
level[6] = 'r';
else
level[6] = '-';
if(st.st_mode & S_IWOTH)
level[7] = 'w';
else
level[7] = '-';
if(st.st_mode & S_IXOTH)
level[8] = 'x';
else
level[8] = '-';
printf("%c",symbol);
printf("%s",level);
printf("%4u\t",st.st_nlink); /*在ac上运行需要用%u*/
printf("%s",uid_n);
printf("\t");
printf("%s",gid);
printf("%8lld\t",st.st_size); /*在ac上运行需要用%lld*/
printf("%24.24s ",ctime(&st.st_mtime));
printf("%s",dir->d_name);
printf("\t");
//printf("\n");
printf("\n");
if(NULL == dir && errno == 0)
break;
if(NULL == dir && errno != 0) {
printf("Line %d occurs %d error\n", __LINE__,errno);
goto err;
}
}
printf("total %d\n",total/2); //getconf PAGESIZE可以查看块的大小
closedir(file);
err:
exit(1);
return 0;
}