Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/cmds/modules/ls/ls.c

    r9bdf1f2a ra701812  
    4242#include <sort.h>
    4343
    44 #include "ls.h"
    4544#include "errors.h"
    4645#include "config.h"
     
    4948#include "cmds.h"
    5049
     50/* Various values that can be returned by ls_scope() */
     51#define LS_BOGUS 0
     52#define LS_FILE  1
     53#define LS_DIR   2
     54
     55/** Structure to represent a directory entry.
     56 *
     57 * Useful to keep together important information
     58 * for sorting directory entries.
     59 */
     60struct dir_elem_t {
     61        char *name;
     62        struct stat s;
     63};
     64
    5165static const char *cmdname = "ls";
    52 
    53 static ls_job_t ls;
    5466
    5567static struct option const long_options[] = {
    5668        { "help", no_argument, 0, 'h' },
    5769        { "unsort", no_argument, 0, 'u' },
    58         { "recursive", no_argument, 0, 'r' },
    5970        { 0, 0, 0, 0 }
    6071};
    61 
    62 /* Prototypes for the ls command, excluding entry points. */
    63 static unsigned int ls_start(ls_job_t *);
    64 static void ls_print(struct dir_elem_t *);
    65 static int ls_cmp(void *, void *, void *);
    66 static signed int ls_scan_dir(const char *, DIR *, struct dir_elem_t **);
    67 static unsigned int ls_recursive(const char *, DIR *);
    68 static unsigned int ls_scope(const char *, struct dir_elem_t *);
    69 
    70 static unsigned int ls_start(ls_job_t *ls)
    71 {
    72         ls->recursive = 0;
    73         ls->sort = 1;
    74 
    75         return 1;
    76 }
    7772
    7873/** Print an entry.
     
    9792}
    9893
     94
    9995/** Compare 2 directory elements.
    10096 *
     
    131127 *                              0 otherwise.
    132128 */
    133 static signed int ls_scan_dir(const char *d, DIR *dirp,
    134     struct dir_elem_t **dir_list_ptr)
     129static void ls_scan_dir(const char *d, DIR *dirp, int sort)
    135130{
    136131        int alloc_blocks = 20;
     
    145140       
    146141        if (!dirp)
    147                 return -1;
     142                return;
    148143
    149144        buff = (char *) malloc(PATH_MAX);
    150145        if (!buff) {
    151146                cli_error(CL_ENOMEM, "ls: failed to scan %s", d);
    152                 return -1;
     147                return;
    153148        }
    154149       
     
    157152                cli_error(CL_ENOMEM, "ls: failed to scan %s", d);
    158153                free(buff);
    159                 return -1;
     154                return;
    160155        }
    161156       
     
    192187        }
    193188       
    194         if (ls.sort) {
     189        if (sort) {
    195190                if (!qsort(&tosort[0], nbdirs, sizeof(struct dir_elem_t),
    196191                    ls_cmp, NULL)) {
     
    201196        for (i = 0; i < nbdirs; i++)
    202197                ls_print(&tosort[i]);
    203 
    204         /* Populate the directory list. */
    205         if (ls.recursive) {
    206                 tmp = (struct dir_elem_t *) realloc(*dir_list_ptr,
    207                     nbdirs * sizeof(struct dir_elem_t));
    208                 if (!tmp) {
    209                         cli_error(CL_ENOMEM, "ls: failed to scan %s", d);
    210                         goto out;
    211                 }
    212                 *dir_list_ptr = tmp;
    213 
    214                 for (i = 0; i < nbdirs; i++) {
    215                         (*dir_list_ptr)[i].name = str_dup(tosort[i].name);
    216                         if (!(*dir_list_ptr)[i].name) {
    217                                 cli_error(CL_ENOMEM, "ls: failed to scan %s", d);
    218                                 goto out;
    219                         }
    220                 }
    221         }
    222198       
    223199out:
     
    226202        free(tosort);
    227203        free(buff);
    228 
    229         return nbdirs;
    230 }
    231 
    232 /** Visit a directory recursively.
    233  *
    234  * ls_recursive visits all the subdirectories recursively and
    235  * prints the files and directories in them.
    236  *
    237  * @param path  Path the current directory being visited.
    238  * @param dirp  Directory stream.
    239  */
    240 static unsigned int ls_recursive(const char *path, DIR *dirp)
    241 {
    242         int i, nbdirs, ret;
    243         unsigned int scope;
    244         char *subdir_path;
    245         DIR *subdirp;
    246         struct dir_elem_t *dir_list;
    247        
    248         const char * const trailing_slash = "/";
    249 
    250         nbdirs = 0;
    251         dir_list = (struct dir_elem_t *) malloc(sizeof(struct dir_elem_t));
    252 
    253         printf("\n%s:\n", path);
    254 
    255         subdir_path = (char *) malloc(PATH_MAX);
    256         if (!subdir_path) {
    257                 ret = CMD_FAILURE;
    258                 goto out;
    259         }
    260 
    261         nbdirs = ls_scan_dir(path, dirp, &dir_list);
    262         if (nbdirs == -1) {
    263                 ret = CMD_FAILURE;
    264                 goto out;
    265         }
    266 
    267         for (i = 0; i < nbdirs; ++i) {
    268                 memset(subdir_path, 0, PATH_MAX);
    269 
    270                 if (str_size(subdir_path) + str_size(path) + 1 <= PATH_MAX)
    271                         str_append(subdir_path, PATH_MAX, path);
    272                 if (path[str_size(path)-1] != '/' &&
    273                     str_size(subdir_path) + str_size(trailing_slash) + 1 <= PATH_MAX)
    274                         str_append(subdir_path, PATH_MAX, trailing_slash);
    275                 if (str_size(subdir_path) +
    276                     str_size(dir_list[i].name) + 1 <= PATH_MAX)
    277                         str_append(subdir_path, PATH_MAX, dir_list[i].name);
    278 
    279                 scope = ls_scope(subdir_path, &dir_list[i]);
    280                 switch (scope) {
    281                 case LS_FILE:
    282                         break;
    283                 case LS_DIR:
    284                         subdirp = opendir(subdir_path);
    285                         if (!subdirp) {
    286                                 /* May have been deleted between scoping it and opening it */
    287                                 cli_error(CL_EFAIL, "Could not stat %s", dir_list[i].name);
    288                                 ret = CMD_FAILURE;
    289                                 goto out;
    290                         }
    291 
    292                         ret = ls_recursive(subdir_path, subdirp);
    293                         closedir(subdirp);
    294                         if (ret == CMD_FAILURE)
    295                                 goto out;
    296                         break;
    297                 case LS_BOGUS:
    298                         ret = CMD_FAILURE;
    299                         goto out;
    300                 }       
    301         }
    302    
    303         ret = CMD_SUCCESS;
    304 
    305 out:
    306         for (i = 0; i < nbdirs; i++)
    307                 free(dir_list[i].name);
    308         free(dir_list);
    309         free(subdir_path);
    310 
    311         return ret;
    312 }
    313 
    314 static unsigned int ls_scope(const char *path, struct dir_elem_t *de)
    315 {
    316         if (stat(path, &de->s)) {
    317                 cli_error(CL_ENOENT, path);
    318                 return LS_BOGUS;
    319         }
    320 
    321         if (de->s.is_file)
    322                 return LS_FILE;
    323         else if (de->s.is_directory)
    324                 return LS_DIR;
    325 
    326         return LS_BOGUS;
    327204}
    328205
     
    338215                "Options:\n"
    339216                "  -h, --help       A short option summary\n"
    340                 "  -u, --unsort     Do not sort directory entries\n"
    341                 "  -r, --recursive  List subdirectories recursively\n",
     217                "  -u, --unsort     Do not sort directory entries\n",
    342218                cmdname);
    343219        }
     
    352228        DIR *dirp;
    353229        int c, opt_ind;
    354         int ret = 0;
    355         unsigned int scope;
    356 
    357         if (!ls_start(&ls)) {
    358                 cli_error(CL_EFAIL, "%s: Could not initialize", cmdname);
    359                 return CMD_FAILURE;
    360         }
     230        int sort = 1;
    361231
    362232        argc = cli_count_args(argv);
    363233       
    364234        for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
    365                 c = getopt_long(argc, argv, "hur", long_options, &opt_ind);
     235                c = getopt_long(argc, argv, "hu", long_options, &opt_ind);
    366236                switch (c) {
    367237                case 'h':
     
    369239                        return CMD_SUCCESS;
    370240                case 'u':
    371                         ls.sort = 0;
    372                         break;
    373                 case 'r':
    374                         ls.recursive = 1;
     241                        sort = 0;
    375242                        break;
    376243                }
     
    384251                return CMD_FAILURE;
    385252        }
    386         memset(de.name, 0, PATH_MAX);
     253        memset(de.name, 0, sizeof(PATH_MAX));
    387254       
    388255        if (argc == 0)
     
    390257        else
    391258                str_cpy(de.name, PATH_MAX, argv[optind]);
    392 
    393         scope = ls_scope(de.name, &de);
    394         switch (scope) {
    395         case LS_FILE:
     259       
     260        if (stat(de.name, &de.s)) {
     261                cli_error(CL_ENOENT, de.name);
     262                free(de.name);
     263                return CMD_FAILURE;
     264        }
     265
     266        if (de.s.is_file) {
    396267                ls_print(&de);
    397                 break;
    398         case LS_DIR:
     268        } else {
    399269                dirp = opendir(de.name);
    400270                if (!dirp) {
     
    404274                        return CMD_FAILURE;
    405275                }
    406                 if (ls.recursive)
    407                         ret = ls_recursive(de.name, dirp);
    408                 else 
    409                         ret = ls_scan_dir(de.name, dirp, NULL);
    410 
     276                ls_scan_dir(de.name, dirp, sort);
    411277                closedir(dirp);
    412                 break;
    413         case LS_BOGUS:
    414                 return CMD_FAILURE;
    415278        }
    416279
    417280        free(de.name);
    418281
    419         if (ret == -1 || ret == CMD_FAILURE)
    420                 return CMD_FAILURE;
    421         else
    422                 return CMD_SUCCESS;
    423 }
    424 
     282        return CMD_SUCCESS;
     283}
     284
Note: See TracChangeset for help on using the changeset viewer.