Changeset ba63912 in mainline
- Timestamp:
- 2011-04-01T13:44:30Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2859445
- Parents:
- a30e435
- Location:
- uspace/app/bdsh/cmds/modules/ls
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/ls/ls.c
ra30e435 rba63912 48 48 #include "util.h" 49 49 #include "entry.h" 50 #include "ls.h"51 50 #include "cmds.h" 51 52 /* Various values that can be returned by ls_scope() */ 53 #define LS_BOGUS 0 54 #define LS_FILE 1 55 #define LS_DIR 2 56 57 /** Structure to represent a directory entry. 58 * 59 * Useful to keep together important informations 60 * for sorting directory entries. 61 */ 62 struct dir_elem_t { 63 char *name; 64 struct stat s; 65 }; 52 66 53 67 static const char *cmdname = "ls"; … … 59 73 }; 60 74 75 /** Print an entry. 76 * 77 * ls_print currently does nothing more than print the entry. 78 * In the future, we will likely pass the absolute path, and 79 * some sort of ls_options structure that controls how each 80 * entry is printed and what is printed about it. 81 * 82 * Now we just print basic DOS style lists. 83 * 84 * @param de Directory element. 85 */ 86 static void ls_print(struct dir_elem_t *de) 87 { 88 if (de->s.is_file) 89 printf("%-40s\t%llu\n", de->name, (long long) de->s.size); 90 else if (de->s.is_directory) 91 printf("%-40s\t<dir>\n", de->name); 92 else 93 printf("%-40s\n", de->name); 94 } 95 96 61 97 /** Compare 2 directory elements. 62 98 * 63 99 * It compares 2 elements of a directory : a file is considered 64 * as lower than a directory, and if they have the same type,100 * as bigger than a directory, and if they have the same type, 65 101 * they are compared alphabetically. 66 102 * 67 103 * @param a Pointer to the structure of the first element. 68 104 * @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. 105 * @param arg Pointer for an other and optionnal argument. 106 * 107 * @return -1 if a < b, 1 otherwise. 73 108 */ 74 109 static int ls_cmp(void *a, void *b, void *arg) 75 110 { 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)) 111 struct dir_elem_t *da = a; 112 struct dir_elem_t *db = b; 113 114 if ((da->s.is_directory && db->s.is_file) || 115 ((da->s.is_directory == db->s.is_directory) && 116 str_cmp(da->name, db->name) < 0)) 85 117 return -1; 86 118 else … … 100 132 { 101 133 int alloc_blocks = 20; 102 int i = 0;134 int i; 103 135 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 dir ent * dp = NULL;109 struct stat s;110 111 if (! 136 int rc; 137 int len; 138 char *buff; 139 struct dir_elem_t *tmp; 140 struct dir_elem_t *tosort; 141 struct dirent *dp; 142 143 if (!dirp) 112 144 return; 113 145 114 buff = (char *) malloc(PATH_MAX);115 if ( NULL ==buff) {146 buff = (char *) malloc(PATH_MAX); 147 if (!buff) { 116 148 cli_error(CL_ENOMEM, "ls: failed to scan %s", d); 117 149 return; 118 150 } 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 by 125 * 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 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) { 151 152 tosort = (struct dir_elem_t *) malloc(alloc_blocks * sizeof(*tosort)); 153 if (!tosort) { 137 154 cli_error(CL_ENOMEM, "ls: failed to scan %s", d); 138 155 free(buff); 139 156 return; 140 157 } 141 memset(tosort, 0, sizeof(tosort));142 158 143 159 while ((dp = readdir(dirp))) { 144 nbdirs++; 145 146 if (nbdirs > alloc_blocks) { 160 if (nbdirs + 1 > alloc_blocks) { 147 161 alloc_blocks += alloc_blocks; 148 162 149 tmp = (struct dir_elem_t *) realloc(tosort,150 alloc_blocks*sizeof(struct dir_elem_t));151 if ( NULL ==tmp) {163 tmp = (struct dir_elem_t *) realloc(tosort, 164 alloc_blocks * sizeof(struct dir_elem_t)); 165 if (!tmp) { 152 166 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; 167 goto out; 159 168 } 160 161 169 tosort = tmp; 162 170 } 163 171 164 / / fill the name field165 tosort[nbdirs -1].name = (char *)malloc(str_length(dp->d_name)+1);166 if ( NULL == tosort[nbdirs-1].name) {172 /* fill the name field */ 173 tosort[nbdirs].name = (char *) malloc(str_length(dp->d_name) + 1); 174 if (!tosort[nbdirs].name) { 167 175 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; 176 goto out; 174 177 } 175 178 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 field 180 memset(buff, 0, sizeof(buff)); 181 snprintf(buff, PATH_MAX - 1, "%s/%s", d, tosort[nbdirs-1].name); 182 183 rc = stat(buff, &s); 179 str_cpy(tosort[nbdirs].name, str_length(dp->d_name) + 1, dp->d_name); 180 len = snprintf(buff, PATH_MAX - 1, "%s/%s", d, tosort[nbdirs].name); 181 buff[len] = '\0'; 182 183 rc = stat(buff, &tosort[nbdirs++].s); 184 184 if (rc != 0) { 185 185 printf("ls: skipping bogus node %s\n", buff); 186 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 memset(buff, 0, sizeof(buff)); 204 /* Don't worry if inserting a double slash, this will be fixed by 205 * 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); 187 goto out; 188 } 189 } 190 191 if (sort) { 192 if (!qsort(&tosort[0], nbdirs, sizeof(struct dir_elem_t), 193 ls_cmp, NULL)) { 194 printf("Sorting error.\n"); 195 } 196 } 197 198 for (i = 0; i < nbdirs; i++) 199 ls_print(&tosort[i]); 200 201 out: 202 for(i = 0; i < nbdirs; i++) 208 203 free(tosort[i].name); 209 }210 211 204 free(tosort); 212 205 free(buff); 213 214 return;215 }216 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, and221 * some sort of ls_options structure that controls how each222 * entry is printed and what is printed about it.223 *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 */229 static void ls_print(const char *name, const char *pathname)230 {231 struct stat s;232 int rc;233 234 rc = stat(pathname, &s);235 if (rc != 0) {236 /* Odd chance it was deleted from the time readdir() found it */237 printf("ls: skipping bogus node %s\n", pathname);238 printf("rc=%d\n", rc);239 return;240 }241 242 if (s.is_file)243 printf("%-40s\t%llu\n", name, (long long) s.size);244 else if (s.is_directory)245 printf("%-40s\t<dir>\n", name);246 else247 printf("%-40s\n", name);248 249 return;250 206 } 251 207 … … 271 227 { 272 228 unsigned int argc; 273 struct stat s; 274 char *buff; 229 struct dir_elem_t de; 275 230 DIR *dirp; 276 231 int c, opt_ind; … … 291 246 } 292 247 293 int dir = (int) argc > optind ? (int)argc-1 : optind-1;294 argc -= (optind -1);295 296 buff= (char *) malloc(PATH_MAX);297 if ( NULL == buff) {248 int dir = (int) argc > optind ? (int) argc - 1 : optind - 1; 249 argc -= (optind - 1); 250 251 de.name = (char *) malloc(PATH_MAX); 252 if (!de.name) { 298 253 cli_error(CL_ENOMEM, "%s: ", cmdname); 299 254 return CMD_FAILURE; 300 255 } 301 memset( buff, 0, sizeof(buff));256 memset(de.name, 0, sizeof(PATH_MAX)); 302 257 303 258 if (argc == 1) 304 getcwd( buff, PATH_MAX);259 getcwd(de.name, PATH_MAX); 305 260 else 306 str_cpy( buff, PATH_MAX, argv[dir]);307 308 if (stat( buff, &s)) {309 cli_error(CL_ENOENT, buff);310 free( buff);261 str_cpy(de.name, PATH_MAX, argv[dir]); 262 263 if (stat(de.name, &de.s)) { 264 cli_error(CL_ENOENT, de.name); 265 free(de.name); 311 266 return CMD_FAILURE; 312 267 } 313 268 314 if ( s.is_file) {315 ls_print( buff, buff);269 if (de.s.is_file) { 270 ls_print(&de); 316 271 } else { 317 dirp = opendir( buff);272 dirp = opendir(de.name); 318 273 if (!dirp) { 319 274 /* May have been deleted between scoping it and opening it */ 320 cli_error(CL_EFAIL, "Could not stat %s", buff);321 free( buff);275 cli_error(CL_EFAIL, "Could not stat %s", de.name); 276 free(de.name); 322 277 return CMD_FAILURE; 323 278 } 324 ls_scan_dir( buff, dirp, sort);279 ls_scan_dir(de.name, dirp, sort); 325 280 closedir(dirp); 326 281 } 327 282 328 free( buff);283 free(de.name); 329 284 330 285 return CMD_SUCCESS; -
uspace/app/bdsh/cmds/modules/ls/ls.h
ra30e435 rba63912 2 2 #define LS_H 3 3 4 /* Various values that can be returned by ls_scope() */5 #define LS_BOGUS 06 #define LS_FILE 17 #define LS_DIR 28 9 static void ls_scan_dir(const char *, DIR *, int);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 4 22 5 #endif /* LS_H */
Note:
See TracChangeset
for help on using the changeset viewer.