/* 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; }
/* 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; }