コード例 #1
0
ファイル: vfs_dirsort.c プロジェクト: Arkhont/samba
static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle,
				       const char *fname, const char *mask,
				       uint32 attr)
{
	struct dirsort_privates *data = NULL;

	/* set up our private data about this directory */
	data = (struct dirsort_privates *)SMB_MALLOC(
		sizeof(struct dirsort_privates));

	if (!data) {
		return NULL;
	}

	data->directory_list = NULL;
	data->pos = 0;

	/* Open the underlying directory and count the number of entries */
	data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask,
						      attr);

	data->fd = dirfd(data->source_directory);

	SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
				struct dirsort_privates, return NULL);

	if (!open_and_sort_dir(handle)) {
		SMB_VFS_NEXT_CLOSEDIR(handle,data->source_directory);
		return NULL;
	}

	return data->source_directory;
}
コード例 #2
0
ファイル: vfs_dirsort.c プロジェクト: AIdrifter/samba
static struct dirent *dirsort_readdir(vfs_handle_struct *handle,
					  DIR *dirp,
					  SMB_STRUCT_STAT *sbuf)
{
	struct dirsort_privates *data = NULL;
	struct timespec current_mtime;

	SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates,
				return NULL);

	if (get_sorted_dir_mtime(handle, data, &current_mtime) == false) {
		return NULL;
	}

	/* throw away cache and re-read the directory if we've changed */
	if (timespec_compare(&current_mtime, &data->mtime) > 1) {
		open_and_sort_dir(handle, data);
	}

	if (data->pos >= data->number_of_entries) {
		return NULL;
	}

	return &data->directory_list[data->pos++];
}
コード例 #3
0
ファイル: vfs_dirsort.c プロジェクト: Arkhont/samba
static SMB_STRUCT_DIRENT *dirsort_readdir(vfs_handle_struct *handle,
					  SMB_STRUCT_DIR *dirp,
					  SMB_STRUCT_STAT *sbuf)
{
	struct dirsort_privates *data = NULL;
	time_t current_mtime;
	struct stat dir_stat;

	SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates,
				return NULL);

	if (fstat(data->fd, &dir_stat) == -1) {
		return NULL;
	}

	current_mtime = dir_stat.st_mtime;

	/* throw away cache and re-read the directory if we've changed */
	if (current_mtime > data->mtime) {
		open_and_sort_dir(handle);
	}

	if (data->pos >= data->number_of_entries) {
		return NULL;
	}

	return &data->directory_list[data->pos++];
}
コード例 #4
0
ファイル: vfs_dirsort.c プロジェクト: abartlet/samba-old
static void dirsort_seekdir(vfs_handle_struct *handle, DIR *dirp,
			    long offset)
{
	struct timespec current_mtime;
	struct dirsort_privates *data = NULL;

	SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return);

	/* Find the entry holding dirp. */
	while(data && (data->source_directory != dirp)) {
		data = data->next;
	}
	if (data == NULL) {
		return;
	}
	if (offset >= data->number_of_entries) {
		return;
	}
	data->pos = offset;

	if (get_sorted_dir_mtime(handle, data, &current_mtime) == false) {
		return;
	}

	if (timespec_compare(&current_mtime, &data->mtime)) {
		/* Directory changed. We must re-read the
		   cache and search for the name that was
		   previously stored at the offset being
		   requested, otherwise after the re-sort
		   we will point to the wrong entry. The
		   OS/2 incremental delete code relies on
		   this. */
		unsigned int i;
		char *wanted_name = talloc_strdup(handle->conn,
					data->directory_list[offset].d_name);
		if (wanted_name == NULL) {
			return;
		}
		SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory);
		open_and_sort_dir(handle, data);
		/* Now search for where we were. */
		data->pos = 0;
		for (i = 0; i < data->number_of_entries; i++) {
			if(strcmp(wanted_name, data->directory_list[i].d_name) == 0) {
				data->pos = i;
				break;
			}
		}
		TALLOC_FREE(wanted_name);
	}
}
コード例 #5
0
ファイル: vfs_dirsort.c プロジェクト: abartlet/samba-old
static DIR *dirsort_opendir(vfs_handle_struct *handle,
				       const char *fname, const char *mask,
				       uint32 attr)
{
	struct dirsort_privates *list_head = NULL;
	struct dirsort_privates *data = NULL;

	if (SMB_VFS_HANDLE_TEST_DATA(handle)) {
		/* Find the list head of all open directories. */
		SMB_VFS_HANDLE_GET_DATA(handle, list_head, struct dirsort_privates,
				return NULL);
	}

	/* set up our private data about this directory */
	data = talloc_zero(handle->conn, struct dirsort_privates);
	if (!data) {
		return NULL;
	}

	data->smb_fname = synthetic_smb_fname(data, fname, NULL, NULL);
	if (data->smb_fname == NULL) {
		TALLOC_FREE(data);
		return NULL;
	}

	/* Open the underlying directory and count the number of entries */
	data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask,
						      attr);

	if (data->source_directory == NULL) {
		TALLOC_FREE(data);
		return NULL;
	}

	if (!open_and_sort_dir(handle, data)) {
		SMB_VFS_NEXT_CLOSEDIR(handle,data->source_directory);
		TALLOC_FREE(data);
		return NULL;
	}

	/* Add to the private list of all open directories. */
	DLIST_ADD(list_head, data);
	SMB_VFS_HANDLE_SET_DATA(handle, list_head, NULL,
				struct dirsort_privates, return NULL);

	return data->source_directory;
}
コード例 #6
0
static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle,
				       const char *fname, const char *mask,
				       uint32 attr)
{
	NTSTATUS status;
	struct dirsort_privates *data = NULL;

	/* set up our private data about this directory */
	data = talloc_zero(handle->conn, struct dirsort_privates);
	if (!data) {
		return NULL;
	}

	status = create_synthetic_smb_fname(data,
					fname,
					NULL,
					NULL,
					&data->smb_fname);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(data);
		return NULL;
	}

	/* Open the underlying directory and count the number of entries */
	data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask,
						      attr);

	if (data->source_directory == NULL) {
		TALLOC_FREE(data);
		return NULL;
	}

	if (!open_and_sort_dir(handle, data)) {
		SMB_VFS_NEXT_CLOSEDIR(handle,data->source_directory);
		TALLOC_FREE(data);
		return NULL;
	}

	SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
				struct dirsort_privates, return NULL);

	return data->source_directory;
}
コード例 #7
0
ファイル: vfs_dirsort.c プロジェクト: sprymak/samba
static DIR *dirsort_fdopendir(vfs_handle_struct *handle,
					files_struct *fsp,
					const char *mask,
					uint32 attr)
{
	struct dirsort_privates *data = NULL;

	/* set up our private data about this directory */
	data = (struct dirsort_privates *)SMB_MALLOC(
		sizeof(struct dirsort_privates));

	if (!data) {
		return NULL;
	}

	data->directory_list = NULL;
	data->pos = 0;

	/* Open the underlying directory and count the number of entries */
	data->source_directory = SMB_VFS_NEXT_FDOPENDIR(handle, fsp, mask,
						      attr);

	if (data->source_directory == NULL) {
		SAFE_FREE(data);
		return NULL;
	}

	data->fd = dirfd(data->source_directory);

	SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
				struct dirsort_privates, return NULL);

	if (!open_and_sort_dir(handle)) {
		SMB_VFS_NEXT_CLOSEDIR(handle,data->source_directory);
		/* fd is now closed. */
		fsp->fh->fd = -1;
		return NULL;
	}

	return data->source_directory;
}
コード例 #8
0
ファイル: vfs_dirsort.c プロジェクト: AIdrifter/samba
static DIR *dirsort_fdopendir(vfs_handle_struct *handle,
					files_struct *fsp,
					const char *mask,
					uint32 attr)
{
	struct dirsort_privates *data = NULL;

	/* set up our private data about this directory */
	data = talloc_zero(handle->conn, struct dirsort_privates);
	if (!data) {
		return NULL;
	}

	data->fsp = fsp;

	/* Open the underlying directory and count the number of entries */
	data->source_directory = SMB_VFS_NEXT_FDOPENDIR(handle, fsp, mask,
						      attr);

	if (data->source_directory == NULL) {
		TALLOC_FREE(data);
		return NULL;
	}

	if (!open_and_sort_dir(handle, data)) {
		SMB_VFS_NEXT_CLOSEDIR(handle,data->source_directory);
		TALLOC_FREE(data);
		/* fd is now closed. */
		fsp->fh->fd = -1;
		return NULL;
	}

	SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates,
				struct dirsort_privates, return NULL);

	return data->source_directory;
}