如果是做作业的孩子找到了这里,希望不要直接copy,供参考,其实我做的也不一定好嘻嘻。
其实这里,我考虑了输出的排序问题, 所以用了数组保存,可能感觉挺繁琐的 = =。一般情况下大家都是直接while输出。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<dirent.h>
#include<sys/types.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<pwd.h>
#include<grp.h>
#include<time.h>
#define BUFFERSIZE 512
char* info[200][7];
int num;
int allSize;
int n_year;
int isDir;
void getCode(int mode,char *code){
switch(mode){
case 7: code[0] = 'r';
code[1] = 'w';
code[2] = 'x';
break;
case 6: code[0] = 'r';
code[1] = 'w';
code[2] = '-';
break;
case 5: code[0] = 'r';
code[1] = '-';
code[2] = 'x';
break;
case 4: code[0] = 'r';
code[1] = '-';
code[2] = '-';
break;
case 3: code[0] = '-';
code[1] = 'w';
code[2] = 'x';
break;
case 2: code[0] = '-';
code[1] = 'w';
code[2] = '-';
break;
case 1: code[0] = '-';
code[1] = '-';
code[2] = 'x';
break;
default: code[0] = '-';
code[1] = '-';
code[2] = '-';
break;
};
code[3]='\0';
}
void getType(int i,mode_t mode){
if (S_ISREG(mode)){
info[i][0][0] = '-';
}else if(S_ISDIR(mode)){
info[i][0][0] = 'd';
}else if(S_ISBLK(mode)){
info[i][0][0] = 'b';
}else if(S_ISCHR(mode)){
info[i][0][0] = 'c';
}else if(S_ISFIFO(mode)){
info[i][0][0] = 'p';
}else if(S_ISLNK(mode)){
info[i][0][0] = 'l';
}else if(S_ISSOCK(mode)){
info[i][0][0] = 's';
}else{
info[i][0][0] = '-';
}
}
void getNumber(int num,char *nlink){
int i=0;
int cur=num;
while(cur > 0){
cur = cur/10;
i++;
}
cur = i;
if(num == 0){
nlink[0] = '0';
nlink[1] = '\0';
return;
}
while(num > 0){
nlink[i-1] = (num%10)+'0';
num = num / 10;
i--;
}
nlink[cur]='\0';
}
void getOwner(int id,char *owner){
struct passwd *data;
data = getpwuid(id);
strcpy(owner,data->pw_name);
}
void getGroup(int id,char *grp){
struct group *data;
data = getgrgid(id);
strcpy(grp,data->gr_name);
}
void getTime(time_t btime,char *atime){
char *mon[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
struct tm *p;
char clock[5];
atime[0]='\0';
p=localtime(&btime);
if(n_year == p->tm_year){
strcat(atime,mon[p->tm_mon]);
strcat(atime," ");
getNumber(p->tm_mday,clock);
strcat(atime,clock);
strcat(atime," ");
getNumber(p->tm_hour,clock);
if(p->tm_hour < 10){
strcat(atime,"0");
}
strcat(atime,clock);
strcat(atime,":");
if(p->tm_min < 10){
strcat(atime,"0");
}
getNumber(p->tm_min,clock);
strcat(atime,clock);
} else {
strcat(atime,mon[p->tm_mon]);
strcat(atime," ");
getNumber(p->tm_mday,clock);
strcat(atime,clock);
strcat(atime," ");
getNumber(p->tm_year+1900,clock);
strcat(atime,clock);
}
}
void calBlock(int size,mode_t mode){
if(S_ISLNK(mode)){
return;
}
int blocks = size / 4096;
if(size % 4096 > 0){
blocks++;
}
blocks*=4;
allSize+=blocks;
}
int addInfo(int x,char *path,char *name){
int i;
struct stat buf;
char code[12],code1[5];
char nlink[12],owner[80],group[80];
char time[30],fullpath[100],linkname[100];
linkname[0]='\0';
fullpath[0]='\0';
if(isDir==0){
strcpy(fullpath,path);
name = (char*)malloc(100*sizeof(char));
strcpy(name,strrchr(path,'/')+1);
} else {
strcat(fullpath,path);
strcat(fullpath,"/");
strcat(fullpath,name);
}
//get code of power
code[1]='\0';
for(i=0;i<=6;i++){
info[x][i] = (char*)malloc(100*sizeof(char));
}
lstat(fullpath,&buf);
getCode((buf.st_mode>>6)&7,code1);
strcat(code,code1);
getCode((buf.st_mode>>3)&7,code1);
strcat(code,code1);
getCode(buf.st_mode&7,code1);
strcat(code,code1);
code[10]='.';
code[11]='\0';
strcpy(info[x][0],code);
getType(x,buf.st_mode);
//get num of number
getNumber(buf.st_nlink,nlink);
strcpy(info[x][1],nlink);
//get owner
getOwner(buf.st_uid,owner);
strcpy(info[x][2],owner);
//get group
getGroup(buf.st_gid,group);
strcpy(info[x][3],group);
//get size
calBlock(buf.st_size,buf.st_mode);
getNumber(buf.st_size,nlink);
strcpy(info[x][4],nlink);
//get time
getTime(buf.st_mtime,time);
strcpy(info[x][5],time);
//get name of file
if(S_ISLNK(buf.st_mode)){
strcpy(info[x][6],name);
strcat(info[x][6]," -> ");
readlink(fullpath,linkname,100);
strcat(info[x][6],linkname);
}else{
strcpy(info[x][6],name);
}
}
int readList(char *path){
DIR *dir;
struct dirent *p;
struct stat buf;
time_t now=time(NULL);
struct tm *n = localtime(&now);
n_year = n->tm_year;
num=0;
allSize=0;
if((dir=opendir(path)) == NULL && access(path,F_OK)!=0){
return -1;
} else if(dir==NULL && access(path,F_OK) == 0){
addInfo(num,path,NULL);
isDir=0;
num++;
return;
}
isDir=1;
while((p=readdir(dir)) != NULL){
if(strcmp(p->d_name,".")==0 || strcmp(p->d_name,"..")==0 || p->d_name[0]=='.')
continue;
addInfo(num,path,p->d_name);
num++;
}
}
void sort(){
int i,j,k,t;
char temp[7][200];
for(i=num-1;i>1;i--){
for(j=0;j<=i-1;j++){
t = strcmp(info[j][6],info[j+1][6]);
if(t >= 1){
for(k=0;k<=6;k++){
strcpy(temp[k],info[j][k]);
}
for(k=0;k<=6;k++){
strcpy(info[j][k],info[j+1][k]);
}
for(k=0;k<=6;k++){
strcpy(info[j+1][k],temp[k]);
}
}
}
}
}
void displayList(){
int i,j;
sort();
if(isDir==1)
printf("Total:%d\n",allSize);
for(i=0;i<num;i++){
for(j=0;j<=6;j++){
if(j==0)
printf("%10s",info[i][j]);
else if(j==1 || j==2 || j==3 || j==4)
printf("%8s",info[i][j]);
else
printf("%15s",info[i][j]);
}
printf("\n");
}
}
int main(int argc,char **arvg){
char path[1026];
if(argc == 1){
getcwd(path,1024);
}else if(argc == 2){
strcpy(path,arvg[1]);
}
if(readList(path)==-1){
printf("Directory/File not exists.\n");
return;
}
displayList();
return 0;
}