Changes in / [beb6b3d:917a8c8] in mainline
- Location:
- uspace/app/bdsh/cmds/modules/ls
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/ls/ls.c
rbeb6b3d r917a8c8 38 38 #include <dirent.h> 39 39 #include <fcntl.h> 40 #include <getopt.h>41 40 #include <sys/types.h> 42 41 #include <sys/stat.h> 43 42 #include <str.h> 44 #include <sort.h>45 43 46 44 #include "errors.h" … … 53 51 static const char *cmdname = "ls"; 54 52 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 }; 53 static void ls_scan_dir(const char *d, DIR *dirp) 54 { 55 struct dirent *dp; 56 char *buff; 60 57 61 /** Compare 2 directory elements.62 *63 * It compares 2 elements of a directory : a file is considered64 * 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 else87 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 109 58 if (! dirp) 110 59 return; … … 115 64 return; 116 65 } 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 by123 * 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 }127 66 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 141 67 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 field163 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 field178 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++) {201 68 memset(buff, 0, sizeof(buff)); 202 69 /* Don't worry if inserting a double slash, this will be fixed by 203 70 * 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); 207 73 } 208 209 free(tosort); 74 210 75 free(buff); 211 76 … … 213 78 } 214 79 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 219 82 * some sort of ls_options structure that controls how each 220 83 * entry is printed and what is printed about it. 221 84 * 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 227 87 static void ls_print(const char *name, const char *pathname) 228 88 { … … 254 114 } else { 255 115 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); 263 118 } 264 119 … … 272 127 char *buff; 273 128 DIR *dirp; 274 int c, opt_ind;275 int sort = 1;276 129 277 130 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 294 132 buff = (char *) malloc(PATH_MAX); 295 133 if (NULL == buff) { … … 298 136 } 299 137 memset(buff, 0, sizeof(buff)); 300 138 301 139 if (argc == 1) 302 140 getcwd(buff, PATH_MAX); 303 141 else 304 str_cpy(buff, PATH_MAX, argv[ dir]);305 142 str_cpy(buff, PATH_MAX, argv[1]); 143 306 144 if (stat(buff, &s)) { 307 145 cli_error(CL_ENOENT, buff); … … 320 158 return CMD_FAILURE; 321 159 } 322 ls_scan_dir(buff, dirp , sort);160 ls_scan_dir(buff, dirp); 323 161 closedir(dirp); 324 162 } -
uspace/app/bdsh/cmds/modules/ls/ls.h
rbeb6b3d r917a8c8 7 7 #define LS_DIR 2 8 8 9 static void ls_scan_dir(const char *, DIR * , int);9 static void ls_scan_dir(const char *, DIR *); 10 10 static void ls_print(const char *, const char *); 11 12 /** Structure to represent a directory entry.13 *14 * Useful to keep together important informations15 * for sorting directory entries.16 */17 struct dir_elem_t {18 char * name;19 int isdir;20 };21 11 22 12 #endif /* LS_H */
Note:
See TracChangeset
for help on using the changeset viewer.
