linux c 模仿ls
/*
ls -l -a -i -h
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <glob.h>
#include <dirent.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#define BUFSIZE 1024
void mystat(char *path);
//文件所有属性
void listl(char *path)
{
struct stat stat;
char buf[BUFSIZE] = {};
glob_t pglob;
if(lstat(path, &stat) < 0)//失败返回-1
{
perror("lstat()");
return;
}
if(!S_ISDIR(stat.st_mode))//判断是不是目录
{
mystat(path);
return;
}
strcpy(buf, path);//复制字符串
strcat(buf, "/*");//链接字符串
glob(buf, 0, NULL, &pglob);//匹配路径
for(int i = 0; i < pglob.gl_pathc; i++)
{
mystat(pglob.gl_pathv[i]);
}
globfree(&pglob);
}
void mystat(char *path)
{
struct stat mystat;
if (lstat(path, &mystat) == -1) {
perror("stat()");
return ;
}
// 类型
switch(mystat.st_mode & S_IFMT) {
case S_IFREG:
printf("-");
break;
case S_IFDIR:
putchar('d');
break;
case S_IFSOCK:
printf("s");
break;
case S_IFLNK:
printf("l");
break;
case S_IFBLK:
putchar('b');
break;
case S_IFCHR:
printf("c");
break;
case S_IFIFO:
printf("p");
break;
default:
break;
}
// 权限
if (mystat.st_mode & S_IRUSR)
putchar('r');
else
putchar('-');
if (mystat.st_mode & S_IWUSR)
putchar('w');
else
putchar('-');
if (mystat.st_mode & S_IXUSR) {
if (mystat.st_mode & S_ISUID) {
putchar('s');
} else
putchar('x');
} else
putchar('-');
if (mystat.st_mode & S_IRGRP)
putchar('r');
else
putchar('-');
if (mystat.st_mode & S_IWGRP)
putchar('w');
else
putchar('-');
if (mystat.st_mode & S_IXGRP) {
if (mystat.st_mode & S_ISGID) {
putchar('s');
} else
putchar('x');
} else
putchar('-');
if (mystat.st_mode & S_IROTH)
putchar('r');
else
putchar('-');
if (mystat.st_mode & S_IWOTH)
putchar('w');
else
putchar('-');
if (mystat.st_mode & S_IXOTH) {
if (mystat.st_mode & S_ISVTX) {
putchar('s');
} else
putchar('x');
} else
putchar('-');
// 硬链接
printf(" %ld ", mystat.st_nlink);
// 文件拥有者名
struct passwd *pwd = NULL;
pwd = getpwuid(mystat.st_uid);
printf("%s ", pwd->pw_name);
// 文件所属组
struct group *grp = NULL;
grp = getgrgid(mystat.st_gid);
printf("%s ", grp->gr_name);
// 总字节个数 磁盘空间大小st_blocks/2 k
printf("%ld ", mystat.st_size);
// 获取文件时间 atime mtime ctime
struct tm *tmp = NULL;
tmp = localtime(&mystat.st_mtim.tv_sec);
// if error
char buf[BUFSIZE] = {};
strftime(buf, BUFSIZE, "%m月 %d %H:%M", tmp);
printf("%s ", buf);
// 文件名
char *p = strrchr(path,'/');
printf("%s ", ++p);
putchar('\n');
return;
}
//文件名(包括隐含文件)
void lista(char *path)
{
struct stat stat;
char buf[BUFSIZE] = {};
glob_t pglob;
if(lstat(path, &stat) < 0)
{
perror("lstat()");
return;
}
if(!S_ISDIR(stat.st_mode))
{
printf("%s \n",path);
return;
}
strcpy(buf, path);
strcat(buf, "/*");
glob(buf, 0, NULL, &pglob);
//隐藏文件
memset(buf,'\0',BUFSIZE);
strcpy(buf, path);
strcat(buf, "/.*");
glob(buf, GLOB_APPEND, NULL, &pglob);
for(int i = 0; i < pglob.gl_pathc; i++)
{
if(lstat(((pglob.gl_pathv)[i]),&stat) < 0){
perror("lstat()");
return;
}
char *p = strrchr((pglob.gl_pathv)[i],'/');
printf("%s \n",++p);
}
globfree(&pglob);
// printf("文件名\n");
}
//文件大小+文件名
void listi(char *path)
{
struct stat stat;
char buf[BUFSIZE] = {};
glob_t pglob;
if(lstat(path, &stat) < 0)
{
perror("lstat()");
return;
}
if(!S_ISDIR(stat.st_mode))
{
printf("%ld %s \n",stat.st_ino,path);
return;
}
strcpy(buf, path);
strcat(buf, "/*");
glob(buf, 0, NULL, &pglob);
for(int i = 0; i < pglob.gl_pathc; i++)
{
if(lstat(((pglob.gl_pathv)[i]),&stat) < 0){
perror("lstat()");
return;
}
char *p = strrchr((pglob.gl_pathv)[i],'/');
printf("%ld %s \n",stat.st_ino,++p);
}
globfree(&pglob);
// printf("文件大小 文件名\n");
}
//文件名(不包括隐含文件)
void listh(char *path)
{
struct stat stat;
char buf[BUFSIZE] = {};
glob_t pglob;
if(lstat(path, &stat) < 0)
{
perror("lstat()");
return;
}
if(!S_ISDIR(stat.st_mode))
{
printf("%ld %s \n",stat.st_size,path);
return;
}
strcpy(buf, path);
strcat(buf, "/*");
glob(buf, 0, NULL, &pglob);
for(int i = 0; i < pglob.gl_pathc; i++)
{
if(lstat(((pglob.gl_pathv)[i]),&stat) < 0){
perror("lstat()");
return;
}
char *p = strrchr((pglob.gl_pathv)[i],'/');
printf("%s \n",++p);
}
globfree(&pglob);
// printf("文件名\n");
}
int main(int argc, char *argv[])
{
char *optstring = "-l:a:h:i:";
int c;
while(1){
c = getopt(argc, argv, optstring);
if(c == -1)
break;
switch(c){
case 'l':
listl(optarg);
break;
case 'a':
lista(optarg);
break;
case 'i':
listi(optarg);
break;
case 'h':
listh(optarg);
break;
default:
break;
}
}
return 0;
}

浙公网安备 33010602011771号