⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pvfs_search.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	dir = search->dir;	status = pvfs_list_seek_ofs(dir, io->search_next.in.id.server_cookie, 				    &search->current_index);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	search->last_used = time(NULL);	status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.data_level,				  &reply_count, search_private, callback);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	io->search_next.out.count = reply_count;	/* not matching any entries means end of search */	if (reply_count == 0) {		talloc_free(search);	}	return NT_STATUS_OK;}/*    list files in a directory matching a wildcard pattern*/static NTSTATUS pvfs_search_first_trans2(struct ntvfs_module_context *ntvfs,					 struct ntvfs_request *req, union smb_search_first *io, 					 void *search_private, 					 bool (*callback)(void *, const union smb_search_data *)){	struct pvfs_dir *dir;	struct pvfs_state *pvfs = ntvfs->private_data;	struct pvfs_search_state *search;	uint_t reply_count;	uint16_t search_attrib, max_count;	const char *pattern;	NTSTATUS status;	struct pvfs_filename *name;	int id;	search_attrib = io->t2ffirst.in.search_attrib;	pattern       = io->t2ffirst.in.pattern;	max_count     = io->t2ffirst.in.max_count;	/* resolve the cifs name to a posix name */	status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	if (!name->has_wildcard && !name->exists) {		return NT_STATUS_NO_SUCH_FILE;	}	status = pvfs_access_check_parent(pvfs, req, name, SEC_DIR_TRAVERSE | SEC_DIR_LIST);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	/* we initially make search a child of the request, then if we	   need to keep it long term we steal it for the private	   structure */	search = talloc(req, struct pvfs_search_state);	if (!search) {		return NT_STATUS_NO_MEMORY;	}	/* do the actual directory listing */	status = pvfs_list_start(pvfs, name, search, &dir);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	id = idr_get_new(pvfs->search.idtree, search, MAX_SEARCH_HANDLES);	if (id == -1) {		return NT_STATUS_INSUFFICIENT_RESOURCES;	}	search->pvfs = pvfs;	search->handle = id;	search->dir = dir;	search->current_index = 0;	search->search_attrib = search_attrib;	search->must_attrib = 0;	search->last_used = 0;	search->num_ea_names = io->t2ffirst.in.num_names;	search->ea_names = io->t2ffirst.in.ea_names;	search->te = NULL;	DLIST_ADD(pvfs->search.list, search);	talloc_set_destructor(search, pvfs_search_destructor);	status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.data_level,				  &reply_count, search_private, callback);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	/* not matching any entries is an error */	if (reply_count == 0) {		return NT_STATUS_NO_SUCH_FILE;	}	io->t2ffirst.out.count = reply_count;	io->t2ffirst.out.handle = search->handle;	io->t2ffirst.out.end_of_search = pvfs_list_eos(dir, search->current_index) ? 1 : 0;	/* work out if we are going to keep the search state	   and allow for a search continue */	if ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE) ||	    ((io->t2ffirst.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && 	     io->t2ffirst.out.end_of_search)) {		talloc_free(search);	} else {		talloc_steal(pvfs, search);	}	return NT_STATUS_OK;}/* continue a search */static NTSTATUS pvfs_search_next_trans2(struct ntvfs_module_context *ntvfs,					struct ntvfs_request *req, union smb_search_next *io, 					void *search_private, 					bool (*callback)(void *, const union smb_search_data *)){	struct pvfs_state *pvfs = ntvfs->private_data;	struct pvfs_search_state *search;	struct pvfs_dir *dir;	uint_t reply_count;	uint16_t handle;	NTSTATUS status;	handle = io->t2fnext.in.handle;	search = idr_find(pvfs->search.idtree, handle);	if (search == NULL) {		/* we didn't find the search handle */		return NT_STATUS_INVALID_HANDLE;	}		dir = search->dir;		status = NT_STATUS_OK;	/* work out what type of continuation is being used */	if (io->t2fnext.in.last_name && *io->t2fnext.in.last_name) {		status = pvfs_list_seek(dir, io->t2fnext.in.last_name, &search->current_index);		if (!NT_STATUS_IS_OK(status) && io->t2fnext.in.resume_key) {			status = pvfs_list_seek_ofs(dir, io->t2fnext.in.resume_key, 						    &search->current_index);		}	} else if (!(io->t2fnext.in.flags & FLAG_TRANS2_FIND_CONTINUE)) {		status = pvfs_list_seek_ofs(dir, io->t2fnext.in.resume_key, 					    &search->current_index);	}	if (!NT_STATUS_IS_OK(status)) {		return status;	}	search->num_ea_names = io->t2fnext.in.num_names;	search->ea_names = io->t2fnext.in.ea_names;	status = pvfs_search_fill(pvfs, req, io->t2fnext.in.max_count, search, io->generic.data_level,				  &reply_count, search_private, callback);	if (!NT_STATUS_IS_OK(status)) {		return status;	}	io->t2fnext.out.count = reply_count;	io->t2fnext.out.end_of_search = pvfs_list_eos(dir, search->current_index) ? 1 : 0;	/* work out if we are going to keep the search state */	if ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE) ||	    ((io->t2fnext.in.flags & FLAG_TRANS2_FIND_CLOSE_IF_END) && 	     io->t2fnext.out.end_of_search)) {		talloc_free(search);	}	return NT_STATUS_OK;}static NTSTATUS pvfs_search_first_smb2(struct ntvfs_module_context *ntvfs,				       struct ntvfs_request *req, const struct smb2_find *io, 				       void *search_private, 				       bool (*callback)(void *, const union smb_search_data *)){	struct pvfs_dir *dir;	struct pvfs_state *pvfs = ntvfs->private_data;	struct pvfs_search_state *search;	uint_t reply_count;	uint16_t max_count;	const char *pattern;	NTSTATUS status;	struct pvfs_filename *name;	struct pvfs_file *f;	f = pvfs_find_fd(pvfs, req, io->in.file.ntvfs);	if (!f) {		return NT_STATUS_FILE_CLOSED;	}	/* its only valid for directories */	if (f->handle->fd != -1) {		return NT_STATUS_INVALID_PARAMETER;	}	if (!(f->access_mask & SEC_DIR_LIST)) {		return NT_STATUS_ACCESS_DENIED;	}	if (f->search) {		talloc_free(f->search);		f->search = NULL;	}	if (strequal(io->in.pattern, "")) {		return NT_STATUS_OBJECT_NAME_INVALID;	}	if (strchr_m(io->in.pattern, '\\')) {		return NT_STATUS_OBJECT_NAME_INVALID;	}	if (strchr_m(io->in.pattern, '/')) {		return NT_STATUS_OBJECT_NAME_INVALID;	}	if (strequal("", f->handle->name->original_name)) {		pattern = talloc_asprintf(req, "\\%s", io->in.pattern);		NT_STATUS_HAVE_NO_MEMORY(pattern);	} else {		pattern = talloc_asprintf(req, "\\%s\\%s",					  f->handle->name->original_name,					  io->in.pattern);		NT_STATUS_HAVE_NO_MEMORY(pattern);	}	/* resolve the cifs name to a posix name */	status = pvfs_resolve_name(pvfs, req, pattern, PVFS_RESOLVE_WILDCARD, &name);	NT_STATUS_NOT_OK_RETURN(status);	if (!name->has_wildcard && !name->exists) {		return NT_STATUS_NO_SUCH_FILE;	}	/* we initially make search a child of the request, then if we	   need to keep it long term we steal it for the private	   structure */	search = talloc(req, struct pvfs_search_state);	NT_STATUS_HAVE_NO_MEMORY(search);	/* do the actual directory listing */	status = pvfs_list_start(pvfs, name, search, &dir);	NT_STATUS_NOT_OK_RETURN(status);	search->pvfs		= pvfs;	search->handle		= INVALID_SEARCH_HANDLE;	search->dir		= dir;	search->current_index	= 0;	search->search_attrib	= 0x0000FFFF;	search->must_attrib	= 0;	search->last_used	= 0;	search->num_ea_names	= 0;	search->ea_names	= NULL;	search->te		= NULL;	if (io->in.continue_flags & SMB2_CONTINUE_FLAG_SINGLE) {		max_count = 1;	} else {		max_count = UINT16_MAX;	}	status = pvfs_search_fill(pvfs, req, max_count, search, io->data_level,				  &reply_count, search_private, callback);	NT_STATUS_NOT_OK_RETURN(status);	/* not matching any entries is an error */	if (reply_count == 0) {		return NT_STATUS_NO_SUCH_FILE;	}	f->search = talloc_steal(f, search);	return NT_STATUS_OK;}static NTSTATUS pvfs_search_next_smb2(struct ntvfs_module_context *ntvfs,				      struct ntvfs_request *req, const struct smb2_find *io, 				      void *search_private, 				      bool (*callback)(void *, const union smb_search_data *)){	struct pvfs_state *pvfs = ntvfs->private_data;	struct pvfs_search_state *search;	uint_t reply_count;	uint16_t max_count;	NTSTATUS status;	struct pvfs_file *f;	f = pvfs_find_fd(pvfs, req, io->in.file.ntvfs);	if (!f) {		return NT_STATUS_FILE_CLOSED;	}	/* its only valid for directories */	if (f->handle->fd != -1) {		return NT_STATUS_INVALID_PARAMETER;	}	/* if there's no search started on the dir handle, it's like a search_first */	search = f->search;	if (!search) {		return pvfs_search_first_smb2(ntvfs, req, io, search_private, callback);	}	if (io->in.continue_flags & SMB2_CONTINUE_FLAG_RESTART) {		search->current_index = 0;	}	if (io->in.continue_flags & SMB2_CONTINUE_FLAG_SINGLE) {		max_count = 1;	} else {		max_count = UINT16_MAX;	}	status = pvfs_search_fill(pvfs, req, max_count, search, io->data_level,				  &reply_count, search_private, callback);	NT_STATUS_NOT_OK_RETURN(status);	/* not matching any entries is an error */	if (reply_count == 0) {		return STATUS_NO_MORE_FILES;	}	return NT_STATUS_OK;}/*    list files in a directory matching a wildcard pattern*/NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,			   struct ntvfs_request *req, union smb_search_first *io, 			   void *search_private, 			   bool (*callback)(void *, const union smb_search_data *)){	switch (io->generic.level) {	case RAW_SEARCH_SEARCH:	case RAW_SEARCH_FFIRST:	case RAW_SEARCH_FUNIQUE:		return pvfs_search_first_old(ntvfs, req, io, search_private, callback);	case RAW_SEARCH_TRANS2:		return pvfs_search_first_trans2(ntvfs, req, io, search_private, callback);	case RAW_SEARCH_SMB2:		return pvfs_search_first_smb2(ntvfs, req, &io->smb2, search_private, callback);	}	return NT_STATUS_INVALID_LEVEL;}/* continue a search */NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs,			  struct ntvfs_request *req, union smb_search_next *io, 			  void *search_private, 			  bool (*callback)(void *, const union smb_search_data *)){	switch (io->generic.level) {	case RAW_SEARCH_SEARCH:	case RAW_SEARCH_FFIRST:		return pvfs_search_next_old(ntvfs, req, io, search_private, callback);	case RAW_SEARCH_FUNIQUE:		return NT_STATUS_INVALID_LEVEL;	case RAW_SEARCH_TRANS2:		return pvfs_search_next_trans2(ntvfs, req, io, search_private, callback);	case RAW_SEARCH_SMB2:		return pvfs_search_next_smb2(ntvfs, req, &io->smb2, search_private, callback);	}	return NT_STATUS_INVALID_LEVEL;}/* close a search */NTSTATUS pvfs_search_close(struct ntvfs_module_context *ntvfs,			   struct ntvfs_request *req, union smb_search_close *io){	struct pvfs_state *pvfs = ntvfs->private_data;	struct pvfs_search_state *search;	uint16_t handle = INVALID_SEARCH_HANDLE;	switch (io->generic.level) {	case RAW_FINDCLOSE_GENERIC:		return NT_STATUS_INVALID_LEVEL;	case RAW_FINDCLOSE_FCLOSE:		handle = io->fclose.in.id.handle;		break;	case RAW_FINDCLOSE_FINDCLOSE:		handle = io->findclose.in.handle;		break;	}	search = idr_find(pvfs->search.idtree, handle);	if (search == NULL) {		/* we didn't find the search handle */		return NT_STATUS_INVALID_HANDLE;	}	talloc_free(search);	return NT_STATUS_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -