The directory is about to be deleted: if DEL_RECURSE is given, delete all * its contents, otherwise just checks for content. Returns DR_SUCCESS or * DR_NOT_EMPTY. Note that fname must point to a MAXPATHLEN buffer! (The * buffer is used for recursion, but returned unchanged.) */
| 46 | * buffer is used for recursion, but returned unchanged.) |
| 47 | */ |
| 48 | static enum delret delete_dir_contents(char *fname, uint16 flags) |
| 49 | { |
| 50 | struct file_list *dirlist; |
| 51 | enum delret ret; |
| 52 | unsigned remainder; |
| 53 | void *save_filters; |
| 54 | int j, dlen; |
| 55 | char *p; |
| 56 | |
| 57 | if (DEBUG_GTE(DEL, 3)) { |
| 58 | rprintf(FINFO, "delete_dir_contents(%s) flags=%d\n", |
| 59 | fname, flags); |
| 60 | } |
| 61 | |
| 62 | dlen = strlen(fname); |
| 63 | save_filters = push_local_filters(fname, dlen); |
| 64 | |
| 65 | non_perishable_cnt = 0; |
| 66 | dirlist = get_dirlist(fname, dlen, 0); |
| 67 | ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS; |
| 68 | |
| 69 | if (!dirlist->used) |
| 70 | goto done; |
| 71 | |
| 72 | if (!(flags & DEL_RECURSE)) { |
| 73 | ret = DR_NOT_EMPTY; |
| 74 | goto done; |
| 75 | } |
| 76 | |
| 77 | p = fname + dlen; |
| 78 | if (dlen != 1 || *fname != '/') |
| 79 | *p++ = '/'; |
| 80 | remainder = MAXPATHLEN - (p - fname); |
| 81 | |
| 82 | /* We do our own recursion, so make delete_item() non-recursive. */ |
| 83 | flags = (flags & ~(DEL_RECURSE|DEL_MAKE_ROOM|DEL_NO_UID_WRITE)) |
| 84 | | DEL_DIR_IS_EMPTY; |
| 85 | |
| 86 | for (j = dirlist->used; j--; ) { |
| 87 | struct file_struct *fp = dirlist->files[j]; |
| 88 | |
| 89 | if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) { |
| 90 | if (DEBUG_GTE(DEL, 1)) { |
| 91 | rprintf(FINFO, |
| 92 | "mount point, %s, pins parent directory\n", |
| 93 | f_name(fp, NULL)); |
| 94 | } |
| 95 | ret = DR_NOT_EMPTY; |
| 96 | continue; |
| 97 | } |
| 98 | |
| 99 | strlcpy(p, fp->basename, remainder); |
| 100 | if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US) |
| 101 | do_chmod_at(fname, fp->mode | S_IWUSR); |
| 102 | /* Save stack by recursing to ourself directly. */ |
| 103 | if (S_ISDIR(fp->mode)) { |
| 104 | if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS) |
| 105 | ret = DR_NOT_EMPTY; |
no test coverage detected