Changes in / [beb6b3d:917a8c8] in mainline


Ignore:
Location:
uspace/app/bdsh/cmds/modules/ls
Files:
2 edited

Legend:

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

    rbeb6b3d r917a8c8  
    3838#include <dirent.h>
    3939#include <fcntl.h>
    40 #include <getopt.h>
    4140#include <sys/types.h>
    4241#include <sys/stat.h>
    4342#include <str.h>
    44 #include <sort.h>
    4543
    4644#include "errors.h"
     
    5351static const char *cmdname = "ls";
    5452
    55 static struct option const long_options[] = {
    56         { "help", no_argument, 0, 'h' },
    57         { "unsort", no_argument, 0, 'u' },     
    58         { 0, 0, 0, 0 }
    59 };
     53static void ls_scan_dir(const char *d, DIR *dirp)
     54{
     55        struct dirent *dp;
     56        char *buff;
    6057
    61 /** Compare 2 directory elements.
    62  *
    63  * It compares 2 elements of a directory : a file is considered
    64  * as lower than a directory, and if they have the same type,
    65  * they are compared alphabetically.
    66  *
    67  * @param a             Pointer to the structure of the first element.
    68  * @param b             Pointer to the structure of the second element.
    69  * @param arg   Pointer for an other and optionnal argument.
    70  *
    71  * @return              -1 if a < b,
    72  *                              1 otherwise.
    73  */
    74 static int ls_cmp(void *a, void *b, void *arg)
    75 {
    76         int a_isdir = (*((struct dir_elem_t *)a)).isdir;
    77         char * a_name = (*((struct dir_elem_t *)a)).name;
    78        
    79         int b_isdir = (*((struct dir_elem_t *)b)).isdir;
    80         char * b_name = (*((struct dir_elem_t *)b)).name;
    81        
    82         if ((!a_isdir && b_isdir)
    83                 || (((!b_isdir && !a_isdir) || (b_isdir && a_isdir))
    84                 && str_cmp(a_name, b_name) < 0))
    85                 return -1;
    86         else
    87                 return 1;
    88 }
    89 
    90 /** Scan a directory.
    91  *
    92  * Scan the content of a directory and print it.
    93  *
    94  * @param d             Name of the directory.
    95  * @param dirp  Directory stream.
    96  */
    97 static void ls_scan_dir(const char *d, DIR *dirp, int sort)
    98 {
    99         int alloc_blocks = 20;
    100         int i = 0;
    101         int nbdirs = 0;
    102         int rc = 0;
    103         char * buff = NULL;
    104         struct dir_elem_t * tmp = NULL;
    105         struct dir_elem_t * tosort = NULL;
    106         struct dirent * dp = NULL;
    107         struct stat s;
    108        
    10958        if (! dirp)
    11059                return;
     
    11564                return;
    11665        }
    117         memset(buff, 0, sizeof(buff));
    118        
    119         if (!sort) {
    120                 while ((dp = readdir(dirp))) {
    121                         memset(buff, 0, sizeof(buff));
    122                         /* Don't worry if inserting a double slash, this will be fixed by
    123                          * absolutize() later with subsequent calls to open() or readdir() */
    124                         snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name);
    125                         ls_print(dp->d_name, buff);
    126                 }
    12766
    128                 free(buff);
    129 
    130                 return;
    131         }
    132        
    133         tosort = (struct dir_elem_t *)malloc(alloc_blocks*sizeof(struct dir_elem_t));
    134         if (NULL == tosort) {
    135                 cli_error(CL_ENOMEM, "ls: failed to scan %s", d);
    136                 free(buff);
    137                 return;
    138         }
    139         memset(tosort, 0, sizeof(tosort));
    140        
    14167        while ((dp = readdir(dirp))) {
    142                 nbdirs++;
    143                
    144                 if (nbdirs > alloc_blocks) {
    145                         alloc_blocks += alloc_blocks;
    146                        
    147                         tmp = (struct dir_elem_t *)realloc(tosort,
    148                                         alloc_blocks*sizeof(struct dir_elem_t));
    149                         if (NULL == tmp) {
    150                                 cli_error(CL_ENOMEM, "ls: failed to scan %s", d);
    151                                 for(i=0;i<(nbdirs-1);i++) {
    152                                         free(tosort[i].name);
    153                                 }
    154                                 free(tosort);
    155                                 free(buff);
    156                                 return;
    157                         }
    158                        
    159                         tosort = tmp;
    160                 }
    161                
    162                 // fill the name field
    163                 tosort[nbdirs-1].name = (char *)malloc(str_length(dp->d_name)+1);
    164                 if (NULL == tosort[nbdirs-1].name) {
    165                         cli_error(CL_ENOMEM, "ls: failed to scan %s", d);
    166                         for(i=0;i<(nbdirs-1);i++) {
    167                                 free(tosort[i].name);
    168                         }
    169                         free(tosort);
    170                         free(buff);
    171                         return;
    172                 }
    173                
    174                 memset(tosort[nbdirs-1].name, 0, str_length(dp->d_name)+1);
    175                 str_cpy(tosort[nbdirs-1].name, str_length(dp->d_name)+1, dp->d_name);
    176                
    177                 // fill the isdir field
    178                 memset(buff, 0, sizeof(buff));
    179                 snprintf(buff, PATH_MAX - 1, "%s/%s", d, tosort[nbdirs-1].name);
    180                
    181                 rc = stat(buff, &s);
    182                 if (rc != 0) {
    183                         printf("ls: skipping bogus node %s\n", buff);
    184                         printf("rc=%d\n", rc);
    185                         for(i=0;i<nbdirs;i++) {
    186                                 free(tosort[i].name);
    187                         }
    188                         free(tosort);
    189                         free(buff);
    190                         return;
    191                 }
    192                
    193                 tosort[nbdirs-1].isdir = s.is_directory ? 1 : 0;
    194         }
    195        
    196         if (!qsort(&tosort[0], nbdirs, sizeof(struct dir_elem_t), ls_cmp, NULL)) {
    197                 printf("Sorting error.\n");
    198         }
    199        
    200         for(i=0;i<nbdirs;i++) {
    20168                memset(buff, 0, sizeof(buff));
    20269                /* Don't worry if inserting a double slash, this will be fixed by
    20370                 * absolutize() later with subsequent calls to open() or readdir() */
    204                 snprintf(buff, PATH_MAX - 1, "%s/%s", d, tosort[i].name);
    205                 ls_print(tosort[i].name, buff);
    206                 free(tosort[i].name);
     71                snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name);
     72                ls_print(dp->d_name, buff);
    20773        }
    208        
    209         free(tosort);
     74
    21075        free(buff);
    21176
     
    21378}
    21479
    215 /** Print an entry.
    216  *
    217  * ls_print currently does nothing more than print the entry.
    218  * In the future, we will likely pass the absolute path, and
     80/* ls_print currently does nothing more than print the entry.
     81 * in the future, we will likely pass the absolute path, and
    21982 * some sort of ls_options structure that controls how each
    22083 * entry is printed and what is printed about it.
    22184 *
    222  * Now we just print basic DOS style lists.
    223  *
    224  * @param name          Name of the entry.
    225  * @param pathname      Path of the entry.
    226  */
     85 * Now we just print basic DOS style lists */
     86
    22787static void ls_print(const char *name, const char *pathname)
    22888{
     
    254114        } else {
    255115                help_cmd_ls(HELP_SHORT);
    256                 printf(
    257                 "Usage:  %s [options] [path]\n"
    258                 "If not path is given, the current working directory is used.\n"
    259                 "Options:\n"
    260                 "  -h, --help       A short option summary\n"
    261                 "  -u, --unsort     Do not sort directory entries\n",
    262                 cmdname);
     116                printf("  `%s' [path], if no path is given the current "
     117                                "working directory is used.\n", cmdname);
    263118        }
    264119
     
    272127        char *buff;
    273128        DIR *dirp;
    274         int c, opt_ind;
    275         int sort = 1;
    276129
    277130        argc = cli_count_args(argv);
    278        
    279         for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
    280                 c = getopt_long(argc, argv, "hu", long_options, &opt_ind);
    281                 switch (c) {
    282                 case 'h':
    283                         help_cmd_ls(HELP_LONG);
    284                         return CMD_SUCCESS;
    285                 case 'u':
    286                         sort = 0;
    287                         break;
    288                 }
    289         }
    290        
    291         int dir = (int)argc > optind ? (int)argc-1 : optind-1;
    292         argc -= (optind-1);
    293        
     131
    294132        buff = (char *) malloc(PATH_MAX);
    295133        if (NULL == buff) {
     
    298136        }
    299137        memset(buff, 0, sizeof(buff));
    300        
     138
    301139        if (argc == 1)
    302140                getcwd(buff, PATH_MAX);
    303141        else
    304                 str_cpy(buff, PATH_MAX, argv[dir]);
    305        
     142                str_cpy(buff, PATH_MAX, argv[1]);
     143
    306144        if (stat(buff, &s)) {
    307145                cli_error(CL_ENOENT, buff);
     
    320158                        return CMD_FAILURE;
    321159                }
    322                 ls_scan_dir(buff, dirp, sort);
     160                ls_scan_dir(buff, dirp);
    323161                closedir(dirp);
    324162        }
  • uspace/app/bdsh/cmds/modules/ls/ls.h

    rbeb6b3d r917a8c8  
    77#define LS_DIR   2
    88
    9 static void ls_scan_dir(const char *, DIR *, int);
     9static void ls_scan_dir(const char *, DIR *);
    1010static void ls_print(const char *, const char *);
    11 
    12 /** Structure to represent a directory entry.
    13  *
    14  * Useful to keep together important informations
    15  * for sorting directory entries.
    16  */
    17 struct dir_elem_t {
    18         char * name;
    19         int isdir;
    20 };
    2111
    2212#endif /* LS_H */
Note: See TracChangeset for help on using the changeset viewer.