(myls)模拟" ls "命令

来源:互联网 发布:软件新技术有哪些 编辑:程序博客网 时间:2024/05/01 17:36

/*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);

}

原创粉丝点击