44
45
#include "errors.h"
45
46
#include "config.h"
50
/* Various values that can be returned by ls_scope() */
55
/** Structure to represent a directory entry.
57
* Useful to keep together important information
58
* for sorting directory entries.
65
51
static const char *cmdname = "ls";
67
55
static struct option const long_options[] = {
68
56
{ "help", no_argument, 0, 'h' },
69
57
{ "unsort", no_argument, 0, 'u' },
58
{ "recursive", no_argument, 0, 'r' },
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 *);
70
static unsigned int ls_start(ls_job_t *ls)
73
78
/** Print an entry.
75
80
* ls_print currently does nothing more than print the entry.
196
201
for (i = 0; i < nbdirs; i++)
197
202
ls_print(&tosort[i]);
204
/* Populate the directory list. */
206
tmp = (struct dir_elem_t *) realloc(*dir_list_ptr,
207
nbdirs * sizeof(struct dir_elem_t));
209
cli_error(CL_ENOMEM, "ls: failed to scan %s", d);
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);
200
224
for(i = 0; i < nbdirs; i++)
201
225
free(tosort[i].name);
232
/** Visit a directory recursively.
234
* ls_recursive visits all the subdirectories recursively and
235
* prints the files and directories in them.
237
* @param path Path the current directory being visited.
238
* @param dirp Directory stream.
240
static unsigned int ls_recursive(const char *path, DIR *dirp)
246
struct dir_elem_t *dir_list;
248
const char * const trailing_slash = "/";
251
dir_list = (struct dir_elem_t *) malloc(sizeof(struct dir_elem_t));
253
printf("\n%s:\n", path);
255
subdir_path = (char *) malloc(PATH_MAX);
261
nbdirs = ls_scan_dir(path, dirp, &dir_list);
267
for (i = 0; i < nbdirs; ++i) {
268
memset(subdir_path, 0, PATH_MAX);
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);
279
scope = ls_scope(subdir_path, &dir_list[i]);
284
subdirp = opendir(subdir_path);
286
/* May have been deleted between scoping it and opening it */
287
cli_error(CL_EFAIL, "Could not stat %s", dir_list[i].name);
292
ret = ls_recursive(subdir_path, subdirp);
294
if (ret == CMD_FAILURE)
306
for (i = 0; i < nbdirs; i++)
307
free(dir_list[i].name);
314
static unsigned int ls_scope(const char *path, struct dir_elem_t *de)
316
if (stat(path, &de->s)) {
317
cli_error(CL_ENOENT, path);
323
else if (de->s.is_directory)
206
329
void help_cmd_ls(unsigned int level)
214
337
"If not path is given, the current working directory is used.\n"
216
339
" -h, --help A short option summary\n"
217
" -u, --unsort Do not sort directory entries\n",
340
" -u, --unsort Do not sort directory entries\n"
341
" -r, --recursive List subdirectories recursively\n",
227
351
struct dir_elem_t de;
357
if (!ls_start(&ls)) {
358
cli_error(CL_EFAIL, "%s: Could not initialize", cmdname);
232
362
argc = cli_count_args(argv);
234
364
for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
235
c = getopt_long(argc, argv, "hu", long_options, &opt_ind);
365
c = getopt_long(argc, argv, "hur", long_options, &opt_ind);
238
368
help_cmd_ls(HELP_LONG);
239
369
return CMD_SUCCESS;
250
383
cli_error(CL_ENOMEM, "%s: ", cmdname);
251
384
return CMD_FAILURE;
253
memset(de.name, 0, sizeof(PATH_MAX));
386
memset(de.name, 0, PATH_MAX);
256
389
getcwd(de.name, PATH_MAX);
258
391
str_cpy(de.name, PATH_MAX, argv[optind]);
260
if (stat(de.name, &de.s)) {
261
cli_error(CL_ENOENT, de.name);
393
scope = ls_scope(de.name, &de);
269
399
dirp = opendir(de.name);
271
401
/* May have been deleted between scoping it and opening it */