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; }
/* * 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); }
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; }
size_t str_len(const string_t *str) { return buffer_get_used_size(str); }
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); }