您的位置:首页 > 运维架构 > Linux

ls(1)命令的简单实现(一)

2013-05-25 07:50 405 查看
这个命令主要利用opendir函数读出DIR结构体,然后用readdir函数读出struct dirent结构体,最后利用dirent结构体里面的d_name来用lstat函数读出文件的各种属性,最后格式化输出,下面的代码主要实现了无参数的默认文件名输出,还有实现了带‘-l’参数的属性输出,目前只是实现了‘-l’参数,以后再努力实现其他参数。

/********************************************************
Program:
List all the file of the directory.
History:
2013/04/08  dingdong  First release
2013/05/21  dingdong  Second release[not finish]
2013/05/24  dingdong  Third release[finish '-l']
*********************************************************/

#include "apue.h"
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>

void	parameters_l(char *temp);/*'-l' parameter*/

int
main(int argc,char *argv[])
{
DIR				*dp;
struct  dirent	*dirp;
int				i,j,k=0,count=0;/*count for format,per 5 d_name print '\n'*/
int				flag1=0,flag2=0;/*flag2 for extra parameters
flag1 check have parameters or not,
*/
char 			buf[10];

if(argc==1)/*current directory by default*/
argv[1]=".";

else if(argc>=2)
{
if(argv[1][0]=='-')flag1=1;
else flag1=0;
}

if(flag1&&argc==2)/*have no parameters and argc==2*/
argv[2]=".";

if(flag1)/*have parameters*/
{
for(i=1;i<argc;i++)
{
for(j=0;argv[i][j]!='\0';j++)
{
if(argv[i][j]!='-')/*collect the parameters*/
{
buf[k]=argv[i][j];
k++;
}
}
}
buf[k]='\0';

for(k=0;buf[k]!='\0';k++)
{
switch(buf[k])
{
case 'l':parameters_l(argv[2]);break;
default :flag2=1;
printf("%s: extra operand %s\n",argv[0],argv[1]);
break;
}
if(flag2)break;/*if have extra operand then break*/
}
}/*if(flag2)*/

else if(!flag1)/*not parameters*/
{
if((dp=opendir(argv[1]))==NULL)
err_sys("can't open %s",argv[1]);
while((dirp=readdir(dp))!=NULL)
{
printf("%-12s  ",dirp->d_name);
count++;
if(count==7)
{
count=0;
printf("\n");
}
}
printf("\n");
closedir(dp);
}
exit(0);
}

void parameters_l(char *temp)
{

DIR 			*dp;
struct dirent   *dirp;
struct stat     buf;
struct passwd	*uid;
struct group	*gid;
char			*time;/*for ctime */

if((dp=opendir(temp))==NULL)
err_sys("can't open %s",temp);

while((dirp=readdir(dp))!=NULL)
{
char mode[]="----------.";
if(lstat(dirp->d_name,&buf)<0)
err_ret("lstat error");

/*file type*/
if(S_ISDIR(buf.st_mode))mode[0]='d';/*directory*/
if(S_ISCHR(buf.st_mode))mode[0]='b';/*block special file*/
if(S_ISBLK(buf.st_mode))mode[0]='c';/*character special file*/
if(S_ISFIFO(buf.st_mode))mode[0]='f';/*FIFO*/
if(S_ISLNK(buf.st_mode))mode[0]='s';/*socket*/
if(S_ISSOCK(buf.st_mode))mode[0]='l';/*symbolic link*/

/*the mode of the file*/
if(buf.st_mode&S_IRUSR)mode[1]='r';
if(buf.st_mode&S_IWUSR)mode[2]='w';
if(buf.st_mode&S_IXUSR)mode[3]='x';
if(buf.st_mode&S_IRGRP)mode[4]='r';
if(buf.st_mode&S_IWGRP)mode[5]='w';
if(buf.st_mode&S_IXGRP)mode[6]='x';
if(buf.st_mode&S_IROTH)mode[7]='r';
if(buf.st_mode&S_IWOTH)mode[8]='w';
if(buf.st_mode&S_IXOTH)mode[9]='x';

/*user and group*/
if((uid=getpwuid(buf.st_uid))==NULL)
err_sys("getpwuid error");
if((gid=getgrgid(buf.st_gid))==NULL)
err_sys("getgrgid error");

/*ctime for file*/
time=ctime(&buf.st_ctime);
time[strlen(time)-1]='\0';/*ignore the '\n'*/

printf("%s %-2d %-8s %-8s %-5d %-1s %-5s\n",mode,buf.st_nlink,
uid->pw_name,gid->gr_name,buf.st_size,time,dirp->d_name);

}
closedir(dp);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Linux C 编程 Unix ls