/*
*只支持当前目录下的-a, -l, -al的显示。希望对初学者有所帮助。
*/
# include < stdio. h>
# include < stdlib. h>
# include < string . h>
# include < time . h>
# include < sys/ stat. h>
# include < unistd. h>
# include < sys/ types. h>
# include < linux/ limits. h>
# include < dirent. h>
# include < grp. h>
# include < pwd. h>
# include < error . h>
# define NONE 0 //没有参数
# define HAVE_A 1 //参数是-a
# define HAVE_L 2 //参数是-l
# define HAVE_AL 3
# define HANGMAX 123 //一行最多打印的字符数
# define FILEMAX 256
int leave_max = HANGMAX; //记录一行剩余的字符数
int len_max; //目录下最长的文件
int count = 0;
typedef struct file { //记录当前目录下的所用文件名和文件长度
char filename[ FILEMAX] [ 30] ;
int filelen[ FILEMAX] ;
} filelan;
/*
*函数名称:filelan copy_file(char *pathname)
*函数功能:将当前目录下的所用文件拷贝到结构体filelan里
*传递参数:pathname:当前的目录
*返回类型:将拷贝完的文件返回给filelan F
*/
filelan copy_file( char * pathname)
{
DIR * dp;
struct dirent * dirp;
filelan F;
int i;
if ( ( dp = opendir( pathname) ) = = NULL )
printf ( "Cannot open %s/n" , pathname) ;
len_max = 0;
i = 0;
while ( ( dirp = readdir( dp) ) ! = NULL ) {
if ( len_max < ( strlen ( dirp- > d_name) ) )
len_max = strlen ( dirp- > d_name) ;
F. filelen[ i] = strlen ( dirp- > d_name) ;
strcpy ( F. filename[ i] , dirp- > d_name) ;
i+ + ;
count + + ;
}
if ( count > FILEMAX) {
printf ( "Too Many Files!/n" ) ;
exit ( 0) ;
}
// printf("i = %d/n", i);
// printf("count = %d/n", count);
// printf("len_max = %d/n", len_max);
closedir( dp) ;
return F;
}
/*
*函数名称:int part_parameter(int argc, char **argv)
*函数功能:分离主函数传入的参数
*传递参数:argc:主函数参数个数,argv:主函数参数本身
*返回类型:flag:参数分离的结果
*/
int part_parameter( int argc, char * * argv)
{
int flag;
if ( argc = = 1)
flag = NONE ;
else if ( argc = = 2) {
if ( ( strcmp ( argv[ 1] , "-a" ) ) = = 0)
flag = HAVE_A;
else if ( ( strcmp ( argv[ 1] , "-l" ) ) = = 0)
flag = HAVE_L;
else if ( ( strcmp ( argv[ 1] , "-al" ) ) = = 0 | | ( strcmp ( argv[ 1] , "-la" ) ) = = 0)
flag = HAVE_AL;
else {
perror ( "ERROR: <1>can shu/n" ) ;
exit ( 0) ;
}
}
else if ( argc = = 3) {
if ( ( ( strcmp ( argv[ 1] , "-a" ) ) = = 0) & & ( ( strcmp ( argv[ 2] , "-l" ) ) ) = = 0)
flag = HAVE_AL;
else if ( ( ( strcmp ( argv[ 1] , "-l" ) ) = = 0) & & ( ( strcmp ( argv[ 2] , "-a" ) ) ) = = 0)
flag = HAVE_AL;
else {
perror ( "ERROR: <2>cna shu/n" ) ;
exit ( 0) ;
}
}
return flag;
}
/*
*函数名称:show_file(int flag, filelan F)
*函数功能:显示当前目录下的文件。
*传递参数:flag:判断是否为-a的参数。F:将拷贝好的结构体传入此函数。
*返回类型:无
*/
void show_file( int flag, filelan F)
{
int i, j;
int len;
for ( i = 0; i < count ; i+ + )
{
if ( len_max > leave_max) {
printf ( "/n" ) ;
leave_max = HANGMAX;
}
if ( flag = = NONE )
if ( F. filename[ i] [ 0] = = '.' )
continue ;
len = F. filelen[ i] ;
len = len_max - len;
printf ( "%s" , F. filename[ i] ) ;
for ( j = 0; j < len; j+ + )
printf ( " " ) ;
printf ( " " ) ;
leave_max = leave_max - ( len_max+ 2) ;
}
printf ( "/n" ) ;
}
/*
*函数名称:void show_file_l(char *filename)
*函数功能:主要显示有-l参数的文件
*传递参数:filename:要显示的文件名
*返回类型:无
*/
void show_file_l( char * filename)
{
char file_time[ 32] ;
struct stat file_stat;
struct passwd * psd; //获得文件所有者的用户名
struct group * grp; //获取文件所有者的所属组的组名
if ( lstat( filename, & file_stat) = = - 1) {
perror ( "Cannot get the information of the file!/n" ) ;
exit ( 0) ;
}
//获取并打印文件类型
if ( S_ISREG( file_stat. st_mode ) )
printf ( "-" ) ;
else if ( S_ISDIR( file_stat. st_mode ) )
printf ( "d" ) ;
else if ( S_ISCHR( file_stat. st_mode ) )
printf ( "c" ) ;
else if ( S_ISBLK( file_stat. st_mode ) )
printf ( "b" ) ;
else if ( S_ISFIFO( file_stat. st_mode ) )
printf ( "f" ) ;
else if ( S_ISLNK( file_stat. st_mode ) )
printf ( "l" ) ;
else if ( S_ISSOCK( file_stat. st_mode ) )
printf ( "s" ) ;
//获取并打印文件所有者的权限
if ( file_stat. st_mode & S_IRUSR)
printf ( "r" ) ;
else printf ( "-" ) ;
if ( file_stat. st_mode & S_IWUSR)
printf ( "w" ) ;
else printf ( "-" ) ;
if ( file_stat. st_mode & S_IXUSR)
printf ( "x" ) ;
else printf ( "-" ) ;
//获取并打印文件所有者同组成员的权限
if ( file_stat. st_mode & S_IRGRP)
printf ( "r" ) ;
else printf ( "-" ) ;
if ( file_stat. st_mode & S_IWGRP)
printf ( "w" ) ;
else printf ( "-" ) ;
if ( file_stat. st_mode & S_IXGRP)
printf ( "x" ) ;
else printf ( "-" ) ;
//获取并打印其他用户的权限
if ( file_stat. st_mode & S_IROTH )
printf ( "r" ) ;
else printf ( "-" ) ;
if ( file_stat. st_mode & S_IWOTH)
printf ( "w" ) ;
else printf ( "-" ) ;
if ( file_stat. st_mode & S_IXOTH)
printf ( "x" ) ;
else printf ( "-" ) ;
printf ( " " ) ;
psd = getpwuid( file_stat. st_uid) ;
grp = getgrgid( file_stat. st_gid) ;
printf ( "%4d " , file_stat. st_nlink) ;
printf ( "%-8s" , psd- > pw_name) ;
printf ( "%-8s" , grp- > gr_name) ;
printf ( "%6d " , file_stat. st_size) ;
strcpy ( file_time, ctime ( & file_stat. st_mtime) ) ;
file_time[ strlen ( file_time) - 1] = '/0' ;
printf ( " %s" , file_time) ;
printf ( " %s/n" , filename) ;
}
//主函数:分离参数并且调用以上函数实现功能
int main( int argc, char * * argv)
{
int flag, i;
filelan F;
F = copy_file( "./" ) ;
flag = part_parameter( argc, argv) ;
// printf("flag = %d/n", flag);
switch ( flag) {
case NONE :
show_file( NONE , F) ;
break ;
case HAVE_A:
show_file( HAVE_A, F) ;
break ;
case HAVE_L:
for ( i = 0; i < count ; i+ + ) {
if ( F. filename[ i] [ 0] = = '.' )
continue ;
show_file_l( F. filename[ i] ) ;
}
break ;
case HAVE_AL:
for ( i = 0; i < count ; i+ + ) {
show_file_l( F. filename[ i] ) ;
}
break ;
}
return 0;
}