linux 下myls实现

来源:互联网 发布:有人做淘宝秒杀群 编辑:程序博客网 时间:2024/06/05 23:07
==============================================================================================================================================================================
作者:心梦无痕
 
 完成时间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 //无参数
#definePARAM_A    1//-a
#definePARAM_L    2//-l

#definePARAM_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;
    chardirname[1024];
    chardirlist[256][1204];
    structdirent * ptr;
    struct statst;
    inti=0,j=0;
    charpath1[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;
    structdirent* ptr;
    intcount;
    charfilename[256][PATH_MAX+1],temp[PATH_MAX+1];
    inti,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("toolage\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)
{
    inti,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)
{

    inti,j;
    charfilename[NAME_MAX+1];
    struct statfilestat;
   
   
   //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)
    {
       casePARAM_NONE:
         if(filename[0]!='.')
          {
            show_ruler(filename);      
          }
       break;
      
       casePARAM_A:
      show_ruler(filename);
       break;
      
       casePARAM_L:
      if(filename[0]!='.')
       {
         show_attribute(filestat,filename);
          printf("%s\n",filename);
       }
       break;

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

      
       casePARAM_R:
         find_all(filename);
       break;

       default:
       break;
    }
}


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

   
   if(S_ISLNK(buf.st_mode))
    {
      printf("1");
    }
    elseif(S_ISREG(buf.st_mode))
    {
      printf("-");
    }
    elseif(S_ISDIR(buf.st_mode))
    {
      printf("d");
    }
    elseif(S_ISCHR(buf.st_mode))
    {
      printf("c");
    }
    elseif(S_ISBLK(buf.st_mode))
    {
      printf("b");
    }
    elseif(S_ISFIFO(buf.st_mode))
    {
      printf("f");
    }
    elseif(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)
{
    inti,j,k,num;
    charpath[PATH_MAX+1];
    charparam[32];
    intflag_param=PARAM_NONE;
    struct statbuf;

    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;
       }elseif(param[i]=='l'){
         flag_param|=PARAM_L;
         continue;
       }
       elseif(param[i]=='R')
       {
         flag_param|=PARAM_R;
       }
       else
       {
          printf("myls :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 orfile 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);
}
0 0
原创粉丝点击