コード例 #1
0
ファイル: vfs_netatalk.c プロジェクト: DanilKorotenko/samba
static int atalk_unlink(struct vfs_handle_struct *handle,
			const struct smb_filename *smb_fname)
{
	int ret = 0, i;
	char *path = NULL;
	char *adbl_path = NULL;
	char *orig_path = NULL;
	SMB_STRUCT_STAT adbl_info;
	SMB_STRUCT_STAT orig_info;
	NTSTATUS status;

	ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);

	status = get_full_smb_filename(talloc_tos(), smb_fname, &path);
	if (!NT_STATUS_IS_OK(status)) {
		return ret;
	}

	/* no .AppleDouble sync if veto or hide list is empty,
	 * otherwise "Cannot find the specified file" error will be caused
	 */

	if (!handle->conn->veto_list) return ret;
	if (!handle->conn->hide_list) return ret;

	for (i = 0; handle->conn->veto_list[i].name; i ++) {
		if (strstr_m(handle->conn->veto_list[i].name, APPLEDOUBLE))
			break;
	}

	if (!handle->conn->veto_list[i].name) {
		for (i = 0; handle->conn->hide_list[i].name; i ++) {
			if (strstr_m(handle->conn->hide_list[i].name, APPLEDOUBLE))
				break;
			else {
				DEBUG(3, ("ATALK: %s is not hidden, skipped..\n",
				  APPLEDOUBLE));		
				goto exit_unlink;
			}
		}
	}

	if (atalk_build_paths(talloc_tos(), handle->conn->cwd, path,
			      &adbl_path, &orig_path,
			      &adbl_info, &orig_info) != 0)
		goto exit_unlink;

	if (S_ISDIR(orig_info.st_ex_mode) || S_ISREG(orig_info.st_ex_mode)) {
		DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
		goto exit_unlink;
	}

	atalk_unlink_file(adbl_path);

exit_unlink:
	TALLOC_FREE(path);
	TALLOC_FREE(adbl_path);
	TALLOC_FREE(orig_path);
	return ret;
}
コード例 #2
0
ファイル: vfs_acl_common.c プロジェクト: ekohl/samba
static int unlink_acl_common(struct vfs_handle_struct *handle,
			const struct smb_filename *smb_fname)
{
	int ret;

	/* Try the normal unlink first. */
	ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
	if (ret == 0) {
		return 0;
	}
	if (errno == EACCES || errno == EPERM) {
		/* Failed due to access denied,
		   see if we need to root override. */

		/* Don't do anything fancy for streams. */
		if (smb_fname->stream_name) {
			return -1;
		}
		return acl_common_remove_object(handle,
					smb_fname->base_name,
					false);
	}

	DEBUG(10,("unlink_acl_common: unlink of %s failed %s\n",
		smb_fname->base_name,
		strerror(errno) ));
	return -1;
}
コード例 #3
0
ファイル: vfs_acl_tdb.c プロジェクト: hazenme/dd-wrt
static int unlink_acl_tdb(vfs_handle_struct *handle, const char *path)
{
	SMB_STRUCT_STAT sbuf;
	struct db_context *db;
	int ret = -1;

	SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);

	if (lp_posix_pathnames()) {
		ret = SMB_VFS_LSTAT(handle->conn, path, &sbuf);
	} else {
		ret = SMB_VFS_STAT(handle->conn, path, &sbuf);
	}

	if (ret == -1) {
		return -1;
	}

	ret = SMB_VFS_NEXT_UNLINK(handle, path);

	if (ret == -1) {
		return -1;
	}

	acl_tdb_delete(handle, db, &sbuf);
	return 0;
}
コード例 #4
0
ファイル: vfs_streams_xattr.c プロジェクト: Alexander--/samba
static int streams_xattr_unlink(vfs_handle_struct *handle,
				const struct smb_filename *smb_fname)
{
	NTSTATUS status;
	int ret = -1;
	char *xattr_name = NULL;

	if (!is_ntfs_stream_smb_fname(smb_fname)) {
		return SMB_VFS_NEXT_UNLINK(handle, smb_fname);
	}

	/* If the default stream is requested, just open the base file. */
	if (is_ntfs_default_stream_smb_fname(smb_fname)) {
		struct smb_filename *smb_fname_base = NULL;

		smb_fname_base = cp_smb_filename(talloc_tos(), smb_fname);
		if (smb_fname_base == NULL) {
			errno = ENOMEM;
			return -1;
		}

		ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_base);

		TALLOC_FREE(smb_fname_base);
		return ret;
	}

	status = streams_xattr_get_name(handle, talloc_tos(),
					smb_fname->stream_name, &xattr_name);
	if (!NT_STATUS_IS_OK(status)) {
		errno = map_errno_from_nt_status(status);
		goto fail;
	}

	ret = SMB_VFS_REMOVEXATTR(handle->conn, smb_fname, xattr_name);

	if ((ret == -1) && (errno == ENOATTR)) {
		errno = ENOENT;
		goto fail;
	}

	ret = 0;

 fail:
	TALLOC_FREE(xattr_name);
	return ret;
}
コード例 #5
0
ファイル: vfs_posix_eadb.c プロジェクト: AIdrifter/samba
/*
 * On unlink we need to delete the tdb record
 */
static int posix_eadb_unlink(vfs_handle_struct *handle,
			    const struct smb_filename *smb_fname)
{
	struct smb_filename *smb_fname_tmp = NULL;
	int ret = -1;

	struct tdb_wrap *ea_tdb;

	SMB_VFS_HANDLE_GET_DATA(handle, ea_tdb, struct tdb_wrap, return -1);

	smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
	if (smb_fname_tmp == NULL) {
		errno = ENOMEM;
		return -1;
	}

	if (lp_posix_pathnames()) {
		ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname_tmp);
	} else {
		ret = SMB_VFS_NEXT_STAT(handle, smb_fname_tmp);
	}
	if (ret == -1) {
		goto out;
	}

	if (smb_fname_tmp->st.st_ex_nlink == 1) {
		NTSTATUS status;

		/* Only remove record on last link to file. */

		if (tdb_transaction_start(ea_tdb->tdb) != 0) {
			ret = -1;
			goto out;
		}

		status = unlink_posix_eadb_raw(ea_tdb, smb_fname->base_name, -1);
		if (!NT_STATUS_IS_OK(status)) {
			tdb_transaction_cancel(ea_tdb->tdb);
			ret = -1;
			goto out;
		}
	}

	ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);

	if (ret == -1) {
		tdb_transaction_cancel(ea_tdb->tdb);
		goto out;
	} else {
		if (tdb_transaction_commit(ea_tdb->tdb) != 0) {
			ret = -1;
			goto out;
		}
	}

out:
	TALLOC_FREE(smb_fname_tmp);
	return ret;
}
コード例 #6
0
ファイル: onefs_streams.c プロジェクト: sprymak/samba
int onefs_unlink(vfs_handle_struct *handle,
		 const struct smb_filename *smb_fname)
{
	struct smb_filename *smb_fname_onefs = NULL;
	int ret;
	int dir_fd, saved_errno;
	NTSTATUS status;

	/* Not a stream. */
	if (!is_ntfs_stream_smb_fname(smb_fname)) {
		return SMB_VFS_NEXT_UNLINK(handle, smb_fname);
	}

	status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
					     &smb_fname_onefs);
	if (!NT_STATUS_IS_OK(status)) {
		errno = map_errno_from_nt_status(status);
		return -1;
	}

	/* Default stream (the ::$DATA was just stripped off). */
	if (!is_ntfs_stream_smb_fname(smb_fname_onefs)) {
		ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_onefs);
		goto out;
	}

	dir_fd = get_stream_dir_fd(handle->conn, smb_fname_onefs->base_name,
				   NULL);
	if (dir_fd < 0) {
		ret = -1;
		goto out;
	}

	ret = enc_unlinkat(dir_fd, smb_fname_onefs->stream_name, ENC_DEFAULT,
			   0);

	saved_errno = errno;
	close(dir_fd);
	errno = saved_errno;
 out:
	TALLOC_FREE(smb_fname_onefs);
	return ret;
}
コード例 #7
0
static int atalk_unlink(struct vfs_handle_struct *handle, struct connection_struct *conn, const char *path)
{
	int ret = 0, i;
	char *adbl_path = 0;
	char *orig_path = 0;
	SMB_STRUCT_STAT adbl_info;
	SMB_STRUCT_STAT orig_info;
	TALLOC_CTX *ctx;

	ret = SMB_VFS_NEXT_UNLINK(handle, conn, path);

	if (!conn || !path) return ret;

	/* no .AppleDouble sync if veto or hide list is empty,
	 * otherwise "Cannot find the specified file" error will be caused
	 */

	if (!conn->veto_list) return ret;
	if (!conn->hide_list) return ret;

	for (i = 0; conn->veto_list[i].name; i ++) {
		if (strstr(conn->veto_list[i].name, APPLEDOUBLE))
			break;
	}

	if (!conn->veto_list[i].name) {
		for (i = 0; conn->hide_list[i].name; i ++) {
			if (strstr(conn->hide_list[i].name, APPLEDOUBLE))
				break;
			else {
				DEBUG(3, ("ATALK: %s is not hidden, skipped..\n",
				  APPLEDOUBLE));		
				return ret;
			}
		}
	}

	if (!(ctx = talloc_init("unlink_file")))
		return ret;

	if (atalk_build_paths(ctx, conn->origpath, path, &adbl_path, &orig_path, 
	  &adbl_info, &orig_info) != 0)
		return ret;

	if (S_ISDIR(orig_info.st_mode) || S_ISREG(orig_info.st_mode)) {
		DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
		goto exit_unlink;
	}

	atalk_unlink_file(adbl_path);

exit_unlink:	
	talloc_destroy(ctx);
	return ret;
}
コード例 #8
0
ファイル: vfs_audit.c プロジェクト: gojdic/samba
static int audit_unlink(vfs_handle_struct *handle, const char *path)
{
	int result;

	result = SMB_VFS_NEXT_UNLINK(handle, path);

	syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
	       path,
	       (result < 0) ? "failed: " : "",
	       (result < 0) ? strerror(errno) : "");

	return result;
}
コード例 #9
0
static int greyhole_unlink(vfs_handle_struct *handle, const struct smb_filename *path)
{
	int result;

	result = SMB_VFS_NEXT_UNLINK(handle, path);

	if (result >= 0) {
		gh_spoolf("unlink\n%s\n%s\n\n",
			lp_servicename(talloc_tos(), handle->conn->params->service),
			path->base_name);
	}

	return result;
}
コード例 #10
0
ファイル: vfs_audit.c プロジェクト: DanilKorotenko/samba
static int audit_unlink(vfs_handle_struct *handle,
			const struct smb_filename *smb_fname)
{
	int result;

	result = SMB_VFS_NEXT_UNLINK(handle, smb_fname);

	syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
	       smb_fname->base_name,
	       (result < 0) ? "failed: " : "",
	       (result < 0) ? strerror(errno) : "");

	return result;
}
コード例 #11
0
ファイル: vfs_extd_audit.c プロジェクト: DanilKorotenko/samba
static int audit_unlink(vfs_handle_struct *handle,
			const struct smb_filename *smb_fname)
{
	int result;

	result = SMB_VFS_NEXT_UNLINK(handle, smb_fname);

	if (lp_syslog() > 0) {
		syslog(audit_syslog_priority(handle), "unlink %s %s%s\n",
		       smb_fname->base_name,
		       (result < 0) ? "failed: " : "",
		       (result < 0) ? strerror(errno) : "");
	}
	DEBUG(0, ("vfs_extd_audit: unlink %s %s %s\n",
	       smb_fname_str_dbg(smb_fname),
	       (result < 0) ? "failed: " : "",
	       (result < 0) ? strerror(errno) : ""));

	return result;
}
コード例 #12
0
static int greyhole_unlink(vfs_handle_struct *handle, const char *path)
{
	int result;
	FILE *spoolf;
	char filename[38];
	struct timeval tp;

	result = SMB_VFS_NEXT_UNLINK(handle, path);

	if (result >= 0) {
		gettimeofday(&tp, (struct timezone *) NULL);
		snprintf(filename, 37, "/var/spool/greyhole/%.0f", ((double) (tp.tv_sec)*1000000.0) + (((double) tp.tv_usec)));
		spoolf = fopen(filename, "wt");
		fprintf(spoolf, "unlink\n%s\n%s\n\n",
			lp_servicename(handle->conn->params->service),
			path);
		fclose(spoolf);
	}

	return result;
}
コード例 #13
0
static int unlink_acl_common(struct vfs_handle_struct *handle,
			const struct smb_filename *smb_fname)
{
	int ret;

	ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
	if (!(ret == -1 && (errno == EACCES || errno == EPERM))) {
		DEBUG(10,("unlink_acl_common: unlink of %s failed %s\n",
			smb_fname->base_name,
			strerror(errno) ));
		return ret;
	}
	/* Don't do anything fancy for streams. */
	if (smb_fname->stream_name) {
		return ret;
	}

	return acl_common_remove_object(handle,
					smb_fname->base_name,
					false);
}
コード例 #14
0
static int unlink_acl_tdb(vfs_handle_struct *handle,
                          const struct smb_filename *smb_fname)
{
    struct smb_filename *smb_fname_tmp = NULL;
    struct db_context *db;
    NTSTATUS status;
    int ret = -1;

    SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);

    status = copy_smb_filename(talloc_tos(), smb_fname, &smb_fname_tmp);
    if (!NT_STATUS_IS_OK(status)) {
        errno = map_errno_from_nt_status(status);
        goto out;
    }

    if (lp_posix_pathnames()) {
        ret = SMB_VFS_LSTAT(handle->conn, smb_fname_tmp);
    } else {
        ret = SMB_VFS_STAT(handle->conn, smb_fname_tmp);
    }

    if (ret == -1) {
        goto out;
    }

    ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);

    if (ret == -1) {
        goto out;
    }

    acl_tdb_delete(handle, db, &smb_fname_tmp->st);
out:
    return ret;
}
コード例 #15
0
static int acl_common_remove_object(vfs_handle_struct *handle,
					const char *path,
					bool is_directory)
{
	connection_struct *conn = handle->conn;
	struct file_id id;
	files_struct *fsp = NULL;
	int ret = 0;
	char *parent_dir = NULL;
	const char *final_component = NULL;
	struct smb_filename local_fname;
	int saved_errno = 0;

	if (!parent_dirname(talloc_tos(), path,
			&parent_dir, &final_component)) {
		saved_errno = ENOMEM;
		goto out;
	}

	DEBUG(10,("acl_common_remove_object: removing %s %s/%s\n",
		is_directory ? "directory" : "file",
		parent_dir, final_component ));

	/* cd into the parent dir to pin it. */
	ret = SMB_VFS_CHDIR(conn, parent_dir);
	if (ret == -1) {
		saved_errno = errno;
		goto out;
	}

	ZERO_STRUCT(local_fname);
	local_fname.base_name = CONST_DISCARD(char *,final_component);

	/* Must use lstat here. */
	ret = SMB_VFS_LSTAT(conn, &local_fname);
	if (ret == -1) {
		saved_errno = errno;
		goto out;
	}

	/* Ensure we have this file open with DELETE access. */
	id = vfs_file_id_from_sbuf(conn, &local_fname.st);
	for (fsp = file_find_di_first(id); fsp; file_find_di_next(fsp)) {
		if (fsp->access_mask & DELETE_ACCESS &&
				fsp->delete_on_close) {
			/* We did open this for delete,
			 * allow the delete as root.
			 */
			break;
		}
	}

	if (!fsp) {
		DEBUG(10,("acl_common_remove_object: %s %s/%s "
			"not an open file\n",
			is_directory ? "directory" : "file",
			parent_dir, final_component ));
		saved_errno = EACCES;
		goto out;
	}

	become_root();
	if (is_directory) {
		ret = SMB_VFS_NEXT_RMDIR(handle, final_component);
	} else {
		ret = SMB_VFS_NEXT_UNLINK(handle, &local_fname);
	}
	unbecome_root();

	if (ret == -1) {
		saved_errno = errno;
	}

  out:

	TALLOC_FREE(parent_dir);

	vfs_ChDir(conn, conn->connectpath);
	if (saved_errno) {
		errno = saved_errno;
	}
	return ret;
}
コード例 #16
0
ファイル: vfs_cap.c プロジェクト: jameshilliard/WECB-BH-GPL
static int cap_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *path)
{
	pstring cappath;
	capencode(cappath, path);
	return SMB_VFS_NEXT_UNLINK(handle, conn, cappath);
}
コード例 #17
0
static int skel_unlink(vfs_handle_struct *handle,  const char *path)
{
	return SMB_VFS_NEXT_UNLINK(handle, path);
}
コード例 #18
0
ファイル: vfs_recycle.c プロジェクト: Alexandr-Galko/samba
/**
 * Check if file should be recycled
 **/
static int recycle_unlink(vfs_handle_struct *handle,
    const struct smb_filename *smb_fname)
{
	connection_struct *conn = handle->conn;
	char *path_name = NULL;
       	char *temp_name = NULL;
	char *final_name = NULL;
	struct smb_filename *smb_fname_final = NULL;
	const char *base;
	char *repository = NULL;
	int i = 1;
	SMB_OFF_T maxsize, minsize;
	SMB_OFF_T file_size; /* space_avail;	*/
	bool exist;
	NTSTATUS status;
	int rc = -1;

	repository = talloc_sub_advanced(NULL, lp_servicename(SNUM(conn)),
					conn->session_info->unix_name,
					conn->connectpath,
					conn->session_info->utok.gid,
					conn->session_info->sanitized_username,
					conn->session_info->info3->base.domain.string,
					recycle_repository(handle));
	ALLOC_CHECK(repository, done);
	/* shouldn't we allow absolute path names here? --metze */
	/* Yes :-). JRA. */
	trim_char(repository, '\0', '/');

	if(!repository || *(repository) == '\0') {
		DEBUG(3, ("recycle: repository path not set, purging %s...\n",
			  smb_fname_str_dbg(smb_fname)));
		rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
		goto done;
	}

	/* we don't recycle the recycle bin... */
	if (strncmp(smb_fname->base_name, repository,
		    strlen(repository)) == 0) {
		DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n"));
		rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
		goto done;
	}

	file_size = recycle_get_file_size(handle, smb_fname);
	/* it is wrong to purge filenames only because they are empty imho
	 *   --- simo
	 *
	if(fsize == 0) {
		DEBUG(3, ("recycle: File %s is empty, purging...\n", file_name));
		rc = SMB_VFS_NEXT_UNLINK(handle,file_name);
		goto done;
	}
	 */

	/* FIXME: this is wrong, we should check the whole size of the recycle bin is
	 * not greater then maxsize, not the size of the single file, also it is better
	 * to remove older files
	 */
	maxsize = recycle_maxsize(handle);
	if(maxsize > 0 && file_size > maxsize) {
		DEBUG(3, ("recycle: File %s exceeds maximum recycle size, "
			  "purging... \n", smb_fname_str_dbg(smb_fname)));
		rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
		goto done;
	}
	minsize = recycle_minsize(handle);
	if(minsize > 0 && file_size < minsize) {
		DEBUG(3, ("recycle: File %s lowers minimum recycle size, "
			  "purging... \n", smb_fname_str_dbg(smb_fname)));
		rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
		goto done;
	}

	/* FIXME: this is wrong: moving files with rename does not change the disk space
	 * allocation
	 *
	space_avail = SMB_VFS_NEXT_DISK_FREE(handle, ".", True, &bsize, &dfree, &dsize) * 1024L;
	DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size));
	if(space_avail < file_size) {
		DEBUG(3, ("recycle: Not enough diskspace, purging file %s\n", file_name));
		rc = SMB_VFS_NEXT_UNLINK(handle, file_name);
		goto done;
	}
	 */

	/* extract filename and path */
	base = strrchr(smb_fname->base_name, '/');
	if (base == NULL) {
		base = smb_fname->base_name;
		path_name = SMB_STRDUP("/");
		ALLOC_CHECK(path_name, done);
	}
	else {
		path_name = SMB_STRDUP(smb_fname->base_name);
		ALLOC_CHECK(path_name, done);
		path_name[base - smb_fname->base_name] = '\0';
		base++;
	}

	/* original filename with path */
	DEBUG(10, ("recycle: fname = %s\n", smb_fname_str_dbg(smb_fname)));
	/* original path */
	DEBUG(10, ("recycle: fpath = %s\n", path_name));
	/* filename without path */
	DEBUG(10, ("recycle: base = %s\n", base));

	if (matchparam(recycle_exclude(handle), base)) {
		DEBUG(3, ("recycle: file %s is excluded \n", base));
		rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
		goto done;
	}

	if (matchdirparam(recycle_exclude_dir(handle), path_name)) {
		DEBUG(3, ("recycle: directory %s is excluded \n", path_name));
		rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
		goto done;
	}

	if (recycle_keep_dir_tree(handle) == True) {
		if (asprintf(&temp_name, "%s/%s", repository, path_name) == -1) {
			ALLOC_CHECK(temp_name, done);
		}
	} else {
		temp_name = SMB_STRDUP(repository);
	}
	ALLOC_CHECK(temp_name, done);

	exist = recycle_directory_exist(handle, temp_name);
	if (exist) {
		DEBUG(10, ("recycle: Directory already exists\n"));
	} else {
		DEBUG(10, ("recycle: Creating directory %s\n", temp_name));
		if (recycle_create_dir(handle, temp_name) == False) {
			DEBUG(3, ("recycle: Could not create directory, "
				  "purging %s...\n",
				  smb_fname_str_dbg(smb_fname)));
			rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
			goto done;
		}
	}

	if (asprintf(&final_name, "%s/%s", temp_name, base) == -1) {
		ALLOC_CHECK(final_name, done);
	}

	/* Create smb_fname with final base name and orig stream name. */
	status = create_synthetic_smb_fname(talloc_tos(), final_name,
					    smb_fname->stream_name, NULL,
					    &smb_fname_final);
	if (!NT_STATUS_IS_OK(status)) {
		rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
		goto done;
	}

	/* new filename with path */
	DEBUG(10, ("recycle: recycled file name: %s\n",
		   smb_fname_str_dbg(smb_fname_final)));

	/* check if we should delete file from recycle bin */
	if (recycle_file_exist(handle, smb_fname_final)) {
		if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) {
			DEBUG(3, ("recycle: Removing old file %s from recycle "
				  "bin\n", smb_fname_str_dbg(smb_fname_final)));
			if (SMB_VFS_NEXT_UNLINK(handle,
						smb_fname_final) != 0) {
				DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno)));
			}
		}
	}

	/* rename file we move to recycle bin */
	i = 1;
	while (recycle_file_exist(handle, smb_fname_final)) {
		SAFE_FREE(final_name);
		if (asprintf(&final_name, "%s/Copy #%d of %s", temp_name, i++, base) == -1) {
			ALLOC_CHECK(final_name, done);
		}
		TALLOC_FREE(smb_fname_final->base_name);
		smb_fname_final->base_name = talloc_strdup(smb_fname_final,
							   final_name);
		if (smb_fname_final->base_name == NULL) {
			rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
			goto done;
		}
	}

	DEBUG(10, ("recycle: Moving %s to %s\n", smb_fname_str_dbg(smb_fname),
		smb_fname_str_dbg(smb_fname_final)));
	rc = SMB_VFS_NEXT_RENAME(handle, smb_fname, smb_fname_final);
	if (rc != 0) {
		DEBUG(3, ("recycle: Move error %d (%s), purging file %s "
			  "(%s)\n", errno, strerror(errno),
			  smb_fname_str_dbg(smb_fname),
			  smb_fname_str_dbg(smb_fname_final)));
		rc = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
		goto done;
	}

	/* touch access date of moved file */
	if (recycle_touch(handle) == True || recycle_touch_mtime(handle))
		recycle_do_touch(handle, smb_fname_final,
				 recycle_touch_mtime(handle));

done:
	SAFE_FREE(path_name);
	SAFE_FREE(temp_name);
	SAFE_FREE(final_name);
	TALLOC_FREE(smb_fname_final);
	TALLOC_FREE(repository);
	return rc;
}
コード例 #19
0
ファイル: skel_transparent.c プロジェクト: 0x24bin/winexe-1
static int skel_unlink(vfs_handle_struct *handle,
		       const struct smb_filename *smb_fname)
{
	return SMB_VFS_NEXT_UNLINK(handle, smb_fname);
}
コード例 #20
0
ファイル: vfs_recycle.c プロジェクト: hajuuk/R7000
/**
 * Check if file should be recycled
 **/
static int recycle_unlink(vfs_handle_struct *handle, connection_struct *conn, const char *file_name)
{
	char *path_name = NULL;
       	char *temp_name = NULL;
	char *final_name = NULL;
	const char *base;
	char *repository = NULL;
	int i = 1;
	int maxsize;
	SMB_OFF_T file_size; /* space_avail;	*/
	BOOL exist;
	int rc = -1;

	repository = alloc_sub_conn(conn, recycle_repository(handle));
	ALLOC_CHECK(repository, done);
	/* shouldn't we allow absolute path names here? --metze */
	trim_char(repository, '/', '/');
	
	if(!repository || *(repository) == '\0') {
		DEBUG(3, ("recycle: repository path not set, purging %s...\n", file_name));
		rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
		goto done;
	}

	/* we don't recycle the recycle bin... */
	if (strncmp(file_name, repository, strlen(repository)) == 0) {
		DEBUG(3, ("recycle: File is within recycling bin, unlinking ...\n"));
		rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
		goto done;
	}

	file_size = recycle_get_file_size(handle, file_name);
	/* it is wrong to purge filenames only because they are empty imho
	 *   --- simo
	 *
	if(fsize == 0) {
		DEBUG(3, ("recycle: File %s is empty, purging...\n", file_name));
		rc = SMB_VFS_NEXT_UNLINK(handle,conn,file_name);
		goto done;
	}
	 */

	/* FIXME: this is wrong, we should check the hole size of the recycle bin is
	 * not greater then maxsize, not the size of the single file, also it is better
	 * to remove older files
	 */
	maxsize = recycle_maxsize(handle);
	if(maxsize > 0 && file_size > maxsize) {
		DEBUG(3, ("recycle: File %s exceeds maximum recycle size, purging... \n", file_name));
		rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
		goto done;
	}

	/* FIXME: this is wrong: moving files with rename does not change the disk space
	 * allocation
	 *
	space_avail = SMB_VFS_NEXT_DISK_FREE(handle, conn, ".", True, &bsize, &dfree, &dsize) * 1024L;
	DEBUG(5, ("space_avail = %Lu, file_size = %Lu\n", space_avail, file_size));
	if(space_avail < file_size) {
		DEBUG(3, ("recycle: Not enough diskspace, purging file %s\n", file_name));
		rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
		goto done;
	}
	 */

	/* extract filename and path */
	base = strrchr(file_name, '/');
	if (base == NULL) {
		base = file_name;
		path_name = SMB_STRDUP("/");
		ALLOC_CHECK(path_name, done);
	}
	else {
		path_name = SMB_STRDUP(file_name);
		ALLOC_CHECK(path_name, done);
		path_name[base - file_name] = '\0';
		base++;
	}

	DEBUG(10, ("recycle: fname = %s\n", file_name));	/* original filename with path */
	DEBUG(10, ("recycle: fpath = %s\n", path_name));	/* original path */
	DEBUG(10, ("recycle: base = %s\n", base));		/* filename without path */

	if (matchparam(recycle_exclude(handle), base)) {
		DEBUG(3, ("recycle: file %s is excluded \n", base));
		rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
		goto done;
	}

	/* FIXME: this check will fail if we have more than one level of directories,
	 * we shoud check for every level 1, 1/2, 1/2/3, 1/2/3/4 .... 
	 * 	---simo
	 */
	if (checkparam(recycle_exclude_dir(handle), path_name)) {
		DEBUG(3, ("recycle: directory %s is excluded \n", path_name));
		rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
		goto done;
	}

	if (recycle_keep_dir_tree(handle) == True) {
		asprintf(&temp_name, "%s/%s", repository, path_name);
	} else {
		temp_name = SMB_STRDUP(repository);
	}
	ALLOC_CHECK(temp_name, done);

	exist = recycle_directory_exist(handle, temp_name);
	if (exist) {
		DEBUG(10, ("recycle: Directory already exists\n"));
	} else {
		DEBUG(10, ("recycle: Creating directory %s\n", temp_name));
		if (recycle_create_dir(handle, temp_name) == False) {
			DEBUG(3, ("recycle: Could not create directory, purging %s...\n", file_name));
			rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
			goto done;
		}
	}

	asprintf(&final_name, "%s/%s", temp_name, base);
	ALLOC_CHECK(final_name, done);
	DEBUG(10, ("recycle: recycled file name: %s\n", final_name));		/* new filename with path */

	/* check if we should delete file from recycle bin */
	if (recycle_file_exist(handle, final_name)) {
		if (recycle_versions(handle) == False || matchparam(recycle_noversions(handle), base) == True) {
			DEBUG(3, ("recycle: Removing old file %s from recycle bin\n", final_name));
			if (SMB_VFS_NEXT_UNLINK(handle, conn, final_name) != 0) {
				DEBUG(1, ("recycle: Error deleting old file: %s\n", strerror(errno)));
			}
		}
	}

	/* rename file we move to recycle bin */
	i = 1;
	while (recycle_file_exist(handle, final_name)) {
		SAFE_FREE(final_name);
		asprintf(&final_name, "%s/Copy #%d of %s", temp_name, i++, base);
	}

	DEBUG(10, ("recycle: Moving %s to %s\n", file_name, final_name));
	rc = SMB_VFS_NEXT_RENAME(handle, conn, file_name, final_name);
	if (rc != 0) {
		DEBUG(3, ("recycle: Move error %d (%s), purging file %s (%s)\n", errno, strerror(errno), file_name, final_name));
		rc = SMB_VFS_NEXT_UNLINK(handle, conn, file_name);
		goto done;
	}

	/* touch access date of moved file */
	if (recycle_touch(handle) == True )
		recycle_do_touch(handle, final_name);

done:
	SAFE_FREE(path_name);
	SAFE_FREE(temp_name);
	SAFE_FREE(final_name);
	SAFE_FREE(repository);
	return rc;
}