Beispiel #1
0
/*
  the search fill loop
*/
static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, 
				 unsigned int max_count,
				 struct pvfs_search_state *search,
				 enum smb_search_data_level level,
				 unsigned int *reply_count,
				 void *search_private, 
				 bool (*callback)(void *, const union smb_search_data *))
{
	struct pvfs_dir *dir = search->dir;
	NTSTATUS status;

	*reply_count = 0;

	if (max_count == 0) {
		max_count = 1;
	}

	while ((*reply_count) < max_count) {
		union smb_search_data *file;
		const char *name;
		off_t ofs = search->current_index;

		name = pvfs_list_next(dir, &search->current_index);
		if (name == NULL) break;

		file = talloc(mem_ctx, union smb_search_data);
		if (!file) {
			return NT_STATUS_NO_MEMORY;
		}

		status = fill_search_info(pvfs, level, 
					  pvfs_list_unix_path(dir), name, 
					  search, search->current_index, file);
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(file);
			continue;
		}

		if (!callback(search_private, file)) {
			talloc_free(file);
			search->current_index = ofs;
			break;
		}

		(*reply_count)++;
		talloc_free(file);
	}

	pvfs_search_setup_timer(search);

	return NT_STATUS_OK;
}
Beispiel #2
0
/*
  delete a file - the dirtype specifies the file types to include in the search. 
  The name can contain CIFS wildcards, but rarely does (except with OS/2 clients)
*/
NTSTATUS pvfs_unlink(struct ntvfs_module_context *ntvfs,
		     struct ntvfs_request *req,
		     union smb_unlink *unl)
{
	struct pvfs_state *pvfs = talloc_get_type(ntvfs->private_data,
				  struct pvfs_state);
	struct pvfs_dir *dir;
	NTSTATUS status;
	uint32_t total_deleted=0;
	struct pvfs_filename *name;
	const char *fname;
	off_t ofs;

	/* resolve the cifs name to a posix name */
	status = pvfs_resolve_name(pvfs, req, unl->unlink.in.pattern, 
				   PVFS_RESOLVE_WILDCARD |
				   PVFS_RESOLVE_STREAMS |
				   PVFS_RESOLVE_NO_OPENDB,
				   &name);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	if (!name->exists && !name->has_wildcard) {
		return NT_STATUS_OBJECT_NAME_NOT_FOUND;
	}

	if (name->exists && 
	    (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY)) {
		return NT_STATUS_FILE_IS_A_DIRECTORY;
	}

	if (!name->has_wildcard) {
		return pvfs_unlink_one(pvfs, req, unl, name);
	}

	/*
	 * disable async requests in the wildcard case
	 * untill we have proper tests for this
	 */
	req->async_states->state &= ~NTVFS_ASYNC_STATE_MAY_ASYNC;

	/* get list of matching files */
	status = pvfs_list_start(pvfs, name, req, &dir);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	status = NT_STATUS_NO_SUCH_FILE;
	talloc_free(name);

	ofs = 0;

	while ((fname = pvfs_list_next(dir, &ofs))) {
		/* this seems to be a special case */
		if ((unl->unlink.in.attrib & FILE_ATTRIBUTE_DIRECTORY) &&
		    (ISDOT(fname) || ISDOTDOT(fname))) {
			return NT_STATUS_OBJECT_NAME_INVALID;
		}

		/* get a pvfs_filename object */
		status = pvfs_resolve_partial(pvfs, req,
					      pvfs_list_unix_path(dir),
					      fname,
					      PVFS_RESOLVE_NO_OPENDB,
					      &name);
		if (!NT_STATUS_IS_OK(status)) {
			return status;
		}

		status = pvfs_unlink_one(pvfs, req, unl, name);
		if (NT_STATUS_IS_OK(status)) {
			total_deleted++;
		}

		talloc_free(name);
	}

	if (total_deleted > 0) {
		status = NT_STATUS_OK;
	}

	return status;
}