/* 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.) */ static enum delret delete_dir_contents(char *fname, uint16 flags) { struct file_list *dirlist; enum delret ret; unsigned remainder; void *save_filters; int j, dlen; char *p; if (DEBUG_GTE(DEL, 3)) { rprintf(FINFO, "delete_dir_contents(%s) flags=%d\n", fname, flags); } dlen = strlen(fname); save_filters = push_local_filters(fname, dlen); non_perishable_cnt = 0; dirlist = get_dirlist(fname, dlen, 0); ret = non_perishable_cnt ? DR_NOT_EMPTY : DR_SUCCESS; if (!dirlist->used) goto done; if (!(flags & DEL_RECURSE)) { ret = DR_NOT_EMPTY; goto done; } p = fname + dlen; if (dlen != 1 || *fname != '/') *p++ = '/'; remainder = MAXPATHLEN - (p - fname); /* We do our own recursion, so make delete_item() non-recursive. */ flags = (flags & ~(DEL_RECURSE|DEL_MAKE_ROOM|DEL_NO_UID_WRITE)) | DEL_DIR_IS_EMPTY; for (j = dirlist->used; j--; ) { struct file_struct *fp = dirlist->files[j]; if (fp->flags & FLAG_MOUNT_DIR && S_ISDIR(fp->mode)) { if (DEBUG_GTE(DEL, 1)) { rprintf(FINFO, "mount point, %s, pins parent directory\n", f_name(fp, NULL)); } ret = DR_NOT_EMPTY; continue; } strlcpy(p, fp->basename, remainder); if (!(fp->mode & S_IWUSR) && !am_root && fp->flags & FLAG_OWNED_BY_US) do_chmod(fname, fp->mode | S_IWUSR); /* Save stack by recursing to ourself directly. */ if (S_ISDIR(fp->mode)) { if (delete_dir_contents(fname, flags | DEL_RECURSE) != DR_SUCCESS) ret = DR_NOT_EMPTY; } if (delete_item(fname, fp->mode, flags) != DR_SUCCESS) ret = DR_NOT_EMPTY; } fname[dlen] = '\0'; done: flist_free(dirlist); pop_local_filters(save_filters); if (ret == DR_NOT_EMPTY) { rprintf(FINFO, "cannot delete non-empty directory: %s\n", fname); } return ret; }
long profile_init(const char **files, profile_t *ret_profile) { const char **fs; profile_t profile; prf_file_t new_file, *last; long retval = 0; char **cpp, *cp, **array = 0; profile = malloc(sizeof(struct _profile_t)); if (!profile) return ENOMEM; memset(profile, 0, sizeof(struct _profile_t)); profile->magic = PROF_MAGIC_PROFILE; last = &profile->first_file; /* if the filenames list is not specified return an empty profile */ if ( files ) { for (fs = files; !PROFILE_LAST_FILESPEC(*fs); fs++) { retval = get_dirlist(*fs, &array); if (retval == 0) { if (!array) continue; for (cpp = array; (cp = *cpp); cpp++) { retval = profile_open_file(cp, &new_file); if (retval == EACCES) continue; if (retval) goto errout; *last = new_file; last = &new_file->next; } } else if ((retval != ENOTDIR) && strcmp(*fs, default_filename)) goto errout; retval = profile_open_file(*fs, &new_file); /* if this file is missing, skip to the next */ if (retval == ENOENT || retval == EACCES) { continue; } if (retval) goto errout; *last = new_file; last = &new_file->next; } /* * If all the files were not found, return the appropriate error. */ if (!profile->first_file) { profile_release(profile); return ENOENT; } } free_list(array); *ret_profile = profile; return 0; errout: free_list(array); profile_release(profile); return retval; }