Changes in uspace/app/bdsh/cmds/modules/mkdir/mkdir.c [36ab7c7:738b549] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/mkdir/mkdir.c
r36ab7c7 r738b549 36 36 #include <stdarg.h> 37 37 #include <str.h> 38 #include <errno.h> 39 #include <str_error.h> 40 #include <vfs/vfs.h> 38 41 39 42 #include "config.h" … … 83 86 /* This is kind of clunky, but effective for now */ 84 87 static unsigned int 85 create_directory(const char * path, unsigned int p)88 create_directory(const char *user_path, bool create_parents) 86 89 { 87 DIR *dirp; 88 char *tmp = NULL, *buff = NULL, *wdp = NULL; 89 char *dirs[255]; 90 unsigned int absolute = 0, i = 0, ret = 0; 91 92 /* Its a good idea to allocate path, plus we (may) need a copy of 93 * path to tokenize if parents are specified */ 94 if (NULL == (tmp = str_dup(path))) { 90 /* Ensure we would always work with absolute and canonified path. */ 91 char *path = absolutize(user_path, NULL); 92 if (path == NULL) { 95 93 cli_error(CL_ENOMEM, "%s: path too big?", cmdname); 96 94 return 1; 97 95 } 98 96 99 if (NULL == (wdp = (char *) malloc(PATH_MAX))) { 100 cli_error(CL_ENOMEM, "%s: could not alloc cwd", cmdname); 101 free(tmp); 102 return 1; 103 } 104 105 /* The only reason for wdp is to be (optionally) verbose */ 106 getcwd(wdp, PATH_MAX); 107 108 /* Typical use without specifying the creation of parents */ 109 if (p == 0) { 110 dirp = opendir(tmp); 111 if (dirp) { 112 cli_error(CL_EEXISTS, "%s: can not create %s, try -p", cmdname, path); 113 closedir(dirp); 114 goto finit; 115 } 116 if (-1 == (mkdir(tmp, 0))) { 117 cli_error(CL_EFAIL, "%s: could not create %s", cmdname, path); 118 goto finit; 119 } 120 } 121 122 /* Parents need to be created, path has to be broken up */ 123 124 /* See if path[0] is a slash, if so we have to remember to append it */ 125 if (tmp[0] == '/') 126 absolute = 1; 127 128 /* TODO: Canonify the path prior to tokenizing it, see below */ 129 dirs[i] = strtok(tmp, "/"); 130 while (dirs[i] && i < 255) 131 dirs[++i] = strtok(NULL, "/"); 132 133 if (NULL == dirs[0]) 134 return 1; 135 136 if (absolute == 1) { 137 asprintf(&buff, "/%s", dirs[0]); 138 mkdir(buff, 0); 139 chdir(buff); 140 free(buff); 141 getcwd(wdp, PATH_MAX); 142 i = 1; 97 int rc; 98 int ret = 0; 99 100 if (!create_parents) { 101 rc = mkdir(path, 0); 102 if (rc != EOK) { 103 cli_error(CL_EFAIL, "%s: could not create %s (%s)", 104 cmdname, path, str_error(rc)); 105 ret = 1; 106 } 143 107 } else { 144 i = 0; 145 } 146 147 while (dirs[i] != NULL) { 148 /* Sometimes make or scripts conjoin odd paths. Account for something 149 * like this: ../../foo/bar/../foo/foofoo/./bar */ 150 if (!str_cmp(dirs[i], "..") || !str_cmp(dirs[i], ".")) { 151 if (0 != (chdir(dirs[i]))) { 152 cli_error(CL_EFAIL, "%s: impossible path: %s", 153 cmdname, path); 154 ret ++; 155 goto finit; 156 } 157 getcwd(wdp, PATH_MAX); 158 } else { 159 if (-1 == (mkdir(dirs[i], 0))) { 160 cli_error(CL_EFAIL, 161 "%s: failed at %s/%s", wdp, dirs[i]); 162 ret ++; 163 goto finit; 164 } 165 if (0 != (chdir(dirs[i]))) { 166 cli_error(CL_EFAIL, "%s: failed creating %s\n", 167 cmdname, dirs[i]); 168 ret ++; 108 /* Create the parent directories as well. */ 109 size_t off = 0; 110 while (1) { 111 size_t prev_off = off; 112 wchar_t cur_char = str_decode(path, &off, STR_NO_LIMIT); 113 if ((cur_char == 0) || (cur_char == U_SPECIAL)) { 169 114 break; 170 115 } 171 } 172 i++; 173 } 174 goto finit; 175 176 finit: 177 free(wdp); 178 free(tmp); 116 if (cur_char != '/') { 117 continue; 118 } 119 if (prev_off == 0) { 120 continue; 121 } 122 /* 123 * If we are here, it means that: 124 * - we found / 125 * - it is not the first / (no need to create root 126 * directory) 127 * 128 * We would now overwrite the / with 0 to terminate the 129 * string (that shall be okay because we are 130 * overwriting at the beginning of UTF sequence). 131 * That would allow us to create the directories 132 * in correct nesting order. 133 * 134 * Notice that we ignore EEXIST errors as some of 135 * the parent directories may already exist. 136 */ 137 char slash_char = path[prev_off]; 138 path[prev_off] = 0; 139 rc = mkdir(path, 0); 140 if (rc == EEXIST) { 141 rc = EOK; 142 } 143 144 if (rc != EOK) { 145 cli_error(CL_EFAIL, "%s: could not create %s (%s)", 146 cmdname, path, str_error(rc)); 147 ret = 1; 148 goto leave; 149 } 150 151 path[prev_off] = slash_char; 152 } 153 /* Create the final directory. */ 154 rc = mkdir(path, 0); 155 if (rc != EOK) { 156 cli_error(CL_EFAIL, "%s: could not create %s (%s)", 157 cmdname, path, str_error(rc)); 158 ret = 1; 159 } 160 } 161 162 leave: 163 free(path); 179 164 return ret; 180 165 } … … 182 167 int cmd_mkdir(char **argv) 183 168 { 184 unsigned int argc, create_parents = 0, i, ret = 0, follow= 0;185 unsigned int verbose = 0;169 unsigned int argc, i, ret = 0; 170 bool create_parents = false, follow = false, verbose = false; 186 171 int c, opt_ind; 187 char *cwd;188 172 189 173 argc = cli_count_args(argv); … … 193 177 switch (c) { 194 178 case 'p': 195 create_parents = 1;179 create_parents = true; 196 180 break; 197 181 case 'v': 198 verbose = 1;182 verbose = true; 199 183 break; 200 184 case 'h': … … 205 189 return CMD_SUCCESS; 206 190 case 'f': 207 follow = 1;191 follow = true; 208 192 break; 209 193 case 'm': … … 221 205 } 222 206 223 if (NULL == (cwd = (char *) malloc(PATH_MAX))) {224 cli_error(CL_ENOMEM, "%s: could not allocate cwd", cmdname);225 return CMD_FAILURE;226 }227 228 memset(cwd, 0, sizeof(cwd));229 getcwd(cwd, PATH_MAX);230 231 207 for (i = optind; argv[i] != NULL; i++) { 232 if (verbose == 1)208 if (verbose) 233 209 printf("%s: creating %s%s\n", 234 210 cmdname, argv[i], … … 237 213 } 238 214 239 if (follow == 0) 240 chdir(cwd); 241 242 free(cwd); 215 if (follow && (argv[optind] != NULL)) { 216 chdir(argv[optind]); 217 } 243 218 244 219 if (ret)
Note:
See TracChangeset
for help on using the changeset viewer.