#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);
}
}
优质内容筛选与推荐>>
1、Linq To SQL分页失败后引发的思考2、【codecs】音视频编解码开源项目大汇总3、c#中常用集合类和集合接口之集合类系列【转】4、系统分析员考试试题结构分析5、Error:java: 无效的源发行版: 11
长按二维码向我转账
受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。