Ejemplo n.º 1
0
/* 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;
}
Ejemplo n.º 2
0
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;
}