static void test_compress_file(const char *in_path, const char *out_path) { const struct compression_handler *handler; struct istream *input, *file_input; struct ostream *output, *file_output; int fd_in, fd_out; struct sha1_ctxt sha1; unsigned char output_sha1[SHA1_RESULTLEN], input_sha1[SHA1_RESULTLEN]; const unsigned char *data; size_t size; ssize_t ret; handler = compression_lookup_handler_from_ext(out_path); if (handler == NULL) i_fatal("Can't detect compression algorithm from path %s", out_path); if (handler->create_ostream == NULL) i_fatal("Support not compiled in for %s", handler->name); /* write the compressed output file */ fd_in = open(in_path, O_RDONLY); if (fd_in == -1) i_fatal("open(%s) failed: %m", in_path); fd_out = open(out_path, O_TRUNC | O_CREAT | O_RDWR, 0600); if (fd_out == -1) i_fatal("creat(%s) failed: %m", out_path); sha1_init(&sha1); file_output = o_stream_create_fd_file(fd_out, 0, FALSE); output = handler->create_ostream(file_output, 1); input = i_stream_create_fd_autoclose(&fd_in, IO_BLOCK_SIZE); while (i_stream_read_data(input, &data, &size, 0) > 0) { sha1_loop(&sha1, data, size); o_stream_nsend(output, data, size); i_stream_skip(input, size); } if (o_stream_nfinish(output) < 0) { i_fatal("write(%s) failed: %s", out_path, o_stream_get_error(output)); } i_stream_destroy(&input); o_stream_destroy(&output); o_stream_destroy(&file_output); sha1_result(&sha1, output_sha1); /* verify that we can read the compressed file */ sha1_init(&sha1); file_input = i_stream_create_fd(fd_out, IO_BLOCK_SIZE, FALSE); input = handler->create_istream(file_input, FALSE); while ((ret = i_stream_read_data(input, &data, &size, 0)) > 0) { sha1_loop(&sha1, data, size); i_stream_skip(input, size); } i_stream_destroy(&input); i_stream_destroy(&file_input); sha1_result(&sha1, input_sha1); if (memcmp(input_sha1, output_sha1, sizeof(input_sha1)) != 0) i_fatal("Decompression couldn't get the original input"); i_close_fd(&fd_out); }
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 test_istream_base64_encoder_seek(const char *textin, const char *textout) { unsigned int offset, len = strlen(textout); struct istream *input, *input_data; const unsigned char *data; size_t size; ssize_t ret; input_data = i_stream_create_from_data(textin, strlen(textin)); input = i_stream_create_base64_encoder(input_data, 4, TRUE); while (i_stream_read(input) > 0) ; i_stream_skip(input, i_stream_get_data_size(input)); for (offset = 0; offset < len; offset++) { i_stream_seek(input, offset); while ((ret = i_stream_read(input)) > 0) ; test_assert(ret == -1); data = i_stream_get_data(input, &size); test_assert(size == len-offset); test_assert(memcmp(data, textout+offset, size) == 0); i_stream_skip(input, size); } i_stream_unref(&input); i_stream_unref(&input_data); }
int message_get_header_size(struct istream *input, struct message_size *hdr, bool *has_nuls_r) { const unsigned char *msg; size_t i, size, startpos, missing_cr_count; int ret; memset(hdr, 0, sizeof(struct message_size)); *has_nuls_r = FALSE; missing_cr_count = 0; startpos = 0; while ((ret = i_stream_read_bytes(input, &msg, &size, startpos + 1)) > 0) { for (i = startpos; i < size; i++) { if (msg[i] != '\n') { if (msg[i] == '\0') *has_nuls_r = TRUE; continue; } hdr->lines++; if (i == 0 || msg[i-1] != '\r') { /* missing CR */ missing_cr_count++; } if (i == 0 || (i == 1 && msg[i-1] == '\r')) { /* no headers at all */ break; } if ((i > 0 && msg[i-1] == '\n') || (i > 1 && msg[i-2] == '\n' && msg[i-1] == '\r')) { /* \n\n or \n\r\n - end of headers */ break; } } if (i < size) { /* end of header */ startpos = i+1; break; } /* leave the last two characters, they may be \r\n */ startpos = size == 1 ? 1 : 2; i_stream_skip(input, i - startpos); hdr->physical_size += i - startpos; } i_assert(ret == -1 || ret > 0); ret = input->stream_errno != 0 ? -1 : 0; i_stream_skip(input, startpos); hdr->physical_size += startpos; hdr->virtual_size = hdr->physical_size + missing_cr_count; i_assert(hdr->virtual_size >= hdr->physical_size); return ret; }
static void i_stream_zlib_seek(struct istream_private *stream, uoff_t v_offset, bool mark) { struct zlib_istream *zstream = (struct zlib_istream *) stream; uoff_t start_offset = stream->istream.v_offset - stream->skip; if (v_offset < start_offset) { /* have to seek backwards */ i_stream_zlib_reset(zstream); start_offset = 0; } else if (zstream->high_pos != 0) { stream->pos = zstream->high_pos; zstream->high_pos = 0; } if (v_offset <= start_offset + stream->pos) { /* seeking backwards within what's already cached */ stream->skip = v_offset - start_offset; stream->istream.v_offset = v_offset; zstream->high_pos = stream->pos; stream->pos = stream->skip; } else { /* read and cache forward */ ssize_t ret; do { size_t avail = stream->pos - stream->skip; if (stream->istream.v_offset + avail >= v_offset) { i_stream_skip(&stream->istream, v_offset - stream->istream.v_offset); ret = -1; break; } i_stream_skip(&stream->istream, avail); } while ((ret = i_stream_read(&stream->istream)) > 0); i_assert(ret == -1); if (stream->istream.v_offset != v_offset) { /* some failure, we've broken it */ if (stream->istream.stream_errno != 0) { i_error("zlib_istream.seek(%s) failed: %s", i_stream_get_name(&stream->istream), strerror(stream->istream.stream_errno)); i_stream_close(&stream->istream); } else { /* unexpected EOF. allow it since we may just want to check if there's anything.. */ i_assert(stream->istream.eof); } } } if (mark) zstream->marked = TRUE; }
static int managesieve_parser_read_literal_data(struct managesieve_parser *parser, const unsigned char *data, size_t data_size) { if (parser->literal_skip_crlf) { /* skip \r\n or \n, anything else gives an error */ if (data_size == 0) return FALSE; if (*data == '\r') { parser->line_size++; data++; data_size--; i_stream_skip(parser->input, 1); if (data_size == 0) return FALSE; } if (*data != '\n') { parser->error = "Missing LF after literal size"; return FALSE; } parser->line_size++; data++; data_size--; i_stream_skip(parser->input, 1); parser->literal_skip_crlf = FALSE; i_assert(parser->cur_pos == 0); } if ((parser->flags & MANAGESIEVE_PARSE_FLAG_STRING_STREAM) == 0) { /* now we just wait until we've read enough data */ if (data_size < parser->literal_size) { return FALSE; } else { if ( !uni_utf8_data_is_valid (data, (size_t)parser->literal_size) ) { parser->error = "Invalid UTF-8 character in literal string."; return FALSE; } managesieve_parser_save_arg(parser, data, (size_t)parser->literal_size); parser->cur_pos = (size_t)parser->literal_size; return TRUE; } } else { /* we don't read the data; we just create a stream for the literal */ parser->eol = TRUE; parser->str_stream = i_stream_create_limit (parser->input, parser->literal_size); managesieve_parser_save_arg(parser, NULL, 0); return TRUE; } }
static void test_istream_children(void) { struct istream *parent, *child1, *child2; const unsigned char *data; size_t size; test_begin("istream children"); parent = test_istream_create_data("123456789", 9); test_istream_set_max_buffer_size(parent, 3); child1 = i_stream_create_limit(parent, (uoff_t)-1); child2 = i_stream_create_limit(parent, (uoff_t)-1); /* child1 read beginning */ test_assert(i_stream_read(child1) == 3); data = i_stream_get_data(child1, &size); test_assert(size == 3 && memcmp(data, "123", 3) == 0); i_stream_skip(child1, 3); /* child1 read middle.. */ test_assert(i_stream_read(child1) == 3); data = i_stream_get_data(child1, &size); test_assert(size == 3 && memcmp(data, "456", 3) == 0); /* child2 read beginning.. */ test_assert(i_stream_read(child2) == 3); data = i_stream_get_data(child2, &size); test_assert(size == 3 && memcmp(data, "123", 3) == 0); /* child1 check middle again.. the parent has been modified, so it can't return the original data (without some code changes). */ data = i_stream_get_data(child1, &size); test_assert(size == 0); i_stream_skip(child1, 3); /* child1 read end */ test_assert(i_stream_read(child1) == 3); data = i_stream_get_data(child1, &size); test_assert(size == 3 && memcmp(data, "789", 3) == 0); i_stream_skip(child1, 3); test_assert(i_stream_read(child1) == -1); /* child2 check beginning again.. */ data = i_stream_get_data(child2, &size); test_assert(size == 0); i_stream_skip(child2, 3); /* child2 read middle */ test_assert(i_stream_read(child2) == 3); data = i_stream_get_data(child2, &size); test_assert(size == 3 && memcmp(data, "456", 3) == 0); i_stream_skip(child2, 3); i_stream_destroy(&child1); i_stream_destroy(&child2); i_stream_destroy(&parent); test_end(); }
int message_get_body_size(struct istream *input, struct message_size *body, bool *has_nuls_r) { const unsigned char *msg; size_t i, size, missing_cr_count; int ret; memset(body, 0, sizeof(struct message_size)); *has_nuls_r = FALSE; missing_cr_count = 0; if ((ret = i_stream_read_more(input, &msg, &size)) <= 0) { i_assert(ret == -1); return ret < 0 && input->stream_errno != 0 ? -1 : 0; } if (msg[0] == '\n') missing_cr_count++; do { for (i = 1; i < size; i++) { if (msg[i] > '\n') continue; if (msg[i] == '\n') { if (msg[i-1] != '\r') { /* missing CR */ missing_cr_count++; } /* increase after making sure we didn't break at virtual \r */ body->lines++; } else if (msg[i] == '\0') { *has_nuls_r = TRUE; } } /* leave the last character, it may be \r */ i_stream_skip(input, i - 1); body->physical_size += i - 1; } while ((ret = i_stream_read_bytes(input, &msg, &size, 2)) > 0); i_assert(ret == -1); ret = input->stream_errno != 0 ? -1 : 0; i_stream_skip(input, 1); body->physical_size++; body->virtual_size = body->physical_size + missing_cr_count; i_assert(body->virtual_size >= body->physical_size); return ret; }
static struct istream *mail_raw_create_stream (struct mail_user *ruser, int fd, time_t *mtime_r, const char **sender) { struct istream *input, *input2, *input_list[2]; const unsigned char *data; size_t i, size; int ret, tz; char *env_sender = NULL; *mtime_r = (time_t)-1; fd_set_nonblock(fd, FALSE); input = i_stream_create_fd(fd, 4096, FALSE); input->blocking = TRUE; /* If input begins with a From-line, drop it */ ret = i_stream_read_data(input, &data, &size, 5); if (ret > 0 && size >= 5 && memcmp(data, "From ", 5) == 0) { /* skip until the first LF */ i_stream_skip(input, 5); while ( i_stream_read_data(input, &data, &size, 0) > 0 ) { for (i = 0; i < size; i++) { if (data[i] == '\n') break; } if (i != size) { (void)mbox_from_parse(data, i, mtime_r, &tz, &env_sender); i_stream_skip(input, i + 1); break; } i_stream_skip(input, size); } } if (env_sender != NULL && sender != NULL) { *sender = t_strdup(env_sender); } i_free(env_sender); if (input->v_offset == 0) { input2 = input; i_stream_ref(input2); } else { input2 = i_stream_create_limit(input, (uoff_t)-1); } i_stream_unref(&input); input_list[0] = input2; input_list[1] = NULL; input = i_stream_create_seekable(input_list, MAIL_MAX_MEMORY_BUFFER, seekable_fd_callback, (void*)ruser); i_stream_unref(&input2); return input; }
static bool imap_parser_read_literal_data(struct imap_parser *parser, const unsigned char *data, size_t data_size) { if (parser->literal_skip_crlf) { /* skip \r\n or \n, anything else gives an error */ if (data_size == 0) return FALSE; if (*data == '\r') { parser->line_size++; data++; data_size--; i_stream_skip(parser->input, 1); if (data_size == 0) return FALSE; } if (*data != '\n') { parser->error = IMAP_PARSE_ERROR_BAD_SYNTAX; parser->error_msg = "Missing LF after literal size"; return FALSE; } parser->line_size++; data++; data_size--; i_stream_skip(parser->input, 1); parser->literal_skip_crlf = FALSE; i_assert(parser->cur_pos == 0); } if ((parser->flags & IMAP_PARSE_FLAG_LITERAL_SIZE) == 0 || parser->cur_type == ARG_PARSE_LITERAL_DATA_FORCED) { /* now we just wait until we've read enough data */ if (data_size < parser->literal_size) return FALSE; else { imap_parser_save_arg(parser, data, (size_t)parser->literal_size); parser->cur_pos = (size_t)parser->literal_size; return TRUE; } } else { /* we want to save only literal size, not the literal itself. */ parser->literal_size_return = TRUE; imap_parser_save_arg(parser, uchar_empty_ptr, 0); return FALSE; } }
static int i_stream_seekable_stat(struct istream_private *stream, bool exact) { struct seekable_istream *sstream = (struct seekable_istream *)stream; const struct stat *st; uoff_t old_offset; ssize_t ret; if (sstream->size != (uoff_t)-1) { /* we've already reached EOF and know the size */ stream->statbuf.st_size = sstream->size; return 0; } if (sstream->membuf != NULL) { /* we want to know the full size of the file, so read until we're finished */ old_offset = stream->istream.v_offset; do { i_stream_skip(&stream->istream, stream->pos - stream->skip); } while ((ret = i_stream_seekable_read(stream)) > 0); if (ret == 0) { i_panic("i_stream_stat() used for non-blocking " "seekable stream %s offset %"PRIuUOFF_T, i_stream_get_name(sstream->cur_input), sstream->cur_input->v_offset); } i_stream_skip(&stream->istream, stream->pos - stream->skip); i_stream_seek(&stream->istream, old_offset); unref_streams(sstream); } if (stream->istream.stream_errno != 0) return -1; if (sstream->fd_input != NULL) { /* using a file backed buffer, we can use real fstat() */ if (i_stream_stat(sstream->fd_input, exact, &st) < 0) return -1; stream->statbuf = *st; } else { /* buffer is completely in memory */ i_assert(sstream->membuf != NULL); stream->statbuf.st_size = sstream->membuf->used; } return 0; }
static void imap_zlib_client_skip_line(struct client *client) { const unsigned char *data; size_t data_size; data = i_stream_get_data(client->input, &data_size); i_assert(data_size > 0); if (data[0] == '\n') i_stream_skip(client->input, 1); else if (data[0] == '\r' && data_size > 1 && data[1] == '\n') i_stream_skip(client->input, 2); else i_unreached(); client->input_skip_line = FALSE; }
static void server_handle_input(struct server_connection *conn, const unsigned char *data, size_t size) { string_t *str; size_t i, start; if (printing_conn == conn) { /* continue printing */ } else if (printing_conn == NULL) { printing_conn = conn; } else { /* someone else is printing. don't continue until it goes away */ io_remove(&conn->io); return; } if (data[size-1] == '\001') { /* last character is an escape */ size--; } str = t_str_new(128); for (i = start = 0; i < size; i++) { if (data[i] == '\n') { if (i != start) { i_error("doveadm server sent broken print input"); server_connection_destroy(&conn); return; } conn->state = SERVER_REPLY_STATE_RET; i_stream_skip(conn->input, i + 1); print_connection_released(); return; } if (data[i] == '\t') { server_flush_field(conn, str, data + start, i - start); start = i + 1; } } if (start != size) { conn->streaming = TRUE; stream_data(str, data + start, size - start); } i_stream_skip(conn->input, size); }
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; }
static int i_stream_lzma_stat(struct istream_private *stream, bool exact) { struct lzma_istream *zstream = (struct lzma_istream *) stream; const struct stat *st; size_t size; if (i_stream_stat(stream->parent, exact, &st) < 0) { stream->istream.stream_errno = stream->parent->stream_errno; return -1; } stream->statbuf = *st; /* when exact=FALSE always return the parent stat's size, even if we know the exact value. this is necessary because otherwise e.g. mbox code can see two different values and think that a compressed mbox file keeps changing. */ if (!exact) return 0; if (zstream->stream_size == (uoff_t)-1) { uoff_t old_offset = stream->istream.v_offset; do { size = i_stream_get_data_size(&stream->istream); i_stream_skip(&stream->istream, size); } while (i_stream_read(&stream->istream) > 0); i_stream_seek(&stream->istream, old_offset); if (zstream->stream_size == (uoff_t)-1) return -1; } stream->statbuf.st_size = zstream->stream_size; return 0; }
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); }
uoff_t istream_raw_mbox_get_body_offset(struct istream *stream) { struct raw_mbox_istream *rstream = (struct raw_mbox_istream *)stream->real_stream; uoff_t offset; i_assert(rstream->seeked); if (rstream->body_offset != (uoff_t)-1) return rstream->body_offset; offset = stream->v_offset; i_stream_seek(stream, rstream->hdr_offset); while (rstream->body_offset == (uoff_t)-1) { i_stream_skip(stream, i_stream_get_data_size(stream)); if (i_stream_raw_mbox_read(&rstream->istream) < 0) { if (rstream->corrupted) { i_error("Unexpectedly lost From-line from mbox file " "%s at %"PRIuUOFF_T, i_stream_get_name(stream), rstream->from_offset); } else { i_assert(rstream->body_offset != (uoff_t)-1); } break; } } i_stream_seek(stream, offset); return rstream->body_offset; }
static void i_stream_tee_destroy(struct iostream_private *stream) { struct tee_child_istream *tstream = (struct tee_child_istream *)stream; struct tee_istream *tee = tstream->tee; struct tee_child_istream **p; if (tstream->istream.istream.v_offset > tee->max_read_offset) tee->max_read_offset = tstream->istream.istream.v_offset; for (p = &tee->children; *p != NULL; p = &(*p)->next) { if (*p == tstream) { *p = tstream->next; break; } } if (tee->children == NULL) { /* last child. the tee is now destroyed */ i_assert(tee->input->v_offset <= tee->max_read_offset); i_stream_skip(tee->input, tee->max_read_offset - tee->input->v_offset); i_stream_unref(&tee->input); i_free(tee); } else { tee_streams_skip(tstream->tee); } /* i_stream_unref() shouldn't unref the parent */ tstream->istream.parent = NULL; }
static int i_stream_zlib_read_trailer(struct zlib_istream *zstream) { struct istream_private *stream = &zstream->istream; const unsigned char *data; size_t size; int ret; ret = i_stream_read_bytes(stream->parent, &data, &size, GZ_TRAILER_SIZE); if (size == zstream->prev_size) { stream->istream.stream_errno = stream->parent->stream_errno; if (ret == -1 && stream->istream.stream_errno == 0) { zlib_read_error(zstream, "missing gz trailer"); stream->istream.stream_errno = EINVAL; } return ret; } zstream->prev_size = size; if (size < GZ_TRAILER_SIZE) return 0; if (data_get_uint32(data) != zstream->crc32) { zlib_read_error(zstream, "gz trailer has wrong CRC value"); stream->istream.stream_errno = EINVAL; return -1; } i_stream_skip(stream->parent, GZ_TRAILER_SIZE); zstream->prev_size = 0; zstream->trailer_read = TRUE; return 1; }
static ssize_t i_stream_mail_filter_read_once(struct mail_filter_istream *mstream) { struct istream_private *stream = &mstream->istream; ssize_t ret; if (mstream->ext_out != NULL) { /* we haven't sent everything yet */ (void)o_stream_send_istream(mstream->ext_out, stream->parent); if (mstream->ext_out->stream_errno != 0) { stream->istream.stream_errno = mstream->ext_out->stream_errno; return -1; } if (i_stream_is_eof(stream->parent)) { o_stream_destroy(&mstream->ext_out); /* if we wanted to be a blocking stream, from now on the rest of the reads are */ if (stream->istream.blocking) net_set_nonblock(mstream->fd, FALSE); if (shutdown(mstream->fd, SHUT_WR) < 0) i_error("ext-filter: shutdown() failed: %m"); } } i_stream_skip(mstream->ext_in, mstream->prev_ret); ret = i_stream_read_copy_from(&stream->istream, mstream->ext_in); mstream->prev_ret = ret < 0 ? 0 : ret; return ret; }
static void cmd_dump_imapzlib(int argc ATTR_UNUSED, char *argv[]) { struct istream *input, *input2; const unsigned char *data; size_t size; const char *line; int fd; fd = open(argv[1], O_RDONLY); if (fd < 0) i_fatal("open(%s) failed: %m", argv[1]); input = i_stream_create_fd_autoclose(&fd, 1024*32); while ((line = i_stream_read_next_line(input)) != NULL) { /* skip tag */ printf("%s\r\n", line); while (*line != ' ' && *line != '\0') line++; if (*line == '\0') continue; line++; if (strcmp(line, "OK Begin compression.") == 0 || strcasecmp(line, "COMPRESS DEFLATE") == 0) break; } input2 = i_stream_create_deflate(input, TRUE); i_stream_unref(&input); while (i_stream_read_more(input2, &data, &size) != -1) { fwrite(data, 1, size, stdout); i_stream_skip(input2, size); } i_stream_unref(&input2); fflush(stdout); }
static int imapc_mail_get_hdr_hash(struct index_mail *imail) { struct istream *input; const unsigned char *data; size_t size; uoff_t old_offset; struct sha1_ctxt sha1_ctx; unsigned char sha1_output[SHA1_RESULTLEN]; const char *sha1_str; sha1_init(&sha1_ctx); old_offset = imail->data.stream == NULL ? 0 : imail->data.stream->v_offset; if (mail_get_hdr_stream(&imail->mail.mail, NULL, &input) < 0) return -1; while (i_stream_read_data(input, &data, &size, 0) > 0) { sha1_loop(&sha1_ctx, data, size); i_stream_skip(input, size); } i_stream_seek(imail->data.stream, old_offset); sha1_result(&sha1_ctx, sha1_output); sha1_str = binary_to_hex(sha1_output, sizeof(sha1_output)); imail->data.guid = p_strdup(imail->mail.data_pool, sha1_str); return 0; }
int client_auth_read_line(struct client *client) { const unsigned char *data; size_t i, size; unsigned int len; if (i_stream_read_data(client->input, &data, &size, 0) == -1) { client_destroy(client, "Disconnected"); return -1; } /* see if we have a full line */ for (i = 0; i < size; i++) { if (data[i] == '\n') break; } if (client->auth_response == NULL) client->auth_response = str_new(default_pool, I_MAX(i+1, 256)); if (str_len(client->auth_response) + i > LOGIN_MAX_AUTH_BUF_SIZE) { client_destroy(client, "Authentication response too large"); return -1; } str_append_n(client->auth_response, data, i); i_stream_skip(client->input, i == size ? size : i+1); /* drop trailing \r */ len = str_len(client->auth_response); if (len > 0 && str_c(client->auth_response)[len-1] == '\r') str_truncate(client->auth_response, len-1); return i < size; }
static void script_client_script_input(struct script_client *sclient) { struct istream *input = sclient->script_input; struct ostream *output = sclient->output; const unsigned char *data; size_t size; int ret = 0; if ( input != NULL ) { while ( (ret=i_stream_read_data(input, &data, &size, 0)) > 0 ) { if ( output != NULL ) { ssize_t sent; if ( (sent=o_stream_send(output, data, size)) < 0 ) { script_client_fail(sclient, SCRIPT_CLIENT_ERROR_IO); return; } size = (size_t)sent; } i_stream_skip(input, size); } if ( ret < 0 ) { if ( input->eof ) { script_client_disconnect(sclient, FALSE); return; } script_client_fail(sclient, SCRIPT_CLIENT_ERROR_IO); } } }
int managesieve_parser_read_args (struct managesieve_parser *parser, unsigned int count, enum managesieve_parser_flags flags, const struct managesieve_arg **args_r) { parser->flags = flags; while ( !parser->eol && (count == 0 || IS_UNFINISHED(parser) || array_count(&parser->root_list) < count) ) { if ( !managesieve_parser_read_arg(parser) ) break; if ( parser->line_size > parser->max_line_size ) { parser->error = "MANAGESIEVE command line too large"; break; } } if ( parser->error != NULL ) { /* error, abort */ parser->line_size += parser->cur_pos; i_stream_skip(parser->input, parser->cur_pos); parser->cur_pos = 0; *args_r = NULL; return -1; } else if ( (!IS_UNFINISHED(parser) && count > 0 && array_count(&parser->root_list) >= count) || parser->eol ) { /* all arguments read / end of line. */ return finish_line(parser, count, args_r); } else { /* need more data */ *args_r = NULL; return -2; } }
static void test_ostream_dot_one(const struct dot_test *test) { struct istream *test_input; struct ostream *output, *test_output; buffer_t *output_data; const unsigned char *data; size_t size; ssize_t ret; test_input = test_istream_create(test->input); output_data = buffer_create_dynamic(pool_datastack_create(), 1024); test_output = o_stream_create_buffer(output_data); output = o_stream_create_dot(test_output, FALSE); while ((ret = i_stream_read(test_input)) > 0 || ret == -2) { data = i_stream_get_data(test_input, &size); ret = o_stream_send(output, data, size); test_assert(ret >= 0); if (ret <= 0) break; i_stream_skip(test_input, ret); } test_assert(test_input->eof); test_assert(o_stream_flush(output) > 0); o_stream_unref(&output); o_stream_unref(&test_output); test_assert(strcmp(str_c(output_data), test->output) == 0); i_stream_unref(&test_input); }
static const struct stat * i_stream_bzlib_stat(struct istream_private *stream, bool exact) { struct bzlib_istream *zstream = (struct bzlib_istream *) stream; const struct stat *st; size_t size; st = i_stream_stat(stream->parent, exact); if (st == NULL) return NULL; if (zstream->eof_offset == (uoff_t)-1 && !exact) return st; stream->statbuf = *st; if (zstream->eof_offset == (uoff_t)-1) { uoff_t old_offset = stream->istream.v_offset; do { (void)i_stream_get_data(&stream->istream, &size); i_stream_skip(&stream->istream, size); } while (i_stream_read(&stream->istream) > 0); i_stream_seek(&stream->istream, old_offset); if (zstream->eof_offset == (uoff_t)-1) return NULL; } stream->statbuf.st_size = zstream->eof_offset; return &stream->statbuf; }
static int client_run_url(struct client *client) { const unsigned char *data; size_t size; ssize_t ret = 0; while (i_stream_read_data(client->msg_part_input, &data, &size, 0) > 0) { if ((ret = o_stream_send(client->output, data, size)) < 0) break; i_stream_skip(client->msg_part_input, ret); if (o_stream_get_buffer_used_size(client->output) >= 4096) { if ((ret = o_stream_flush(client->output)) < 0) break; if (ret == 0) return 0; } } if (client->output->closed || ret < 0) { imap_msgpart_url_free(&client->url); return -1; } if (client->msg_part_input->eof) { o_stream_send(client->output, "\n", 1); imap_msgpart_url_free(&client->url); return 1; } return 0; }
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(); }
static int sieve_attribute_set_active_script(struct mail_storage *storage, struct sieve_storage *svstorage, const struct mail_attribute_value *value) { struct istream *input; if (value->value != NULL) { input = i_stream_create_from_data(value->value, strlen(value->value)); } else if (value->value_stream != NULL) { input = value->value_stream; i_stream_ref(input); } else { return sieve_attribute_unset_active_script(storage, svstorage, value->last_change); } /* skip over the 'S' type */ i_stream_skip(input, 1); if (sieve_storage_save_as_active (svstorage, input, value->last_change) < 0) { mail_storage_set_critical(storage, "Failed to save active sieve script: %s", sieve_storage_get_last_error(svstorage, NULL)); i_stream_unref(&input); return -1; } sieve_storage_set_modified(svstorage, value->last_change); i_stream_unref(&input); return 0; }