Esempio n. 1
0
static int
mail_transaction_log_file_read_more(struct mail_transaction_log_file *file)
{
	void *data;
	size_t size;
	uint32_t read_offset;
	ssize_t ret;

	read_offset = file->buffer_offset + buffer_get_used_size(file->buffer);

	do {
		data = buffer_append_space_unsafe(file->buffer, LOG_PREFETCH);
		ret = pread(file->fd, data, LOG_PREFETCH, read_offset);
		if (ret > 0)
			read_offset += ret;

		size = read_offset - file->buffer_offset;
		buffer_set_used_size(file->buffer, size);
	} while (ret > 0 || (ret < 0 && errno == EINTR));

	file->last_size = read_offset;

	if (ret < 0) {
		if (errno == ESTALE) {
			/* log file was deleted in NFS server, fail silently */
			return 0;
		}
		log_file_set_syscall_error(file, "pread()");
		return -1;
	}
	return 1;
}
static void part_serialize(struct message_part *part, buffer_t *dest,
			   unsigned int *children_count_r)
{
	unsigned int count, children_count;
	size_t children_offset;
	bool root = part->parent == NULL;

	count = 0;
	while (part != NULL) {
		/* create serialized part */
		buffer_append(dest, &part->flags, sizeof(part->flags));
		if (root)
			root = FALSE;
		else {
			buffer_append(dest, &part->physical_pos,
				      sizeof(part->physical_pos));
		}
		buffer_append(dest, &part->header_size.physical_size,
			      sizeof(part->header_size.physical_size));
		buffer_append(dest, &part->header_size.virtual_size,
			      sizeof(part->header_size.virtual_size));
		buffer_append(dest, &part->body_size.physical_size,
			      sizeof(part->body_size.physical_size));
		buffer_append(dest, &part->body_size.virtual_size,
			      sizeof(part->body_size.virtual_size));

		if ((part->flags & (MESSAGE_PART_FLAG_TEXT |
				    MESSAGE_PART_FLAG_MESSAGE_RFC822)) != 0) {
			buffer_append(dest, &part->body_size.lines,
				      sizeof(part->body_size.lines));
		}

		if ((part->flags & (MESSAGE_PART_FLAG_MULTIPART |
				    MESSAGE_PART_FLAG_MESSAGE_RFC822)) != 0) {
			children_offset = buffer_get_used_size(dest);
			children_count = 0;
			buffer_append(dest, &children_count,
				      sizeof(children_count));

			if (part->children != NULL) {
				part_serialize(part->children, dest,
					       &children_count);

				buffer_write(dest, children_offset,
					     &children_count,
					     sizeof(children_count));
			}
		} else {
			i_assert(part->children == NULL);
		}

		count++;
		part = part->next;
	}

	*children_count_r = count;
}
Esempio n. 3
0
/*
 * Convert string to big-endian ucs2.
 */
void *ucs2be_str(pool_t pool, const char *str, size_t *size)
{
	buffer_t *buf = buffer_create_dynamic(pool, 32);

	while (*str) {
		buffer_append_c(buf, '\0');
		buffer_append_c(buf, *str++);
	}

	*size = buffer_get_used_size(buf);
	return buffer_free_without_data(&buf);
}
Esempio n. 4
0
static unsigned char *
t_unicode_str(const char *src, bool ucase, size_t *size)
{
    buffer_t *wstr;

    wstr = buffer_create_dynamic(unsafe_data_stack_pool, 32);
    for ( ; *src; src++) {
        buffer_append_c(wstr, ucase ? i_toupper(*src) : *src);
        buffer_append_c(wstr, '\0');
    }

    *size = buffer_get_used_size(wstr);
    return buffer_free_without_data(&wstr);
}
static bool _save_block_index_record
(struct sieve_binary *sbin, struct ostream *stream, unsigned int id)
{
	struct sieve_binary_block *block;
	struct sieve_binary_block_index header;

	block = sieve_binary_block_get(sbin, id);
	if ( block == NULL )
		return FALSE;

	header.id = id;
	header.size = buffer_get_used_size(block->data);
	header.ext_id = block->ext_index;
	header.offset = block->offset;

	if ( !_save_full(sbin, stream, &header, sizeof(header)) ) {
		sieve_sys_error(sbin->svinst,
			"binary save: failed to save block index header %d", id);
		return FALSE;
	}

	return TRUE;
}
Esempio n. 6
0
size_t str_len(const string_t *str)
{
	return buffer_get_used_size(str);
}
Esempio n. 7
0
int mail_transaction_log_file_map(struct mail_transaction_log_file *file,
				  uoff_t start_offset, uoff_t end_offset)
{
	struct mail_index *index = file->log->index;
	uoff_t map_start_offset = start_offset;
	size_t size;
	int ret;

	if (file->hdr.indexid == 0) {
		/* corrupted */
		return 0;
	}

	i_assert(start_offset >= file->hdr.hdr_size);
	i_assert(start_offset <= end_offset);
	i_assert(file->buffer == NULL || file->mmap_base != NULL ||
		 file->sync_offset >= file->buffer_offset + file->buffer->used);

	if (file->locked_sync_offset_updated && file == file->log->head &&
	    end_offset == (uoff_t)-1) {
		/* we're not interested of going further than sync_offset */
		if (log_file_map_check_offsets(file, start_offset,
					       end_offset) == 0)
			return 0;
		i_assert(start_offset <= file->sync_offset);
		end_offset = file->sync_offset;
	}

	if (file->buffer != NULL && file->buffer_offset <= start_offset) {
		/* see if we already have it */
		size = buffer_get_used_size(file->buffer);
		if (file->buffer_offset + size >= end_offset)
			return 1;
	}

	if (file->locked) {
		/* set this only when we've synced to end of file while locked
		   (either end_offset=(uoff_t)-1 or we had to read anyway) */
		file->locked_sync_offset_updated = TRUE;
	}

	if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file)) {
		if (start_offset < file->buffer_offset || file->buffer == NULL) {
			/* we had moved the log to memory but failed to read
			   the beginning of the log file */
			mail_index_set_error(index,
				"%s: Beginning of the log isn't available",
				file->filepath);
			return 0;
		}
		return log_file_map_check_offsets(file, start_offset,
						  end_offset);
	}

	if (start_offset > file->sync_offset)
		mail_transaction_log_file_skip_to_head(file);
	if (start_offset > file->sync_offset) {
		/* although we could just skip over the unwanted data, we have
		   to sync everything so that modseqs are calculated
		   correctly */
		map_start_offset = file->sync_offset;
	}

	if ((file->log->index->flags & MAIL_INDEX_OPEN_FLAG_MMAP_DISABLE) == 0)
		ret = mail_transaction_log_file_map_mmap(file, map_start_offset);
	else {
		mail_transaction_log_file_munmap(file);
		ret = mail_transaction_log_file_read(file, map_start_offset, FALSE);
	}

	i_assert(file->buffer == NULL || file->mmap_base != NULL ||
		 file->sync_offset >= file->buffer_offset + file->buffer->used);
	if (ret <= 0)
		return ret;

	i_assert(file->buffer != NULL);
	return log_file_map_check_offsets(file, start_offset, end_offset);
}