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 in unix systems. I know i've already posted in the linux programming section, but it seems pretty quiet in there.

    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
    Sayeh
    Guest
    This will break of the malloc() fails... there may be other problems as well. That was just the first that popped out at me.

  3. #3
    Registered User
    Join Date
    Mar 2002
    Posts
    87
    This will break of the malloc
    Huh what do you mean by that??
    PuterPaul.co.uk - Portfolio site

  4. #4
    Registered User
    Join Date
    Mar 2002
    Posts
    87
    Ok I managed to dowload cygwin with gcc and gdb. It compiled fine except when I run it, it dumps the following core file. Can someone please explain to me what this is all about?

    Exception: STATUS_ACCESS_VIOLATION at eip=610948D7
    eax=00000001 ebx=00000080 ecx=610A5C24 edx=00000001 esi=610A0368 edi=00000078
    ebp=0073FC8C esp=0073FC54 program=C:\PROGRAM FILES\RATIONAL\RATIONAL TEST\NUTCROOT\USR\NETSRC\A.EXE
    cs=0177 ds=017F es=017F fs=2FD7 gs=0000 ss=017F
    Stack trace:
    Frame Function Args
    0073FC8C 610948D7 (610A0020, 00000080, 0073FD2C, 6100431E)
    0073FCAC 6102E205 (00000080, 00000000, 0073FD2C, 0040159C)
    0073FD2C 0040182C (00000002, 61562460, 00970278, 00000000)
    0073FD88 61003F42 (00000000, 00000000, 00000000, 0073FF68)
    0073FDB8 61004236 (0040158C, 00000000, 8165CAF4, 00000000)
    0073FDD8 61004275 (00000000, 00000000, FFFFFFFF, 00000001)
    0073FE08 0040188F (0040158C, 0073FC8C, BFFC9490, 0073FF68)
    0073FE38 0040103D (00000000, 8167B194, 00530000, 58450041)
    0073FF78 BFF8B537 (8165CAB0, 8167B194, 00000008, 00000000)
    119 [main] a 452887 handle_exceptions: Error while dumping state (probably corrupted stack)
    PuterPaul.co.uk - Portfolio site

  5. #5
    Sayeh
    Guest
    Sorry, I meant 'if' not 'of'. You don't check to see if the malloc() calls are successful. If they aren't you continue to work with invalid pointers.

  6. #6
    Sayeh
    Guest
    You also need to prototype. The rest can be easily found using a debugger.

  7. #7
    Registered User
    Join Date
    Mar 2002
    Posts
    87
    Err whats this mean?

    Starting program: /cygdrive/c/Program Files/Rational/Rational Test/nutcroot/usr/netsrc/a.exe

    Program received signal SIGSEGV, Segmentation fault.
    0x610948d7 in _libkernel32_a_iname ()
    PuterPaul.co.uk - Portfolio site

  8. #8
    Registered User
    Join Date
    Mar 2002
    Posts
    87
    Heres some updated code, still with the same segmentation fault tho!!

    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
    
    char* workdir(){
      const size_t BUFSIZE = 1024;
      char curdir[BUFSIZE];
      if (getcwd(curdir,BUFSIZE) != curdir){
    	if( errno == ERANGE )
    	  fprintf( stderr, "Path too long.\n" );
    	else
    	  fprintf( stderr, "Can't access current directory\n" );
    	  exit( EXIT_FAILURE );
      }else
        return curdir;
    }
    
    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;
      char* curdir;
      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((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;
      }      
    
      /*format information*/
      mode = sbuf.st_mode;
      if( S_ISLNK( mode ) ) 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_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';
    
      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);
    
    }
    
    void main(int argc, char **argv) {
      int 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=0; index<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 */
            printDetails(argv[1]);               
        }else
          printf("Can't stat %s\n", argv[1]);
      }else{
        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);
              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(direntp); 
    }
    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 Linux Programming
    Replies: 11
    Last Post: 03-20-2002, 04:39 AM