Esempio n. 1
0
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);

	while(data && (data->source_directory != dirp)) {
		data = data->next;
	}
	if (data == NULL) {
		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)) {
		SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory);
		open_and_sort_dir(handle, data);
	}

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

	return &data->directory_list[data->pos++];
}
Esempio n. 2
0
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);
	}
}
Esempio n. 3
0
static bool open_and_sort_dir(vfs_handle_struct *handle,
				struct dirsort_privates *data)
{
	unsigned int i = 0;
	unsigned int total_count = 0;

	data->number_of_entries = 0;

	if (get_sorted_dir_mtime(handle, data, &data->mtime) == false) {
		return false;
	}

	while (SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL)
	       != NULL) {
		total_count++;
	}

	if (total_count == 0) {
		return false;
	}

	/* Open the underlying directory and count the number of entries
	   Skip back to the beginning as we'll read it again */
	SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory);

	/* Set up an array and read the directory entries into it */
	TALLOC_FREE(data->directory_list); /* destroy previous cache if needed */
	data->directory_list = talloc_zero_array(data,
					struct dirent,
					total_count);
	if (!data->directory_list) {
		return false;
	}
	for (i = 0; i < total_count; i++) {
		struct dirent *dp = SMB_VFS_NEXT_READDIR(handle,
						data->source_directory,
						NULL);
		if (dp == NULL) {
			break;
		}
		data->directory_list[i] = *dp;
	}

	data->number_of_entries = i;

	/* Sort the directory entries by name */
	TYPESAFE_QSORT(data->directory_list, data->number_of_entries, compare_dirent);
	return true;
}
Esempio n. 4
0
static bool open_and_sort_dir (vfs_handle_struct *handle)
{
	SMB_STRUCT_DIRENT *dp;
	struct stat dir_stat;
	long current_pos;
	struct dirsort_privates *data = NULL;

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

	data->number_of_entries = 0;

	if (fstat(data->fd, &dir_stat) == 0) {
		data->mtime = dir_stat.st_mtime;
	}

	while (SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL)
	       != NULL) {
		data->number_of_entries++;
	}

	/* Open the underlying directory and count the number of entries
	   Skip back to the beginning as we'll read it again */
	SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory);

	/* Set up an array and read the directory entries into it */
	SAFE_FREE(data->directory_list); /* destroy previous cache if needed */
	data->directory_list = (SMB_STRUCT_DIRENT *)SMB_MALLOC(
		data->number_of_entries * sizeof(SMB_STRUCT_DIRENT));
	if (!data->directory_list) {
		return false;
	}
	current_pos = data->pos;
	data->pos = 0;
	while ((dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory,
					  NULL)) != NULL) {
		data->directory_list[data->pos++] = *dp;
	}

	/* Sort the directory entries by name */
	data->pos = current_pos;
	TYPESAFE_QSORT(data->directory_list, data->number_of_entries, compare_dirent);
	return true;
}
Esempio n. 5
0
static void skel_rewind_dir(vfs_handle_struct *handle, DIR *dirp)
{
	SMB_VFS_NEXT_REWINDDIR(handle, dirp);
}
Esempio n. 6
0
static void skel_rewinddir(vfs_handle_struct *handle,  SMB_STRUCT_DIR *dirp)
{
	return SMB_VFS_NEXT_REWINDDIR(handle, dirp);
}