コード例 #1
0
ファイル: mdbox-purge.c プロジェクト: jwm/dovecot-notmuch
static int
mdbox_file_read_metadata_hdr(struct dbox_file *file,
			     struct dbox_metadata_header *meta_hdr_r)
{
	const unsigned char *data;
	size_t size;
	int ret;

	ret = i_stream_read_data(file->input, &data, &size,
				 sizeof(*meta_hdr_r));
	if (ret <= 0) {
		i_assert(ret == -1);
		if (file->input->stream_errno == 0) {
			dbox_file_set_corrupted(file, "missing metadata");
			return 0;
		}
		mail_storage_set_critical(&file->storage->storage,
			"read(%s) failed: %m", file->cur_path);
		return -1;
	}

	memcpy(meta_hdr_r, data, sizeof(*meta_hdr_r));
	if (memcmp(meta_hdr_r->magic_post, DBOX_MAGIC_POST,
		   sizeof(meta_hdr_r->magic_post)) != 0) {
		dbox_file_set_corrupted(file, "invalid metadata magic");
		return 0;
	}
	i_stream_skip(file->input, sizeof(*meta_hdr_r));
	return 1;
}
コード例 #2
0
ファイル: dbox-file.c プロジェクト: bsmr-dovecot/core
static int dbox_file_parse_header(struct dbox_file *file, const char *line)
{
	const char *const *tmp, *value;
	unsigned int pos;
	enum dbox_header_key key;

	file->file_version = *line - '0';
	if (!i_isdigit(line[0]) || line[1] != ' ' ||
	    (file->file_version != 1 && file->file_version != DBOX_VERSION)) {
		dbox_file_set_corrupted(file, "Invalid dbox version");
		return -1;
	}
	line += 2;
	pos = 2;

	file->msg_header_size = 0;

	for (tmp = t_strsplit(line, " "); *tmp != NULL; tmp++) {
		uintmax_t time;
		key = **tmp;
		value = *tmp + 1;

		switch (key) {
		case DBOX_HEADER_OLDV1_APPEND_OFFSET:
			break;
		case DBOX_HEADER_MSG_HEADER_SIZE:
			if (str_to_uint_hex(value, &file->msg_header_size) < 0) {
				dbox_file_set_corrupted(file, "Invalid message header size");
				return -1;
			}
			break;
		case DBOX_HEADER_CREATE_STAMP:
			if (str_to_uintmax_hex(value, &time) < 0) {
				dbox_file_set_corrupted(file, "Invalid create time stamp");
				return -1;
			}
			file->create_time = (time_t)time;
			break;
		}
		pos += strlen(value) + 2;
	}

	if (file->msg_header_size == 0) {
		dbox_file_set_corrupted(file, "Missing message header size");
		return -1;
	}
	return 0;
}
コード例 #3
0
ファイル: mdbox-purge.c プロジェクト: jwm/dovecot-notmuch
static int
mdbox_file_metadata_copy(struct dbox_file *file, struct ostream *output)
{
	struct dbox_metadata_header meta_hdr;
	const char *line;
	size_t buf_size;
	int ret;

	if ((ret = mdbox_file_read_metadata_hdr(file, &meta_hdr)) <= 0)
		return ret;

	o_stream_nsend(output, &meta_hdr, sizeof(meta_hdr));
	buf_size = i_stream_get_max_buffer_size(file->input);
	/* use unlimited line length for metadata */
	i_stream_set_max_buffer_size(file->input, (size_t)-1);
	while ((line = i_stream_read_next_line(file->input)) != NULL) {
		if (*line == '\0') {
			/* end of metadata */
			break;
		}
		o_stream_nsend_str(output, line);
		o_stream_nsend(output, "\n", 1);
	}
	i_stream_set_max_buffer_size(file->input, buf_size);

	if (line == NULL) {
		dbox_file_set_corrupted(file, "missing end-of-metadata line");
		return 0;
	}
	o_stream_nsend(output, "\n", 1);
	return 1;
}
コード例 #4
0
ファイル: dbox-mail.c プロジェクト: bjacke/core
int dbox_mail_get_stream(struct mail *_mail, bool get_body ATTR_UNUSED,
			 struct message_size *hdr_size,
			 struct message_size *body_size,
			 struct istream **stream_r)
{
	struct dbox_storage *storage =
		(struct dbox_storage *)_mail->box->storage;
	struct dbox_mail *mail = (struct dbox_mail *)_mail;
	struct index_mail_data *data = &mail->imail.data;
	struct istream *input;
	uoff_t offset;
	int ret;

	if (data->stream == NULL) {
		if (storage->v.mail_open(mail, &offset, &mail->open_file) < 0)
			return -1;

		ret = get_mail_stream(mail, offset, &input);
		if (ret <= 0) {
			if (ret < 0)
				return -1;
			dbox_file_set_corrupted(mail->open_file,
				"uid=%u points to broken data at offset="
				"%"PRIuUOFF_T, _mail->uid, offset);
			if (input != NULL)
				i_stream_unref(&input);
			return -1;
		}
		data->stream = input;
		index_mail_set_read_buffer_size(_mail, input);
	}

	return index_mail_init_stream(&mail->imail, hdr_size, body_size,
				      stream_r);
}
コード例 #5
0
ファイル: dbox-attachment.c プロジェクト: jkerihuel/dovecot
int dbox_attachment_file_get_stream(struct dbox_file *file,
				    struct istream **stream)
{
	const char *ext_refs, *error;
	int ret;

	/* need to read metadata in case there are external references */
	if ((ret = dbox_file_metadata_read(file)) <= 0)
		return ret;

	i_stream_seek(file->input, file->cur_offset + file->msg_header_size);

	ext_refs = dbox_file_metadata_get(file, DBOX_METADATA_EXT_REF);
	if (ext_refs == NULL)
		return 1;

	/* we have external references. */
	T_BEGIN {
		ret = dbox_attachment_file_get_stream_from(file, ext_refs,
							   stream, &error);
		if (ret == 0) {
			dbox_file_set_corrupted(file,
				"Corrupted ext-refs metadata %s: %s",
				ext_refs, error);
		}
	} T_END;
	return ret;
}
コード例 #6
0
ファイル: dbox-file.c プロジェクト: bsmr-dovecot/core
static int dbox_file_read_header(struct dbox_file *file)
{
	const char *line;
	unsigned int hdr_size;
	int ret;

	i_stream_seek(file->input, 0);
	line = i_stream_read_next_line(file->input);
	if (line == NULL) {
		if (file->input->stream_errno == 0) {
			dbox_file_set_corrupted(file,
				"EOF while reading file header");
			return 0;
		}

		dbox_file_set_syscall_error(file, "read()");
		return -1;
	}
	hdr_size = file->input->v_offset;
	T_BEGIN {
		ret = dbox_file_parse_header(file, line) < 0 ? 0 : 1;
	} T_END;
	if (ret > 0)
		file->file_header_size = hdr_size;
	return ret;
}