Changes in uspace/app/bdsh/cmds/modules/ls/ls.c [1e2629f:19f857a] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/ls/ls.c
r1e2629f r19f857a 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 * @param sort 1 if the output must be sorted,97 * 0 otherwise.98 */99 static void ls_scan_dir(const char *d, DIR *dirp, int sort)100 {101 int alloc_blocks = 20;102 int i = 0;103 int nbdirs = 0;104 int rc = 0;105 char * buff = NULL;106 struct dir_elem_t * tmp = NULL;107 struct dir_elem_t * tosort = NULL;108 struct dirent * dp = NULL;109 struct stat s;110 111 58 if (! dirp) 112 59 return; … … 117 64 return; 118 65 } 119 memset(buff, 0, sizeof(buff));120 121 if (!sort) {122 while ((dp = readdir(dirp))) {123 memset(buff, 0, sizeof(buff));124 /* Don't worry if inserting a double slash, this will be fixed by125 * absolutize() later with subsequent calls to open() or readdir() */126 snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name);127 ls_print(dp->d_name, buff);128 }129 66 130 free(buff);131 132 return;133 }134 135 tosort = (struct dir_elem_t *)malloc(alloc_blocks*sizeof(struct dir_elem_t));136 if (NULL == tosort) {137 cli_error(CL_ENOMEM, "ls: failed to scan %s", d);138 free(buff);139 return;140 }141 memset(tosort, 0, sizeof(tosort));142 143 67 while ((dp = readdir(dirp))) { 144 nbdirs++;145 146 if (nbdirs > alloc_blocks) {147 alloc_blocks += alloc_blocks;148 149 tmp = (struct dir_elem_t *)realloc(tosort,150 alloc_blocks*sizeof(struct dir_elem_t));151 if (NULL == tmp) {152 cli_error(CL_ENOMEM, "ls: failed to scan %s", d);153 for(i=0;i<(nbdirs-1);i++) {154 free(tosort[i].name);155 }156 free(tosort);157 free(buff);158 return;159 }160 161 tosort = tmp;162 }163 164 // fill the name field165 tosort[nbdirs-1].name = (char *)malloc(str_length(dp->d_name)+1);166 if (NULL == tosort[nbdirs-1].name) {167 cli_error(CL_ENOMEM, "ls: failed to scan %s", d);168 for(i=0;i<(nbdirs-1);i++) {169 free(tosort[i].name);170 }171 free(tosort);172 free(buff);173 return;174 }175 176 memset(tosort[nbdirs-1].name, 0, str_length(dp->d_name)+1);177 str_cpy(tosort[nbdirs-1].name, str_length(dp->d_name)+1, dp->d_name);178 179 // fill the isdir field180 memset(buff, 0, sizeof(buff));181 snprintf(buff, PATH_MAX - 1, "%s/%s", d, tosort[nbdirs-1].name);182 183 rc = stat(buff, &s);184 if (rc != 0) {185 printf("ls: skipping bogus node %s\n", buff);186 printf("rc=%d\n", rc);187 for(i=0;i<nbdirs;i++) {188 free(tosort[i].name);189 }190 free(tosort);191 free(buff);192 return;193 }194 195 tosort[nbdirs-1].isdir = s.is_directory ? 1 : 0;196 }197 198 if (!qsort(&tosort[0], nbdirs, sizeof(struct dir_elem_t), ls_cmp, NULL)) {199 printf("Sorting error.\n");200 }201 202 for(i=0;i<nbdirs;i++) {203 68 memset(buff, 0, sizeof(buff)); 204 69 /* Don't worry if inserting a double slash, this will be fixed by 205 70 * absolutize() later with subsequent calls to open() or readdir() */ 206 snprintf(buff, PATH_MAX - 1, "%s/%s", d, tosort[i].name); 207 ls_print(tosort[i].name, buff); 208 free(tosort[i].name); 71 snprintf(buff, PATH_MAX - 1, "%s/%s", d, dp->d_name); 72 ls_print(dp->d_name, buff); 209 73 } 210 211 free(tosort); 74 212 75 free(buff); 213 76 … … 215 78 } 216 79 217 /** Print an entry. 218 * 219 * ls_print currently does nothing more than print the entry. 220 * 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 221 82 * some sort of ls_options structure that controls how each 222 83 * entry is printed and what is printed about it. 223 84 * 224 * Now we just print basic DOS style lists. 225 * 226 * @param name Name of the entry. 227 * @param pathname Path of the entry. 228 */ 85 * Now we just print basic DOS style lists */ 86 229 87 static void ls_print(const char *name, const char *pathname) 230 88 { … … 256 114 } else { 257 115 help_cmd_ls(HELP_SHORT); 258 printf( 259 "Usage: %s [options] [path]\n" 260 "If not path is given, the current working directory is used.\n" 261 "Options:\n" 262 " -h, --help A short option summary\n" 263 " -u, --unsort Do not sort directory entries\n", 264 cmdname); 116 printf(" `%s' [path], if no path is given the current " 117 "working directory is used.\n", cmdname); 265 118 } 266 119 … … 274 127 char *buff; 275 128 DIR *dirp; 276 int c, opt_ind;277 int sort = 1;278 129 279 130 argc = cli_count_args(argv); 280 281 for (c = 0, optind = 0, opt_ind = 0; c != -1;) { 282 c = getopt_long(argc, argv, "hu", long_options, &opt_ind); 283 switch (c) { 284 case 'h': 285 help_cmd_ls(HELP_LONG); 286 return CMD_SUCCESS; 287 case 'u': 288 sort = 0; 289 break; 290 } 291 } 292 293 int dir = (int)argc > optind ? (int)argc-1 : optind-1; 294 argc -= (optind-1); 295 131 296 132 buff = (char *) malloc(PATH_MAX); 297 133 if (NULL == buff) { … … 300 136 } 301 137 memset(buff, 0, sizeof(buff)); 302 138 303 139 if (argc == 1) 304 140 getcwd(buff, PATH_MAX); 305 141 else 306 str_cpy(buff, PATH_MAX, argv[ dir]);307 142 str_cpy(buff, PATH_MAX, argv[1]); 143 308 144 if (stat(buff, &s)) { 309 145 cli_error(CL_ENOENT, buff); … … 322 158 return CMD_FAILURE; 323 159 } 324 ls_scan_dir(buff, dirp , sort);160 ls_scan_dir(buff, dirp); 325 161 closedir(dirp); 326 162 }
Note:
See TracChangeset
for help on using the changeset viewer.