您的位置:首页 > 其它

(myls)模拟" ls "命令

2010-09-16 20:50 701 查看
/*2010-09-16*/
/*模拟" ls "命令*/

/*程序用到的函数:lstat();sprintf();open();read();strstr();readlink();opendir();readdir();closedir();strlen();bzero();*/

/*myls*/
#include <string.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>

void myls(const char* path)
{
const char* savepath=path;
char BUF[500];
struct stat buf;
int ret;

bzero(BUF,500);
ret=lstat(path,&buf);
if(ret==-1)
{
perror("stat");
exit(-1);
}
if(S_ISREG(buf.st_mode))
sprintf(BUF,"-");
else if(S_ISDIR(buf.st_mode))
sprintf(BUF,"d");
else if(S_ISLNK(buf.st_mode))//这个判断不能少!
sprintf(BUF,"l");

/**********************判断用户权限**********************/
if(buf.st_mode & S_IRUSR)
sprintf(BUF+1,"r");
else sprintf(BUF+1,"-");
if(buf.st_mode & S_IWUSR)
sprintf(BUF+2,"w");
else sprintf(BUF+2,"-");
if(buf.st_mode & S_IXUSR)
sprintf(BUF+3,"x");
else sprintf(BUF+3,"-");

if(buf.st_mode & S_IRGRP)
sprintf(BUF+4,"r");
else sprintf(BUF+4,"-");
if(buf.st_mode & S_IWGRP)
sprintf(BUF+5,"w");
else sprintf(BUF+5,"-");
if(buf.st_mode & S_IXGRP)
sprintf(BUF+6,"x");
else sprintf(BUF+6,"-");

if(buf.st_mode & S_IROTH)
sprintf(BUF+7,"r");
else sprintf(BUF+7,"-");
if(buf.st_mode & S_IWOTH)
sprintf(BUF+8,"w");
else sprintf(BUF+8,"-");
if(buf.st_mode & S_IXOTH)
sprintf(BUF+9,"x");
else sprintf(BUF+9,"-");

sprintf(BUF+10," ");

/**********************处理硬链接个数**********************/
sprintf(BUF+11,"%d",buf.st_nlink);
sprintf(BUF+12," ");

/**********************处理用户名**********************/

int fd;
char fbuf[100];
char a;
char name[1000];//数组不能太小!!!
char uid[50];//数组不能太小!!!!
int i=0;
char* p;

bzero(uid,50);
i= sprintf(uid,"%d",buf.st_uid);//用这种方法将int型转换成字符串
if(i==-1)
{
perror("uid");
}
uid[i]='/0';
i=0;

fd=open("/etc/passwd",O_RDONLY);
while(1)
{
ret=read(fd,fbuf,20);
if(ret==0)
break;
p=strstr(fbuf,uid);
if(NULL!=p)//若找到匹配的子字符串
{
do{
p--;
}while(*p!='/n');

p++;//跳过'/n'

do{
name[i]=*p;//取'/n'与':'之间的字符串
i++;
p++;
}while(*p!=':');
// name[i]='/0';
break;//若不退出,段错误
}
}
p=NULL;
sprintf(BUF+13,"%s",name);
sprintf(BUF+13+strlen(name)," ");

/**********************处理软链接**********************/

int j;
int len;

len=sprintf(BUF+14+strlen(name),"%ld",buf.st_size);//把其长度记下
for(i=0;i<8-len;i++)
{
sprintf(BUF+14+strlen(name)+len+i," ");
}
sprintf(BUF+14+strlen(name)+len+i," ");

/**********************处理并打印文件/目录名**********************/

int pathlen;//定义路径字符串长度

pathlen=strlen(path);
path=(path+pathlen-1);//path为一维指针
for(j=pathlen-1;j>0;j--)//从后往前找'/',如果没找到则指向文件名的开始
{
path--;
if(*path=='/')
break;
}
path++;//跳过'/'
pathlen=sprintf(BUF+15+strlen(name)+len+i,"%s",path);//sprintf的使用要非常紧凑?

/**********************处理软链接**********************/
if(S_ISLNK(buf.st_mode))
{
char linkbuf[200];//不能太小!
ret=readlink(savepath,linkbuf,200);//读软链接
sprintf(BUF+15+strlen(name)+len+i+pathlen," -> ");
sprintf(BUF+19+strlen(name)+len+i+pathlen,"%s",linkbuf);

}
ret=strlen(BUF);
BUF[ret]='/0';
printf("%s/n",BUF);
close(fd);
}

int main(int argc,char **argv)
{
if(argc!=2)
{
fprintf(stderr,"Wrong usage...");
exit(1);
}

struct stat stbuf;
int ret;

ret=lstat(argv[1],&stbuf);
if(ret==-1)
{
perror("lstat");
exit(1);
}

if(S_ISREG(stbuf.st_mode))//判断,如果打开的是一个普通文件,则直接打印其信息,退出
{
myls(argv[1]);
exit(1);
}
else if(S_ISLNK(stbuf.st_mode))//如果打开的是一个软链接
{
char lbuf[100];
bzero(lbuf,100);//如果不清零的话打印时会出现乱码
readlink(argv[1],lbuf,100);
printf("%s->%s/n",argv[1],lbuf);
exit(1);
}
else /***************如果打开的是一个目录则作以下处理**********/
{
DIR* dirp=opendir(argv[1]);
if(dirp==NULL)
{
perror("opendir");
exit(1);
}

char* father=argv[1];
char buf[256];
struct dirent* fdirp;

while(1)
{
fdirp=readdir(dirp);
if(fdirp==NULL)
break;
if(father[strlen(father)-1]=='/')
sprintf(buf,"%s%s",argv[1],fdirp->d_name);
else
sprintf(buf,"%s/%s",argv[1],fdirp->d_name);
myls(buf);//buf中存的是路径
}
closedir(dirp);
}
exit(0);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐