#ifdef HAVE_CONFIG_H #include #endif #include #include #include /*strcpy() strcat() definition*/ #include /* getcwd() definition */ #include /*getopt() optind definition */ #include /*exit signal definition */ #include /*MAXPATHLEN definition */ #include /*stat() struct stat definition */ #include /*scandir() alphasort() struct dirent(and direct def) definition */ /*Will hold Filename, attributes and full path of files */ typedef struct { char fullpathname[MAXPATHLEN]; /*path + fn->dname, helps for stat() and recursive option */ struct direct *fn; /*d_name etc */ struct stat *fs; /*status&attributes */ }flstat; static int oneflag, lflag, rflag, aflag; /*Program Options */ static int myls(char*); /*the LS routine */ static void usage(); /*shows usage of Program */ static flstat **getattr(char*,struct direct**,int); /*Reads filelist and returns a new with atributes added */ static void print(flstat**,int); /*Prints the contents of a flielist */ int file_select(); /*Used by scandir() to handle files shown */ int main(int argc, char *argv[]) { int c; /*temp used to get options from command line */ char pathname[MAXPATHLEN]; /*path to execute command */ /*parsing command line options */ while ((c = getopt(argc, argv, "aRrl1")) != -1) { switch (c) { case 'a': /*Show hidden option */ aflag = 1; break; case 'R':/*Recursively option */ case 'r':/*compatibility */ rflag = 1; break; case 'l':/*detail option */ lflag = 1; case '1':/*expand */ oneflag = 1; break; default: /*Else show usage */ usage(); } } if (argv[optind] == 0) /*if not a path for ls given */ getcwd(pathname,MAXPATHLEN); /*use Current working path */ else strcpy(pathname,argv[optind]); /*use path given */ myls(pathname); /*Execute ls */ return EXIT_SUCCESS; } /*basic routine of our program */ static int myls(char *path) { int filecount,i; char tmp[MAXPATHLEN]; struct stat *buf = (struct stat*)malloc(sizeof(struct stat)); /*buffer of file status */ struct direct **files; /*will get a list of files */ flstat **flist; /*will keep list of files and attributes */ /*if path given was NULL, errormsg&exit*/ if (path == NULL) { fprintf(stderr, "Error on getting PATH"); exit(EXIT_FAILURE); } stat(path,buf); /*Get status for path */ /*if not a directory, errormsg&exit */ if (!S_ISDIR(buf->st_mode)) { fprintf(stderr, "Fatal error - PATH given is not a directory"); exit(EXIT_FAILURE); } filecount = scandir(path,&files,(void*)file_select,alphasort); /*scanning our path */ flist = getattr(path,files,filecount); /*Moving the list to flist and getting file status&attributes */ free(files); /*No longer usefull, the list is now on the flist */ printf("%s:\ntotal %d\n",path,filecount); /*printing a header(the path) and counted files */ print(flist,filecount); /*-r -R Recursively option */ if (rflag == 1){ /*if enabled */ for (i=0; i < filecount; i++) /*Look for direcrories in the list */ { if (!(strcmp(flist[i]->fn->d_name,".") == 0 || strcmp(flist[i]->fn->d_name,"..") == 0)){ /*skip . and .. */ if (S_ISDIR(flist[i]->fs->st_mode)) /*if got a directory */ { printf("\n"); myls(flist[i]->fullpathname); /*Execute myls for it */ } } } } return EXIT_SUCCESS; } /*Returns a list with filenames, attributes and full paths */ static flstat **getattr(char *path, struct direct **list, int size) { int i; flstat **thelist = (flstat**)malloc(size*sizeof(flstat*)); for (i = 0; i < size; i++) { /*Allocating memory for element */ thelist[i] = (flstat*)malloc(sizeof(flstat)); /*Creating a full path name of each file*/ strcpy (thelist[i]->fullpathname,path); strncat(thelist[i]->fullpathname,"/",MAXPATHLEN); strncat(thelist[i]->fullpathname,list[i]->d_name,MAXPATHLEN); /*Creating new node and adding it to list */ thelist[i]->fs = (struct stat*)malloc(sizeof(struct stat)); stat(thelist[i]->fullpathname,thelist[i]->fs); /*get file stat */ /*Putting the direct from scandir to our struct */ thelist[i]->fn = list[i]; } return thelist; } /*Prints the contents of the list provided */ static void print(flstat **list,int size) { int i; char sep = '\t'; if (oneflag == 1) sep = '\n'; for (i = 0; i < size; i++) printf("%s%c",list[i]->fn->d_name,sep); printf("\n"); return; } /*Handles the files shown */ int file_select(struct direct *entry) { /*if not Show All mode, return 0 for hidden files */ if (aflag != 1) if (entry->d_name[0] == '.') return 0; return !0; /*else show all without check */ } /*Prints Usage of program */ static void usage() { fprintf(stderr, "%s\n%s\n", "usage: lscomp [-aRr] [FILE] ...", " List information about the FILEs"); exit(EX_USAGE); }