Thread: Shortening main

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

    Talking Shortening main

    I'm normally pretty good at shoretning code, Give me some ideas for shortening my main method of the following code. Which does the following commands "ls, ls -l, ls -a, ls -al"

    Code:
    #include <stdio.h>
    #include <sys/types.h>
    #include <fcntl.h>
    #include <dirent.h>
    #include <stdlib.h>
    #include <time.h>
    #include <regex.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 printDetailsAll(char* filename,char* path);
    void printDetails(char* filename);
    int matchDetails(char* filename);
    char *get_regerror(int errcode,regex_t *compiled);
    
    int main(int argc, char **argv) {
      int count,index,result;
      char *curdir;
      struct stat sbuf;
      struct dirent **direntp;
      char path[FILENAME_MAX];
    
      if(argv[1] != '\0'){ /*If argument supplied*/
        if(strcmp(argv[1], "-al") == 0){
    	  if(argv[2] != '\0'){/*ls '-al' on an argument*/
            if(stat(argv[2], &sbuf) != -1){
              if(S_ISDIR(sbuf.st_mode)){ /* Is a directory */
                count = scandir(argv[2],&direntp,NULL,alphasort);
                if(count){
                  for(index=0; index<count; ++index){
                    strcpy(path,argv[1]);
                    printDetailsAll(direntp[index]->d_name,path);
                    free(direntp[index]);
    			  }
    			}else{
                  fprintf(stderr,"Can't open %s\n",argv[1]);
                  exit(EXIT_FAILURE);
    			}
    		  }else
                printDetailsAll(argv[2],NULL);             
    		}else
              fprintf(stderr,"Can't stat %s\n", argv[1]);
    	  }else{/*ls '-al' on curdir*/
    	    curdir = workdir(); 
            if(stat(curdir,&sbuf) !=-1){
              count = scandir(curdir,&direntp,NULL,alphasort);
              if(count){
                for(index=0; index<count; ++index){
    		      printDetailsAll(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);
    	  }
    	}else if(strcmp(argv[1], "-l") == 0){
    	  if(argv[2] != '\0'){/*ls -l on an argument*/
    	    if(stat(argv[2], &sbuf) != -1){
              if(S_ISDIR(sbuf.st_mode)){ /* Is a directory */
                count = scandir(argv[2],&direntp,NULL,alphasort);
                if(count){
                  for(index=0; index<count; ++index){
                    strcpy(path,argv[1]);
    				result = matchDetails(direntp[index]->d_name);
    				if(result > 0)
                      printDetailsAll(direntp[index]->d_name,path);
                    free(direntp[index]);
    			  }
    			}else{
                  fprintf(stderr,"Can't open %s\n",argv[1]);
                  exit(EXIT_FAILURE);
    			}
    		  }else
                printDetailsAll(argv[2],NULL);             
    		}else
              fprintf(stderr,"Can't stat %s\n", argv[1]);
    	  }else{/*ls -l on current dir*/
    	    curdir = workdir(); 
            if(stat(curdir,&sbuf) !=-1){
              count = scandir(curdir,&direntp,NULL,alphasort);
              if(count){
                for(index=0; index<count; ++index){
    			  result = matchDetails(direntp[index]->d_name);
    			  if(result > 0)
    		        printDetailsAll(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);
    	  }
    	}else if(strcmp(argv[1], "-a") == 0){
    	  if(argv[2] != '\0'){/*ls -a on an argument*/
    	    if(stat(argv[2], &sbuf) != -1){
    		  if(S_ISDIR(sbuf.st_mode)){ /* Is a directory */
                count = scandir(argv[2],&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
                printDetails(argv[2]);             
    		}else
              fprintf(stderr,"Can't stat %s\n", argv[1]);
    	  }else{
    	    curdir = workdir(); 
            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);
              exit(EXIT_FAILURE);
    		}
            free(curdir);
    	  }
    	}
      }else{  /*Normal ls command on curdir*/
        curdir = workdir(); 
        if(stat(curdir,&sbuf) !=-1){
          count = scandir(curdir,&direntp,NULL,alphasort);
          if(count){
            for(index=0; index<count; ++index){
    		  result = matchDetails(direntp[index]->d_name);
    		  if(result > 0)
                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);
          exit(EXIT_FAILURE);
        }
        free(curdir);
      }
      return EXIT_SUCCESS;
    }
    
    /*Get the current working directory*/
    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;
        }
      }
    }
    
    
    /*Will print all details of a file/dir. */
    void printDetailsAll(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%-6s%-8d%-10s%-10s%-10d%-10s%s\n",
             type,usr,grp,oth,sbuf.st_nlink,
             uid,gid,sbuf.st_size,mod,filename);
    
    }
    
    /*Used to print the filename*/
    void printDetails(char* filename){
      printf("%s\n",filename);
    
    }
    
    /*Used to find process directories*/
    int matchDetails(char* filename){
      int status,regstat;
      char *pattern = "^[^.].*$"; /*Match all strings without a begining '.'*/
      char *result;
    
      regex_t re;
      if((regstat = regcomp(&re,pattern,REG_EXTENDED | REG_NOSUB)) != 0){
        result = get_regerror(regstat,&re);
        fprintf(stderr,"%s\n",result);
        return(0);
      }
      if((status = regexec(&re,filename,(size_t) 0,NULL,0)) != 0)
        return(0);
      regfree(&re);
    	
      return(1);
    
    }
    
    /*Used to store regex errors*/
    char *get_regerror(int errcode,regex_t *compiled){
      size_t length = regerror(errcode,compiled,NULL,0);
      char *buffer = malloc(length);
      (void) regerror(errcode,compiled,buffer,length);
      return buffer;
    }
    PuterPaul.co.uk - Portfolio site

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    > if(argv[1] != '\0'){ /*If argument supplied*/

    There is a reason they include 'argc'.

    if( argc < 2 ) /*...no argument...*/
    {

    }
    else /*...arguments...*/
    {

    }

    Furthermore, if you want to shorten main, just pass the arguments to another function.

    myfunction( argc[1] );

    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  2. confused about adding controls to main window
    By terracota in forum Windows Programming
    Replies: 4
    Last Post: 11-24-2004, 12:35 PM
  3. int main (), main (), main (void), int main (void) HELP!!!
    By SmokingMonkey in forum C++ Programming
    Replies: 7
    Last Post: 05-31-2003, 09:46 PM
  4. what to do with the main window
    By stallion in forum Windows Programming
    Replies: 2
    Last Post: 01-28-2003, 08:58 PM
  5. getting a function to return to main??
    By Neildadon in forum C++ Programming
    Replies: 7
    Last Post: 12-16-2002, 10:24 AM