Create any necessary directories in fname. Any missing directories are * created with default permissions. Returns < 0 on error, or the number * of directories created. */
| 184 | * created with default permissions. Returns < 0 on error, or the number |
| 185 | * of directories created. */ |
| 186 | int make_path(char *fname, int flags) |
| 187 | { |
| 188 | char *end, *p; |
| 189 | int ret = 0; |
| 190 | |
| 191 | if (flags & MKP_SKIP_SLASH) { |
| 192 | while (*fname == '/') |
| 193 | fname++; |
| 194 | } |
| 195 | |
| 196 | while (*fname == '.' && fname[1] == '/') |
| 197 | fname += 2; |
| 198 | |
| 199 | if (flags & MKP_DROP_NAME) { |
| 200 | end = strrchr(fname, '/'); |
| 201 | if (!end || end == fname) |
| 202 | return 0; |
| 203 | *end = '\0'; |
| 204 | } else |
| 205 | end = fname + strlen(fname); |
| 206 | |
| 207 | /* Try to find an existing dir, starting from the deepest dir. */ |
| 208 | for (p = end; ; ) { |
| 209 | if (dry_run) { |
| 210 | STRUCT_STAT st; |
| 211 | if (do_stat(fname, &st) == 0) { |
| 212 | if (S_ISDIR(st.st_mode)) |
| 213 | errno = EEXIST; |
| 214 | else |
| 215 | errno = ENOTDIR; |
| 216 | } |
| 217 | } else if (do_mkdir(fname, ACCESSPERMS) == 0) { |
| 218 | ret++; |
| 219 | break; |
| 220 | } |
| 221 | |
| 222 | if (errno != ENOENT) { |
| 223 | STRUCT_STAT st; |
| 224 | if (errno != EEXIST || (do_stat(fname, &st) == 0 && !S_ISDIR(st.st_mode))) |
| 225 | ret = -ret - 1; |
| 226 | break; |
| 227 | } |
| 228 | while (1) { |
| 229 | if (p == fname) { |
| 230 | /* We got a relative path that doesn't exist, so assume that '.' |
| 231 | * is there and just break out and create the whole thing. */ |
| 232 | p = NULL; |
| 233 | goto double_break; |
| 234 | } |
| 235 | if (*--p == '/') { |
| 236 | if (p == fname) { |
| 237 | /* We reached the "/" dir, which we assume is there. */ |
| 238 | goto double_break; |
| 239 | } |
| 240 | *p = '\0'; |
| 241 | break; |
| 242 | } |
| 243 | } |
no test coverage detected