用C語言實作linux下的ls -l指令。與檔案相關的結構體、函數等等知識請看"stat結構體以及檔案相關函數"
#include
#include
#include
#include
#include
#include
#include
#include
void do_ls(char *dirname);
void dostat(char *filename);
void show_file_info(char *filename, struct stat *info_p);
void mode_to_letters(int mode, char * str);
char *uid_to_name(uid_t uid);
char *gid_to_name(gid_t gid);
int main(int argc, char **argv)
{
if (argc == 1)
{
do_ls( "." );
}
else
{
while ( --argc )
{
printf("%s:\n", *++argv );
chdir(*argv); //切換到指定目錄後再顯示該目錄的内容
do_ls( *argv );
chdir(""); //再回到目前工作目錄來
}
}
return 0;
}
void do_ls( char * dirname )
{
DIR *dir_ptr;
struct dirent *direntp;
if ( ( dir_ptr = opendir( dirname ) ) == NULL )
{
fprintf(stderr,"ls1: cannot open %s, not a directory. treat as a file shown below:\n", dirname);
dostat( dirname ); //如果不是目錄就當作檔案來顯示其屬性
}
else
{
while ( ( direntp = readdir( dir_ptr ) ) != NULL )
{
dostat( direntp->d_name );
}
closedir(dir_ptr);
}
}
void dostat( char *filename )
{
struct stat info;
if ( stat(filename, &info) == -1 )
{
perror( filename );
}
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("%s" , modestr);
//st_nlink連接配接該檔案的硬連結數,剛建立的檔案值為1
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);
printf("%.12s ", 4+ctime(&info_p->st_mtime));
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_ptr;
static char numstr[10];
//擷取使用者ID
if ((pw_ptr = getpwuid(uid)) == NULL)
{
sprintf(numstr,"%d", uid);
return numstr;
}
else
{
return pw_ptr->pw_name ;
}
}
char *gid_to_name( gid_t gid )
{
struct group *grp_ptr;
static char numstr[10];
//擷取組ID
if ((grp_ptr = getgrgid(gid)) == NULL)
{
sprintf(numstr,"%d", gid);
return numstr;
}
else
{
return grp_ptr->gr_name;
}
}