uint32_t mail_index_ext_register(struct mail_index *index, const char *name, uint32_t default_hdr_size, uint16_t default_record_size, uint16_t default_record_align) { struct mail_index_registered_ext rext; uint32_t ext_id; if (*name == '\0' || strcmp(name, str_sanitize(name, -1)) != 0) i_panic("mail_index_ext_register(%s): Invalid name", name); if (default_record_size != 0 && default_record_align == 0) { i_panic("mail_index_ext_register(%s): " "Invalid record alignment", name); } if (mail_index_ext_lookup(index, name, &ext_id)) return ext_id; memset(&rext, 0, sizeof(rext)); rext.name = p_strdup(index->extension_pool, name); rext.index_idx = array_count(&index->extensions); rext.hdr_size = default_hdr_size; rext.record_size = default_record_size; rext.record_align = default_record_align; array_append(&index->extensions, &rext, 1); return rext.index_idx; }
static void t_pop_verify(void) { struct stack_block *block; unsigned char *p; size_t pos, max_pos, used_size, alloc_size; block = current_frame_block->block[frame_pos]; pos = block->size - current_frame_block->block_space_used[frame_pos]; while (block != NULL) { used_size = block->size - block->left; p = STACK_BLOCK_DATA(block); while (pos < used_size) { alloc_size = *(size_t *)(p + pos); if (used_size - pos < alloc_size) i_panic("data stack: saved alloc size broken"); pos += MEM_ALIGN(sizeof(alloc_size)); max_pos = pos + MEM_ALIGN(alloc_size + SENTRY_COUNT); pos += alloc_size; for (; pos < max_pos; pos++) { if (p[pos] != CLEAR_CHR) i_panic("data stack: buffer overflow"); } } /* if we had used t_buffer_get(), the rest of the buffer may not contain CLEAR_CHRs. but we've already checked all the allocations, so there's no need to check them anyway. */ block = block->next; pos = 0; } }
static void *mremap_move(struct anon_header *hdr, size_t new_size) { void *new_base; char *p; size_t block_size, old_size; new_base = mmap_anon(new_size); if (new_base == MAP_FAILED) return MAP_FAILED; /* If we're moving large memory areas, it takes less memory to copy the memory pages in smaller blocks. */ old_size = hdr->size; block_size = 1024*1024; p = (char *) hdr + header_size + hdr->size; do { if (block_size > old_size) block_size = old_size; p -= block_size; old_size -= block_size; memcpy((char *) new_base + old_size, p, block_size); if (munmap((void *) p, block_size) < 0) i_panic("munmap() failed: %m"); } while (old_size != 0); if (munmap((void *) hdr, header_size) < 0) i_panic("munmap() failed: %m"); return new_base; }
void fd_debug_verify_leaks(int first_fd, int last_fd) { struct ip_addr addr, raddr; in_port_t port, rport; struct stat st; int old_errno; for (; first_fd <= last_fd; first_fd++) { if (fcntl(first_fd, F_GETFD, 0) == -1 && errno == EBADF) continue; old_errno = errno; if (net_getsockname(first_fd, &addr, &port) == 0) { if (addr.family == AF_UNIX) { struct sockaddr_un sa; socklen_t socklen = sizeof(sa); if (getsockname(first_fd, (void *)&sa, &socklen) < 0) sa.sun_path[0] = '\0'; i_panic("Leaked UNIX socket fd %d: %s", first_fd, sa.sun_path); } if (net_getpeername(first_fd, &raddr, &rport) < 0) { memset(&raddr, 0, sizeof(raddr)); rport = 0; } i_panic("Leaked socket fd %d: %s:%u -> %s:%u", first_fd, net_ip2addr(&addr), port, net_ip2addr(&raddr), rport); } if (fstat(first_fd, &st) == 0) { #ifdef __APPLE__ /* OSX workaround: gettimeofday() calls shm_open() internally and the fd won't get closed on exec. We'll just skip all ino/dev=0 files and hope they weren't anything else. */ if (st.st_ino == 0 && st.st_dev == 0) continue; #endif #ifdef HAVE_SYS_SYSMACROS_H i_panic("Leaked file fd %d: dev %s.%s inode %s", first_fd, dec2str(major(st.st_dev)), dec2str(minor(st.st_dev)), dec2str(st.st_ino)); #else i_panic("Leaked file fd %d: dev %s inode %s", first_fd, dec2str(st.st_dev), dec2str(st.st_ino)); #endif } i_panic("Leaked unknown fd %d (errno = %s)", first_fd, strerror(old_errno)); } }
static ssize_t o_stream_zlib_send_chunk(struct zlib_ostream *zstream, const void *data, size_t size) { z_stream *zs = &zstream->zs; int ret, flush; i_assert(zstream->outbuf_used == 0); flush = zstream->ostream.corked || zstream->gz ? Z_NO_FLUSH : Z_SYNC_FLUSH; if (!zstream->header_sent) { if (o_stream_zlib_send_gz_header(zstream) < 0) return -1; } zs->next_in = (void *)data; zs->avail_in = size; while (zs->avail_in > 0) { if (zs->avail_out == 0) { /* previous block was compressed. send it and start compression for a new block. */ zs->next_out = zstream->outbuf; zs->avail_out = sizeof(zstream->outbuf); zstream->outbuf_used = sizeof(zstream->outbuf); if ((ret = o_stream_zlib_send_outbuf(zstream)) < 0) return -1; if (ret == 0) { /* parent stream's buffer full */ break; } } ret = deflate(zs, flush); switch (ret) { case Z_OK: case Z_BUF_ERROR: break; case Z_STREAM_ERROR: i_assert(zstream->gz); i_panic("zlib.write(%s) failed: Can't write more data to .gz after flushing", o_stream_get_name(&zstream->ostream.ostream)); default: i_panic("zlib.write(%s) failed with unexpected code %d", o_stream_get_name(&zstream->ostream.ostream), ret); } } size -= zs->avail_in; zstream->crc = crc32_data_more(zstream->crc, data, size); zstream->bytes32 += size; zstream->flushed = flush == Z_SYNC_FLUSH && zs->avail_in == 0 && zs->avail_out == sizeof(zstream->outbuf); return size; }
static inline void buffer_check_limits(struct real_buffer *buf, size_t pos, size_t data_size) { unsigned int extra; size_t new_size; if (unlikely((size_t)-1 - pos < data_size)) { i_panic("Buffer write out of range (%"PRIuSIZE_T " + %"PRIuSIZE_T")", pos, data_size); } new_size = pos + data_size; if (new_size > buf->used && buf->used < buf->dirty) { /* clear used..dirty area */ size_t max = I_MIN(I_MIN(buf->alloc, buf->dirty), new_size); memset(buf->w_buffer + buf->used, 0, max - buf->used); } /* always keep +1 byte allocated available in case str_c() is called for this buffer. this is mainly for cases where the buffer is allocated from data stack, and str_c() is called in a separate stack frame. */ extra = buf->dynamic ? 1 : 0; if (new_size + extra > buf->alloc) { if (unlikely(!buf->dynamic)) { i_panic("Buffer full (%"PRIuSIZE_T" > %"PRIuSIZE_T", " "pool %s)", pos + data_size, buf->alloc, buf->pool == NULL ? "<none>" : pool_get_name(buf->pool)); } buffer_alloc(buf, pool_get_exp_grown_size(buf->pool, buf->alloc, new_size + extra)); } #if 0 else if (new_size > buf->used && buf->alloced && !buf->pool->alloconly_pool && !buf->pool->datastack_pool) { void *new_buf; /* buffer's size increased: move the buffer's memory elsewhere. this should help catch bugs where old pointers are tried to be used to access the buffer's memory */ new_buf = p_malloc(buf->pool, buf->alloc); memcpy(new_buf, buf->w_buffer, buf->alloc); p_free(buf->pool, buf->w_buffer); buf->w_buffer = new_buf; buf->r_buffer = new_buf; } #endif if (new_size > buf->used) buf->used = new_size; i_assert(buf->used <= buf->alloc); }
void io_loop_handler_run_internal(struct ioloop *ioloop) { struct ioloop_handler_context *ctx = ioloop->handler_context; struct kevent *events; const struct kevent *event; struct timeval tv; struct timespec ts; struct io_file *io; unsigned int events_count; int ret, i, msecs; /* get the time left for next timeout task */ msecs = io_loop_get_wait_time(ioloop, &tv); ts.tv_sec = tv.tv_sec; ts.tv_nsec = tv.tv_usec * 1000; /* wait for events */ events = array_get_modifiable(&ctx->events, &events_count); if (events_count > 0) { ret = kevent (ctx->kq, NULL, 0, events, events_count, &ts); if (ret < 0 && errno != EINTR) i_panic("kevent() failed: %m"); } else { if (msecs < 0) i_panic("BUG: No IOs or timeouts set. Not waiting for infinity."); usleep(msecs * 1000); ret = 0; } /* reference all IOs */ for (i = 0; i < ret; i++) { io = (void *)events[i].udata; i_assert(io->refcount > 0); io->refcount++; } /* execute timeout handlers */ io_loop_handle_timeouts(ioloop); for (i = 0; i < ret; i++) { /* io_loop_handle_add() may cause events array reallocation, so we have use array_idx() */ event = array_idx(&ctx->events, i); io = (void *)event->udata; /* callback is NULL if io_remove() was already called */ if (io->io.callback != NULL) io_loop_call_io(&io->io); i_assert(io->refcount > 0); if (--io->refcount == 0) i_free(io); } }
static void *pool_system_malloc(pool_t pool ATTR_UNUSED, size_t size) { void *mem; #ifdef DEBUG int old_errno = errno; #endif if (unlikely(size == 0 || size > SSIZE_T_MAX)) i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size); #ifndef USE_GC mem = calloc(size, 1); #else mem = GC_malloc(size); #endif if (unlikely(mem == NULL)) { i_fatal_status(FATAL_OUTOFMEM, "pool_system_malloc(%"PRIuSIZE_T "): Out of memory", size); } #ifdef DEBUG /* we rely on errno not changing. it shouldn't. */ i_assert(errno == old_errno); #endif return mem; }
void i_stream_default_seek_nonseekable(struct istream_private *stream, uoff_t v_offset, bool mark ATTR_UNUSED) { size_t available; if (stream->istream.v_offset > v_offset) i_panic("stream %s doesn't support seeking backwards", i_stream_get_name(&stream->istream)); while (stream->istream.v_offset < v_offset) { (void)i_stream_read(&stream->istream); available = stream->pos - stream->skip; if (available == 0) { if (stream->istream.stream_errno != 0) { /* read failed */ return; } io_stream_set_error(&stream->iostream, "Can't seek to offset %"PRIuUOFF_T ", because we have data only up to offset %" PRIuUOFF_T" (eof=%d)", v_offset, stream->istream.v_offset, stream->istream.eof ? 1 : 0); stream->istream.stream_errno = ESPIPE; return; } if (available <= v_offset - stream->istream.v_offset) i_stream_skip(&stream->istream, available); else { i_stream_skip(&stream->istream, v_offset - stream->istream.v_offset); } } }
static void login_host_callback(const struct ip_addr *ip, const char *errormsg, void *context) { struct login_host_request *request = context; struct director *dir = request->conn->dir; const char *line, *line_params; unsigned int secs; if (ip != NULL) { secs = dir->set->director_user_expire / 2; line = t_strdup_printf("%s\thost=%s\tproxy_refresh=%u", request->line, net_ip2addr(ip), secs); } else { if (strncmp(request->line, "OK\t", 3) == 0) line_params = request->line + 3; else if (strncmp(request->line, "PASS\t", 5) == 0) line_params = request->line + 5; else i_panic("BUG: Unexpected line: %s", request->line); i_error("director: User %s host lookup failed: %s", request->username, errormsg); line = t_strconcat("FAIL\t", t_strcut(line_params, '\t'), "\ttemp", NULL); } login_connection_send_line(request->conn, line); login_connection_unref(&request->conn); i_free(request->username); i_free(request->line); i_free(request); }
struct mail_user *mail_user_alloc(const char *username, const struct setting_parser_info *set_info, const struct mail_user_settings *set) { struct mail_user *user; const char *error; pool_t pool; i_assert(username != NULL); i_assert(*username != '\0'); pool = pool_alloconly_create(MEMPOOL_GROWING"mail user", 16*1024); user = p_new(pool, struct mail_user, 1); user->pool = pool; user->refcount = 1; user->username = p_strdup(pool, username); user->set_info = set_info; user->unexpanded_set = settings_dup(set_info, set, pool); user->set = settings_dup(set_info, set, pool); user->service = master_service_get_name(master_service); user->default_normalizer = uni_utf8_to_decomposed_titlecase; /* check settings so that the duplicated structure will again contain the parsed fields */ if (!settings_check(set_info, pool, user->set, &error)) i_panic("Settings check unexpectedly failed: %s", error); user->v.deinit = mail_user_deinit_base; user->v.stats_fill = mail_user_stats_fill_base; p_array_init(&user->module_contexts, user->pool, 5); return user; }
bool ioloop_iolist_add(struct io_list *list, struct io_file *io) { int i, idx; if ((io->io.condition & IO_READ) != 0) idx = IOLOOP_IOLIST_INPUT; else if ((io->io.condition & IO_WRITE) != 0) idx = IOLOOP_IOLIST_OUTPUT; else if ((io->io.condition & IO_ERROR) != 0) idx = IOLOOP_IOLIST_ERROR; else { i_unreached(); } if (list->ios[idx] != NULL) { i_panic("io_add(0x%x) called twice fd=%d, callback=%p -> %p", io->io.condition, io->fd, list->ios[idx]->io.callback, io->io.callback); } i_assert(list->ios[idx] == NULL); list->ios[idx] = io; /* check if this was the first one */ for (i = 0; i < IOLOOP_IOLIST_IOS_PER_FD; i++) { if (i != idx && list->ios[i] != NULL) return FALSE; } return TRUE; }
void client_command_cancel(struct client_command_context **_cmd) { struct client_command_context *cmd = *_cmd; bool cmd_ret; switch (cmd->state) { case CLIENT_COMMAND_STATE_WAIT_INPUT: /* a bit kludgy check: cancel command only if it has context set. currently only append command matches this check. all other commands haven't even started the processing yet. */ if (cmd->context == NULL) break; /* fall through */ case CLIENT_COMMAND_STATE_WAIT_EXTERNAL: case CLIENT_COMMAND_STATE_WAIT_OUTPUT: cmd->cancel = TRUE; break; case CLIENT_COMMAND_STATE_WAIT_UNAMBIGUITY: case CLIENT_COMMAND_STATE_WAIT_SYNC: /* commands haven't started yet */ break; case CLIENT_COMMAND_STATE_DONE: i_unreached(); } cmd_ret = !cmd->cancel || cmd->func == NULL ? TRUE : command_exec(cmd); if (!cmd_ret) { if (cmd->client->output->closed) i_panic("command didn't cancel itself: %s", cmd->name); } else { client_command_free(*_cmd != NULL ? _cmd : &cmd); } }
bool t_try_realloc(void *mem, size_t size) { size_t last_alloc_size; if (unlikely(size == 0 || size > SSIZE_T_MAX)) i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size); last_alloc_size = current_frame_block->last_alloc_size[frame_pos]; /* see if we're trying to grow the memory we allocated last */ if (STACK_BLOCK_DATA(current_block) + (current_block->size - current_block->left - last_alloc_size) == mem) { /* yeah, see if we have space to grow */ size = MEM_ALIGN(size); if (current_block->left >= size - last_alloc_size) { /* just shrink the available size */ current_block->left -= size - last_alloc_size; current_frame_block->last_alloc_size[frame_pos] = size; return TRUE; } } return FALSE; }
void fts_icu_utf8_to_utf16(buffer_t *dest_utf16, const char *src_utf8) { UErrorCode err = U_ZERO_ERROR; unsigned int src_bytes = strlen(src_utf8); int32_t utf16_len; UChar *dest_data, *retp = NULL; int32_t avail_uchars = 0; /* try to encode with the current buffer size */ avail_uchars = buffer_get_writable_size(dest_utf16) / sizeof(UChar); dest_data = buffer_get_space_unsafe(dest_utf16, 0, buffer_get_writable_size(dest_utf16)); retp = u_strFromUTF8Lenient(dest_data, avail_uchars, &utf16_len, src_utf8, src_bytes, &err); if (err == U_BUFFER_OVERFLOW_ERROR) { /* try again with a larger buffer */ dest_data = buffer_get_space_unsafe(dest_utf16, 0, utf16_len * sizeof(UChar)); err = U_ZERO_ERROR; retp = u_strFromUTF8Lenient(dest_data, utf16_len, &utf16_len, src_utf8, src_bytes, &err); } if (U_FAILURE(err)) { i_panic("LibICU u_strFromUTF8Lenient() failed: %s", u_errorName(err)); } buffer_set_used_size(dest_utf16, utf16_len * sizeof(UChar)); i_assert(retp == dest_data); }
void fts_icu_utf16_to_utf8(string_t *dest_utf8, const UChar *src_utf16, unsigned int src_len) { int32_t dest_len = 0; int32_t sub_num = 0; char *dest_data, *retp = NULL; UErrorCode err = U_ZERO_ERROR; /* try to encode with the current buffer size */ dest_data = buffer_get_space_unsafe(dest_utf8, 0, buffer_get_writable_size(dest_utf8)); retp = u_strToUTF8WithSub(dest_data, buffer_get_writable_size(dest_utf8), &dest_len, src_utf16, src_len, UNICODE_REPLACEMENT_CHAR, &sub_num, &err); if (err == U_BUFFER_OVERFLOW_ERROR) { /* try again with a larger buffer */ dest_data = buffer_get_space_unsafe(dest_utf8, 0, dest_len); err = U_ZERO_ERROR; retp = u_strToUTF8WithSub(dest_data, buffer_get_writable_size(dest_utf8), &dest_len, src_utf16, src_len, UNICODE_REPLACEMENT_CHAR, &sub_num, &err); } if (U_FAILURE(err)) { i_panic("LibICU u_strToUTF8WithSub() failed: %s", u_errorName(err)); } buffer_set_used_size(dest_utf8, dest_len); i_assert(retp == dest_data); }
static void data_stack_last_buffer_reset(bool preserve_data ATTR_UNUSED) { if (last_buffer_block != NULL) { #ifdef DEBUG unsigned char *p; unsigned int i; p = STACK_BLOCK_DATA(current_block) + (current_block->size - current_block->left) + MEM_ALIGN(sizeof(size_t)) + MEM_ALIGN(last_buffer_size); #endif /* reset t_buffer_get() mark - not really needed but makes it easier to notice if t_malloc()/t_push()/t_pop() is called between t_buffer_get() and t_buffer_alloc(). do this before we get to i_panic() to avoid recursive panics. */ last_buffer_block = NULL; #ifdef DEBUG for (i = 0; i < SENTRY_COUNT; i++) { if (p[i] != CLEAR_CHR) i_panic("t_buffer_get(): buffer overflow"); } if (!preserve_data) { p = STACK_BLOCK_DATA(current_block) + (current_block->size - current_block->left); memset(p, CLEAR_CHR, SENTRY_COUNT); } #endif } }
static struct stack_block *mem_block_alloc(size_t min_size) { struct stack_block *block; size_t prev_size, alloc_size; prev_size = current_block == NULL ? 0 : current_block->size; alloc_size = nearest_power(prev_size + min_size); #ifndef USE_GC block = malloc(SIZEOF_MEMBLOCK + alloc_size); #else block = GC_malloc(SIZEOF_MEMBLOCK + alloc_size); #endif if (unlikely(block == NULL)) { if (outofmem) { if (min_size > outofmem_area.block.left) abort(); return &outofmem_area.block; } outofmem = TRUE; i_panic("data stack: Out of memory when allocating %" PRIuSIZE_T" bytes", alloc_size + SIZEOF_MEMBLOCK); } block->size = alloc_size; block->left = 0; block->lowwater = block->size; block->next = NULL; #ifdef DEBUG memset(STACK_BLOCK_DATA(block), CLEAR_CHR, alloc_size); #endif return block; }
static void io_loop_handle_timeouts_real(struct ioloop *ioloop) { struct priorityq_item *item; struct timeval tv, tv_call; unsigned int t_id; if (gettimeofday(&ioloop_timeval, NULL) < 0) i_fatal("gettimeofday(): %m"); /* Don't bother comparing usecs. */ if (unlikely(ioloop_time > ioloop_timeval.tv_sec)) { /* time moved backwards */ io_loops_timeouts_update(-(long)(ioloop_time - ioloop_timeval.tv_sec)); ioloop->time_moved_callback(ioloop_time, ioloop_timeval.tv_sec); /* the callback may have slept, so check the time again. */ if (gettimeofday(&ioloop_timeval, NULL) < 0) i_fatal("gettimeofday(): %m"); } else if (unlikely(ioloop_timeval.tv_sec > ioloop->next_max_time)) { io_loops_timeouts_update(ioloop_timeval.tv_sec - ioloop->next_max_time); /* time moved forwards */ ioloop->time_moved_callback(ioloop->next_max_time, ioloop_timeval.tv_sec); } ioloop_time = ioloop_timeval.tv_sec; tv_call = ioloop_timeval; while ((item = priorityq_peek(ioloop->timeouts)) != NULL) { struct timeout *timeout = (struct timeout *)item; /* use tv_call to make sure we don't get to infinite loop in case callbacks update ioloop_timeval. */ if (timeout_get_wait_time(timeout, &tv, &tv_call) > 0) break; /* update timeout's next_run and reposition it in the queue */ timeout_reset_timeval(timeout, &tv_call); if (timeout->log != NULL) { ioloop->cur_log = timeout->log; io_loop_log_ref(ioloop->cur_log); i_set_failure_prefix(timeout->log->prefix); } t_id = t_push(); timeout->callback(timeout->context); if (t_pop() != t_id) { i_panic("Leaked a t_pop() call in timeout handler %p", (void *)timeout->callback); } if (ioloop->cur_log != NULL) { io_loop_log_unref(&ioloop->cur_log); i_set_failure_prefix(ioloop->default_log_prefix); } } }
int munmap_anon(void *start, size_t length ATTR_UNUSED) { struct anon_header *hdr; if (start == NULL || start == MAP_FAILED) { errno = EINVAL; return -1; } hdr = (struct anon_header *) ((char *) start - header_size); if (hdr->signature != MMAP_SIGNATURE) i_panic("movable_munmap(): Invalid address"); if (munmap((void *) hdr, hdr->size + header_size) < 0) i_panic("munmap() failed: %m"); return 0; }
static struct test_istream *test_istream_find(struct istream *input) { struct istream *in; for (in = input; in != NULL; in = in->real_stream->parent) { if (in->real_stream->read == test_read) return (struct test_istream *)in->real_stream; } i_panic("%s isn't test-istream", i_stream_get_name(input)); }
static const struct stat * i_stream_base64_encoder_stat(struct istream_private *stream, bool exact) { if (exact) { /* too much trouble to implement until it's actually needed */ i_panic("istream-base64-encoder: " "stat() doesn't support getting exact size"); } return i_stream_stat(stream->parent, exact); }
const char *mail_thread_type_to_str(enum mail_thread_type type) { unsigned int i; for (i = 0; i < N_ELEMENTS(mail_thread_type_strings); i++) { if (mail_thread_type_strings[i].type == type) return mail_thread_type_strings[i].name; } i_panic("Unknown mail_thread_type %d", type); }
static void multiclient_key_init(struct multiclient_key *key, int fd, const char *path) { struct stat stbuf; if (fstat(fd, &stbuf) < 0) i_panic("multiclient_key_init(%s): fstat(%d) failed: %m", path, fd); key->dev = stbuf.st_dev; key->ino = stbuf.st_ino; }
static void i_stream_tee_sync(struct istream_private *stream) { struct tee_child_istream *tstream = (struct tee_child_istream *)stream; tee_streams_skip(tstream->tee); if (i_stream_get_data_size(tstream->tee->input) != 0) { i_panic("tee-istream: i_stream_sync() called " "with data still buffered"); } i_stream_sync(tstream->tee->input); }
static struct notify_mail_txn * notify_context_find_mail_txn(struct notify_context *ctx, struct mailbox_transaction_context *t) { struct notify_mail_txn *mail_txn = ctx->mail_txn_list; for (; mail_txn != NULL; mail_txn = mail_txn->next) { if (mail_txn->parent_mailbox_txn == t) return mail_txn; } i_panic("no notify_mail_txn found"); }
static int o_stream_lzma_send_flush(struct lzma_ostream *zstream) { lzma_stream *zs = &zstream->strm; unsigned int len; bool done = FALSE; int ret; if (zs->avail_in != 0) { i_assert(zstream->ostream.ostream.last_failed_errno != 0); zstream->ostream.ostream.stream_errno = zstream->ostream.ostream.last_failed_errno; return -1; } if (zstream->flushed) return 0; if ((ret = o_stream_flush_parent_if_needed(&zstream->ostream)) <= 0) return ret; if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) return ret; i_assert(zstream->outbuf_used == 0); do { ret = lzma_code(zs, LZMA_FINISH); switch (ret) { case LZMA_OK: break; case LZMA_STREAM_END: done = TRUE; break; case LZMA_MEM_ERROR: i_fatal_status(FATAL_OUTOFMEM, "lzma.write(%s): Out of memory", o_stream_get_name(&zstream->ostream.ostream)); default: i_panic("lzma.write(%s) flush failed with unexpected code %d", o_stream_get_name(&zstream->ostream.ostream), ret); } if (zs->avail_out == 0 || done) { len = sizeof(zstream->outbuf) - zs->avail_out; zs->next_out = zstream->outbuf; zs->avail_out = sizeof(zstream->outbuf); zstream->outbuf_used = len; if ((ret = o_stream_zlib_send_outbuf(zstream)) <= 0) return ret; } } while (!done); zstream->flushed = TRUE; return 0; }
static int pop3c_mail_get_stream(struct mail *_mail, bool get_body, struct message_size *hdr_size, struct message_size *body_size, struct istream **stream_r) { struct index_mail *mail = (struct index_mail *)_mail; struct pop3c_mailbox *mbox = (struct pop3c_mailbox *)_mail->box; enum pop3c_capability capa; const char *name, *cmd, *error; struct istream *input; if (get_body && mail->data.stream != NULL) { name = i_stream_get_name(mail->data.stream); if (strncmp(name, "RETR", 4) == 0) { /* we've fetched the body */ } else if (strncmp(name, "TOP", 3) == 0) { /* we've fetched the header, but we need the body now too */ index_mail_close_streams(mail); } else { i_panic("Unexpected POP3 stream name: %s", name); } } if (mail->data.stream == NULL) { capa = pop3c_client_get_capabilities(mbox->client); if (get_body || (capa & POP3C_CAPABILITY_TOP) == 0) { cmd = t_strdup_printf("RETR %u\r\n", _mail->seq); get_body = TRUE; } else { cmd = t_strdup_printf("TOP %u 0\r\n", _mail->seq); } if (pop3c_client_cmd_stream(mbox->client, cmd, &input, &error) < 0) { mail_storage_set_error(mbox->box.storage, !pop3c_client_is_connected(mbox->client) ? MAIL_ERROR_TEMP : MAIL_ERROR_EXPUNGED, error); return -1; } mail->data.stream = input; if (mail->mail.v.istream_opened != NULL) { if (mail->mail.v.istream_opened(_mail, &mail->data.stream) < 0) { index_mail_close_streams(mail); return -1; } } i_stream_set_name(mail->data.stream, t_strcut(cmd, '\r')); if (get_body) pop3c_mail_cache_size(mail); } return index_mail_init_stream(mail, hdr_size, body_size, stream_r); }
const char * dsync_deserializer_decode_get(struct dsync_deserializer_decoder *decoder, const char *key) { const char *value; if (!dsync_deserializer_decode_try(decoder, key, &value)) { i_panic("dsync_deserializer_decode_get() " "used for non-required key %s", key); } return value; }
const void * mail_user_set_get_driver_settings(const struct setting_parser_info *info, const struct mail_user_settings *set, const char *driver) { const void *dset; dset = settings_find_dynamic(info, set, driver); if (dset == NULL) { i_panic("Default settings not found for storage driver %s", driver); } return dset; }