ls 列出目录下的文件信息,在一下程序中,我只实现了参数:-a,-i,-l,-aF,具体代码如下,解析看注释(有些多余的输出是我在写代码时,用于测试):
#include <stdio.h>
#include <time.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>
#define MAX_LEN 1024
char *filename[MAX_LEN];
long inode[MAX_LEN];
void do_lsl(char *);
void do_lsa(char *,char, char);
void dostat(char *);
void show_file_info(char *,struct stat *);
void mode_to_letters(int,char[]);
char * uid_to_name(uid_t);
char * gid_to_name(gid_t);
void filename_sort();
void show_filename(char);
void stat_info(char *, struct stat *);
void main(int argc, char *argv[])
{
char *param;
char *path;
char ch1, ch2;
if(argc <= 1)
{
printf("请至少输入一个参数!\n");
return;
}
else if(argc == 2)
{
param = argv[1];
path = ".";
}
else
{
param = argv[1];
path = argv[2];
chdir(path);
}
ch1 = param[1];
if(strlen(param)>=3)
{
ch2 = param[2];
printf("--%d\n",strlen(param));
}
system("pwd");
switch(ch1)
{
case 'a':
do_lsa(path,ch1,ch2);
break;
case 'l':
do_lsl(path);
break;
case 'i':
do_lsa(path,ch1,ch2);
break;
}
}
void do_lsa(char dirname[],char ch1, char ch2)
{
struct stat info;
int i = 0, len;
DIR *dir_ptr;
struct dirent *direntp;
if((dir_ptr = opendir(dirname)) == NULL)
{
fprintf(stderr, "ls:cannot open %s\n",dirname);
}
else
{
while((direntp = readdir(dir_ptr)) != NULL)
{
inode[i] = direntp->d_ino;
len = sizeof(direntp->d_name);
filename[i] = (char *)malloc(len+3);
strcpy(filename[i],direntp->d_name);
if(ch2 == 'F')
{
if(stat(filename[i],&info) == -1)
{
printf("%d\n",errno);
return;
}
else
{
stat_info(filename[i],&info);
}
}
i++;
}
}
show_filename(ch1);
}
void show_filename(char ch)
{
int i,j;
filename_sort();
for(i=0; filename[i] != NULL; i++)
{ if(ch == 'i')
printf("%ld\t",inode[i]);
printf("%s\n", filename[i]);
}
}
void stat_info(char *filename, struct stat *info)
{
int mode = info->st_mode;
if(S_ISDIR(mode))
{
strcat(filename, "/");
return;
}
if(S_ISFIFO(mode))
{
strcat(filename, "|");
return;
}
if(S_ISSOCK(mode))
{
strcat(filename, "=");
return;
}
if(mode & S_IXUSR)
{
strcat(filename, "*");
return;
}
}
void filename_sort()
{
int i,j;
char *tmp;
for(i=0; filename[i]!=NULL; i++)
{
for(j=0; filename[j]!=NULL; j++)
{
if(strcmp(filename[i],filename[j]) <= 0)
{
tmp = (char *)malloc(sizeof(filename[j]+1));
strcpy(tmp, filename[j]);
strcpy(filename[j], filename[i]);
strcpy(filename[i], tmp);
}
}
}
}
void do_lsl(char dirname[])
{
DIR *dir_ptr;
struct dirent *direntp;
if((dir_ptr=opendir(dirname))==NULL)
fprintf(stderr,"ls:cannot open %s\n",dirname);
else
{
while((direntp=readdir(dir_ptr))!=NULL)
{
dostat(direntp->d_name);
}
closedir(dir_ptr);
}
}
void dostat(char *filename)
{
struct stat info;
if(lstat(filename,&info)==-1)
perror("lstat");
else
show_file_info(filename,&info);
}
void show_file_info(char *filename,struct stat *info_p)
{
char modestr[11];
mode_to_letters(info_p->st_mode,modestr);
printf("%-12s",modestr);
printf("%-4d",(int)info_p->st_nlink);
printf("%-8s",uid_to_name(info_p->st_uid));
printf("%-8s",gid_to_name(info_p->st_gid));
printf("%-8ld",(long)info_p->st_size);
time_t timelong=info_p->st_mtime;
struct tm *htime=localtime(&timelong);
printf("%-4d-%02d-%02d %02d:%02d",htime->tm_year+1900,htime->tm_mon+1,htime->tm_mday,htime->tm_hour,htime->tm_min);
printf(" %s\n",filename);
}
void mode_to_letters(int mode,char str[])
{
strcpy(str,"----------");
if(S_ISDIR(mode))
str[0]='d';
if(S_ISCHR(mode))
str[0]='c';
if(S_ISBLK(mode))
str[0]='b';
if(mode & S_IRUSR)
str[1]='r';
if(mode & S_IWUSR)
str[2]='w';
if(mode & S_IXUSR)
str[3]='x';
if(mode & S_IRGRP)
str[4]='r';
if(mode & S_IWGRP)
str[5]='w';
if(mode & S_IXGRP)
str[6]='x';
if(mode & S_IROTH)
str[7]='r';
if(mode & S_IWOTH)
str[8]='w';
if(mode & S_IXOTH)
str[9]='x';
}
char * uid_to_name(uid_t uid)
{
struct passwd *pw_str;
static char numstr[10];
if((pw_str=getpwuid(uid))==NULL)
{
sprintf(numstr,"%d",uid);
return numstr;
}
else
return pw_str->pw_name;
}
char * gid_to_name(gid_t gid)
{
struct group *grp_ptr;
static char numstr[10];
if((grp_ptr=getgrgid(gid))==NULL)
{
sprintf(numstr,"%d",gid);
return numstr;
}
else
return grp_ptr->gr_name;
}