Changes in uspace/app/bdsh/cmds/modules/ls/ls.c [9bdf1f2a:a701812] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/ls/ls.c
r9bdf1f2a ra701812 42 42 #include <sort.h> 43 43 44 #include "ls.h"45 44 #include "errors.h" 46 45 #include "config.h" … … 49 48 #include "cmds.h" 50 49 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 */ 60 struct dir_elem_t { 61 char *name; 62 struct stat s; 63 }; 64 51 65 static const char *cmdname = "ls"; 52 53 static ls_job_t ls;54 66 55 67 static struct option const long_options[] = { 56 68 { "help", no_argument, 0, 'h' }, 57 69 { "unsort", no_argument, 0, 'u' }, 58 { "recursive", no_argument, 0, 'r' },59 70 { 0, 0, 0, 0 } 60 71 }; 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 }77 72 78 73 /** Print an entry. … … 97 92 } 98 93 94 99 95 /** Compare 2 directory elements. 100 96 * … … 131 127 * 0 otherwise. 132 128 */ 133 static signed int ls_scan_dir(const char *d, DIR *dirp, 134 struct dir_elem_t **dir_list_ptr) 129 static void ls_scan_dir(const char *d, DIR *dirp, int sort) 135 130 { 136 131 int alloc_blocks = 20; … … 145 140 146 141 if (!dirp) 147 return -1;142 return; 148 143 149 144 buff = (char *) malloc(PATH_MAX); 150 145 if (!buff) { 151 146 cli_error(CL_ENOMEM, "ls: failed to scan %s", d); 152 return -1;147 return; 153 148 } 154 149 … … 157 152 cli_error(CL_ENOMEM, "ls: failed to scan %s", d); 158 153 free(buff); 159 return -1;154 return; 160 155 } 161 156 … … 192 187 } 193 188 194 if ( ls.sort) {189 if (sort) { 195 190 if (!qsort(&tosort[0], nbdirs, sizeof(struct dir_elem_t), 196 191 ls_cmp, NULL)) { … … 201 196 for (i = 0; i < nbdirs; i++) 202 197 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 }222 198 223 199 out: … … 226 202 free(tosort); 227 203 free(buff); 228 229 return nbdirs;230 }231 232 /** Visit a directory recursively.233 *234 * ls_recursive visits all the subdirectories recursively and235 * 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;327 204 } 328 205 … … 338 215 "Options:\n" 339 216 " -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", 342 218 cmdname); 343 219 } … … 352 228 DIR *dirp; 353 229 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; 361 231 362 232 argc = cli_count_args(argv); 363 233 364 234 for (c = 0, optind = 0, opt_ind = 0; c != -1;) { 365 c = getopt_long(argc, argv, "hu r", long_options, &opt_ind);235 c = getopt_long(argc, argv, "hu", long_options, &opt_ind); 366 236 switch (c) { 367 237 case 'h': … … 369 239 return CMD_SUCCESS; 370 240 case 'u': 371 ls.sort = 0; 372 break; 373 case 'r': 374 ls.recursive = 1; 241 sort = 0; 375 242 break; 376 243 } … … 384 251 return CMD_FAILURE; 385 252 } 386 memset(de.name, 0, PATH_MAX);253 memset(de.name, 0, sizeof(PATH_MAX)); 387 254 388 255 if (argc == 0) … … 390 257 else 391 258 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) { 396 267 ls_print(&de); 397 break; 398 case LS_DIR: 268 } else { 399 269 dirp = opendir(de.name); 400 270 if (!dirp) { … … 404 274 return CMD_FAILURE; 405 275 } 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); 411 277 closedir(dirp); 412 break;413 case LS_BOGUS:414 return CMD_FAILURE;415 278 } 416 279 417 280 free(de.name); 418 281 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.