Changes in uspace/app/bdsh/cmds/modules/mkdir/mkdir.c [738b549:36ab7c7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/cmds/modules/mkdir/mkdir.c
r738b549 r36ab7c7 36 36 #include <stdarg.h> 37 37 #include <str.h> 38 #include <errno.h>39 #include <str_error.h>40 #include <vfs/vfs.h>41 38 42 39 #include "config.h" … … 86 83 /* This is kind of clunky, but effective for now */ 87 84 static unsigned int 88 create_directory(const char * user_path, bool create_parents)85 create_directory(const char *path, unsigned int p) 89 86 { 90 /* Ensure we would always work with absolute and canonified path. */ 91 char *path = absolutize(user_path, NULL); 92 if (path == NULL) { 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))) { 93 95 cli_error(CL_ENOMEM, "%s: path too big?", cmdname); 94 96 return 1; 95 97 } 96 98 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 } 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; 107 143 } else { 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)) { 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 ++; 114 169 break; 115 170 } 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); 171 } 172 i++; 173 } 174 goto finit; 175 176 finit: 177 free(wdp); 178 free(tmp); 164 179 return ret; 165 180 } … … 167 182 int cmd_mkdir(char **argv) 168 183 { 169 unsigned int argc, i, ret= 0;170 bool create_parents = false, follow = false, verbose = false;184 unsigned int argc, create_parents = 0, i, ret = 0, follow = 0; 185 unsigned int verbose = 0; 171 186 int c, opt_ind; 187 char *cwd; 172 188 173 189 argc = cli_count_args(argv); … … 177 193 switch (c) { 178 194 case 'p': 179 create_parents = true;195 create_parents = 1; 180 196 break; 181 197 case 'v': 182 verbose = true;198 verbose = 1; 183 199 break; 184 200 case 'h': … … 189 205 return CMD_SUCCESS; 190 206 case 'f': 191 follow = true;207 follow = 1; 192 208 break; 193 209 case 'm': … … 205 221 } 206 222 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 207 231 for (i = optind; argv[i] != NULL; i++) { 208 if (verbose )232 if (verbose == 1) 209 233 printf("%s: creating %s%s\n", 210 234 cmdname, argv[i], … … 213 237 } 214 238 215 if (follow && (argv[optind] != NULL)) { 216 chdir(argv[optind]); 217 } 239 if (follow == 0) 240 chdir(cwd); 241 242 free(cwd); 218 243 219 244 if (ret)
Note:
See TracChangeset
for help on using the changeset viewer.