Ejemplo n.º 1
0
static struct istream *
fs_sis_read_stream(struct fs_file *_file, size_t max_buffer_size)
{
	struct sis_fs_file *file = (struct sis_fs_file *)_file;

	return fs_read_stream(file->super, max_buffer_size);
}
Ejemplo n.º 2
0
static int
fs_sis_open(struct fs *_fs, const char *path, enum fs_open_mode mode,
	    enum fs_open_flags flags, struct fs_file **file_r)
{
	struct sis_fs *fs = (struct sis_fs *)_fs;
	struct sis_fs_file *file;
	struct fs_file *super;
	const char *dir, *hash;

	if (mode == FS_OPEN_MODE_APPEND) {
		fs_set_error(_fs, "APPEND mode not supported");
		return -1;
	}

	if (fs_open(fs->super, path, mode | flags, &super) < 0) {
		fs_sis_copy_error(fs);
		return -1;
	}

	switch (mode) {
	case FS_OPEN_MODE_RDONLY:
		*file_r = super;
		return 0;
	case FS_OPEN_MODE_CREATE:
	case FS_OPEN_MODE_REPLACE:
		break;
	case FS_OPEN_MODE_APPEND:
		i_unreached();
	}

	if (fs_sis_path_parse(_fs, path, &dir, &hash) < 0)
		return -1;

	file = i_new(struct sis_fs_file, 1);
	file->file.fs = _fs;
	file->file.path = i_strdup(fs_file_path(super));
	file->super = super;
	file->open_mode = mode;
	file->hash = i_strdup(hash);

	/* if hashes/<hash> already exists, open it */
	file->hash_path = i_strdup_printf("%s/"HASH_DIR_NAME"/%s", dir, hash);
	if (fs_open(fs->super, file->hash_path, FS_OPEN_MODE_RDONLY,
		    &file->hash_file) < 0 && errno != ENOENT) {
		i_error("fs-sis: Couldn't open hash file: %s",
			fs_last_error(fs->super));
	}
	if (file->hash_file != NULL) {
		file->hash_input =
			fs_read_stream(file->hash_file, IO_BLOCK_SIZE);
	}

	*file_r = &file->file;
	return 0;
}
Ejemplo n.º 3
0
static ssize_t i_stream_fs_file_read(struct istream_private *stream)
{
    struct fs_file_istream *fstream = (struct fs_file_istream *)stream;
    struct istream *input;

    if (fstream->istream.parent == NULL) {
        input = fs_read_stream(fstream->file,
                               i_stream_get_max_buffer_size(&stream->istream));
        i_stream_init_parent(stream, input);
        i_stream_unref(&input);
    }

    i_stream_seek(stream->parent, stream->parent_start_offset +
                  stream->istream.v_offset);
    return i_stream_read_copy_from_parent(&stream->istream);
}
Ejemplo n.º 4
0
static struct istream *
fs_compress_read_stream(struct fs_file *_file, size_t max_buffer_size)
{
	struct compress_fs_file *file = (struct compress_fs_file *)_file;
	struct istream *input;

	if (file->input != NULL) {
		i_stream_ref(file->input);
		i_stream_seek(file->input, 0);
		return file->input;
	}

	input = fs_read_stream(file->super_read, max_buffer_size);
	file->input = file->fs->handler->create_istream(input, FALSE);
	i_stream_unref(&input);
	i_stream_ref(file->input);
	return file->input;
}
Ejemplo n.º 5
0
static struct istream *
fs_crypt_read_stream(struct fs_file *_file, size_t max_buffer_size)
{
	struct crypt_fs_file *file = (struct crypt_fs_file *)_file;
	struct istream *input;

	if (file->input != NULL) {
		i_stream_ref(file->input);
		i_stream_seek(file->input, 0);
		return file->input;
	}

	input = fs_read_stream(file->super_read, max_buffer_size);

	file->input = i_stream_create_decrypt_callback(input,
				fs_crypt_istream_get_key, file);
	i_stream_unref(&input);
	i_stream_ref(file->input);
	return file->input;
}
Ejemplo n.º 6
0
static struct fs_file *
fs_sis_file_init(struct fs *_fs, const char *path,
		 enum fs_open_mode mode, enum fs_open_flags flags)
{
	struct sis_fs *fs = (struct sis_fs *)_fs;
	struct sis_fs_file *file;
	const char *dir, *hash;

	file = i_new(struct sis_fs_file, 1);
	file->file.fs = _fs;
	file->file.path = i_strdup(path);
	file->fs = fs;
	file->open_mode = mode;
	if (mode == FS_OPEN_MODE_APPEND) {
		fs_set_error(_fs, "APPEND mode not supported");
		return &file->file;
	}

	if (fs_sis_path_parse(_fs, path, &dir, &hash) < 0) {
		fs_set_error(_fs, "Invalid path");
		return &file->file;
	}

	/* if hashes/<hash> already exists, open it */
	file->hash_path = i_strdup_printf("%s/"HASH_DIR_NAME"/%s", dir, hash);
	file->hash_file = fs_file_init(_fs->parent, file->hash_path,
				       FS_OPEN_MODE_READONLY);

	file->hash_input = fs_read_stream(file->hash_file, IO_BLOCK_SIZE);
	if (i_stream_read(file->hash_input) == -1) {
		/* doesn't exist */
		if (errno != ENOENT) {
			i_error("fs-sis: Couldn't read hash file %s: %m",
				file->hash_path);
		}
		i_stream_destroy(&file->hash_input);
	}

	file->super = fs_file_init(_fs->parent, path, mode | flags);
	return &file->file;
}
Ejemplo n.º 7
0
static void test_fs_metawrap_stat(void)
{
	struct fs *fs;
	struct fs_file *file;
	struct test_fs_file *test_file;
	struct istream *input;
	struct stat st;
	const char *error;
	unsigned int i;

	test_begin("fs metawrap stat");

	if (fs_init("metawrap", "test", &fs_set, &fs, &error) < 0)
		i_fatal("fs_init() failed: %s", error);

	for (i = 0; i < 2; i++) {
		file = fs_file_init(fs, "foo", FS_OPEN_MODE_READONLY);

		test_file = test_fs_file_get(fs, "foo");
		str_append(test_file->contents, "key:value\n\n12345678901234567890");

		if (i == 0) {
			input = fs_read_stream(file, 2);
			test_istream_set_max_buffer_size(test_file->input, 2);
		} else {
			input = NULL;
		}

		test_assert_idx(fs_stat(file, &st) == 0 && st.st_size == 20, i);

		if (input != NULL)
			i_stream_unref(&input);
		fs_file_deinit(&file);
	}
	fs_deinit(&fs);
	test_end();
}