linuxnbsp;下myls实现

 2023-09-05 阅读 55 评论 0

摘要:===================================================
==============================================================================================================================================================================
作者:心梦无痕
 
 完成时间2013 .7 .26
 
 
 程序主体思路来自,linuxc 编程实战 自己实现ls
 
  find(); 除外
 
 
 分析原代碼的一些感悟,该程序将命令行中的参数转化为宏(以数字替换)
 --1.#define  PARAM_NONE 0 在main函数中,int flag=PARAM_NONE ;得到flag时,
 通过判断,参数赋值给flag
 flag|=(定义过该代表命令的宏)
 
   有     0|x==x;
  获得命令参数标志
  如有多个选项直接讨论他们相加的情况,避免了直接对,选项名的讨论。
 
 --2.定义了每一行容纳长度的宏
 当前行的占用长度,以此作为衡量尺度判断,该文件名应该放到该行还是下一行。
 再问件名间打印固定的空格数,(也可定义为宏);
 如果使用固定个数打印,如果某行文件名较长的话,就不能显示全文件名;
 然而该方法会自动将其放到下一行打印
 
 
 =============================================================================================================================================================================



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <dirent.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>
#include <string.h>


#define PARAM_NONE 0 //无参数
#define PARAM_A    1 //-a
#define PARAM_L    2 //-l

#define PARAM_R    10

#define MAXROWLEN  80//一行显示的最多字数

int sys_leave=MAXROWLEN;
int sys_maxlen;


void show_attribute(struct stat buf,char* filename);

void display(int flag,char* pathname);

void show_ruler(char *);



void find_all(char* dirnamex)
{
    DIR * dir=NULL;
    char dirname[1024];
    char dirlist[256][1204];
    struct dirent * ptr;
    struct stat st;
    int i=0,j=0;
    char path1[512];

    puts(dirnamex);

    chdir(dirnamex);
    getwd(dirname);
    printf("dir:%s\n",dirname);

    if((dir=opendir("./"))==NULL)   
    {
        printf("null");
        return ;
    }

    i=0;
    while((ptr=readdir(dir))!=NULL)
    {
        if(stat(ptr->d_name,&st)==-1)
        {
            perror("error name");
        }
       
        if(strcmp(ptr->d_name,".")&&strcmp(ptr->d_name,".."))
        {
            //puts(ptr->d_name); 

            show_ruler(ptr->d_name);

            if(S_ISDIR(st.st_mode))
            {
                strcpy(dirlist[i++],ptr->d_name);
            }
        }
    }

    for(j=0;j<i;j++)
    {
        find_all(dirlist[j]);
    }
    //回到上层目录,将其设置为工作目录
    chdir("..");
}

void display_dir(int flag,char* path)
{
    DIR* dir;
    struct dirent* ptr;
    int count;
    char filename[256][PATH_MAX+1],temp[PATH_MAX+1];
    int i,j,len;

    dir=opendir(path);

    if(dir==NULL)
    {
        exit(1);
    }

    while((ptr=readdir(dir))!=NULL)
    {
        if(sys_maxlen<strlen(ptr->d_name))
        sys_maxlen=strlen(ptr->d_name);
        count++;
    }
   
    closedir(dir);

    if(count>256)
    {
        printf("too lage\n");
        exit(1);
    }

    len=strlen(path);

    dir=opendir(path);
    for(i=0;i<count;i++)
    {
        ptr=readdir(dir);
        if(ptr==NULL)
        {
            printf("readdir\n");
            exit(1);
        }
       
        strncpy(filename[i],path,len);
        filename[i][len]='\0';
        strcat(filename[i],ptr->d_name);
        filename[i][strlen(ptr->d_name)+len]='\0';
    }

   
    for(i=0;i<count-1;i++)
    {
        for(j=0;j<count-1-i;j++)
        {
            if(strcmp(filename[j],filename[j+1])>0)
            {
                strcpy(temp,filename[j+1]);
                temp[strlen(filename[j+1])]='\0';

                strcpy(filename[j+1],filename[j]);
                filename[j+1][strlen(filename[j])]='\0';

                strcpy(filename[j],temp);
                filename[j][strlen(temp)]='\0';
            }
        }
   
    }

    for(i=0;i<count;i++)
    {
        display(flag,filename[i]);
    }
    closedir(dir);

    if((flag&PARAM_L)==0)
    printf("\n");
}









void show_error(char* errorcase,int len)
{

    fprintf(stderr,"len:%d",len);
    perror(errorcase);
    exit(1);

}

void show_ruler(char* filename)
{
    int i,len;
    if(sys_leave<sys_maxlen)
    {
        //新行开始,预留回复
        printf("\n");
        sys_leave=MAXROWLEN;
    }
    //获得长度
    len=strlen(filename);
    //获得空格数
    len=sys_maxlen-len;
    printf("%-s",filename);

    for(i=0;i<len;i++)
    {
        printf(" ");
    }

    printf(" ");
    sys_leave-=sys_maxlen;
    sys_leave-=2;
}


void display(int flag,char* pathname)
{

    int i,j;
    char filename[NAME_MAX+1];
    struct stat filestat;
   
   
    //for(i=0,j=0;*(pathname+i)!="\0";i++)
    for(i=0,j=0;i<strlen(pathname);i++)
    {
        if(*(pathname+i)=='/')
        {
            continue;
            j=0;
        }
        filename[j++]=*(pathname+i);
    }
    filename[j]='\0';

   
    strcpy(filename,filename+1);



   
    if(lstat(pathname,&filestat)==-1)
    {
        show_error("setstat",__LINE__);
    }

   
    switch(flag)
    {
        case PARAM_NONE:
            if(filename[0]!='.')
            {
                show_ruler(filename);       
            }
        break;
       
        case PARAM_A:
        show_ruler(filename);
        break;
       
        case PARAM_L:
        if(filename[0]!='.')
        {
            show_attribute(filestat,filename);
            printf(" %s\n",filename);
        }
        break;

        case PARAM_A+PARAM_L:
        {
            show_attribute(filestat,filename);
            printf(" %s\n",filename);
        }
        break;

       
        case PARAM_R:
            find_all(filename);
        break;

        default :
        break;
    }
}


void show_attribute(struct stat buf,char* filename)
{
    //时间的格式位数
    char buf_time[32];
    struct passwd *password;
    struct group *grp;

   
    if(S_ISLNK(buf.st_mode))
    {
        printf("1");
    }
    else if(S_ISREG(buf.st_mode))
    {
        printf("-");
    }
    else if(S_ISDIR(buf.st_mode))
    {
        printf("d");
    }
    else if(S_ISCHR(buf.st_mode))
    {
        printf("c");
    }
    else if(S_ISBLK(buf.st_mode))
    {
        printf("b");
    }
    else if(S_ISFIFO(buf.st_mode))
    {
        printf("f");
    }
    else if(S_ISSOCK(buf.st_mode))
    {
        printf("s");
    }
   
    if(buf.st_mode&S_IRUSR)
    {
        printf("r");
    }
    else
    {
        printf("-");
    }
   
    if(buf.st_mode&S_IWUSR)
    {
        printf("w");
    }
    else
    {
        printf("-");
    }

   
    if(buf.st_mode&S_IXUSR)
    {
        printf("x");
    }
    else
    {
        printf("-");
    }

   
    if(buf.st_mode&S_IRGRP){
        printf("r");
    }else{
        printf("-");
    }
   
    if(buf.st_mode&S_IWGRP){
        printf("w");
    }else{
        printf("-");
    }

    if(buf.st_mode&S_IRGRP){
        printf("x");
    }else{
        printf("-");
    }

   
    if(buf.st_mode&S_IROTH){
        printf("r");
    }else{
        printf("-");
    }
    if(buf.st_mode&S_IWOTH){
        printf("w");
    }else{
        printf("-");
    }
    if(buf.st_mode&S_IXOTH){
        printf("x");
    }else{
        printf("-");
    }

    printf("    ");

   
    password=getpwuid(buf.st_uid);
    grp=getgrgid(buf.st_gid);
    printf("M",(int)buf.st_nlink);
    printf("%-8s",password->pw_name);
    printf("%-8s",grp->gr_name);

    printf("m",(int)buf.st_size);
    strcpy(buf_time,ctime(&buf.st_mtime));
    buf_time[strlen(buf_time)-1]='\0';
    printf("  %s",buf_time);
}


void main(int argc,char** argv)
{
    int i,j,k,num;
    char path[PATH_MAX+1];
    char param[32];
    int flag_param=PARAM_NONE;
    struct stat buf;

    j=0;
    num=0;
    for(i=1;i<argc;i++){
        if(argv[i][0]=='-'){
            for(k=1;k<strlen(argv[i]);k++,j++){
                param[j]=argv[i][k];
            }
            num++; //- count
        }
    }

    for(i=0;i<j;i++)
    {
        if(param[i]=='a'){
            flag_param|=PARAM_A;
            continue;
        }else if(param[i]=='l'){
            flag_param|=PARAM_L;
            continue;
        }
        else if(param[i]=='R')
        {
            flag_param|=PARAM_R;
        }
        else
        {
            printf("my ls :invalid option %c\n",param[i]);
            exit(1);
        }
    }
    param[j]='\0';

    if(num+1==argc)
    {
        strcpy(path,"./");
        path[2]='\0';
        display_dir(flag_param,path);
        return;
    }

    i=1;
    do{
        if(argv[i][0]=='-'){
            i++;
            continue;
        }else{
            strcpy(path,argv[i]);
       

        //not dir or file showerror
        if(stat(path,&buf)==-1)
        {
            show_error("stat",__LINE__);
        }
        if(S_ISDIR(buf.st_mode)){
            if(path[strlen(argv[i])-1]!='/'){
                path[strlen(argv[i])-1]='/';
                path[strlen(argv[i])+1]='\0';
            }else{
                path[strlen(argv[i])]='\0';
            }
            display_dir(flag_param,path);
            i++;
        }
        else {
            display(flag_param,path);
            i++;
        }
    }
   
    }while(i<argc);
}

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/2886.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息