/*
*只支持當前目錄下的-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;
}