#include <stdio.h> #include <getopt.h> #include <sys/types.h> #include <unistd.h> #include <sys/stat.h> #include <time.h> #include <grp.h> #include <pwd.h> #include <dirent.h> #include <glob.h> #include <string.h> #define BUFSIZE 1024 /* 1.尝试实现ls命令的功能 加选项-l -a -i -h */ int stat_show(struct stat file_st,char flg); int l_show(char *file_name, struct stat File_st,char flg); int _show(char *file_name, struct stat File_st,char flg); int main(int argc, char **argv) { struct option opts[2] = {{"ls", no_argument, NULL, 'A'}, {0, 0, 0, 0}}; struct stat file_st; glob_t glober; int c = 0; char *f_name = NULL; char buf[BUFSIZE] = {}; if (argc < 2) { printf("argv<\n"); return -1; } while (1) { // ‘-’ 开头识别非选项参数 c = getopt_long(argc, argv, "-l::a::i::h::", opts, NULL); if (c == -1) break; //获取文件信息 if (stat(argv[2], &file_st) == -1) { perror("stat()"); return -1; } switch (c) { case 'l': //-l后不带其他选项 if (optarg == NULL) { _show(argv[2], file_st,c); break; } //-l后带其他选项 else { switch (*optarg) { //选项为 a case 'a': l_show(argv[2], file_st,'a'); break; //选项为 i case 'i': l_show(argv[2], file_st,'i'); break; //选项为 h case 'h': l_show(argv[2], file_st,'h'); break; default: break; } } break; case 'i': _show(argv[2], file_st,c); break; case 'h': _show(argv[2], file_st,c); break; case 'a': _show(argv[2], file_st,c); break; default: break; } } } /*-l显示*/ int stat_show(struct stat file_st,char flg) { struct passwd *pwd = NULL; struct group *grp = NULL; struct tm *time = NULL; char buf[100] = {}; if(flg=='i') printf("%ld ",file_st.st_ino); //文件类型 switch (file_st.st_mode & __S_IFMT) { case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; case S_IFBLK: printf("b"); break; case S_IFIFO: printf("p"); break; case S_IFCHR: printf("c"); break; case S_IFLNK: printf("l"); break; case S_IFSOCK: printf("s"); break; default: break; } //文件权限 //拥有者 if (file_st.st_mode & S_IRUSR) putchar('r'); else putchar('-'); if (file_st.st_mode & S_IWUSR) putchar('w'); else putchar('-'); if (file_st.st_mode & S_IXUSR) { if (file_st.st_mode & S_ISUID) putchar('s'); else putchar('x'); if (file_st.st_mode & S_ISGID) putchar('g'); } else putchar('-'); //所属组 if (file_st.st_mode & S_IRGRP) putchar('r'); else putchar('-'); if (file_st.st_mode & S_IWGRP) putchar('w'); else putchar('-'); if (file_st.st_mode & S_IXGRP) { if (file_st.st_mode & S_ISUID) putchar('s'); else putchar('x'); if (file_st.st_mode & S_ISGID) putchar('g'); } else putchar('-'); //其他组 if (file_st.st_mode & S_IROTH) putchar('r'); else putchar('-'); if (file_st.st_mode & S_IWOTH) putchar('w'); else putchar('-'); if (file_st.st_mode & S_IXOTH) { if (file_st.st_mode & S_ISUID) putchar('s'); else putchar('x'); if (file_st.st_mode & S_ISGID) putchar('g'); } else putchar('-'); putchar(' '); //文件硬链接数 printf("%ld ", file_st.st_nlink); //文件名拥有者名 pwd = getpwuid(file_st.st_uid); printf("%s ", pwd->pw_name); //文件所属组名 grp = getgrgid(file_st.st_gid); printf("%s ", grp->gr_name); //文件大小获取 if(flg=='h') printf("%ldk ", (file_st.st_size)/1024); else printf("%ld ", file_st.st_size); //时间获取 time = localtime(&file_st.st_mtim.tv_sec); strftime(buf, 100, "%m月 %d %H:%M:%S", time); printf("%s ", buf); return 0; } /*-l后有其他选项*/ int l_show(char *file_name, struct stat File_st,char flg) { glob_t glober; struct stat file_st; int c = 0; char *f_name = NULL; //去掉 ‘/’ 的文件名 char buf[BUFSIZE] = {}; //非目录文件 if (!S_ISDIR(File_st.st_mode)) { stat_show(File_st, 'a'); printf("%s \n", file_name); } //目录文件 memset(buf, '\0', BUFSIZE); strcpy(buf, file_name); strcat(buf, "/*"); //尾追加 “/*” 因glob() glob(buf, 0, NULL, &glober); //追加隐藏文件 if(flg=='a') { memset(buf, '\0', BUFSIZE); strcpy(buf, file_name); strcat(buf, "/.*"); //尾追加 “/.” 因glob() 不记录隐藏文件 glob(buf, GLOB_APPEND, NULL, &glober); } for (int i = 0; i < glober.gl_pathc; i++) { stat((glober.gl_pathv)[i], &file_st); stat_show(file_st, flg); f_name = strrchr((glober.gl_pathv)[i], '/'); printf("%s \n", f_name + 1); } globfree(&glober); return 0; } /*一个选项*/ int _show(char *file_name, struct stat File_st,char flg) { struct stat file_st; glob_t glober; int c = 0; char buf[BUFSIZE] = {}; //非目录文件 if (!S_ISDIR(File_st.st_mode)) { stat_show(File_st, flg); printf("%s \n", file_name); return 0; } //目录文件 memset(buf, '\0', BUFSIZE); strcpy(buf, file_name); strcat(buf, "/*"); //尾追加 “/*” 因glob() glob(buf, 0, NULL, &glober); // -a if (flg == 'a') { //追加隐藏文件 memset(buf, '\0', BUFSIZE); strcpy(buf, file_name); strcat(buf, "/.*"); //尾追加 “/.” 因glob() 不记录隐藏文件 glob(buf, GLOB_APPEND, NULL, &glober); } for (int i = 0; i < glober.gl_pathc; i++) { if (flg == 'l') { stat((glober.gl_pathv)[i], &file_st); stat_show(file_st, flg); } if (flg == 'i') { printf("%ld ", File_st.st_ino); /* code */ } printf("%s \n", (glober.gl_pathv)[i] + 2); } globfree(&glober); }
#include
<stdio.h>
#include
<getopt.h>
#include
<sys/types.h>
#include
<unistd.h>
#include
<sys/stat.h>
#include
<time.h>
#include
<grp.h>
#include
<pwd.h>
#include
<dirent.h>
#include
<glob.h>
#include
<string.h>
#define BUFSIZE
1024
/*
1.尝试实现ls命令的功能 加选项-l -a -i -h
*/
int stat_show(
struct stat file_st,
char flg);
int l_show(
char *file_name,
struct stat File_st,
char flg);
int _show(
char *file_name,
struct stat File_st,
char flg);
int main(
int argc,
char **argv)
{
struct option opts[
2] = {{
"ls", no_argument,
NULL,
'A'}, {
0,
0,
0,
0}};
struct stat file_st;
glob_t glober;
int c =
0;
char *f_name =
NULL;
char buf[BUFSIZE] = {};
if (argc <
2)
{
printf(
"argv<\n");
return -
1;
}
while (
1)
{
// ‘-’ 开头识别非选项参数
c = getopt_long(argc, argv,
"-l::a::i::h::", opts,
NULL);
if (c == -
1)
break;
//获取文件信息
if (stat(argv[
2], &file_st) == -
1)
{
perror(
"stat()");
return -
1;
}
switch (c)
{
case
'l':
//-l后不带其他选项
if (optarg ==
NULL)
{
_show(argv[
2], file_st,c);
break;
}
//-l后带其他选项
else
{
switch (*optarg)
{
//选项为 a
case
'a':
l_show(argv[
2], file_st,
'a');
break;
//选项为 i
case
'i':
l_show(argv[
2], file_st,
'i');
break;
//选项为 h
case
'h':
l_show(argv[
2], file_st,
'h');
break;
default:
break;
}
}
break;
case
'i':
_show(argv[
2], file_st,c);
break;
case
'h':
_show(argv[
2], file_st,c);
break;
case
'a':
_show(argv[
2], file_st,c);
break;
default:
break;
}
}
}
/*-l显示*/
int stat_show(
struct stat file_st,
char flg)
{
struct passwd *pwd =
NULL;
struct group *grp =
NULL;
struct tm *time =
NULL;
char buf[
100] = {};
if(flg==
'i')
printf(
"%ld ",file_st.st_ino);
//文件类型
switch (file_st.st_mode & __S_IFMT)
{
case S_IFREG:
printf(
"-");
break;
case S_IFDIR:
printf(
"d");
break;
case S_IFBLK:
printf(
"b");
break;
case S_IFIFO:
printf(
"p");
break;
case S_IFCHR:
printf(
"c");
break;
case S_IFLNK:
printf(
"l");
break;
case S_IFSOCK:
printf(
"s");
break;
default:
break;
}
//文件权限
//拥有者
if (file_st.st_mode & S_IRUSR)
putchar(
'r');
else
putchar(
'-');
if (file_st.st_mode & S_IWUSR)
putchar(
'w');
else
putchar(
'-');
if (file_st.st_mode & S_IXUSR)
{
if (file_st.st_mode & S_ISUID)
putchar(
's');
else
putchar(
'x');
if (file_st.st_mode & S_ISGID)
putchar(
'g');
}
else
putchar(
'-');
//所属组
if (file_st.st_mode & S_IRGRP)
putchar(
'r');
else
putchar(
'-');
if (file_st.st_mode & S_IWGRP)
putchar(
'w');
else
putchar(
'-');
if (file_st.st_mode & S_IXGRP)
{
if (file_st.st_mode & S_ISUID)
putchar(
's');
else
putchar(
'x');
if (file_st.st_mode & S_ISGID)
putchar(
'g');
}
else
putchar(
'-');
//其他组
if (file_st.st_mode & S_IROTH)
putchar(
'r');
else
putchar(
'-');
if (file_st.st_mode & S_IWOTH)
putchar(
'w');
else
putchar(
'-');
if (file_st.st_mode & S_IXOTH)
{
if (file_st.st_mode & S_ISUID)
putchar(
's');
else
putchar(
'x');
if (file_st.st_mode & S_ISGID)
putchar(
'g');
}
else
putchar(
'-');
putchar(
' ');
//文件硬链接数
printf(
"%ld ", file_st.st_nlink);
//文件名拥有者名
pwd = getpwuid(file_st.st_uid);
printf(
"%s ", pwd->pw_name);
//文件所属组名
grp = getgrgid(file_st.st_gid);
printf(
"%s ", grp->gr_name);
//文件大小获取
if(flg==
'h')
printf(
"%ldk ", (file_st.st_size)/
1024);
else
printf(
"%ld ", file_st.st_size);
//时间获取
time = localtime(&file_st.st_mtim.tv_sec);
strftime(buf,
100,
"
%
m月 %d
%
H:
%
M:%S", time);
printf(
"%s ", buf);
return
0;
}
/*-l后有其他选项*/
int l_show(
char *file_name,
struct stat File_st,
char flg)
{
glob_t glober;
struct stat file_st;
int c =
0;
char *f_name =
NULL;
//去掉 ‘/’ 的文件名
char buf[BUFSIZE] = {};
//非目录文件
if (!S_ISDIR(File_st.st_mode))
{
stat_show(File_st,
'a');
printf(
"%s \n", file_name);
}
//目录文件
memset(buf,
'\0', BUFSIZE);
strcpy(buf, file_name);
strcat(buf,
"/*");
//尾追加 “/*” 因glob()
glob(buf,
0,
NULL, &glober);
//追加隐藏文件
if(flg==
'a')
{
memset(buf,
'\0', BUFSIZE);
strcpy(buf, file_name);
strcat(buf,
"/.*");
//尾追加 “/.” 因glob() 不记录隐藏文件
glob(buf, GLOB_APPEND,
NULL, &glober);
}
for (
int i =
0; i < glober.gl_pathc; i++)
{
stat((glober.gl_pathv)[i], &file_st);
stat_show(file_st, flg);
f_name = strrchr((glober.gl_pathv)[i],
'/');
printf(
"%s \n", f_name +
1);
}
return
0;
}
/*一个选项*/
int _show(
char *file_name,
struct stat File_st,
char flg)
{
struct stat file_st;
glob_t glober;
int c =
0;
char *f_name =
NULL;
char buf[BUFSIZE] = {};
//非目录文件
if (!S_ISDIR(File_st.st_mode))
{
stat_show(File_st, flg);
printf(
"%s \n", file_name);
return
0;
}
//目录文件
memset(buf,
'\0', BUFSIZE);
strcpy(buf, file_name);
strcat(buf,
"/*");
//尾追加 “/*” 因glob()
glob(buf,
0,
NULL, &glober);
// -a
if (flg ==
'a')
{
//追加隐藏文件
memset(buf,
'\0', BUFSIZE);
strcpy(buf, file_name);
strcat(buf,
"/.*");
//尾追加 “/.” 因glob() 不记录隐藏文件
glob(buf, GLOB_APPEND,
NULL, &glober);
}
for (
int i =
0; i < glober.gl_pathc; i++)
{
if (flg ==
'l')
{
stat((glober.gl_pathv)[i], &file_st);
stat_show(file_st, flg);
}
if (flg ==
'i')
{
printf(
"%ld ", File_st.st_ino);
/* code */
}
printf(
"%s \n", (glober.gl_pathv)[i] +
2);
}
}