Thread: Implementing "ls -al"

  1. #1
    Registered User
    Join Date
    Mar 2002
    Posts
    87

    Talking Implementing "ls -al"

    Can someone do me a favour and check if the following code works, i'm away from my linux machine. The following code should hopefully produce an output similar to that of the "ls -al" command.

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

    #define SIZE 256

    charworkdir(){
      
    size_t size FILENAME_MAX;
      while(
    1){
        
    charwdbuf = (char*)malloc(size);
        if(
    getcwd(wdbuf,size) == wdbuf)
          return 
    wdbuf;
        
    free(wdbuf);
        if(
    errno != ERANGE)return 0;
        
    size *=2;
      }
    }

    void printDetails(char *filename){

      
    struct passwd *my_passwd;
      
    struct group *my_group;
      
    struct stat sbuf;
      
    struct tm *strtime;

      
    int fdes;
      
    unsigned char type ='?';
      
    unsigned char usr[] = "---";
      
    unsigned char grp[] = "---";
      
    unsigned char oth[] = "---";
      
    unsigned char uid[9], gid[9];
      
    unsigned char mod[13];
      
    mode_t mode;
      
    charcurdir;
      
    time_t now;
      
    int year;

      
    /*Concatenate dir names*/
      
    curdir workdir();
      
    strcat(curdir,"/");
      
    strcat(curdir,filename);

      
    /*stat the final dir name*/
      
    if(stat(curdir,&sbuf) != -1){
        if(
    S_ISLNK(sbuf.st_mode)){
          if(
    lstat(curdir,&sbuf) == -1){
            
    fprintf(stderr,"Can't stat %s\n",filename);
            return;
          }
        }else if(
    S_ISREG(sbuf.st_mode)){
          if(
    fstat(fdes,&sbuf) == -1){
            
    fprintf(stderr,"Can't stat %s\n",filename);
            return;
          }
        }
      }else{
        
    fprintf(stderr,"Can't stat %s\n",filename);
        return;
      }      

      
    /*format information*/
      
    mode sbuf.st_mode;
      if( 
    S_ISLNKmode ) ) type 'l'/*symlink*/
      
    else if( S_ISDIR mode ) ) type 'd'/*directory*/
      
    else if( S_ISCHR mode ) ) type 'c'/*character raw device*/
      
    else if( S_ISBLK mode ) ) type 'b'/*block raw device*/
      
    else if( S_ISFIFOmode ) ) type 'p'/*named pipe*/
      
    else if( S_ISSOCKmode ) ) type 's'/*Unix domain socket*/
      
    else if( S_ISREG mode ) ) type '-'/*regular file*/
      
    if( mode S_IRUSR usr[0] = 'r';
      if( 
    mode S_IWUSR usr[1] = 'w';
      if( 
    mode S_IXUSR usr[2] = 'x';
      if( 
    mode S_ISUID usr[2] = 's'/* set UID bit*/
      
    if( mode S_IRGRP grp[0] = 'r';
      if( 
    mode S_IWGRP grp[1] = 'w';
      if( 
    mode S_IXGRP grp[2] = 'x';
      if( 
    mode S_ISGID grp[2] = 's'/* set GID bit*/
      
    if( mode S_IROTH oth[0] = 'r';
      if( 
    mode S_IWOTH oth[1] = 'w';
      if( 
    mode S_IXOTH oth[2] = 'x';

      
    my_passwd getpwuid(sbuf.st_uid);
      if(
    my_passwd)
        
    strncpy(uid,my_passwd->pw_name,8);
      else
        
    snprintf(uid,9,"%d",sbuf.st_uid);

      
    my_group getgrgid(sbuf.st_gid);
      if(
    my_group)
        
    strncpy(gid,my_group->gr_name,8);
      else
        
    snprintf(gid,9,"%d",sbuf.st_gid);

      
    time(&now);
      
    year localtime(&now)->tm_year;
      
    strtime localtime(&sbuf.st_ctime);
      if(
    strtime->tm_year == year)
        
    strftime(mod,13,"%b %e %R",strtime);
      else
        
    strftime(mod,13,"%b %e %Y",strtime);
             
      
    /*print the details*/
      
    printf("%c%s%s%s %4u %-8s %81u %12s %s\n",
            
    type,usr,grp,oth,sbuf.st_nlink,
            
    uid,gid,sbuf.st_size,mod,filename);
      
    free(curdir);

    }

    int main(int argcchar **argv) {
      
    int fdes,count,index;
      
    char *curdir;
      
    struct stat sbuf;
      
    struct dirent **direntp;

      
    curdir workdir();

      if(
    argv[1] != '\0'){
        if(
    stat(argv[1], &sbuf) != -1){
          if(
    S_ISDIR(sbuf.st_mode)){ /* Is a directory */
            
    count scandir(argv[1],&direntp,NULL,alphasort);
            if(
    count){
              for(
    index=0index<count; ++index){
                
    printDetails(direntp[index]->d_name);
                
    free(direntp[index]);
              }
            }else{
              
    fprintf(stderr,"Can't open %s\n",argv[1]);
              exit(
    EXIT_FAILURE);
            }
          }else if(
    S_ISREG(sbuf.st_mode)){ /* Is a regular file */
            
    if((fdes open(argv[1],O_RDONLY)) != ENOENT){
              
    printDetails(argv[1]);
              
    close(fdes);
            }else
              
    printf("Can't open %s reg\n",argv[1]);
          }
        }else
          
    printf("Can't stat %s\n"argv[1]);
      }else{
        if(
    stat(curdir,&sbuf) !=-1){
          
    count scandir(curdir,&direntp,NULL,alphasort);
          if(
    count){
            for(
    index=0index<count; ++index){
              
    printDetails(direntp[index]->d_name);
              
    free(direntp[index]);
            }
          }else{
            
    fprintf(stderr,"Can't open %s\n",curdir);
            exit(
    EXIT_FAILURE);
          }
        }else
          
    fprintf(stderr,"Can't stat %s\n",curdir);
      }
      
    free(curdir);
      
    free(direntp);
      return 
    EXIT_SUCCESS;

    PuterPaul.co.uk - Portfolio site

  2. #2
    In The Light
    Join Date
    Oct 2001
    Posts
    598

    i tryed it

    howdy >pdstatha<,
    i didnt spend a whole bunch of time with this but this is what gcc2.96 had to say when i tryed to compile your code.



    cd /home/Mike/
    make -k dir
    g++ dir.cpp -o dir
    dir.cpp: In function `void printDetails (char *)':
    dir.cpp:93: cannot convert `unsigned char *' to `char *' for argument
    `1' to `strncpy (char *, const char *, unsigned int)'
    dir.cpp:95: cannot convert `unsigned char *' to `char *' for argument
    `1' to `snprintf (char *, unsigned int, const char *, ...)'
    dir.cpp:99: cannot convert `unsigned char *' to `char *' for argument
    `1' to `strncpy (char *, const char *, unsigned int)'
    dir.cpp:101: cannot convert `unsigned char *' to `char *' for argument
    `1' to `snprintf (char *, unsigned int, const char *, ...)'
    dir.cpp:107: cannot convert `unsigned char *' to `char *' for argument
    `1' to `strftime (char *, unsigned int, const char *, const tm *)'
    dir.cpp:109: cannot convert `unsigned char *' to `char *' for argument
    `1' to `strftime (char *, unsigned int, const char *, const tm *)'
    dir.cpp: In function `int main (int, char **)':
    dir.cpp:127: parse error before `)'
    dir.cpp:140: confused by earlier errors, bailing out
    make: *** [dir] Error 1

    Compilation exited abnormally with code 2 at Wed Mar 6 22:31:03


    sorry.

    M.R.

  3. #3
    Registered User
    Join Date
    Jan 2002
    Posts
    22

    Segmentation fault

    Heyy all,

    Umm itld, now you weren't trying to compile C code with a C++ compiler, now were you?? :-) (!)

    That aside, I found only one bug which prevented the program from compiling, on line 126, change those to double quotes i.e argv[1] != ""

    Still your program does not run, I get segmentation fault, could there be something shady with your code (I haven't really analysed it but here is the output:

    Code:
    beg_g@space:~/test > gcc -o lsal lsal.c
    beg_g@space:~/test > lsal /home
    Segmentation fault
    beg_g@space:~/test >
    I called the file lsal.c


    Cheers.
    -------------------------
    Gerald.

  4. #4
    In The Light
    Join Date
    Oct 2001
    Posts
    598

    newbie trick

    howdy,

    Umm itld, now you weren't trying to compile C code with a C++ compiler, now were you?? :-) (!)
    hey nobody is perfect.

    itld asks himself if this is the only stupid newbie trick he will perform today

    M.R.

  5. #5
    Unregistered
    Guest

    Similar code

    I just had to write some code for class and it was interesting when I saw this topic. Here is my code:

    Code:
    mars:$ more writels2.cpp
    #include <stdio.h>
    #include <dirent.h>
    #include <iostream.h>
    #include <grp.h>
    #include <iomanip.h>
    #include <pwd.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <string.h>
    #include <string>
    #include <time.h>
    
    void showpermiss(struct stat &s, char *p);
    
    
    int main( int argc, char** argv )
    {
       char *p[20];
       char buff[20];
       char p2[20];
       char mdate[30];
       char formating = ' ';
       int counting=1;
    
       cin.getline(buff,20);
       p[0] = strtok(buff," ");
       DIR *dirp;
       struct dirent *direntp;
    
      dirp = opendir(".");
    //if(p[0] == NULL)
     // {
          while((direntp = readdir(dirp)) != NULL)
             {
              if (strcmp(buff, "dir")==0)
                {
                struct stat s;
                stat(direntp->d_name,&s);
                showpermiss(s, p2);
                cout<<p2<<" ";
          //      cout<<s.st_mode;
                cout<<setw(3)<<s.st_nlink;
                struct passwd *pw = getpwuid(s.st_uid);
                cout<<setw(9)<<pw->pw_name;
                struct group * gr = getgrgid(s.st_gid);
                cout<<setw(8)<<gr->gr_name;
                cout<<setw(8)<<s.st_size;
                strcpy(mdate, ctime(&s.st_mtime));
                mdate[16] = 0;
                cout<<" "<<mdate<< " ";
                  //<<ctime(&s.st_mtime);
                cout<<setw(2)<<direntp->d_name<<endl;
            }//endif
    
      else if (strcmp(buff, "-w")==0)
         {
               cout<<direntp->d_name<<endl;
         }//end if
      else if (strcmp(buff, "-pause")==0)
         {
        if (counting < 26)
               {
                struct stat s;
                stat(direntp->d_name,&s);
                showpermiss(s, p2);
                cout<<p2<<" ";
                cout<<setw(3)<<s.st_nlink;
                struct passwd *pw = getpwuid(s.st_uid);
                cout<<setw(9)<<pw->pw_name;
                struct group * gr = getgrgid(s.st_gid);
                cout<<setw(8)<<gr->gr_name;
                cout<<setw(8)<<s.st_size;
                strcpy(mdate, ctime(&s.st_mtime));
                mdate[16] = 0;
                cout<<" "<<mdate<< " ";//<<ctime(&s.st_mtime);
                cout<<setw(2)<<direntp->d_name<<endl;
                counting++;
            }//end if
         }//end if
      else
        if (strcmp(buff, "-F")==0)
         {
            struct stat s;
            stat(direntp->d_name,&s);
            cout<<direntp->d_name;
            if(s.st_mode & S_IFDIR)
                 cout<<"/"<<endl;
          else
            if(s.st_mode & S_IFIFO)
                cout<<"|"<<endl;
          else
            if(s.st_mode & S_IFLNK)
                cout<<"@"<<endl;
          else
            if(s.st_mode & S_IFDOOR)
                cout<<">"<<endl;
          else
            if(s.st_mode & S_IFSOCK)
                cout<<"="<<endl;
          else
            if((s.st_mode & S_IFREG) && (s.st_mode & S_IXUSR) || (s.st_mode &S_IXUSR) || (s.st_mode & S_IXGRP) || (s.st_mode & S_IXOTH))
                cout<<"*"<<endl;
          else
            cout<<"?"<<endl;
       }//end if
    
    }//end while
    closedir(dirp);
    //  return 0;
    }
    
    void showpermiss(struct stat &s, char *p)
    {
            if ( s.st_mode & S_IFIFO)       p[0] = 'p';
              else
            if ( s.st_mode & S_IFCHR )      p[0] = 'c';
              else
            if ( s.st_mode & S_IFDIR )      p[0] = 'd';
              else
            if ( s.st_mode &  S_IFBLK )     p[0] = 'b';
            else
                                            p[0] = '-';
    
    
            p[1] = ( s.st_mode & S_IRUSR ) ? 'r' : '-';
            p[2] = ( s.st_mode & S_IWUSR ) ? 'w' : '-';
            p[3] = ( s.st_mode & S_IXUSR ) ? 'x' : '-';
            p[4] = ( s.st_mode & S_IRGRP ) ? 'r' : '-';
            p[5] = ( s.st_mode & S_IWGRP ) ? 'w' : '-';
            p[6] = ( s.st_mode & S_IXGRP ) ? 'x' : '-';
            p[7] = ( s.st_mode & S_IROTH ) ? 'r' : '-';
            p[8] = ( s.st_mode & S_IWOTH ) ? 'w' : '-';
            p[9] = ( s.st_mode & S_IXOTH ) ? 'x' : '-';
            p[10] = '\0';
    }

  6. #6
    In The Light
    Join Date
    Oct 2001
    Posts
    598

    how?

    howdy,
    i compiled this with one error, i had to comment out this section, S_IFDOOR undeclared??
    Code:
     else
      if(s.st_mode & S_IFDOOR)
      cout<<">"<<endl;
    on but it will not do anything, i am using a command line like this

    ./similar /home/Mike

    but nothing happens. how is this used??

    M.R.

  7. #7
    Registered User
    Join Date
    Mar 2002
    Posts
    87

    Final code

    Just an update, i finally got the code working and here it is if ur interested.

    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <dirent.h>
    #include <stdlib.h>
    #include <time.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/stat.h>
    #include <pwd.h>
    #include <grp.h>
    #include <unistd.h>
    
    /*prototypes*/
    char* workdir(void);
    void printDetails(char* filename,char* path);
    
    int main(int argc, char **argv) {
      int count,index;
      char *curdir;
      struct stat sbuf;
      struct dirent **direntp;
    
      if(argv[1] != '\0'){
        if(stat(argv[1], &sbuf) != -1){
          if(S_ISDIR(sbuf.st_mode)){ /* Is a directory */
            count = scandir(argv[1],&direntp,NULL,alphasort);
            if(count){
              char path[FILENAME_MAX];
              for(index=0; index<count; ++index){
                strcpy(path,argv[1]);
                printDetails(direntp[index]->d_name,path);
                free(direntp[index]);
              }
            }else{
              fprintf(stderr,"Can't open %s\n",argv[1]);
              exit(EXIT_FAILURE);
            }
          }else
            printDetails(argv[1],NULL);             
        }else
          fprintf(stderr,"Can't stat %s\n", argv[1]);
      }else{
        curdir = workdir(); 
        printf("%s\n",curdir);
        if(stat(curdir,&sbuf) !=-1){
          count = scandir(curdir,&direntp,NULL,alphasort);
          if(count){
            for(index=0; index<count; ++index){
              printDetails(direntp[index]->d_name,NULL);
              free(direntp[index]);
            }
          }else{
            fprintf(stderr,"Can't open %s\n",curdir);
            exit(EXIT_FAILURE);
          }
        }else{
          fprintf(stderr,"Can't stat %s\n",curdir);
          exit(EXIT_FAILURE);
        }
        free(curdir);
      }
      return EXIT_SUCCESS;
    }
    
    char* workdir(){
      while(1){
        char* wdbuf = (char*)malloc(FILENAME_MAX);
        if(getcwd(wdbuf,FILENAME_MAX) == wdbuf)
          return wdbuf;
        free(wdbuf);
        if(errno != ERANGE){
          fprintf(stderr,"Out of range\n");
          return 0;
        }
      }
    }
    
    void printDetails(char *filename,char *path){
    
      struct passwd *my_passwd;	/*User details*/
      struct group *my_group;	/*Group details*/
      struct stat sbuf;		/*File details*/
      struct tm *strtime;		/*Time format*/
    
      int fdes;			/*File descriptor*/
      unsigned char type ='?';	/*File type*/
      unsigned char usr[] = "---";  /*User Permissions*/
      unsigned char grp[] = "---";  /*Group Permissions*/
      unsigned char oth[] = "---";	/*Other Permissions*/
      unsigned char uid[9], gid[9]; /*User name and Group name*/
      unsigned char mod[13];	/*Time information*/
      mode_t mode;			/*Used to determine type and permission bits*/
      char* curdir;			/*Used to hold the current working directory*/
      char* buf;                    /*Used to hold a link location*/
      time_t now;			/*Used to format the time*/
      int year;			/*Used to format the time*/
    
      /*If path is null stat by the curdir*/
      if(path == NULL){
        curdir = workdir();
        strcat(curdir,"/");
        strcat(curdir,filename);
        if(stat(curdir,&sbuf) != -1){
          if(S_ISLNK(sbuf.st_mode)){
            if(readlink(curdir,buf,(size_t)FILENAME_MAX) != -1){
              if(lstat(buf,&sbuf) == -1){
                fprintf(stderr,"Can't stat %s\n",filename);
                return;
              }
            }else
              fprintf(stderr,"Can't readlink %s\n",filename);
          }else if(S_ISREG(sbuf.st_mode)){
            if((fdes = open(curdir,O_RDONLY)) != ENOENT){
              if(fstat(fdes,&sbuf) == -1){
                fprintf(stderr,"Can't stat %s\n",filename);
                return;
              }
              close(fdes);
            }else{
              fprintf(stderr,"Can't open %s\n",filename);
              return;
            }
          }
        }else{
          fprintf(stderr,"Can't stat %s\n",filename);
          return;
        }
        free(curdir);
      /*Otherwise stat by the path provided*/
      }else{
        strcat(path,"/");
        strcat(path,filename);
        if(stat(path,&sbuf) != -1){
          if(S_ISLNK(sbuf.st_mode)){
            if(readlink(path,buf,(size_t)FILENAME_MAX) != -1){
              if(lstat(buf,&sbuf) == -1){
                fprintf(stderr,"Can't stat %s\n",filename);
                return;
              }
            }else
              fprintf(stderr,"Can't readlink %s\n",filename);
          }else if(S_ISREG(sbuf.st_mode)){
            if((fdes = open(path,O_RDONLY)) != ENOENT){
              if(fstat(fdes,&sbuf) == -1){
                fprintf(stderr,"Can't stat %s\n",filename);
                return;
              }
              close(fdes);
            }else{
              fprintf(stderr,"Can't open %s\n",filename);
              return;
            }
          }    
        }else{
          fprintf(stderr,"Path: %s\n",path);
          fprintf(stderr,"Can't stat %s\n",curdir);
          return;
        }
      }      
    
      /*Get file types and permissions*/
      mode = sbuf.st_mode;
      if( S_ISLNK( mode ) ){ type = 'l'; /*symlink*/ printf("%c\n",type);}
      else if( S_ISDIR ( mode ) ) type = 'd'; /*directory*/
      else if( S_ISCHR ( mode ) ) type = 'c'; /*character raw device*/
      else if( S_ISBLK ( mode ) ) type = 'b'; /*block raw device*/
      else if( S_ISFIFO( mode ) ) type = 'p'; /*named pipe*/
      else if( S_ISSOCK( mode ) ) type = 's'; /*Unix domain socket*/
      else if( S_ISREG ( mode ) ) type = '-'; /*regular file*/
      if( mode & S_IRUSR ) usr[0] = 'r';
      if( mode & S_IWUSR ) usr[1] = 'w';
      if( mode & S_IXUSR ) usr[2] = 'x';
      if( mode & S_ISUID ) usr[2] = 's'; /* set UID bit*/
      if( mode & S_IRGRP ) grp[0] = 'r';
      if( mode & S_IWGRP ) grp[1] = 'w';
      if( mode & S_IXGRP ) grp[2] = 'x';
      if( mode & S_ISGID ) grp[2] = 's'; /* set GID bit*/
      if( mode & S_IROTH ) oth[0] = 'r';
      if( mode & S_IWOTH ) oth[1] = 'w';
      if( mode & S_IXOTH ) oth[2] = 'x';
    
      /*Get user information*/
      my_passwd = getpwuid(sbuf.st_uid);
      if(my_passwd != NULL){
        strncpy(uid,my_passwd->pw_name,8);
        uid[8] = '\0';
      }else
        snprintf(uid,9,"%d",sbuf.st_uid);
    
      /*Get group information*/
      my_group = getgrgid(sbuf.st_gid);
      if(my_group != NULL){
        strncpy(gid,my_group->gr_name,8);
        gid[8] = '\0';
      }else
        snprintf(gid,9,"%d",sbuf.st_gid);
    
      /*Format the time to readable form*/
      time(&now);
      year = localtime(&now)->tm_year;
      strtime = localtime(&sbuf.st_ctime);
      if(strtime->tm_year == year)
        strftime(mod,13,"%b %e %R",strtime);
      else
        strftime(mod,13,"%b %e %Y",strtime);
             
      /*print the details*/
      printf("%c%s%s%s    %d %s     %s         %d\t%s %s\n",
             type,usr,grp,oth,sbuf.st_nlink,
             uid,gid,sbuf.st_size,mod,filename);
    
    }
    PuterPaul.co.uk - Portfolio site

  8. #8
    In The Light
    Join Date
    Oct 2001
    Posts
    598

    it works

    howdy pdstatha,
    that works very well. compiled and ran with no errors using gcc 2.96/emacs.

    M.R.

  9. #9
    Unregistered
    Guest

    Re: how?

    Originally posted by itld
    howdy,
    i compiled this with one error, i had to comment out this section, S_IFDOOR undeclared??
    Code:
     else
      if(s.st_mode & S_IFDOOR)
      cout<<">"<<endl;
    on but it will not do anything, i am using a command line like this

    ./similar /home/Mike

    but nothing happens. how is this used??

    M.R.
    How's it going? What are you running on? I'm running Unix on SunOS 5.8

  10. #10
    Unregistered
    Guest

    pdstatha's code

    when i tried to compile his code, it said that alphasort was undeclared??

  11. #11
    Unregistered
    Guest

    Re: how?

    Originally posted by itld

    on but it will not do anything, i am using a command line like this

    ./similar /home/Mike

    but nothing happens. how is this used??

    M.R. [/B]

    OH YEAH...to run it, i used a.out and then typed -F to get the formatting characters. to use each other others (dir, -w, and -pause) run a.out again and try to type the command. dont try to run multiples though LoL cuz it wont work )

    a.out
    -F

    a.out
    -pause

    a.out
    -w

    a.out
    dir

  12. #12
    Registered User
    Join Date
    Mar 2002
    Posts
    87

    Question

    Don't know why it does that, it compiles just fine for me. There is one problem with the code though, for some the code which detects a symbolic link does not work correctly. Any ideas??
    PuterPaul.co.uk - Portfolio site

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Implementing of queue using objects?
    By Argo_Jeude in forum C++ Programming
    Replies: 5
    Last Post: 08-07-2007, 11:55 AM
  2. Replies: 12
    Last Post: 12-23-2004, 12:32 AM
  3. Implementing Mathematical Concepts in Code
    By MisterWonderful in forum Tech Board
    Replies: 6
    Last Post: 03-08-2004, 07:44 AM
  4. Implementing a linked list, some problems
    By EvBladeRunnervE in forum C++ Programming
    Replies: 7
    Last Post: 12-12-2003, 09:07 AM
  5. Implementing "ls -al"
    By pdstatha in forum C Programming
    Replies: 7
    Last Post: 03-06-2002, 05:36 PM