Linux下c实现ls
作者:互联网
主要功能及实现:
1,使用命令行参数分析,暂时只支持 -l -a -n ,可混合使用或不使用
2,对于隐藏文件目前只考虑 . 和 ..
源代码如下:
/**************************************************************
> File Name: myls.c
> Author: LuoLiang
> Mail: 1204553475@qq.com
> Created Time: 2022年01月08日 星期六 13时09分11秒
**************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#include <glob.h>
#include <time.h>
#define SIZE 1024
/* 获取文件类型 */
static char getFileType(struct stat *statbuf)
{
switch (statbuf->st_mode & S_IFMT)
{
case S_IFREG:
return '-';
case S_IFDIR:
return 'd';
case S_IFSOCK:
return 's';
case S_IFBLK:
return 'b';
case S_IFIFO:
return 'F';
default:
return '?';
}
}
/* 获取权限信息 */
static char *getPermission(struct stat *statbuf)
{
char *buf;
int i, k = 0;
buf = calloc(9,sizeof(char));
if (buf == NULL)
{
fprintf(stderr,"calloc() fail\n");
exit(1);
}
for (i = 0; i < 9; i++)
buf[i] = '-';
if (statbuf->st_mode & S_IRUSR)
buf[k] = 'r';
if (statbuf->st_mode & S_IWUSR)
buf[k+1] = 'w';
if (statbuf->st_mode & S_IXUSR)
buf[k+2] = 'x';
if (statbuf->st_mode & S_IRGRP)
buf[k+3] = 'r';
if (statbuf->st_mode & S_IWGRP)
buf[k+4] = 'w';
if (statbuf->st_mode & S_IXGRP)
buf[k+5] = 'x';
if (statbuf->st_mode & S_IROTH)
buf[k+6] = 'r';
if (statbuf->st_mode & S_IWOTH)
buf[k+7] = 'w';
if (statbuf->st_mode & S_IXOTH)
buf[k+8] = 'x';
return buf;
}
/* 获取uname */
static char *getUsrname(int uid)
{
struct passwd *uid_line;
uid_line = getpwuid(uid);
if (uid_line == NULL)
{
perror("getpwuid()");
exit(1);
}
return uid_line->pw_name;
}
/* 获取gname */
static char *get_Gropname(int gid)
{
struct group *gid_line;
gid_line = getgrgid(gid);
if (gid_line == NULL)
{
perror("getpwuid()");
exit(1);
}
return gid_line->gr_name;
}
/* 获取文件去掉绝对路径的名字 */
static char *getRealName(char *pathname)
{
char *pos = NULL;
pos = strrchr(pathname,'/');
if (pos)
return pos+1;
return pathname;
}
/*
static int Judge_loop(char *pathname)
{
char *pos = NULL;
pos = strrchr(pathname,'/');
if (strcmp(pos+1,".") == 0 || strcmp(pos+1,"..") == 0)
return 0;
return 1;
}
*/
/* 根据参数打印文件属性 */
static void PrintFileNature(char *pathname,char *optbuf,struct stat *statbuf)
{
char *pms_ret = NULL;
char *uid_ret = NULL;
char *gid_ret = NULL;
char *newname = NULL;
char type;
/* 将mtime改为本地时间 */
struct tm *t = localtime(&statbuf->st_mtime);
pms_ret = getPermission(statbuf);
newname = getRealName(pathname);
type = getFileType(statbuf);
if (optbuf[0] == 'l' && optbuf[2] != 'n')
{
uid_ret = getUsrname(statbuf->st_uid);
gid_ret = get_Gropname(statbuf->st_gid);
printf("%c%s %2ld %-4s %-4s %6ld %-2d月 %-2d %2d:%2d %-s\n",type,pms_ret,statbuf->st_nlink,uid_ret,gid_ret,\
statbuf->st_size,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,newname);
}
if (optbuf[1] == 'a' && optbuf[0] != 'l' && optbuf[2] != 'n')
{
puts(newname);
}
if (optbuf[2] == 'n')
{
printf("%c%s %2ld %-4d %-4d %-6ld %-2d月 %-2d %2d:%2d %-s\n",type,pms_ret,statbuf->st_nlink,statbuf->st_uid,\
statbuf->st_gid,statbuf->st_size,(t->tm_mon)+1,t->tm_mday,t->tm_hour,t->tm_min,newname);
}
if (optbuf[0] == 0 && optbuf[1] == 0 && optbuf[2] == 0)
printf("%s\n",newname);
}
/* 获取文件夹里面文件的信息 */
static void getDirMsg(char *pathname,char *optbuf)
{
int l_ret;
struct stat statbuf;
l_ret = lstat(pathname,&statbuf);
if (l_ret < 0)
{
perror("lstat()");
exit(1);
}
PrintFileNature(pathname,optbuf,&statbuf);
}
/* 通过文件类型进行对应操作 */
static void key_ls(char *pathname,char *optbuf)
{
int l_ret;
struct stat statbuf;
char pattern[SIZE] = {0};
glob_t line;
l_ret = lstat(pathname,&statbuf);
if (l_ret < 0)
{
perror("lstat()");
exit(1);
}
/* 如果是文件,直接打印属性信息 */
if (S_ISREG(statbuf.st_mode))
{
PrintFileNature(pathname,optbuf,&statbuf);
return ;
}
/* 如果是文件夹,获取文件夹下的文件 */
if(S_ISDIR(statbuf.st_mode))
{
/* 文件隐藏文件匹配 */
if (optbuf[1] == 'a')
{
strncpy(pattern,pathname,SIZE);
strncat(pattern,"/.",SIZE-1);
glob(pattern,0,NULL,&line);
strncpy(pattern,pathname,SIZE);
strncat(pattern,"/..",SIZE-1);
glob(pattern,GLOB_APPEND,NULL,&line);
}
strncpy(pattern,pathname,SIZE);
strncat(pattern,"/*",SIZE-1);
if (optbuf[1] == 'a')
glob(pattern,GLOB_APPEND,NULL,&line);
else
glob(pattern,0,NULL,&line);
for (int i = 0; i < line.gl_pathc; i++)
{
getDirMsg(line.gl_pathv[i],optbuf);
}
globfree(&line);
}
else
return ;
return ;
}
/* 根据文件名匹配 */
void func(char **pathname,char *optbuf)
{
int i, k = 0;
if (pathname[0] == NULL)
{
pathname[0] = "./";
}
for (i = 0; pathname[i]; i++)
{
if (k++)
printf("\n");
key_ls(pathname[i],optbuf);
}
}
int main(int argc,char **argv)
{
int opt;
int flag = 1;
int k = 0;
char *pathname[SIZE];
char optbuf[3] = {0};
while ((opt = getopt(argc,argv,"-lan")) != -1)
{
flag = 0;
switch (opt)
{
case 1:
pathname[k++] = argv[optind-1];
break;
//-l
case 'l':
optbuf[0] = 'l';
break;
//-a
case 'a':
optbuf[1] = 'a';
break;
//-n
case 'n':
optbuf[2] = 'n';
break;
}
}
/* 未输入路径,默认为当前路径 */
if (flag)
pathname[k++] = "./";
func(pathname,optbuf);
exit(0);
}
标签:return,实现,statbuf,st,char,pathname,ls,Linux,optbuf 来源: https://blog.csdn.net/pdx_ll/article/details/122525073