static int i_stream_file_stat(struct istream_private *stream, bool exact ATTR_UNUSED) { struct file_istream *fstream = (struct file_istream *) stream; const char *name = i_stream_get_name(&stream->istream); if (!fstream->file) { /* return defaults */ } else if (stream->fd != -1) { if (fstat(stream->fd, &stream->statbuf) < 0) { stream->istream.stream_errno = errno; io_stream_set_error(&stream->iostream, "file_istream.fstat(%s) failed: %m", name); i_error("%s", i_stream_get_error(&stream->istream)); return -1; } } else { if (stat(name, &stream->statbuf) < 0) { stream->istream.stream_errno = errno; io_stream_set_error(&stream->iostream, "file_istream.stat(%s) failed: %m", name); i_error("%s", i_stream_get_error(&stream->istream)); return -1; } } return 0; }
static int server_connection_send_cmd_input_more(struct server_connection *conn) { off_t ret; /* ostream-dot writes only up to max buffer size, so keep it non-zero */ o_stream_set_max_buffer_size(conn->cmd_output, IO_BLOCK_SIZE); ret = o_stream_send_istream(conn->cmd_output, conn->cmd_input); o_stream_set_max_buffer_size(conn->cmd_output, (size_t)-1); if (ret >= 0 && i_stream_have_bytes_left(conn->cmd_input)) { o_stream_set_flush_pending(conn->cmd_output, TRUE); return 0; } if (conn->cmd_input->stream_errno != 0) { i_error("read(%s) failed: %s", i_stream_get_name(conn->cmd_input), i_stream_get_error(conn->cmd_input)); } else if (conn->cmd_output->stream_errno != 0 || o_stream_flush(conn->cmd_output) < 0) { i_error("write(%s) failed: %s", o_stream_get_name(conn->cmd_output), o_stream_get_error(conn->cmd_output)); } i_stream_destroy(&conn->cmd_input); o_stream_destroy(&conn->cmd_output); return ret < 0 ? -1 : 1; }
static void proxy_client_input(struct login_proxy *proxy) { const unsigned char *data; size_t size; ssize_t ret; proxy->last_io = ioloop_time; if (o_stream_get_buffer_used_size(proxy->server_output) > OUTBUF_THRESHOLD) { /* proxy's output buffer is already quite full. don't send more until we're below threshold. */ io_remove(&proxy->client_io); return; } if (i_stream_read_data(proxy->client_input, &data, &size, 0) < 0) { const char *errstr = i_stream_get_error(proxy->client_input); login_proxy_free_errstr(&proxy, errstr, FALSE); return; } o_stream_cork(proxy->server_output); ret = o_stream_send(proxy->server_output, data, size); o_stream_uncork(proxy->server_output); if (ret != (ssize_t)size) login_proxy_free_ostream(&proxy, proxy->server_output, TRUE); else i_stream_skip(proxy->client_input, ret); }
static void test_static_v1_input_short(void) { ssize_t siz; const struct hash_method *hash = hash_method_lookup("sha256"); unsigned char hash_ctx[hash->context_size]; unsigned char hash_dgst[hash->digest_size]; hash->init(hash_ctx); test_begin("test_static_v1_input_short"); struct istream *is_1 = i_stream_create_file(DCRYPT_SRC_DIR"/sample-v1_short.asc", IO_BLOCK_SIZE); struct istream *is_2 = i_stream_create_base64_decoder(is_1); i_stream_unref(&is_1); struct istream *is_3 = i_stream_create_decrypt(is_2, test_v1_kp.priv); i_stream_unref(&is_2); struct istream *is_4 = i_stream_create_hash(is_3, hash, hash_ctx); i_stream_unref(&is_3); while((siz = i_stream_read(is_4))>0) { i_stream_skip(is_4, siz); } if (is_4->stream_errno != 0) i_debug("error: %s", i_stream_get_error(is_4)); test_assert(is_4->stream_errno == 0); i_stream_unref(&is_4); hash->result(hash_ctx, hash_dgst); test_assert(strcmp(test_sample_v1_short_hash, binary_to_hex(hash_dgst, sizeof(hash_dgst))) == 0); test_end(); }
void http_client_request_set_payload(struct http_client_request *req, struct istream *input, bool sync) { int ret; i_assert(req->state == HTTP_REQUEST_STATE_NEW); i_assert(req->payload_input == NULL); i_stream_ref(input); req->payload_input = input; if ((ret = i_stream_get_size(input, TRUE, &req->payload_size)) <= 0) { if (ret < 0) { i_error("i_stream_get_size(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); } req->payload_size = 0; req->payload_chunked = TRUE; } req->payload_offset = input->v_offset; /* prepare request payload sync using 100 Continue response from server */ if ((req->payload_chunked || req->payload_size > 0) && sync) req->payload_sync = TRUE; }
int sieve_file_storage_save_continue (struct sieve_storage_save_context *sctx) { struct sieve_file_save_context *fsctx = (struct sieve_file_save_context *)sctx; switch (o_stream_send_istream(fsctx->output, sctx->input)) { case OSTREAM_SEND_ISTREAM_RESULT_FINISHED: case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT: return 0; case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT: i_unreached(); case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT: sieve_storage_set_critical(sctx->storage, "save: read(%s) failed: %s", i_stream_get_name(sctx->input), i_stream_get_error(sctx->input)); return -1; case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT: sieve_storage_set_critical(sctx->storage, "save: write(%s) failed: %s", fsctx->tmp_path, o_stream_get_error(fsctx->output)); return -1; } return 0; }
static int fts_filter_stopwords_read_list(struct fts_filter_stopwords *filter, const char **error_r) { struct istream *input; const char *line, **words, *path; int ret = 0; path = t_strdup_printf(STOPWORDS_FILE_FORMAT, filter->stopwords_dir, filter->lang->name); input = i_stream_create_file(path, IO_BLOCK_SIZE); while ((line = i_stream_read_next_line(input)) != NULL) T_BEGIN { line = t_strcut(line, STOPWORDS_COMMENT_CHAR1); line = t_strcut(line, STOPWORDS_COMMENT_CHAR2); words = t_strsplit_spaces(line, " \t"); for (; *words != NULL; words++) { const char *word = p_strdup(filter->pool, *words); hash_table_insert(filter->stopwords, word, word); } } T_END; if (input->stream_errno != 0) { *error_r = t_strdup_printf("Failed to read stopword list %s: %s", path, i_stream_get_error(input)); ret = -1; } i_stream_destroy(&input); return ret; }
int json_parser_deinit(struct json_parser **_parser, const char **error_r) { struct json_parser *parser = *_parser; *_parser = NULL; if (parser->error != NULL) { /* actual parser error */ *error_r = parser->error; } else if (parser->input->stream_errno != 0) { *error_r = t_strdup_printf("read(%s) failed: %s", i_stream_get_name(parser->input), i_stream_get_error(parser->input)); } else if (parser->data == parser->end && !i_stream_have_bytes_left(parser->input) && parser->state != JSON_STATE_DONE) { *error_r = "Missing '}'"; } else { *error_r = NULL; } i_stream_unref(&parser->input); array_free(&parser->nesting); str_free(&parser->value); i_free(parser); return *error_r != NULL ? -1 : 0; }
static void login_connection_authreply_input(struct login_connection *conn) { const char *line; while ((line = i_stream_read_next_line(conn->input)) != NULL) T_BEGIN { if (!conn->handshaked) { if (!version_string_verify(line, "director-authreply-client", AUTHREPLY_PROTOCOL_MAJOR_VERSION)) { i_error("authreply client sent invalid handshake: %s", line); login_connection_deinit(&conn); return; } conn->handshaked = TRUE; } else { auth_input_line(line, conn); } } T_END; if (conn->input->eof) { if (conn->input->stream_errno != 0 && conn->input->stream_errno != ECONNRESET) { i_error("read(authreply connection) failed: %s", i_stream_get_error(conn->input)); } login_connection_deinit(&conn); } }
static int cmd_save_to_mailbox(struct save_cmd_context *ctx, struct mailbox *box, struct istream *input) { struct mail_storage *storage = mailbox_get_storage(box); struct mailbox_transaction_context *trans; struct mail_save_context *save_ctx; ssize_t ret; bool save_failed = FALSE; if (mailbox_open(box) < 0) { i_error("Failed to open mailbox %s: %s", mailbox_get_vname(box), mailbox_get_last_error(box, NULL)); doveadm_mail_failed_storage(&ctx->ctx, storage); return -1; } trans = mailbox_transaction_begin(box, MAILBOX_TRANSACTION_FLAG_EXTERNAL); save_ctx = mailbox_save_alloc(trans); if (mailbox_save_begin(&save_ctx, input) < 0) { i_error("Saving failed: %s", mailbox_get_last_error(box, NULL)); doveadm_mail_failed_storage(&ctx->ctx, storage); mailbox_transaction_rollback(&trans); return -1; } while ((ret = i_stream_read(input)) > 0 || ret == -2) { if (mailbox_save_continue(save_ctx) < 0) { save_failed = TRUE; ret = -1; break; } } i_assert(ret == -1); if (input->stream_errno != 0) { i_error("read(msg input) failed: %s", i_stream_get_error(input)); doveadm_mail_failed_error(&ctx->ctx, MAIL_ERROR_TEMP); } else if (save_failed) { i_error("Saving failed: %s", mailbox_get_last_error(box, NULL)); doveadm_mail_failed_storage(&ctx->ctx, storage); } else if (mailbox_save_finish(&save_ctx) < 0) { i_error("Saving failed: %s", mailbox_get_last_error(box, NULL)); doveadm_mail_failed_storage(&ctx->ctx, storage); } else if (mailbox_transaction_commit(&trans) < 0) { i_error("Save transaction commit failed: %s", mailbox_get_last_error(box, NULL)); doveadm_mail_failed_storage(&ctx->ctx, storage); } else { ret = 0; } if (save_ctx != NULL) mailbox_save_cancel(&save_ctx); if (trans != NULL) mailbox_transaction_rollback(&trans); i_assert(input->eof); return ret < 0 ? -1 : 0; }
static int copy_to_temp_file(struct seekable_istream *sstream) { struct istream_private *stream = &sstream->istream; const char *path; const unsigned char *buffer; size_t size; int fd; fd = sstream->fd_callback(&path, sstream->context); if (fd == -1) return -1; /* copy our currently read buffer to it */ i_assert(stream->pos <= sstream->buffer_peak); if (write_full(fd, stream->buffer, sstream->buffer_peak) < 0) { if (!ENOSPACE(errno)) i_error("istream-seekable: write_full(%s) failed: %m", path); i_close_fd(&fd); return -1; } sstream->temp_path = i_strdup(path); sstream->write_peak = sstream->buffer_peak; sstream->fd = fd; sstream->fd_input = i_stream_create_fd_autoclose(&fd, I_MAX(stream->pos, sstream->istream.max_buffer_size)); i_stream_set_name(sstream->fd_input, t_strdup_printf( "(seekable temp-istream for: %s)", i_stream_get_name(&stream->istream))); /* read back the data we just had in our buffer */ for (;;) { buffer = i_stream_get_data(sstream->fd_input, &size); if (size >= stream->pos) break; ssize_t ret; if ((ret = i_stream_read_memarea(sstream->fd_input)) <= 0) { i_assert(ret != 0); i_assert(ret != -2); i_error("istream-seekable: Couldn't read back " "in-memory input %s: %s", i_stream_get_name(&stream->istream), i_stream_get_error(sstream->fd_input)); i_stream_destroy(&sstream->fd_input); i_close_fd(&sstream->fd); return -1; } } /* Set the max buffer size only after we've already read everything into memory. For example with istream-data it's possible that more data exists in buffer than max_buffer_size. */ i_stream_set_max_buffer_size(sstream->fd_input, sstream->istream.max_buffer_size); stream->buffer = buffer; i_stream_free_buffer(&sstream->istream); return 0; }
static void test_static_v2_input(void) { test_begin("test_static_v2_input"); ssize_t amt; const struct hash_method *hash = hash_method_lookup("sha256"); unsigned char hash_ctx[hash->context_size]; unsigned char hash_dgst[hash->digest_size]; hash->init(hash_ctx); struct istream *is_1 = i_stream_create_file(DCRYPT_SRC_DIR"/sample-v2.asc", IO_BLOCK_SIZE); struct istream *is_2 = i_stream_create_base64_decoder(is_1); i_stream_unref(&is_1); struct istream *is_3 = i_stream_create_decrypt(is_2, test_v2_kp.priv); i_stream_unref(&is_2); struct istream *is_4 = i_stream_create_hash(is_3, hash, hash_ctx); i_stream_unref(&is_3); while((amt = i_stream_read(is_4))>0) { i_stream_skip(is_4, amt); } if (is_4->stream_errno != 0) i_debug("error: %s", i_stream_get_error(is_4)); test_assert(is_4->stream_errno == 0); i_stream_unref(&is_4); hash->result(hash_ctx, hash_dgst); test_assert(strcmp(test_sample_v2_hash, binary_to_hex(hash_dgst, sizeof(hash_dgst))) == 0); test_end(); /** this code is left here to show how the sample file is created struct istream *is = i_stream_create_file("../lib-fts/udhr_fra.txt", 8192); struct istream *is_2 = i_stream_create_hash(is, hash, hash_ctx); int fd = open("sample-v2.bin", O_CREAT|O_TRUNC|O_WRONLY, S_IRWXU); struct ostream *os = o_stream_create_fd_file(fd, 0, TRUE); struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v2_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD); const unsigned char *ptr; size_t siz; while(i_stream_read_data(is_2, &ptr, &siz, 0)>0) { o_stream_nsend(os_2, ptr, siz); i_stream_skip(is_2, siz); } i_assert(o_stream_nfinish(os_2)==0); o_stream_close(os_2); i_stream_close(is_2); hash->result(hash_ctx, hash_dgst); printf("%s\n", binary_to_hex(hash_dgst, sizeof(hash_dgst))); */ }
static void fetch_read_error(struct imap_fetch_context *ctx) { struct imap_fetch_state *state = &ctx->state; errno = state->cur_input->stream_errno; mail_storage_set_critical(state->cur_mail->box->storage, "read(%s) failed: %s (FETCH %s for mailbox %s UID %u)", i_stream_get_name(state->cur_input), i_stream_get_error(state->cur_input), state->cur_human_name, mailbox_get_vname(state->cur_mail->box), state->cur_mail->uid); }
static const char *client_get_disconnect_reason(struct client *client) { errno = client->input->stream_errno != 0 ? client->input->stream_errno : client->output->stream_errno; if (errno == 0 || errno == EPIPE) return "Connection closed"; return t_strdup_printf("Connection closed: %s", client->input->stream_errno != 0 ? i_stream_get_error(client->input) : o_stream_get_error(client->output)); }
void test_istream_failure_at(void) { struct istream *input, *data_input; unsigned char test_data[TEST_DATA_LENGTH]; unsigned int i; ssize_t ret; test_begin("istream failure at"); for (i = 0; i < sizeof(test_data); i++) test_data[i] = i; data_input = i_stream_create_from_data(test_data, sizeof(test_data)); for (i = 0; i < TEST_DATA_LENGTH; i++) { i_stream_seek(data_input, 0); input = i_stream_create_failure_at(data_input, i, EIO, TEST_ERRMSG); while ((ret = i_stream_read(input)) > 0) i_stream_skip(input, ret); test_assert_idx(ret == -1 && input->v_offset == i && input->stream_errno == EIO && strcmp(i_stream_get_error(input), TEST_ERRMSG) == 0, i); i_stream_destroy(&input); } /* shouldn't fail */ i_stream_seek(data_input, 0); input = i_stream_create_failure_at(data_input, TEST_DATA_LENGTH, EIO, TEST_ERRMSG); while ((ret = i_stream_read(input)) > 0) i_stream_skip(input, ret); test_assert(ret == -1 && input->stream_errno == 0); i_stream_destroy(&input); /* fail at EOF */ i_stream_seek(data_input, 0); input = i_stream_create_failure_at_eof(data_input, EIO, TEST_ERRMSG); while ((ret = i_stream_read(input)) > 0) i_stream_skip(input, ret); test_assert_idx(ret == -1 && input->v_offset == TEST_DATA_LENGTH && input->stream_errno == EIO && strcmp(i_stream_get_error(input), TEST_ERRMSG) == 0, i); i_stream_destroy(&input); i_stream_destroy(&data_input); test_end(); }
static void test_write_read_v2(void) { test_begin("test_write_read_v2"); unsigned char payload[IO_BLOCK_SIZE*10]; const unsigned char *ptr; size_t pos = 0, siz; random_fill_weak(payload, IO_BLOCK_SIZE*10); buffer_t *buf = buffer_create_dynamic(default_pool, sizeof(payload)); struct ostream *os = o_stream_create_buffer(buf); struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v1_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD); o_stream_nsend(os_2, payload, sizeof(payload)); test_assert(o_stream_nfinish(os_2) == 0); if (os_2->stream_errno != 0) i_debug("error: %s", o_stream_get_error(os_2)); o_stream_unref(&os); o_stream_unref(&os_2); struct istream *is = test_istream_create_data(buf->data, buf->used); /* test regression where read fails due to incorrect behaviour when buffer is full before going to decrypt code */ i_stream_set_max_buffer_size(is, 8192); i_stream_read(is); struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv); size_t offset = 0; test_istream_set_size(is, 0); test_istream_set_allow_eof(is, FALSE); while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) { if (offset == buf->used) test_istream_set_allow_eof(is, TRUE); else test_istream_set_size(is, ++offset); test_assert_idx(pos + siz <= sizeof(payload), pos); if (pos + siz > sizeof(payload)) break; test_assert_idx(siz == 0 || memcmp(ptr, payload + pos, siz) == 0, pos); i_stream_skip(is_2, siz); pos += siz; } test_assert(is_2->stream_errno == 0); if (is_2->stream_errno != 0) i_debug("error: %s", i_stream_get_error(is_2)); i_stream_unref(&is); i_stream_unref(&is_2); buffer_free(&buf); test_end(); }
static int config_read_reply_header(struct istream *istream, const char *path, pool_t pool, const struct master_service_settings_input *input, struct master_service_settings_output *output_r, const char **error_r) { const char *line; ssize_t ret; while ((ret = i_stream_read(istream)) > 0) { line = i_stream_next_line(istream); if (line != NULL) break; } if (ret <= 0) { if (ret == 0) return 1; *error_r = istream->stream_errno != 0 ? t_strdup_printf("read(%s) failed: %s", path, i_stream_get_error(istream)) : t_strdup_printf("read(%s) failed: EOF", path); return -1; } T_BEGIN { const char *const *arg = t_strsplit_tabescaped(line); ARRAY_TYPE(const_string) services; p_array_init(&services, pool, 8); for (; *arg != NULL; arg++) { if (strcmp(*arg, "service-uses-local") == 0) output_r->service_uses_local = TRUE; else if (strcmp(*arg, "service-uses-remote") == 0) output_r->service_uses_remote = TRUE; if (strcmp(*arg, "used-local") == 0) output_r->used_local = TRUE; else if (strcmp(*arg, "used-remote") == 0) output_r->used_remote = TRUE; else if (strncmp(*arg, "service=", 8) == 0) { const char *name = p_strdup(pool, *arg + 8); array_append(&services, &name, 1); } } if (input->service == NULL) { array_append_zero(&services); output_r->specific_services = array_idx(&services, 0); } } T_END; return 0; }
static void test_write_read_v2_short(void) { test_begin("test_write_read_v2_short"); unsigned char payload[1]; const unsigned char *ptr; size_t pos = 0, siz; random_fill_weak(payload, 1); buffer_t *buf = buffer_create_dynamic(default_pool, 64); struct ostream *os = o_stream_create_buffer(buf); struct ostream *os_2 = o_stream_create_encrypt(os, "aes-256-gcm-sha256", test_v1_kp.pub, IO_STREAM_ENC_INTEGRITY_AEAD); o_stream_nsend(os_2, payload, sizeof(payload)); test_assert(o_stream_nfinish(os_2) == 0); if (os_2->stream_errno != 0) i_debug("error: %s", o_stream_get_error(os_2)); o_stream_unref(&os); o_stream_unref(&os_2); struct istream *is = test_istream_create_data(buf->data, buf->used); struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv); size_t offset = 0; test_istream_set_allow_eof(is, FALSE); test_istream_set_size(is, 0); while(i_stream_read_data(is_2, &ptr, &siz, 0)>=0) { if (offset == buf->used) test_istream_set_allow_eof(is, TRUE); test_istream_set_size(is, ++offset); test_assert_idx(pos + siz <= sizeof(payload), pos); if (pos + siz > sizeof(payload)) break; test_assert_idx(siz == 0 || memcmp(ptr, payload + pos, siz) == 0, pos); i_stream_skip(is_2, siz); pos += siz; } test_assert(is_2->stream_errno == 0); if (is_2->stream_errno != 0) i_debug("error: %s", i_stream_get_error(is_2)); i_stream_unref(&is); i_stream_unref(&is_2); buffer_free(&buf); test_end(); }
static void fetch_read_error(struct imap_fetch_context *ctx, const char **disconnect_reason_r) { struct imap_fetch_state *state = &ctx->state; if (state->cur_input->stream_errno == ENOENT) { if (state->cur_mail->expunged) { *disconnect_reason_r = "Mail expunged while it was being FETCHed"; return; } } mail_storage_set_critical(state->cur_mail->box->storage, "read(%s) failed: %s (FETCH %s for mailbox %s UID %u)", i_stream_get_name(state->cur_input), i_stream_get_error(state->cur_input), state->cur_human_name, mailbox_get_vname(state->cur_mail->box), state->cur_mail->uid); *disconnect_reason_r = "FETCH read() failed"; }
static int fts_indexer_input(struct fts_indexer_context *ctx) { const char *line; int percentage; while ((line = i_stream_read_next_line(ctx->input)) != NULL) { /* initial reply: <tag> \t OK following: <tag> \t <percentage> */ if (strncmp(line, "1\t", 2) != 0) { i_error("indexer sent invalid reply: %s", line); return -1; } line += 2; if (strcmp(line, "OK") == 0) continue; if (str_to_int(line, &percentage) < 0 || percentage > 100) { i_error("indexer sent invalid percentage: %s", line); return -1; } if (percentage < 0) { /* indexing failed */ i_error("indexer failed to index mailbox %s", ctx->box->vname); return -1; } ctx->percentage = percentage; if (percentage == 100) { /* finished */ return 1; } } if (ctx->input->stream_errno != 0) { i_error("indexer read(%s) failed: %s", i_stream_get_name(ctx->input), i_stream_get_error(ctx->input)); return -1; } if (ctx->input->eof) { i_error("indexer disconnected unexpectedly"); return -1; } return 0; }
static int server_connection_send_cmd_input_more(struct server_connection *conn) { enum ostream_send_istream_result res; int ret = -1; /* ostream-dot writes only up to max buffer size, so keep it non-zero */ o_stream_set_max_buffer_size(conn->cmd_output, IO_BLOCK_SIZE); res = o_stream_send_istream(conn->cmd_output, conn->cmd_input); o_stream_set_max_buffer_size(conn->cmd_output, (size_t)-1); switch (res) { case OSTREAM_SEND_ISTREAM_RESULT_FINISHED: break; case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT: return 1; case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT: return 0; case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT: i_error("read(%s) failed: %s", i_stream_get_name(conn->cmd_input), i_stream_get_error(conn->cmd_input)); break; case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT: i_error("write(%s) failed: %s", o_stream_get_name(conn->cmd_output), o_stream_get_error(conn->cmd_output)); break; } if (res == OSTREAM_SEND_ISTREAM_RESULT_FINISHED) { if ((ret = o_stream_flush(conn->cmd_output)) == 0) return 0; else if (ret < 0) { i_error("write(%s) failed: %s", o_stream_get_name(conn->cmd_output), o_stream_get_error(conn->cmd_output)); } } i_stream_destroy(&conn->cmd_input); o_stream_destroy(&conn->cmd_output); return ret; }
static void stats_dump(const char *path, const char *cmd) { struct istream *input; const char *const *args; unsigned int i; int fd; fd = doveadm_connect(path); net_set_nonblock(fd, FALSE); if (write_full(fd, cmd, strlen(cmd)) < 0) i_fatal("write(%s) failed: %m", path); input = i_stream_create_fd_autoclose(&fd, (size_t)-1); /* read header */ args = read_next_line(input); if (args == NULL) i_fatal("read(%s) unexpectedly disconnected", path); if (*args == NULL) i_info("no statistics available"); else { for (; *args != NULL; args++) doveadm_print_header_simple(*args); /* read lines */ do { T_BEGIN { args = read_next_line(input); if (args != NULL && args[0] == NULL) args = NULL; if (args != NULL) { for (i = 0; args[i] != NULL; i++) doveadm_print(args[i]); } } T_END; } while (args != NULL); } if (input->stream_errno != 0) i_fatal("read(%s) failed: %s", path, i_stream_get_error(input)); i_stream_destroy(&input); }
static void test_write_read_v1_empty(void) { const unsigned char *ptr; size_t siz; test_begin("test_write_read_v1_empty"); buffer_t *buf = buffer_create_dynamic(default_pool, 64); struct ostream *os = o_stream_create_buffer(buf); struct ostream *os_2 = o_stream_create_encrypt(os, "<unused>", test_v1_kp.pub, IO_STREAM_ENC_VERSION_1); test_assert(o_stream_nfinish(os_2) == 0); if (os_2->stream_errno != 0) i_debug("error: %s", o_stream_get_error(os_2)); o_stream_unref(&os); o_stream_unref(&os_2); /* this should've been enough */ struct istream *is = test_istream_create_data(buf->data, buf->used); struct istream *is_2 = i_stream_create_decrypt(is, test_v1_kp.priv); /* read should not fail */ test_istream_set_allow_eof(is, FALSE); test_istream_set_size(is, 0); size_t offset = 0; ssize_t ret; while ((ret = i_stream_read_data(is_2, &ptr, &siz, 0)) >= 0) { test_assert(ret == 0); if (offset == buf->used) test_istream_set_allow_eof(is, TRUE); else test_istream_set_size(is, ++offset); }; test_assert(is_2->stream_errno == 0); if (is_2->stream_errno != 0) i_debug("error: %s", i_stream_get_error(is_2)); i_stream_unref(&is); i_stream_unref(&is_2); buffer_free(&buf); test_end(); }
static void server_input(struct client *client) { const unsigned char *data; size_t size; if (i_stream_read(client->input) == -1) { if (client->input->stream_errno != 0) { i_fatal("read(server) failed: %s", i_stream_get_error(client->input)); } i_info("Server disconnected"); master_service_stop(master_service); return; } data = i_stream_get_data(client->input, &size); if (write(STDOUT_FILENO, data, size) < 0) i_fatal("write(stdout) failed: %m"); i_stream_skip(client->input, size); }
static int fs_crypt_read_file(const char *set_name, const char *path, char **key_data_r, const char **error_r) { struct istream *input; int ret; input = i_stream_create_file(path, (size_t)-1); while (i_stream_read(input) > 0) ; if (input->stream_errno != 0) { *error_r = t_strdup_printf("%s: read(%s) failed: %s", set_name, path, i_stream_get_error(input)); ret = -1; } else { size_t size; const unsigned char *data = i_stream_get_data(input, &size); *key_data_r = i_strndup(data, size); ret = 0; } i_stream_unref(&input); return ret; }
const char *io_stream_get_disconnect_reason(struct istream *input, struct ostream *output) { const char *errstr; if (input != NULL && input->stream_errno != 0) { errno = input->stream_errno; errstr = i_stream_get_error(input); } else if (output != NULL && output->stream_errno != 0) { errno = output->stream_errno; errstr = o_stream_get_error(output); } else { errno = 0; errstr = ""; } if (errno == 0 || errno == EPIPE) return "Connection closed"; else return t_strdup_printf("Connection closed: %s", errstr); }
static ssize_t read_more(struct seekable_istream *sstream) { size_t size; ssize_t ret; if (sstream->cur_input == NULL) { sstream->istream.istream.eof = TRUE; return -1; } while ((ret = i_stream_read_memarea(sstream->cur_input)) == -1) { if (sstream->cur_input->stream_errno != 0) { io_stream_set_error(&sstream->istream.iostream, "read(%s) failed: %s", i_stream_get_name(sstream->cur_input), i_stream_get_error(sstream->cur_input)); sstream->istream.istream.eof = TRUE; sstream->istream.istream.stream_errno = sstream->cur_input->stream_errno; return -1; } /* go to next stream */ sstream->cur_input = sstream->input[sstream->cur_idx++]; if (sstream->cur_input == NULL) { /* last one, EOF */ sstream->size = sstream->istream.istream.v_offset; sstream->istream.istream.eof = TRUE; unref_streams(sstream); return -1; } /* see if stream has pending data */ size = i_stream_get_data_size(sstream->cur_input); if (size != 0) return size; } return ret; }
static int mail_storage_try_copy(struct mail_save_context **_ctx, struct mail *mail) { struct mail_save_context *ctx = *_ctx; struct mail_private *pmail = (struct mail_private *)mail; struct istream *input; ctx->copying_via_save = TRUE; /* we need to open the file in any case. caching metadata is unlikely to help anything. */ pmail->v.set_uid_cache_updates(mail, TRUE); if (mail_get_stream_because(mail, NULL, NULL, "copying", &input) < 0) { mail_copy_set_failed(ctx, mail, "stream"); return -1; } if (mail_save_copy_default_metadata(ctx, mail) < 0) return -1; if (mailbox_save_begin(_ctx, input) < 0) return -1; ssize_t ret; do { if (mailbox_save_continue(ctx) < 0) break; ret = i_stream_read(input); i_assert(ret != 0); } while (ret != -1); if (input->stream_errno != 0) { mail_storage_set_critical(ctx->transaction->box->storage, "copy: i_stream_read(%s) failed: %s", i_stream_get_name(input), i_stream_get_error(input)); return -1; } return 0; }
static bool cmd_getscript_continue(struct client_command_context *cmd) { struct client *client = cmd->client; struct cmd_getscript_context *ctx = cmd->context; switch (o_stream_send_istream(client->output, ctx->script_stream)) { case OSTREAM_SEND_ISTREAM_RESULT_FINISHED: if ( ctx->script_stream->v_offset != ctx->script_size && !ctx->failed ) { /* Input stream gave less data than expected */ sieve_storage_set_critical(ctx->storage, "GETSCRIPT for script `%s' from %s got too little data: " "%"PRIuUOFF_T" vs %"PRIuUOFF_T, sieve_script_name(ctx->script), sieve_script_location(ctx->script), ctx->script_stream->v_offset, ctx->script_size); client_disconnect(ctx->client, "GETSCRIPT failed"); ctx->failed = TRUE; } break; case OSTREAM_SEND_ISTREAM_RESULT_WAIT_INPUT: i_unreached(); case OSTREAM_SEND_ISTREAM_RESULT_WAIT_OUTPUT: return FALSE; case OSTREAM_SEND_ISTREAM_RESULT_ERROR_INPUT: sieve_storage_set_critical(ctx->storage, "o_stream_send_istream() failed for script `%s' from %s: %s", sieve_script_name(ctx->script), sieve_script_location(ctx->script), i_stream_get_error(ctx->script_stream)); ctx->failed = TRUE; break; case OSTREAM_SEND_ISTREAM_RESULT_ERROR_OUTPUT: client_disconnect(ctx->client, io_stream_get_disconnect_reason(client->input, client->output)); ctx->failed = TRUE; break; } return cmd_getscript_finish(ctx); }
static void lmtp_client_input(struct lmtp_client *client) { const char *line; int ret; lmtp_client_ref(client); o_stream_cork(client->output); while ((line = i_stream_read_next_line(client->input)) != NULL) { T_BEGIN { ret = lmtp_client_input_line(client, line); } T_END; if (ret < 0) { o_stream_uncork(client->output); lmtp_client_unref(&client); return; } if (ret > 0) str_truncate(client->input_multiline, 0); } if (client->input->stream_errno == ENOBUFS) { lmtp_client_fail(client, "501 5.5.4 Command reply line too long"); } else if (client->input->stream_errno != 0) { i_error("lmtp client: read() failed: %s", i_stream_get_error(client->input)); lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE " (read failure)"); } else if (client->input->eof) { lmtp_client_fail(client, ERRSTR_TEMP_REMOTE_FAILURE " (disconnected in input)"); } o_stream_uncork(client->output); if (client->to != NULL) timeout_reset(client->to); lmtp_client_unref(&client); }