Mercurial > dovecot > original-hg > dovecot-1.2
changeset 764:f57c52738f90 HEAD
Renamed IBuffer and OBuffer to IStream and OStream which describes their
functionality better. I tried to keep the variable names and comments also
sensible.
line wrap: on
line diff
--- a/src/auth/login-connection.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/auth/login-connection.c Fri Dec 06 03:09:22 2002 +0200 @@ -2,8 +2,8 @@ #include "common.h" #include "ioloop.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "network.h" #include "login-connection.h" @@ -20,8 +20,8 @@ int fd; IO io; - IBuffer *inbuf; - OBuffer *outbuf; + IStream *input; + OStream *output; AuthRequestType type; }; @@ -35,10 +35,10 @@ i_assert(reply->data_size <= AUTH_MAX_REPLY_DATA_SIZE); - if (o_buffer_send(conn->outbuf, reply, sizeof(AuthReplyData)) < 0) + if (o_stream_send(conn->output, reply, sizeof(AuthReplyData)) < 0) login_connection_destroy(conn); else if (reply->data_size > 0) { - if (o_buffer_send(conn->outbuf, data, reply->data_size) < 0) + if (o_stream_send(conn->output, data, reply->data_size) < 0) login_connection_destroy(conn); } } @@ -50,7 +50,7 @@ unsigned char *data; size_t size; - switch (i_buffer_read(conn->inbuf)) { + switch (i_stream_read(conn->input)) { case 0: return; case -1: @@ -65,7 +65,7 @@ return; } - data = i_buffer_get_modifyable_data(conn->inbuf, &size); + data = i_stream_get_modifyable_data(conn->input, &size); if (size < sizeof(AuthRequestType)) return; @@ -83,7 +83,7 @@ return; memcpy(&request, data, sizeof(request)); - i_buffer_skip(conn->inbuf, sizeof(request)); + i_stream_skip(conn->input, sizeof(request)); /* we have a full init request */ auth_init_request(&request, request_callback, conn); @@ -98,7 +98,7 @@ if (size < sizeof(request) + request.data_size) return; - i_buffer_skip(conn->inbuf, sizeof(request) + request.data_size); + i_stream_skip(conn->input, sizeof(request) + request.data_size); /* we have a full continued request */ auth_continue_request(&request, data + sizeof(request), @@ -122,9 +122,9 @@ conn = i_new(LoginConnection, 1); conn->fd = fd; - conn->inbuf = i_buffer_create_file(fd, default_pool, MAX_INBUF_SIZE, + conn->input = i_stream_create_file(fd, default_pool, MAX_INBUF_SIZE, FALSE); - conn->outbuf = o_buffer_create_file(fd, default_pool, MAX_OUTBUF_SIZE, + conn->output = o_stream_create_file(fd, default_pool, MAX_OUTBUF_SIZE, IO_PRIORITY_DEFAULT, FALSE); conn->io = io_add(fd, IO_READ, login_input, conn); conn->type = AUTH_REQUEST_NONE; @@ -132,7 +132,7 @@ conn->next = connections; connections = conn; - if (o_buffer_send(conn->outbuf, &auth_init_data, + if (o_stream_send(conn->output, &auth_init_data, sizeof(auth_init_data)) < 0) { login_connection_destroy(conn); conn = NULL; @@ -152,8 +152,8 @@ } } - i_buffer_unref(conn->inbuf); - o_buffer_unref(conn->outbuf); + i_stream_unref(conn->input); + o_stream_unref(conn->output); io_remove(conn->io); net_disconnect(conn->fd);
--- a/src/auth/master.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/auth/master.c Fri Dec 06 03:09:22 2002 +0200 @@ -2,7 +2,7 @@ #include "common.h" #include "ioloop.h" -#include "obuffer.h" +#include "ostream.h" #include "network.h" #include "cookie.h" #include "master.h" @@ -11,7 +11,7 @@ static AuthCookieReplyData failure_reply; -static OBuffer *outbuf; +static OStream *output; static IO io_master; static unsigned int master_pos; @@ -35,7 +35,7 @@ } reply->id = request->id; - switch (o_buffer_send(outbuf, reply, sizeof(AuthCookieReplyData))) { + switch (o_stream_send(output, reply, sizeof(AuthCookieReplyData))) { case -2: i_fatal("Master transmit buffer full, aborting"); case -1: @@ -72,7 +72,7 @@ memset(&failure_reply, 0, sizeof(failure_reply)); master_pos = 0; - outbuf = o_buffer_create_file(MASTER_SOCKET_FD, default_pool, + output = o_stream_create_file(MASTER_SOCKET_FD, default_pool, MAX_OUTBUF_SIZE, IO_PRIORITY_DEFAULT, FALSE); io_master = io_add(MASTER_SOCKET_FD, IO_READ, master_input, NULL); @@ -80,6 +80,6 @@ void master_deinit(void) { - o_buffer_unref(outbuf); + o_stream_unref(output); io_remove(io_master); }
--- a/src/auth/userinfo-passwd-file.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/auth/userinfo-passwd-file.c Fri Dec 06 03:09:22 2002 +0200 @@ -7,7 +7,7 @@ #include "userinfo-passwd.h" -#include "ibuffer.h" +#include "istream.h" #include "hash.h" #include "hex-binary.h" #include "md5.h" @@ -295,15 +295,15 @@ static void passwd_file_parse_file(PasswdFile *pw) { - IBuffer *inbuf; + IStream *input; char *const *args; char *line; - inbuf = i_buffer_create_file(pw->fd, default_pool, 2048, FALSE); + input = i_stream_create_file(pw->fd, default_pool, 2048, FALSE); for (;;) { - line = i_buffer_next_line(inbuf); + line = i_stream_next_line(input); if (line == NULL) { - if (i_buffer_read(inbuf) <= 0) + if (i_stream_read(input) <= 0) break; continue; } @@ -319,7 +319,7 @@ } t_pop(); } - i_buffer_unref(inbuf); + i_stream_unref(input); } static PasswdFile *passwd_file_parse(const char *path)
--- a/src/imap/client.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/imap/client.c Fri Dec 06 03:09:22 2002 +0200 @@ -3,8 +3,8 @@ #include "common.h" #include "ioloop.h" #include "network.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "commands.h" #include <stdlib.h> @@ -36,8 +36,8 @@ { Client *client = context; - i_buffer_close(client->inbuf); - o_buffer_close(client->outbuf); + i_stream_close(client->input); + o_stream_close(client->output); } static void client_input_timeout(void *context) @@ -46,7 +46,7 @@ client_send_line(my_client, "* BYE Disconnected for inactivity " "while waiting for command data."); - o_buffer_close(client->outbuf); + o_stream_close(client->output); } Client *client_create(int hin, int hout, MailStorage *storage) @@ -54,9 +54,9 @@ Client *client; client = i_new(Client, 1); - client->inbuf = i_buffer_create_file(hin, default_pool, + client->input = i_stream_create_file(hin, default_pool, MAX_INBUF_SIZE, FALSE); - client->outbuf = o_buffer_create_file(hout, default_pool, 4096, + client->output = o_stream_create_file(hout, default_pool, 4096, IO_PRIORITY_DEFAULT, FALSE); /* always use nonblocking I/O */ @@ -65,15 +65,15 @@ /* set timeout for reading expected data (eg. APPEND). This is different from the actual idle time. */ - i_buffer_set_blocking(client->inbuf, CLIENT_CMDINPUT_TIMEOUT, + i_stream_set_blocking(client->input, CLIENT_CMDINPUT_TIMEOUT, client_input_timeout, client); /* set timeout for sending data */ - o_buffer_set_blocking(client->outbuf, CLIENT_OUTPUT_TIMEOUT, + o_stream_set_blocking(client->output, CLIENT_OUTPUT_TIMEOUT, client_output_timeout, client); client->io = io_add(hin, IO_READ, (IOFunc) client_input, client); - client->parser = imap_parser_create(client->inbuf, client->outbuf, + client->parser = imap_parser_create(client->input, client->output, MAX_INBUF_SIZE); client->last_input = ioloop_time; @@ -87,7 +87,7 @@ void client_destroy(Client *client) { - o_buffer_flush(client->outbuf); + o_stream_flush(client->output); if (client->mailbox != NULL) client->mailbox->close(client->mailbox); @@ -96,8 +96,8 @@ imap_parser_destroy(client->parser); io_remove(client->io); - i_buffer_unref(client->inbuf); - o_buffer_unref(client->outbuf); + i_stream_unref(client->input); + o_stream_unref(client->output); i_free(client); @@ -108,35 +108,35 @@ void client_disconnect(Client *client) { - o_buffer_flush(client->outbuf); + o_stream_flush(client->output); - i_buffer_close(client->inbuf); - o_buffer_close(client->outbuf); + i_stream_close(client->input); + o_stream_close(client->output); } void client_send_line(Client *client, const char *data) { - if (client->outbuf->closed) + if (client->output->closed) return; - (void)o_buffer_send(client->outbuf, data, strlen(data)); - (void)o_buffer_send(client->outbuf, "\r\n", 2); + (void)o_stream_send(client->output, data, strlen(data)); + (void)o_stream_send(client->output, "\r\n", 2); } void client_send_tagline(Client *client, const char *data) { const char *tag = client->cmd_tag; - if (client->outbuf->closed) + if (client->output->closed) return; if (tag == NULL || *tag == '\0') tag = "*"; - (void)o_buffer_send(client->outbuf, tag, strlen(tag)); - (void)o_buffer_send(client->outbuf, " ", 1); - (void)o_buffer_send(client->outbuf, data, strlen(data)); - (void)o_buffer_send(client->outbuf, "\r\n", 2); + (void)o_stream_send(client->output, tag, strlen(tag)); + (void)o_stream_send(client->output, " ", 1); + (void)o_stream_send(client->output, data, strlen(data)); + (void)o_stream_send(client->output, "\r\n", 2); } void client_send_command_error(Client *client, const char *msg) @@ -220,7 +220,7 @@ static void client_command_finished(Client *client) { - client->inbuf_skip_line = TRUE; + client->input_skip_line = TRUE; client_reset_command(client); } @@ -231,18 +231,17 @@ const unsigned char *data; size_t i, data_size; - /* get the beginning of data in input buffer */ - data = i_buffer_get_data(client->inbuf, &data_size); + data = i_stream_get_data(client->input, &data_size); for (i = 0; i < data_size; i++) { if (data[i] == '\n') { - client->inbuf_skip_line = FALSE; - i_buffer_skip(client->inbuf, i+1); + client->input_skip_line = FALSE; + i_stream_skip(client->input, i+1); break; } } - return !client->inbuf_skip_line; + return !client->input_skip_line; } static int client_handle_input(Client *client) @@ -257,7 +256,7 @@ return FALSE; } - if (client->inbuf_skip_line) { + if (client->input_skip_line) { /* we're just waiting for new line.. */ if (!client_skip_line(client)) return FALSE; @@ -306,7 +305,7 @@ { client->last_input = ioloop_time; - switch (i_buffer_read(client->inbuf)) { + switch (i_stream_read(client->input)) { case -1: /* disconnected */ client_destroy(client); @@ -315,19 +314,19 @@ /* parameter word is longer than max. input buffer size. this is most likely an error, so skip the new data until newline is found. */ - client->inbuf_skip_line = TRUE; + client->input_skip_line = TRUE; client_send_command_error(client, "Too long argument."); client_command_finished(client); break; } - o_buffer_cork(client->outbuf); + o_stream_cork(client->output); while (client_handle_input(client)) ; - o_buffer_flush(client->outbuf); + o_stream_flush(client->output); - if (client->outbuf->closed) + if (client->output->closed) client_destroy(client); }
--- a/src/imap/client.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/imap/client.h Fri Dec 06 03:09:22 2002 +0200 @@ -11,8 +11,8 @@ struct _Client { int socket; IO io; - IBuffer *inbuf; - OBuffer *outbuf; + IStream *input; + OStream *output; MailStorage *storage; Mailbox *mailbox; @@ -29,7 +29,7 @@ unsigned int cmd_uid:1; /* used UID command */ unsigned int sync_flags_send_uid:1; unsigned int rawlog:1; - unsigned int inbuf_skip_line:1; /* skip all the data until we've + unsigned int input_skip_line:1; /* skip all the data until we've found a new line */ };
--- a/src/imap/cmd-append.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/imap/cmd-append.c Fri Dec 06 03:09:22 2002 +0200 @@ -2,7 +2,7 @@ #include "common.h" #include "ioloop.h" -#include "obuffer.h" +#include "ostream.h" #include "commands.h" #include "imap-parser.h" #include "imap-date.h" @@ -126,13 +126,13 @@ return TRUE; } - o_buffer_send(client->outbuf, "+ OK\r\n", 6); - o_buffer_flush(client->outbuf); + o_stream_send(client->output, "+ OK\r\n", 6); + o_stream_flush(client->output); /* save the mail */ failed = !box->save(box, flags, custom_flags, internal_date, timezone_offset, - client->inbuf, msg_size); + client->input, msg_size); box->close(box); if (failed) {
--- a/src/imap/cmd-fetch.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/imap/cmd-fetch.c Fri Dec 06 03:09:22 2002 +0200 @@ -264,7 +264,7 @@ /* fetch it */ if (client->mailbox->fetch(client->mailbox, &data, - client->outbuf, &all_found)) { + client->output, &all_found)) { /* NOTE: syncing isn't allowed here */ client_sync_without_expunges(client); client_send_tagline(client, all_found ? "OK Fetch completed." :
--- a/src/imap/cmd-search.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/imap/cmd-search.c Fri Dec 06 03:09:22 2002 +0200 @@ -51,7 +51,7 @@ } else { if (client->mailbox->search(client->mailbox, charset, sargs, NULL, - client->outbuf, client->cmd_uid)) { + client->output, client->cmd_uid)) { /* NOTE: syncing isn't allowed here */ client_sync_without_expunges(client); client_send_tagline(client, "OK Search completed.");
--- a/src/imap/cmd-sort.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/imap/cmd-sort.c Fri Dec 06 03:09:22 2002 +0200 @@ -120,7 +120,7 @@ } else { if (client->mailbox->search(client->mailbox, charset, sargs, sorting, - client->outbuf, client->cmd_uid)) { + client->output, client->cmd_uid)) { /* NOTE: syncing is allowed when returning UIDs */ if (client->cmd_uid) client_sync_full(client);
--- a/src/imap/mail-storage-callbacks.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/imap/mail-storage-callbacks.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "common.h" -#include "obuffer.h" +#include "ostream.h" #include "imap-util.h" #include "commands-util.h" @@ -19,7 +19,7 @@ Client *client = context; client_send_line(client, t_strconcat("* OK ", text, NULL)); - o_buffer_flush(client->outbuf); + o_stream_flush(client->output); } static void notify_no(Mailbox *mailbox __attr_unused__, @@ -28,7 +28,7 @@ Client *client = context; client_send_line(client, t_strconcat("* NO ", text, NULL)); - o_buffer_flush(client->outbuf); + o_stream_flush(client->output); } static void expunge(Mailbox *mailbox, unsigned int seq, void *context)
--- a/src/lib-imap/imap-bodystructure.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-imap/imap-bodystructure.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "temp-string.h" #include "rfc822-tokenize.h" #include "message-parser.h" @@ -220,20 +220,20 @@ t_pop(); } -static void part_parse_headers(MessagePart *part, IBuffer *inbuf, +static void part_parse_headers(MessagePart *part, IStream *input, uoff_t start_offset, Pool pool) { while (part != NULL) { /* note that we want to parse the header of all the message parts, multiparts too. */ - i_assert(part->physical_pos >= inbuf->v_offset - start_offset); - i_buffer_skip(inbuf, part->physical_pos - - (inbuf->v_offset - start_offset)); + i_assert(part->physical_pos >= input->v_offset - start_offset); + i_stream_skip(input, part->physical_pos - + (input->v_offset - start_offset)); - message_parse_header(part, inbuf, NULL, parse_header, pool); + message_parse_header(part, input, NULL, parse_header, pool); if (part->children != NULL) { - part_parse_headers(part->children, inbuf, + part_parse_headers(part->children, input, start_offset, pool); } @@ -426,15 +426,15 @@ } const char *imap_part_get_bodystructure(Pool pool, MessagePart **part, - IBuffer *inbuf, int extended) + IStream *input, int extended) { uoff_t start_offset; if (*part == NULL) - *part = message_parse(pool, inbuf, parse_header, pool); + *part = message_parse(pool, input, parse_header, pool); else { - start_offset = inbuf->v_offset; - part_parse_headers(*part, inbuf, start_offset, pool); + start_offset = input->v_offset; + part_parse_headers(*part, input, start_offset, pool); } return part_get_bodystructure(*part, extended); @@ -584,7 +584,7 @@ const char *imap_body_parse_from_bodystructure(const char *bodystructure) { - IBuffer *inbuf; + IStream *input; ImapParser *parser; ImapArg *args; TempString *str; @@ -595,10 +595,10 @@ len = strlen(bodystructure); str = t_string_new(len); - inbuf = i_buffer_create_from_data(data_stack_pool, bodystructure, len); - (void)i_buffer_read(inbuf); + input = i_stream_create_from_data(data_stack_pool, bodystructure, len); + (void)i_stream_read(input); - parser = imap_parser_create(inbuf, NULL, 0); + parser = imap_parser_create(input, NULL, 0); ret = imap_parser_read_args(parser, 0, IMAP_PARSE_FLAG_NO_UNESCAPE, &args); @@ -611,6 +611,6 @@ i_error("Error parsing IMAP bodystructure: %s", bodystructure); imap_parser_destroy(parser); - i_buffer_unref(inbuf); + i_stream_unref(input); return value; }
--- a/src/lib-imap/imap-bodystructure.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-imap/imap-bodystructure.h Fri Dec 06 03:09:22 2002 +0200 @@ -4,7 +4,7 @@ /* If *part is non-NULL, it's used as base for building the body structure. Otherwise it's set to the root MessagePart and parsed. */ const char *imap_part_get_bodystructure(Pool pool, MessagePart **part, - IBuffer *inbuf, int extended); + IStream *input, int extended); /* Return BODY part from BODYSTRUCTURE */ const char *imap_body_parse_from_bodystructure(const char *bodystructure);
--- a/src/lib-imap/imap-envelope.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-imap/imap-envelope.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "temp-string.h" #include "rfc822-address.h" #include "imap-parser.h" @@ -236,7 +236,7 @@ const char *imap_envelope_parse(const char *envelope, ImapEnvelopeField field) { - IBuffer *inbuf; + IStream *input; ImapParser *parser; ImapArg *args; const char *value; @@ -244,11 +244,11 @@ i_assert(field < IMAP_ENVELOPE_FIELDS); - inbuf = i_buffer_create_from_data(data_stack_pool, envelope, + input = i_stream_create_from_data(data_stack_pool, envelope, strlen(envelope)); - parser = imap_parser_create(inbuf, NULL, 0); + parser = imap_parser_create(input, NULL, 0); - (void)i_buffer_read(inbuf); + (void)i_stream_read(input); ret = imap_parser_read_args(parser, field+1, 0, &args); if (ret > (int)field) { value = imap_envelope_parse_arg(&args[field], field, envelope); @@ -258,6 +258,6 @@ } imap_parser_destroy(parser); - i_buffer_unref(inbuf); + i_stream_unref(input); return value; }
--- a/src/lib-imap/imap-message-cache.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-imap/imap-message-cache.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "temp-string.h" #include "mmap-util.h" #include "message-parser.h" @@ -50,7 +50,7 @@ int messages_count; CachedMessage *open_msg; - IBuffer *open_inbuf; + IStream *open_stream; void *context; }; @@ -161,23 +161,24 @@ } } -static int imap_msgcache_get_inbuf(ImapMessageCache *cache, uoff_t offset) +static int imap_msgcache_get_stream(ImapMessageCache *cache, uoff_t offset) { - if (cache->open_inbuf == NULL) - cache->open_inbuf = cache->iface->open_mail(cache->context); - else if (offset < cache->open_inbuf->v_offset) { + if (cache->open_stream == NULL) + cache->open_stream = cache->iface->open_mail(cache->context); + else if (offset < cache->open_stream->v_offset) { /* need to rewind */ - cache->open_inbuf = - cache->iface->inbuf_rewind(cache->open_inbuf, - cache->context); + cache->open_stream = + cache->iface->stream_rewind(cache->open_stream, + cache->context); } - if (cache->open_inbuf == NULL) + if (cache->open_stream == NULL) return FALSE; - i_assert(offset >= cache->open_inbuf->v_offset); + i_assert(offset >= cache->open_stream->v_offset); - i_buffer_skip(cache->open_inbuf, offset - cache->open_inbuf->v_offset); + i_stream_skip(cache->open_stream, + offset - cache->open_stream->v_offset); return TRUE; } @@ -206,12 +207,12 @@ msg->cached_bodystructure == NULL) { value = cache->iface->get_cached_field(IMAP_CACHE_BODYSTRUCTURE, cache->context); - if (value == NULL && imap_msgcache_get_inbuf(cache, 0)) { + if (value == NULL && imap_msgcache_get_stream(cache, 0)) { msg_get_part(cache); value = imap_part_get_bodystructure(msg->pool, &msg->part, - cache->open_inbuf, + cache->open_stream, TRUE); } @@ -222,7 +223,7 @@ if ((fields & IMAP_CACHE_BODY) && msg->cached_body == NULL) { value = cache->iface->get_cached_field(IMAP_CACHE_BODY, cache->context); - if (value == NULL && cache->open_inbuf != NULL) { + if (value == NULL && cache->open_stream != NULL) { /* we can generate it from cached BODYSTRUCTURE. do it only if the file isn't open already, since this takes more CPU than parsing message headers. */ @@ -234,12 +235,12 @@ } } - if (value == NULL && imap_msgcache_get_inbuf(cache, 0)) { + if (value == NULL && imap_msgcache_get_stream(cache, 0)) { msg_get_part(cache); value = imap_part_get_bodystructure(msg->pool, &msg->part, - cache->open_inbuf, + cache->open_stream, FALSE); } @@ -252,7 +253,7 @@ cache->context); if (value == NULL) { if (msg->envelope == NULL && - imap_msgcache_get_inbuf(cache, 0)) { + imap_msgcache_get_stream(cache, 0)) { /* envelope isn't parsed yet, do it. header size is calculated anyway so save it */ if (msg->hdr_size == NULL) { @@ -260,7 +261,7 @@ MessageSize, 1); } - message_parse_header(NULL, cache->open_inbuf, + message_parse_header(NULL, cache->open_stream, msg->hdr_size, parse_envelope_header, msg); @@ -290,7 +291,7 @@ if (fields & IMAP_CACHE_MESSAGE_PART) { msg_get_part(cache); - if (msg->part == NULL && imap_msgcache_get_inbuf(cache, 0)) { + if (msg->part == NULL && imap_msgcache_get_stream(cache, 0)) { /* we need to parse the message */ MessageHeaderFunc func; @@ -303,7 +304,7 @@ func = NULL; } - msg->part = message_parse(msg->pool, cache->open_inbuf, + msg->part = message_parse(msg->pool, cache->open_stream, func, msg); } else { failed = TRUE; @@ -336,8 +337,8 @@ } } else { /* need to do some light parsing */ - if (imap_msgcache_get_inbuf(cache, 0)) { - message_get_header_size(cache->open_inbuf, + if (imap_msgcache_get_stream(cache, 0)) { + message_get_header_size(cache->open_stream, msg->hdr_size); } else { failed = TRUE; @@ -358,7 +359,7 @@ if (fields & IMAP_CACHE_MESSAGE_OPEN) { /* this isn't needed for anything else than pre-opening the mail and seeing if it fails. */ - failed = !imap_msgcache_get_inbuf(cache, 0); + failed = !imap_msgcache_get_stream(cache, 0); } if ((fields & IMAP_CACHE_INTERNALDATE) && @@ -410,9 +411,9 @@ void imap_msgcache_close(ImapMessageCache *cache) { - if (cache->open_inbuf != NULL) { - i_buffer_unref(cache->open_inbuf); - cache->open_inbuf = NULL; + if (cache->open_stream != NULL) { + i_stream_unref(cache->open_stream); + cache->open_stream = NULL; } cache->open_msg = NULL; @@ -467,7 +468,7 @@ return cache->open_msg->internal_date; } -int imap_msgcache_get_rfc822(ImapMessageCache *cache, IBuffer **inbuf, +int imap_msgcache_get_rfc822(ImapMessageCache *cache, IStream **stream, MessageSize *hdr_size, MessageSize *body_size) { CachedMessage *msg; @@ -476,14 +477,14 @@ i_assert(cache->open_msg != NULL); msg = cache->open_msg; - if (inbuf != NULL) { + if (stream != NULL) { if (msg->hdr_size == NULL) cache_fields(cache, IMAP_CACHE_MESSAGE_HDR_SIZE); offset = hdr_size != NULL ? 0 : msg->hdr_size->physical_size; - if (!imap_msgcache_get_inbuf(cache, offset)) + if (!imap_msgcache_get_stream(cache, offset)) return FALSE; - *inbuf = cache->open_inbuf; + *stream = cache->open_stream; } if (body_size != NULL) { @@ -505,7 +506,7 @@ return TRUE; } -static void get_partial_size(IBuffer *inbuf, +static void get_partial_size(IStream *stream, uoff_t virtual_skip, uoff_t max_virtual_size, MessageSize *partial, MessageSize *dest, int *cr_skipped) @@ -514,12 +515,12 @@ if (partial->virtual_size > virtual_skip) memset(partial, 0, sizeof(MessageSize)); else { - i_buffer_skip(inbuf, partial->physical_size); + i_stream_skip(stream, partial->physical_size); virtual_skip -= partial->virtual_size; } - message_skip_virtual(inbuf, virtual_skip, partial, cr_skipped); - message_get_body_size(inbuf, dest, max_virtual_size); + message_skip_virtual(stream, virtual_skip, partial, cr_skipped); + message_get_body_size(stream, dest, max_virtual_size); if (*cr_skipped) { dest->virtual_size--; @@ -531,7 +532,7 @@ uoff_t virtual_skip, uoff_t max_virtual_size, int get_header, MessageSize *size, - IBuffer **inbuf, int *cr_skipped) + IStream **stream, int *cr_skipped) { CachedMessage *msg; uoff_t physical_skip, full_size; @@ -540,7 +541,7 @@ i_assert(cache->open_msg != NULL); memset(size, 0, sizeof(MessageSize)); - *inbuf = NULL; + *stream = NULL; *cr_skipped = FALSE; msg = cache->open_msg; @@ -575,7 +576,7 @@ if (size_got) { physical_skip = get_header ? 0 : msg->hdr_size->physical_size; } else { - if (!imap_msgcache_get_inbuf(cache, 0)) + if (!imap_msgcache_get_stream(cache, 0)) return FALSE; if (msg->partial_size == NULL) @@ -583,7 +584,7 @@ if (!get_header) virtual_skip += msg->hdr_size->virtual_size; - get_partial_size(cache->open_inbuf, virtual_skip, + get_partial_size(cache->open_stream, virtual_skip, max_virtual_size, msg->partial_size, size, cr_skipped); @@ -591,20 +592,20 @@ } /* seek to wanted position */ - if (!imap_msgcache_get_inbuf(cache, physical_skip)) + if (!imap_msgcache_get_stream(cache, physical_skip)) return FALSE; - *inbuf = cache->open_inbuf; + *stream = cache->open_stream; return TRUE; } -int imap_msgcache_get_data(ImapMessageCache *cache, IBuffer **inbuf) +int imap_msgcache_get_data(ImapMessageCache *cache, IStream **stream) { i_assert(cache->open_msg != NULL); - if (!imap_msgcache_get_inbuf(cache, 0)) + if (!imap_msgcache_get_stream(cache, 0)) return FALSE; - *inbuf = cache->open_inbuf; + *stream = cache->open_stream; return TRUE; }
--- a/src/lib-imap/imap-message-cache.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-imap/imap-message-cache.h Fri Dec 06 03:09:22 2002 +0200 @@ -26,10 +26,10 @@ typedef struct { /* Open mail for reading. */ - IBuffer *(*open_mail)(void *context); - /* Rewind input buffer to beginning, possibly closing the old buffer + IStream *(*open_mail)(void *context); + /* Rewind stream to beginning, possibly closing the old stream if it can't directly be rewinded. */ - IBuffer *(*inbuf_rewind)(IBuffer *inbuf, void *context); + IStream *(*stream_rewind)(IStream *stream, void *context); /* Returns field if it's already cached, or NULL. */ const char *(*get_cached_field)(ImapCacheField field, void *context); @@ -56,7 +56,7 @@ uoff_t vp_header_size, uoff_t vp_body_size, uoff_t full_virtual_size, void *context); -/* Close the IOBuffer for opened message. */ +/* Close the IOStream for opened message. */ void imap_msgcache_close(ImapMessageCache *cache); /* Returns the field from cache, or NULL if it's not cached. */ @@ -71,23 +71,23 @@ /* Returns the internal date of message, or (time_t)-1 if failed. */ time_t imap_msgcache_get_internal_date(ImapMessageCache *cache); -/* Returns TRUE if successful. If inbuf is not NULL, it's set to point to +/* Returns TRUE if successful. If stream is not NULL, it's set to point to beginning of message, or to beginning of message body if hdr_size is NULL. */ -int imap_msgcache_get_rfc822(ImapMessageCache *cache, IBuffer **inbuf, +int imap_msgcache_get_rfc822(ImapMessageCache *cache, IStream **stream, MessageSize *hdr_size, MessageSize *body_size); -/* Returns TRUE if successful. *inbuf is set to point to the first non-skipped +/* Returns TRUE if successful. *stream is set to point to the first non-skipped character. size is set to specify the actual message size in virtual_skip..max_virtual_size range. cr_skipped is set to TRUE if first - character in inbuf is LF, and we should NOT treat it as CR+LF. */ + character in stream is LF, and we should NOT treat it as CR+LF. */ int imap_msgcache_get_rfc822_partial(ImapMessageCache *cache, uoff_t virtual_skip, uoff_t max_virtual_size, int get_header, MessageSize *size, - IBuffer **inbuf, int *cr_skipped); + IStream **stream, int *cr_skipped); -/* Returns TRUE if successful. *inbuf is set to point to beginning of +/* Returns TRUE if successful. *stream is set to point to beginning of message. */ -int imap_msgcache_get_data(ImapMessageCache *cache, IBuffer **inbuf); +int imap_msgcache_get_data(ImapMessageCache *cache, IStream **stream); #endif
--- a/src/lib-imap/imap-parser.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-imap/imap-parser.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,8 +1,8 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "imap-parser.h" #define is_linebreak(c) \ @@ -21,8 +21,8 @@ struct _ImapParser { /* permanent */ Pool pool; - IBuffer *inbuf; - OBuffer *outbuf; + IStream *input; + OStream *output; size_t max_literal_size; ImapParserFlags flags; @@ -58,15 +58,15 @@ parser->list_arg->data.list = parser->cur_list; } -ImapParser *imap_parser_create(IBuffer *inbuf, OBuffer *outbuf, +ImapParser *imap_parser_create(IStream *input, OStream *output, size_t max_literal_size) { ImapParser *parser; parser = i_new(ImapParser, 1); parser->pool = pool_create("IMAP parser", 8192, FALSE); - parser->inbuf = inbuf; - parser->outbuf = outbuf; + parser->input = input; + parser->output = output; parser->max_literal_size = max_literal_size; imap_args_realloc(parser, LIST_ALLOC_SIZE); @@ -112,7 +112,7 @@ break; } - i_buffer_skip(parser->inbuf, i); + i_stream_skip(parser->input, i); parser->cur_pos = 0; *data += i; @@ -311,9 +311,9 @@ return FALSE; } - if (parser->outbuf != NULL) { - o_buffer_send(parser->outbuf, "+ OK\r\n", 6); - o_buffer_flush(parser->outbuf); + if (parser->output != NULL) { + o_stream_send(parser->output, "+ OK\r\n", 6); + o_stream_flush(parser->output); } } @@ -332,7 +332,7 @@ /* expecting digits + "}" */ for (i = parser->cur_pos; i < data_size; i++) { if (data[i] == '}') { - i_buffer_skip(parser->inbuf, i+1); + i_stream_skip(parser->input, i+1); return imap_parser_literal_end(parser); } @@ -365,7 +365,7 @@ if (*data == '\r') { data++; data_size--; - i_buffer_skip(parser->inbuf, 1); + i_stream_skip(parser->input, 1); if (data_size == 0) return FALSE; @@ -377,7 +377,7 @@ } data++; data_size--; - i_buffer_skip(parser->inbuf, 1); + i_stream_skip(parser->input, 1); parser->literal_skip_crlf = FALSE; i_assert(parser->cur_pos == 0); @@ -407,7 +407,7 @@ const char *data; size_t data_size; - data = (const char *) i_buffer_get_data(parser->inbuf, &data_size); + data = (const char *) i_stream_get_data(parser->input, &data_size); if (data_size == 0) return FALSE; @@ -468,9 +468,9 @@ if (!imap_parser_read_literal(parser, data, data_size)) return FALSE; - /* pass through to parsing data. since inbuf->skip was + /* pass through to parsing data. since input->skip was modified, we need to get the data start position again. */ - data = (const char *) i_buffer_get_data(parser->inbuf, + data = (const char *) i_stream_get_data(parser->input, &data_size); /* fall through */ @@ -534,8 +534,7 @@ const char *data; size_t i, data_size; - /* get the beginning of data in input buffer */ - data = (const char *) i_buffer_get_data(parser->inbuf, &data_size); + data = (const char *) i_stream_get_data(parser->input, &data_size); for (i = 0; i < data_size; i++) { if (data[i] == ' ' || data[i] == '\r' || data[i] == '\n') @@ -543,7 +542,7 @@ } if (i < data_size) { - i_buffer_skip(parser->inbuf, i + (data[i] == ' ' ? 1 : 0)); + i_stream_skip(parser->input, i + (data[i] == ' ' ? 1 : 0)); return p_strndup(parser->pool, data, i); } else { return NULL; @@ -555,8 +554,7 @@ const char *data; size_t i, data_size; - /* get the beginning of data in input buffer */ - data = (const char *) i_buffer_get_data(parser->inbuf, &data_size); + data = (const char *) i_stream_get_data(parser->input, &data_size); for (i = 0; i < data_size; i++) { if (data[i] == '\r' || data[i] == '\n') @@ -564,7 +562,7 @@ } if (i < data_size) { - i_buffer_skip(parser->inbuf, i); + i_stream_skip(parser->input, i); return p_strndup(parser->pool, data, i); } else { return NULL;
--- a/src/lib-imap/imap-parser.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-imap/imap-parser.h Fri Dec 06 03:09:22 2002 +0200 @@ -41,18 +41,18 @@ ImapArg args[1]; /* variable size */ }; -/* Create new IMAP argument parser. The max. size of inbuf limits the +/* Create new IMAP argument parser. The max. size of input limits the maximum size of each argument. max_literal_size also limits sizes of literals which we even try to handle if FLAG_LITERAL_SIZE is not set. - outbuf is used for sending command continuation requests for literals. */ -ImapParser *imap_parser_create(IBuffer *inbuf, OBuffer *outbuf, + output is used for sending command continuation requests for literals. */ +ImapParser *imap_parser_create(IStream *input, OStream *output, size_t max_literal_size); void imap_parser_destroy(ImapParser *parser); /* Reset the parser to initial state. */ void imap_parser_reset(ImapParser *parser); -/* Read a number of arguments. This function doesn't call i_buffer_read(), you +/* Read a number of arguments. This function doesn't call i_stream_read(), you need to do that. Returns number of arguments read (may be less than count in case of EOL), -2 if more data is needed or -1 if error occured.
--- a/src/lib-index/mail-index-update-cache.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mail-index-update-cache.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "mail-index.h" #include <unistd.h> @@ -10,12 +10,12 @@ MailDataField cache_fields) { MailIndexUpdate *update; - IBuffer *inbuf; + IStream *input; time_t internal_date; int failed, deleted; - inbuf = index->open_mail(index, rec, &internal_date, &deleted); - if (inbuf == NULL) + input = index->open_mail(index, rec, &internal_date, &deleted); + if (input == NULL) return deleted; cache_fields &= ~rec->data_fields; @@ -23,10 +23,10 @@ update = index->update_begin(index, rec); index->update_field_raw(update, DATA_HDR_INTERNAL_DATE, &internal_date, sizeof(internal_date)); - mail_index_update_headers(update, inbuf, cache_fields, NULL, NULL); + mail_index_update_headers(update, input, cache_fields, NULL, NULL); failed = !index->update_end(update); - i_buffer_unref(inbuf); + i_stream_unref(input); return !failed; }
--- a/src/lib-index/mail-index-update.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mail-index-update.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "ioloop.h" #include "rfc822-date.h" #include "rfc822-tokenize.h" @@ -410,7 +410,7 @@ } } -void mail_index_update_headers(MailIndexUpdate *update, IBuffer *inbuf, +void mail_index_update_headers(MailIndexUpdate *update, IStream *input, MailDataField cache_fields, MessageHeaderFunc header_func, void *context) { @@ -452,16 +452,16 @@ } } - start_offset = inbuf->v_offset; + start_offset = input->v_offset; if (part == NULL) { - part = message_parse(pool, inbuf, + part = message_parse(pool, input, update_header_func, &ctx); } else { /* cached, construct the bodystructure using it. also we need to parse the header.. */ - i_buffer_seek(inbuf, start_offset); - message_parse_header(NULL, inbuf, NULL, + i_stream_seek(input, start_offset); + message_parse_header(NULL, input, NULL, update_header_func, &ctx); } @@ -476,9 +476,9 @@ ((update->rec->data_fields | cache_fields) & DATA_FIELD_BODYSTRUCTURE) == 0) { t_push(); - i_buffer_seek(inbuf, start_offset); + i_stream_seek(input, start_offset); value = imap_part_get_bodystructure(pool, &part, - inbuf, FALSE); + input, FALSE); update->index->update_field(update, DATA_FIELD_BODY, value, 0); t_pop(); @@ -486,9 +486,9 @@ if (cache_fields & DATA_FIELD_BODYSTRUCTURE) { t_push(); - i_buffer_seek(inbuf, start_offset); + i_stream_seek(input, start_offset); value = imap_part_get_bodystructure(pool, &part, - inbuf, TRUE); + input, TRUE); update->index->update_field(update, DATA_FIELD_BODYSTRUCTURE, value, 0); @@ -506,10 +506,10 @@ pool_unref(pool); } else { - message_parse_header(NULL, inbuf, &hdr_size, + message_parse_header(NULL, input, &hdr_size, update_header_func, &ctx); - body_size.physical_size = inbuf->v_limit - inbuf->v_offset; + body_size.physical_size = input->v_limit - input->v_offset; if (body_size.physical_size == 0) body_size.virtual_size = 0; else if (update->data_hdr.virtual_size == 0)
--- a/src/lib-index/mail-index-util.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mail-index-util.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "hostpid.h" #include "file-lock.h" #include "message-size.h"
--- a/src/lib-index/mail-index.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mail-index.h Fri Dec 06 03:09:22 2002 +0200 @@ -280,11 +280,11 @@ index is opened. */ void (*cache_fields_later)(MailIndex *index, MailDataField field); - /* Open mail file and return it as mmap()ed IBuffer. If we fail, + /* Open mail file and return it as mmap()ed IStream. If we fail, we return NULL and set deleted = TRUE if failure was because the mail was just deleted (ie. not an error). internal_date is set if it's non-NULL. */ - IBuffer *(*open_mail)(MailIndex *index, MailIndexRecord *rec, + IStream *(*open_mail)(MailIndex *index, MailIndexRecord *rec, time_t *internal_date, int *deleted); /* Returns internal date of message, or (time_t)-1 if error occured. */ @@ -361,7 +361,7 @@ char *mbox_path; /* mbox-specific path to the actual mbox file */ int mbox_fd; - IBuffer *mbox_inbuf; + IStream *mbox_stream; MailLockType mbox_lock_type; dev_t mbox_dotlock_dev; ino_t mbox_dotlock_ino; @@ -470,7 +470,7 @@ int mail_index_verify_hole_range(MailIndex *index); void mail_index_mark_flag_changes(MailIndex *index, MailIndexRecord *rec, MailFlags old_flags, MailFlags new_flags); -void mail_index_update_headers(MailIndexUpdate *update, IBuffer *inbuf, +void mail_index_update_headers(MailIndexUpdate *update, IStream *input, MailDataField cache_fields, MessageHeaderFunc header_func, void *context); int mail_index_update_cache(MailIndex *index);
--- a/src/lib-index/maildir/maildir-index.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/maildir/maildir-index.h Fri Dec 06 03:09:22 2002 +0200 @@ -20,7 +20,7 @@ int maildir_index_build_dir(MailIndex *index, const char *source_dir, const char *dest_dir); -IBuffer *maildir_open_mail(MailIndex *index, MailIndexRecord *rec, +IStream *maildir_open_mail(MailIndex *index, MailIndexRecord *rec, time_t *internal_date, int *deleted); int maildir_record_update(MailIndex *index, MailIndexUpdate *update, int fd);
--- a/src/lib-index/maildir/maildir-open.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/maildir/maildir-open.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "maildir-index.h" #include "mail-index-data.h" #include "mail-index-util.h" @@ -10,7 +10,7 @@ #include <fcntl.h> #include <sys/stat.h> -IBuffer *maildir_open_mail(MailIndex *index, MailIndexRecord *rec, +IStream *maildir_open_mail(MailIndex *index, MailIndexRecord *rec, time_t *internal_date, int *deleted) { struct stat st; @@ -54,10 +54,10 @@ } if (index->mail_read_mmaped) { - return i_buffer_create_mmap(fd, default_pool, + return i_stream_create_mmap(fd, default_pool, MAIL_MMAP_BLOCK_SIZE, 0, 0, TRUE); } else { - return i_buffer_create_file(fd, default_pool, + return i_stream_create_file(fd, default_pool, MAIL_READ_BLOCK_SIZE, TRUE); } }
--- a/src/lib-index/maildir/maildir-update.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/maildir/maildir-update.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,12 +1,12 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "maildir-index.h" int maildir_record_update(MailIndex *index, MailIndexUpdate *update, int fd) { - IBuffer *inbuf; + IStream *input; MailDataField cache_fields; /* don't even bother opening the file if we're not going to do @@ -17,14 +17,14 @@ t_push(); if (index->mail_read_mmaped) { - inbuf = i_buffer_create_mmap(fd, data_stack_pool, + input = i_stream_create_mmap(fd, data_stack_pool, MAIL_MMAP_BLOCK_SIZE, 0, 0, FALSE); } else { - inbuf = i_buffer_create_file(fd, data_stack_pool, + input = i_stream_create_file(fd, data_stack_pool, MAIL_READ_BLOCK_SIZE, FALSE); } - mail_index_update_headers(update, inbuf, cache_fields, NULL, NULL); - i_buffer_unref(inbuf); + mail_index_update_headers(update, input, cache_fields, NULL, NULL); + i_stream_unref(input); t_pop(); return TRUE; }
--- a/src/lib-index/mbox/mbox-append.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mbox/mbox-append.c Fri Dec 06 03:09:22 2002 +0200 @@ -2,13 +2,13 @@ #include "lib.h" #include "ioloop.h" -#include "ibuffer.h" +#include "istream.h" #include "hex-binary.h" #include "md5.h" #include "mbox-index.h" #include "mail-index-util.h" -static int mbox_index_append_next(MailIndex *index, IBuffer *inbuf) +static int mbox_index_append_next(MailIndex *index, IStream *input) { MailIndexRecord *rec; MailIndexUpdate *update; @@ -22,7 +22,7 @@ /* get the From-line */ pos = 0; - while (i_buffer_read_data(inbuf, &data, &size, pos) > 0) { + while (i_stream_read_data(input, &data, &size, pos) > 0) { for (; pos < size; pos++) { if (data[pos] == '\n') break; @@ -48,13 +48,13 @@ if (internal_date == (time_t)-1) internal_date = ioloop_time; - i_buffer_skip(inbuf, pos+1); - abs_start_offset = inbuf->start_offset + inbuf->v_offset; + i_stream_skip(input, pos+1); + abs_start_offset = input->start_offset + input->v_offset; /* now, find the end of header. also stops at "\nFrom " if it's found (broken messages) */ - mbox_skip_header(inbuf); - eoh_offset = inbuf->v_offset; + mbox_skip_header(input); + eoh_offset = input->v_offset; /* add message to index */ rec = index->append_begin(index); @@ -71,22 +71,22 @@ &abs_start_offset, sizeof(uoff_t)); /* parse the header and cache wanted fields. get the message flags - from Status and X-Status fields. temporarily limit the buffer size + from Status and X-Status fields. temporarily limit the stream length so the message body is parsed properly. - the buffer limit is raised again by mbox_header_func after reading - the headers. it uses Content-Length if available or finds the next - From-line. */ - mbox_header_init_context(&ctx, index, inbuf); + the stream length limit is raised again by mbox_header_func after + reading the headers. it uses Content-Length if available or finds + the next From-line. */ + mbox_header_init_context(&ctx, index, input); ctx.set_read_limit = TRUE; - i_buffer_seek(inbuf, abs_start_offset - inbuf->start_offset); + i_stream_seek(input, abs_start_offset - input->start_offset); - i_buffer_set_read_limit(inbuf, eoh_offset); - mail_index_update_headers(update, inbuf, 0, mbox_header_func, &ctx); + i_stream_set_read_limit(input, eoh_offset); + mail_index_update_headers(update, input, 0, mbox_header_func, &ctx); - i_buffer_seek(inbuf, inbuf->v_limit); - i_buffer_set_read_limit(inbuf, 0); + i_stream_seek(input, input->v_limit); + i_stream_set_read_limit(input, 0); /* save MD5 */ md5_final(&ctx.md5, md5_digest); @@ -110,9 +110,9 @@ return !failed; } -int mbox_index_append(MailIndex *index, IBuffer *inbuf) +int mbox_index_append(MailIndex *index, IStream *input) { - if (inbuf->v_offset == inbuf->v_size) { + if (input->v_offset == input->v_size) { /* no new data */ return TRUE; } @@ -121,10 +121,10 @@ return FALSE; for (;;) { - if (inbuf->start_offset + inbuf->v_offset != 0) { + if (input->start_offset + input->v_offset != 0) { /* we're at the [\r]\n before the From-line, skip it */ - if (!mbox_skip_crlf(inbuf)) { + if (!mbox_skip_crlf(input)) { index_set_error(index, "Error indexing mbox file %s: " "LF not found where expected", @@ -135,10 +135,10 @@ } } - if (inbuf->v_offset == inbuf->v_size) + if (input->v_offset == input->v_size) break; - if (!mbox_index_append_next(index, inbuf)) + if (!mbox_index_append_next(index, input)) return FALSE; }
--- a/src/lib-index/mbox/mbox-index.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mbox/mbox-index.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "rfc822-tokenize.h" #include "mbox-index.h" #include "mbox-lock.h" @@ -49,7 +49,8 @@ return TRUE; } -IBuffer *mbox_get_inbuf(MailIndex *index, uoff_t offset, MailLockType lock_type) +IStream *mbox_get_stream(MailIndex *index, uoff_t offset, + MailLockType lock_type) { i_assert(offset < OFF_T_MAX); @@ -70,11 +71,11 @@ break; } - if (index->mbox_inbuf == NULL) { + if (index->mbox_stream == NULL) { /* FIXME: breaks expunge */ /*if (index->mail_read_mmaped) {*/ - index->mbox_inbuf = - i_buffer_create_mmap(index->mbox_fd, + index->mbox_stream = + i_stream_create_mmap(index->mbox_fd, default_pool, MAIL_MMAP_BLOCK_SIZE, 0, 0, FALSE); @@ -84,34 +85,34 @@ return NULL; } - index->mbox_inbuf = - i_buffer_create_file(index->mbox_fd, + index->mbox_stream = + i_stream_create_file(index->mbox_fd, default_pool, MAIL_READ_BLOCK_SIZE, FALSE); }*/ } - i_buffer_set_read_limit(index->mbox_inbuf, 0); - i_buffer_set_start_offset(index->mbox_inbuf, (uoff_t)offset); - i_buffer_seek(index->mbox_inbuf, 0); + i_stream_set_read_limit(index->mbox_stream, 0); + i_stream_set_start_offset(index->mbox_stream, (uoff_t)offset); + i_stream_seek(index->mbox_stream, 0); - i_buffer_ref(index->mbox_inbuf); - return index->mbox_inbuf; + i_stream_ref(index->mbox_stream); + return index->mbox_stream; } -void mbox_file_close_inbuf(MailIndex *index) +void mbox_file_close_stream(MailIndex *index) { - if (index->mbox_inbuf != NULL) { - i_buffer_close(index->mbox_inbuf); - i_buffer_unref(index->mbox_inbuf); - index->mbox_inbuf = NULL; + if (index->mbox_stream != NULL) { + i_stream_close(index->mbox_stream); + i_stream_unref(index->mbox_stream); + index->mbox_stream = NULL; } } void mbox_file_close_fd(MailIndex *index) { - mbox_file_close_inbuf(index); + mbox_file_close_stream(index); if (index->mbox_fd != -1) { close(index->mbox_fd); @@ -120,13 +121,13 @@ } void mbox_header_init_context(MboxHeaderContext *ctx, MailIndex *index, - IBuffer *inbuf) + IStream *input) { memset(ctx, 0, sizeof(MboxHeaderContext)); md5_init(&ctx->md5); ctx->index = index; - ctx->inbuf = inbuf; + ctx->input = input; ctx->custom_flags = mail_custom_flags_list_get(index->custom_flags); } @@ -261,21 +262,21 @@ break; /* a) use Content-Length, b) search for "From "-line */ - start_offset = ctx->inbuf->v_offset; - i_buffer_set_read_limit(ctx->inbuf, 0); + start_offset = ctx->input->v_offset; + i_stream_set_read_limit(ctx->input, 0); end_offset = start_offset + ctx->content_length; if (ctx->content_length == 0 || - !mbox_verify_end_of_body(ctx->inbuf, end_offset)) { + !mbox_verify_end_of_body(ctx->input, end_offset)) { if (ctx->content_length != 0) - i_buffer_seek(ctx->inbuf, start_offset); - mbox_skip_message(ctx->inbuf); - end_offset = ctx->inbuf->v_offset; + i_stream_seek(ctx->input, start_offset); + mbox_skip_message(ctx->input); + end_offset = ctx->input->v_offset; ctx->content_length = end_offset - start_offset; } - i_buffer_seek(ctx->inbuf, start_offset); - i_buffer_set_read_limit(ctx->inbuf, end_offset); + i_stream_seek(ctx->input, start_offset); + i_stream_set_read_limit(ctx->input, end_offset); break; case 'R': @@ -420,16 +421,16 @@ } } -int mbox_skip_crlf(IBuffer *inbuf) +int mbox_skip_crlf(IStream *input) { const unsigned char *data; size_t size, pos; pos = 0; - while (i_buffer_read_data(inbuf, &data, &size, pos) > 0) { + while (i_stream_read_data(input, &data, &size, pos) > 0) { if (pos == 0) { if (data[0] == '\n') { - i_buffer_skip(inbuf, 1); + i_stream_skip(input, 1); return TRUE; } if (data[0] != '\r') @@ -442,7 +443,7 @@ if (data[1] != '\n') return FALSE; - i_buffer_skip(inbuf, 2); + i_stream_skip(input, 2); return TRUE; } } @@ -451,32 +452,32 @@ return TRUE; } -void mbox_skip_empty_lines(IBuffer *inbuf) +void mbox_skip_empty_lines(IStream *input) { const unsigned char *data; size_t i, size; /* skip empty lines at beginning */ - while (i_buffer_read_data(inbuf, &data, &size, 0) > 0) { + while (i_stream_read_data(input, &data, &size, 0) > 0) { for (i = 0; i < size; i++) { if (data[i] != '\r' && data[i] != '\n') break; } - i_buffer_skip(inbuf, i); + i_stream_skip(input, i); if (i < size) break; } } -static int mbox_is_valid_from(IBuffer *inbuf, size_t startpos) +static int mbox_is_valid_from(IStream *input, size_t startpos) { const unsigned char *msg; size_t i, size; i = startpos; - while (i_buffer_read_data(inbuf, &msg, &size, i) > 0) { + while (i_stream_read_data(input, &msg, &size, i) > 0) { for (; i < size; i++) { if (msg[i] == '\n') { msg += startpos; @@ -490,7 +491,7 @@ return FALSE; } -static void mbox_skip_forward(IBuffer *inbuf, int header) +static void mbox_skip_forward(IStream *input, int header) { const unsigned char *msg; size_t i, size, startpos, eoh; @@ -500,7 +501,7 @@ buffer */ startpos = i = 0; eoh = 0; lastmsg = TRUE; state = '\n'; - while (i_buffer_read_data(inbuf, &msg, &size, startpos) > 0) { + while (i_stream_read_data(input, &msg, &size, startpos) > 0) { for (i = startpos; i < size; i++) { new_state = 0; switch (state) { @@ -544,7 +545,7 @@ break; case 'm': if (msg[i] == ' ') { - if (mbox_is_valid_from(inbuf, i+1)) { + if (mbox_is_valid_from(input, i+1)) { /* Go back "From" */ i -= 4; @@ -557,7 +558,7 @@ if (i > 0 && msg[i-1] == '\r') i--; - i_buffer_skip(inbuf, i); + i_stream_skip(input, i); return; } } @@ -570,7 +571,7 @@ state = msg[i] == '\n' ? '\n' : 0; else { /* end of header position confirmed */ - i_buffer_skip(inbuf, eoh); + i_stream_skip(input, eoh); return; } } @@ -585,20 +586,20 @@ eoh -= i; } - i_buffer_skip(inbuf, i); + i_stream_skip(input, i); } if (eoh != 0) { /* make sure we didn't end with \n\n or \n\r\n. In these cases the last [\r]\n doesn't belong to our message. */ if (eoh < size && (msg[eoh] != '\r' || eoh < size-1)) { - i_buffer_skip(inbuf, eoh); + i_stream_skip(input, eoh); return; } } /* end of file, leave the last [\r]\n */ - msg = i_buffer_get_data(inbuf, &size); + msg = i_stream_get_data(input, &size); if (size == startpos && startpos > 0) { if (msg[startpos-1] == '\n') startpos--; @@ -606,39 +607,39 @@ startpos--; } - i_buffer_skip(inbuf, startpos); + i_stream_skip(input, startpos); } -void mbox_skip_header(IBuffer *inbuf) +void mbox_skip_header(IStream *input) { - mbox_skip_forward(inbuf, TRUE); + mbox_skip_forward(input, TRUE); } -void mbox_skip_message(IBuffer *inbuf) +void mbox_skip_message(IStream *input) { - mbox_skip_forward(inbuf, FALSE); + mbox_skip_forward(input, FALSE); } -int mbox_verify_end_of_body(IBuffer *inbuf, uoff_t end_offset) +int mbox_verify_end_of_body(IStream *input, uoff_t end_offset) { const unsigned char *data; size_t size; - if (end_offset > inbuf->v_size) { + if (end_offset > input->v_size) { /* missing data */ return FALSE; } - i_buffer_seek(inbuf, end_offset); + i_stream_seek(input, end_offset); - if (inbuf->v_offset == inbuf->v_size) { + if (input->v_offset == input->v_size) { /* end of file. a bit unexpected though, since \n is missing. */ return TRUE; } /* read forward a bit */ - if (i_buffer_read_data(inbuf, &data, &size, 6) < 0) + if (i_stream_read_data(input, &data, &size, 6) < 0) return FALSE; /* either there should be the next From-line,
--- a/src/lib-index/mbox/mbox-index.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mbox/mbox-index.h Fri Dec 06 03:09:22 2002 +0200 @@ -11,7 +11,7 @@ MD5Context md5; int received; - IBuffer *inbuf; + IStream *input; uoff_t content_length; int set_read_limit; } MboxHeaderContext; @@ -22,13 +22,13 @@ which is useful when you want to be sure you're not accessing a deleted mbox file. */ int mbox_file_open(MailIndex *index); -IBuffer *mbox_get_inbuf(MailIndex *index, uoff_t offset, - MailLockType lock_type); -void mbox_file_close_inbuf(MailIndex *index); +IStream *mbox_get_stream(MailIndex *index, uoff_t offset, + MailLockType lock_type); +void mbox_file_close_stream(MailIndex *index); void mbox_file_close_fd(MailIndex *index); void mbox_header_init_context(MboxHeaderContext *ctx, MailIndex *index, - IBuffer *inbuf); + IStream *input); void mbox_header_free_context(MboxHeaderContext *ctx); void mbox_header_func(MessagePart *part __attr_unused__, const char *name, size_t name_len, @@ -38,11 +38,11 @@ const char *custom_flags[MAIL_CUSTOM_FLAGS_COUNT], void (*func)(const char *, size_t, int, void *), void *context); -int mbox_skip_crlf(IBuffer *inbuf); -void mbox_skip_empty_lines(IBuffer *inbuf); -void mbox_skip_header(IBuffer *inbuf); -void mbox_skip_message(IBuffer *inbuf); -int mbox_verify_end_of_body(IBuffer *inbuf, uoff_t end_offset); +int mbox_skip_crlf(IStream *input); +void mbox_skip_empty_lines(IStream *input); +void mbox_skip_header(IStream *input); +void mbox_skip_message(IStream *input); +int mbox_verify_end_of_body(IStream *input, uoff_t end_offset); int mbox_mail_get_location(MailIndex *index, MailIndexRecord *rec, uoff_t *offset, uoff_t *hdr_size, uoff_t *body_size); @@ -50,10 +50,10 @@ int mbox_index_rebuild(MailIndex *index); int mbox_index_sync(MailIndex *index, MailLockType lock_type, int *changes); int mbox_sync_full(MailIndex *index); -IBuffer *mbox_open_mail(MailIndex *index, MailIndexRecord *rec, +IStream *mbox_open_mail(MailIndex *index, MailIndexRecord *rec, time_t *internal_date, int *deleted); -int mbox_index_append(MailIndex *index, IBuffer *inbuf); +int mbox_index_append(MailIndex *index, IStream *input); time_t mbox_from_parse_date(const char *msg, size_t size); const char *mbox_from_create(const char *sender, time_t time);
--- a/src/lib-index/mbox/mbox-lock.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mbox/mbox-lock.c Fri Dec 06 03:09:22 2002 +0200 @@ -390,7 +390,7 @@ been changes to file size which would break things. or actually it'd break only if file was shrinked+grown back to exact size, but still possible :) */ - mbox_file_close_inbuf(index); + mbox_file_close_stream(index); index->mbox_lock_type = MAIL_LOCK_UNLOCK; return !failed;
--- a/src/lib-index/mbox/mbox-open.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mbox/mbox-open.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "mbox-index.h" #include "mail-index-data.h" #include "mail-index-util.h" @@ -10,10 +10,10 @@ #include <unistd.h> #include <fcntl.h> -IBuffer *mbox_open_mail(MailIndex *index, MailIndexRecord *rec, +IStream *mbox_open_mail(MailIndex *index, MailIndexRecord *rec, time_t *internal_date, int *deleted) { - IBuffer *inbuf; + IStream *input; uoff_t offset, hdr_size, body_size; i_assert(index->lock_type != MAIL_LOCK_UNLOCK); @@ -27,8 +27,8 @@ if (!mbox_mail_get_location(index, rec, &offset, &hdr_size, &body_size)) return NULL; - inbuf = mbox_get_inbuf(index, offset, MAIL_LOCK_SHARED); - if (inbuf == NULL) + input = mbox_get_stream(index, offset, MAIL_LOCK_SHARED); + if (input == NULL) return NULL; if (internal_date != NULL) @@ -36,6 +36,6 @@ i_assert(index->mbox_sync_counter == index->mbox_lock_counter); - i_buffer_set_read_limit(inbuf, hdr_size + body_size); - return inbuf; + i_stream_set_read_limit(input, hdr_size + body_size); + return input; }
--- a/src/lib-index/mbox/mbox-rebuild.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mbox/mbox-rebuild.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "mbox-index.h" #include "mbox-lock.h" #include "mail-index-data.h" @@ -14,7 +14,7 @@ int mbox_index_rebuild(MailIndex *index) { - IBuffer *inbuf; + IStream *input; struct stat st; int failed; @@ -43,14 +43,14 @@ if (!mail_index_data_reset(index->data)) return FALSE; - inbuf = mbox_get_inbuf(index, 0, MAIL_LOCK_SHARED); - if (inbuf == NULL) + input = mbox_get_stream(index, 0, MAIL_LOCK_SHARED); + if (input == NULL) return FALSE; - mbox_skip_empty_lines(inbuf); - failed = !mbox_index_append(index, inbuf); + mbox_skip_empty_lines(input); + failed = !mbox_index_append(index, input); - i_buffer_unref(inbuf); + i_stream_unref(input); if (failed) return FALSE;
--- a/src/lib-index/mbox/mbox-rewrite.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mbox/mbox-rewrite.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,8 +1,8 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "temp-string.h" #include "write-full.h" #include "mbox-index.h" @@ -16,7 +16,7 @@ #include <fcntl.h> typedef struct { - OBuffer *outbuf; + OStream *output; int failed; uoff_t content_length; @@ -49,21 +49,22 @@ MAIL_INDEX_FLAG_DIRTY_CUSTOMFLAGS); } -static int mbox_write(MailIndex *index, IBuffer *inbuf, OBuffer *outbuf, +static int mbox_write(MailIndex *index, IStream *input, OStream *output, uoff_t end_offset) { uoff_t old_limit; int failed; - i_assert(inbuf->v_offset <= end_offset); + i_assert(input->v_offset <= end_offset); - old_limit = inbuf->v_limit; - i_buffer_set_read_limit(inbuf, end_offset); - if (o_buffer_send_ibuffer(outbuf, inbuf) < 0) { + old_limit = input->v_limit; + i_stream_set_read_limit(input, end_offset); + if (o_stream_send_istream(output, input) < 0) { index_set_error(index, "Error rewriting mbox file %s: %s", - index->mbox_path, strerror(outbuf->buf_errno)); + index->mbox_path, + strerror(output->stream_errno)); failed = TRUE; - } else if (inbuf->v_offset < end_offset) { + } else if (input->v_offset < end_offset) { /* fsck should have noticed it.. */ index_set_error(index, "Error rewriting mbox file %s: " "Unexpected end of file", index->mbox_path); @@ -72,7 +73,7 @@ failed = FALSE; } - i_buffer_set_read_limit(inbuf, old_limit); + i_stream_set_read_limit(input, old_limit); return !failed; } @@ -83,21 +84,21 @@ str = t_strdup_printf("X-IMAPbase: %u %u", ctx->uid_validity, ctx->uid_last); - if (o_buffer_send(ctx->outbuf, str, strlen(str)) < 0) + if (o_stream_send(ctx->output, str, strlen(str)) < 0) return FALSE; for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++) { if (ctx->custom_flags[i] != NULL) { - if (o_buffer_send(ctx->outbuf, " ", 1) < 0) + if (o_stream_send(ctx->output, " ", 1) < 0) return FALSE; - if (o_buffer_send(ctx->outbuf, ctx->custom_flags[i], + if (o_stream_send(ctx->output, ctx->custom_flags[i], strlen(ctx->custom_flags[i])) < 0) return FALSE; } } - if (o_buffer_send(ctx->outbuf, "\n", 1) < 0) + if (o_stream_send(ctx->output, "\n", 1) < 0) return FALSE; return TRUE; @@ -112,16 +113,16 @@ x_keywords == NULL) return TRUE; - if (o_buffer_send(ctx->outbuf, "X-Keywords:", 11) < 0) + if (o_stream_send(ctx->output, "X-Keywords:", 11) < 0) return FALSE; field = 1 << MAIL_CUSTOM_FLAG_1_BIT; for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++, field <<= 1) { if ((ctx->msg_flags & field) && ctx->custom_flags[i] != NULL) { - if (o_buffer_send(ctx->outbuf, " ", 1) < 0) + if (o_stream_send(ctx->output, " ", 1) < 0) return FALSE; - if (o_buffer_send(ctx->outbuf, ctx->custom_flags[i], + if (o_stream_send(ctx->output, ctx->custom_flags[i], strlen(ctx->custom_flags[i])) < 0) return FALSE; } @@ -129,15 +130,15 @@ if (x_keywords != NULL) { /* X-Keywords that aren't custom flags */ - if (o_buffer_send(ctx->outbuf, " ", 1) < 0) + if (o_stream_send(ctx->output, " ", 1) < 0) return FALSE; - if (o_buffer_send(ctx->outbuf, x_keywords, + if (o_stream_send(ctx->output, x_keywords, strlen(x_keywords)) < 0) return FALSE; } - if (o_buffer_send(ctx->outbuf, "\n", 1) < 0) + if (o_stream_send(ctx->output, "\n", 1) < 0) return FALSE; return TRUE; @@ -151,9 +152,9 @@ if (status != NULL) str = t_strconcat(str, status, NULL); - if (o_buffer_send(ctx->outbuf, str, strlen(str)) < 0) + if (o_stream_send(ctx->output, str, strlen(str)) < 0) return FALSE; - if (o_buffer_send(ctx->outbuf, "\n", 1) < 0) + if (o_stream_send(ctx->output, "\n", 1) < 0) return FALSE; return TRUE; @@ -175,9 +176,9 @@ (ctx->msg_flags & MAIL_DELETED) ? "T" : "", x_status, NULL); - if (o_buffer_send(ctx->outbuf, str, strlen(str)) < 0) + if (o_stream_send(ctx->output, str, strlen(str)) < 0) return FALSE; - if (o_buffer_send(ctx->outbuf, "\n", 1) < 0) + if (o_stream_send(ctx->output, "\n", 1) < 0) return FALSE; return TRUE; @@ -190,7 +191,7 @@ i_snprintf(str, sizeof(str), "Content-Length: %"PRIuUOFF_T"\n", ctx->content_length); - if (o_buffer_send(ctx->outbuf, str, strlen(str)) < 0) + if (o_stream_send(ctx->output, str, strlen(str)) < 0) return FALSE; return TRUE; } @@ -283,19 +284,19 @@ (void)mbox_write_content_length(ctx); } else if (name_len > 0) { /* save this header */ - (void)o_buffer_send(ctx->outbuf, name, name_len); - (void)o_buffer_send(ctx->outbuf, ": ", 2); - (void)o_buffer_send(ctx->outbuf, value, value_len); - (void)o_buffer_send(ctx->outbuf, "\n", 1); + (void)o_stream_send(ctx->output, name, name_len); + (void)o_stream_send(ctx->output, ": ", 2); + (void)o_stream_send(ctx->output, value, value_len); + (void)o_stream_send(ctx->output, "\n", 1); } - if (ctx->outbuf->closed) + if (ctx->output->closed) ctx->failed = TRUE; } static int mbox_write_header(MailIndex *index, MailIndexRecord *rec, unsigned int seq, - IBuffer *inbuf, OBuffer *outbuf, uoff_t end_offset, + IStream *input, OStream *output, uoff_t end_offset, uoff_t hdr_size, uoff_t body_size) { /* We need to update fields that define message flags. Standard fields @@ -312,7 +313,7 @@ MboxRewriteContext ctx; MessageSize hdr_parsed_size; - if (inbuf->v_offset >= end_offset) { + if (input->v_offset >= end_offset) { /* fsck should have noticed it.. */ index_set_error(index, "Error rewriting mbox file %s: " "Unexpected end of file", index->mbox_path); @@ -323,16 +324,16 @@ /* parse the header, write the fields we don't want to change */ memset(&ctx, 0, sizeof(ctx)); - ctx.outbuf = outbuf; + ctx.output = output; ctx.seq = seq; ctx.content_length = body_size; ctx.msg_flags = rec->msg_flags; ctx.uid_validity = index->header->uid_validity-1; ctx.custom_flags = mail_custom_flags_list_get(index->custom_flags); - i_buffer_set_read_limit(inbuf, inbuf->v_offset + hdr_size); - message_parse_header(NULL, inbuf, &hdr_parsed_size, header_func, &ctx); - i_buffer_set_read_limit(inbuf, 0); + i_stream_set_read_limit(input, input->v_offset + hdr_size); + message_parse_header(NULL, input, &hdr_parsed_size, header_func, &ctx); + i_stream_set_read_limit(input, 0); i_assert(hdr_parsed_size.physical_size == hdr_size); @@ -354,15 +355,15 @@ t_pop(); /* empty line ends headers */ - (void)o_buffer_send(outbuf, "\n", 1); + (void)o_stream_send(output, "\n", 1); return TRUE; } static int fd_copy(int in_fd, int out_fd, uoff_t out_offset) { - IBuffer *inbuf; - OBuffer *outbuf; + IStream *input; + OStream *output; int ret; i_assert(out_offset <= OFF_T_MAX); @@ -372,22 +373,22 @@ t_push(); - inbuf = i_buffer_create_mmap(in_fd, data_stack_pool, + input = i_stream_create_mmap(in_fd, data_stack_pool, 1024*256, 0, 0, FALSE); - outbuf = o_buffer_create_file(out_fd, data_stack_pool, 1024, 0, FALSE); - o_buffer_set_blocking(outbuf, 60000, NULL, NULL); + output = o_stream_create_file(out_fd, data_stack_pool, 1024, 0, FALSE); + o_stream_set_blocking(output, 60000, NULL, NULL); - ret = o_buffer_send_ibuffer(outbuf, inbuf); + ret = o_stream_send_istream(output, input); if (ret < 0) - errno = outbuf->buf_errno; + errno = output->stream_errno; else { /* we may have shrinked the file */ - i_assert(out_offset + inbuf->v_size <= OFF_T_MAX); - ret = ftruncate(out_fd, (off_t) (out_offset + inbuf->v_size)); + i_assert(out_offset + input->v_size <= OFF_T_MAX); + ret = ftruncate(out_fd, (off_t) (out_offset + input->v_size)); } - o_buffer_unref(outbuf); - i_buffer_unref(inbuf); + o_stream_unref(output); + i_stream_unref(input); t_pop(); return ret; @@ -403,8 +404,8 @@ interrupted (see below). This rewriting relies quite a lot on valid header/body sizes which fsck() should have ensured. */ MailIndexRecord *rec; - IBuffer *inbuf; - OBuffer *outbuf; + IStream *input; + OStream *output; uoff_t offset, hdr_size, body_size, dirty_offset; const char *path; unsigned int seq; @@ -426,7 +427,7 @@ return TRUE; } - tmp_fd = -1; inbuf = NULL; + tmp_fd = -1; input = NULL; failed = TRUE; rewrite = FALSE; do { if (!index->set_lock(index, MAIL_LOCK_EXCLUSIVE)) @@ -435,8 +436,8 @@ if (!index->sync_and_lock(index, MAIL_LOCK_EXCLUSIVE, NULL)) break; - inbuf = mbox_get_inbuf(index, 0, MAIL_LOCK_EXCLUSIVE); - if (inbuf == NULL) + input = mbox_get_stream(index, 0, MAIL_LOCK_EXCLUSIVE); + if (input == NULL) break; if ((index->header->flags & INDEX_DIRTY_FLAGS) == 0) { @@ -456,8 +457,8 @@ if (!rewrite) { if (!index->set_lock(index, MAIL_LOCK_UNLOCK)) failed = TRUE; - if (inbuf != NULL) - i_buffer_unref(inbuf); + if (input != NULL) + i_stream_unref(input); return !failed; } @@ -469,10 +470,10 @@ } dirty_offset = 0; - /* note: we can't use data_stack_pool with outbuf because it's + /* note: we can't use data_stack_pool with output stream because it's being written to inside t_push() .. t_pop() calls */ - outbuf = o_buffer_create_file(tmp_fd, system_pool, 8192, 0, FALSE); - o_buffer_set_blocking(outbuf, 60000, NULL, NULL); + output = o_stream_create_file(tmp_fd, system_pool, 8192, 0, FALSE); + o_stream_set_blocking(output, 60000, NULL, NULL); failed = FALSE; seq = 1; rec = index->lookup(index, 1); @@ -486,14 +487,14 @@ break; } - if (offset < inbuf->v_offset) { + if (offset < input->v_offset) { index_set_corrupted(index, "Invalid message offset"); failed = TRUE; break; } - if (offset + hdr_size + body_size > inbuf->v_size) { + if (offset + hdr_size + body_size > input->v_size) { index_set_corrupted(index, "Invalid message size"); failed = TRUE; @@ -507,19 +508,19 @@ dirty_found = TRUE; dirty_offset = offset; - i_buffer_seek(inbuf, dirty_offset); + i_stream_seek(input, dirty_offset); } if (dirty_found) { /* write the From-line */ - if (!mbox_write(index, inbuf, outbuf, offset)) { + if (!mbox_write(index, input, output, offset)) { failed = TRUE; break; } /* write header, updating flag fields */ offset += hdr_size; - if (!mbox_write_header(index, rec, seq, inbuf, outbuf, + if (!mbox_write_header(index, rec, seq, input, output, offset, hdr_size, body_size)) { failed = TRUE; break; @@ -527,7 +528,7 @@ /* write body */ offset += body_size; - if (!mbox_write(index, inbuf, outbuf, offset)) { + if (!mbox_write(index, input, output, offset)) { failed = TRUE; break; } @@ -545,17 +546,17 @@ if (!failed) { /* always end with a \n */ - (void)o_buffer_send(outbuf, "\n", 1); + (void)o_stream_send(output, "\n", 1); } - if (outbuf->closed) { - errno = outbuf->buf_errno; + if (output->closed) { + errno = output->stream_errno; mbox_set_syscall_error(index, "write()"); failed = TRUE; } - i_buffer_unref(inbuf); - o_buffer_unref(outbuf); + i_stream_unref(input); + o_stream_unref(output); if (!failed) { /* POSSIBLE DATA LOSS HERE. We're writing to the mbox file,
--- a/src/lib-index/mbox/mbox-sync-full.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mbox/mbox-sync-full.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "hex-binary.h" #include "message-parser.h" #include "message-part-serialize.h" @@ -12,20 +12,20 @@ #include <unistd.h> #include <fcntl.h> -static void skip_line(IBuffer *inbuf) +static void skip_line(IStream *input) { const unsigned char *msg; size_t i, size; - while (i_buffer_read_data(inbuf, &msg, &size, 0) > 0) { + while (i_stream_read_data(input, &msg, &size, 0) > 0) { for (i = 0; i < size; i++) { if (msg[i] == '\n') { - i_buffer_skip(inbuf, i+1); + i_stream_skip(input, i+1); return; } } - i_buffer_skip(inbuf, i); + i_stream_skip(input, i); } } @@ -90,7 +90,7 @@ } static int match_next_record(MailIndex *index, MailIndexRecord *rec, - unsigned int seq, IBuffer *inbuf, + unsigned int seq, IStream *input, MailIndexRecord **next_rec, int *dirty) { MailIndexUpdate *update; @@ -102,8 +102,8 @@ *next_rec = NULL; /* skip the From-line */ - skip_line(inbuf); - header_offset = inbuf->v_offset; + skip_line(input); + header_offset = input->v_offset; if (!mbox_mail_get_location(index, rec, NULL, &hdr_size, &body_size)) return FALSE; @@ -111,25 +111,25 @@ if (body_size == 0) { /* possibly broken message, find the next From-line and make sure header parser won't pass it. */ - mbox_skip_header(inbuf); - i_buffer_set_read_limit(inbuf, inbuf->v_offset); - i_buffer_seek(inbuf, header_offset); + mbox_skip_header(input); + i_stream_set_read_limit(input, input->v_offset); + i_stream_seek(input, header_offset); } /* get the MD5 sum of fixed headers and the current message flags in Status and X-Status fields */ - mbox_header_init_context(&ctx, index, inbuf); - message_parse_header(NULL, inbuf, &hdr_parsed_size, + mbox_header_init_context(&ctx, index, input); + message_parse_header(NULL, input, &hdr_parsed_size, mbox_header_func, &ctx); md5_final(&ctx.md5, current_digest); mbox_header_free_context(&ctx); - i_buffer_set_read_limit(inbuf, 0); + i_stream_set_read_limit(input, 0); - body_offset = inbuf->v_offset; + body_offset = input->v_offset; do { if (verify_header_md5sum(index, rec, current_digest) && - mbox_verify_end_of_body(inbuf, body_offset + body_size)) { + mbox_verify_end_of_body(input, body_offset + body_size)) { /* valid message */ update = index->update_begin(index, rec); @@ -179,7 +179,7 @@ return TRUE; } -static int mbox_sync_buf(MailIndex *index, IBuffer *inbuf) +static int mbox_sync_from_stream(MailIndex *index, IStream *input) { MailIndexRecord *rec; uoff_t from_offset; @@ -188,11 +188,11 @@ unsigned int seq; int dirty; - mbox_skip_empty_lines(inbuf); + mbox_skip_empty_lines(input); /* first make sure we start with a "From " line. If file is too small, we'll just treat it as empty mbox file. */ - if (i_buffer_read_data(inbuf, &data, &size, 5) > 0 && + if (i_stream_read_data(input, &data, &size, 5) > 0 && strncmp((const char *) data, "From ", 5) != 0) { index_set_error(index, "File isn't in mbox format: %s", index->mbox_path); @@ -212,11 +212,11 @@ dirty = FALSE; while (rec != NULL) { - from_offset = inbuf->v_offset; - if (inbuf->v_offset != 0) { + from_offset = input->v_offset; + if (input->v_offset != 0) { /* we're at the [\r]\n before the From-line, skip it */ - if (!mbox_skip_crlf(inbuf)) { + if (!mbox_skip_crlf(input)) { /* they just went and broke it, even while we had it locked. */ index_set_error(index, @@ -227,15 +227,15 @@ } } - if (inbuf->v_offset == inbuf->v_size) + if (input->v_offset == input->v_size) break; - if (!match_next_record(index, rec, seq, inbuf, &rec, &dirty)) + if (!match_next_record(index, rec, seq, input, &rec, &dirty)) return FALSE; if (rec == NULL) { /* Get back to line before From */ - i_buffer_seek(inbuf, from_offset); + i_stream_seek(input, from_offset); break; } @@ -255,25 +255,25 @@ index->header->flags &= ~MAIL_INDEX_FLAG_DIRTY_MESSAGES; } - if (inbuf->v_offset == inbuf->v_size) + if (input->v_offset == input->v_size) return TRUE; else - return mbox_index_append(index, inbuf); + return mbox_index_append(index, input); } int mbox_sync_full(MailIndex *index) { - IBuffer *inbuf; + IStream *input; int failed; i_assert(index->lock_type == MAIL_LOCK_EXCLUSIVE); - inbuf = mbox_get_inbuf(index, 0, MAIL_LOCK_SHARED); - if (inbuf == NULL) + input = mbox_get_stream(index, 0, MAIL_LOCK_SHARED); + if (input == NULL) return FALSE; - failed = !mbox_sync_buf(index, inbuf); - i_buffer_unref(inbuf); + failed = !mbox_sync_from_stream(index, input); + i_stream_unref(input); return !failed; }
--- a/src/lib-index/mbox/mbox-sync.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-index/mbox/mbox-sync.c Fri Dec 06 03:09:22 2002 +0200 @@ -119,7 +119,7 @@ } if (index_mtime != st.st_mtime || index->mbox_size != filesize) { - mbox_file_close_inbuf(index); + mbox_file_close_stream(index); index->mbox_size = get_indexed_mbox_size(index); if (index->file_sync_stamp == 0 &&
--- a/src/lib-mail/message-body-search.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-mail/message-body-search.c Fri Dec 06 03:09:22 2002 +0200 @@ -2,7 +2,7 @@ #include "lib.h" #include "base64.h" -#include "ibuffer.h" +#include "istream.h" #include "charset-utf8.h" #include "rfc822-tokenize.h" #include "quoted-printable.h" @@ -134,7 +134,7 @@ } } -static int message_search_header(PartSearchContext *ctx, IBuffer *inbuf) +static int message_search_header(PartSearchContext *ctx, IStream *input) { ctx->hdr_search_ctx = message_header_search_init(data_stack_pool, ctx->body_ctx->key, @@ -143,7 +143,7 @@ /* we default to text content-type */ ctx->content_type_text = TRUE; - message_parse_header(NULL, inbuf, NULL, header_find, ctx); + message_parse_header(NULL, input, NULL, header_find, ctx); return ctx->found; } @@ -252,7 +252,7 @@ return 0; } -static int message_search_body(PartSearchContext *ctx, IBuffer *inbuf, +static int message_search_body(PartSearchContext *ctx, IStream *input, MessagePart *part) { const unsigned char *data, *decoded; @@ -280,15 +280,15 @@ ctx->match_count = 0; ctx->matches = t_malloc(sizeof(size_t) * ctx->body_ctx->key_len); - i_buffer_skip(inbuf, part->physical_pos + - part->header_size.physical_size - inbuf->v_offset); + i_stream_skip(input, part->physical_pos + + part->header_size.physical_size - input->v_offset); - old_limit = inbuf->v_limit; - i_buffer_set_read_limit(inbuf, inbuf->v_offset + + old_limit = input->v_limit; + i_stream_set_read_limit(input, input->v_offset + part->body_size.physical_size); found = FALSE; pos = 0; - while (i_buffer_read_data(inbuf, &data, &data_size, pos) > 0) { + while (i_stream_read_data(input, &data, &data_size, pos) > 0) { /* limit the size of t_malloc()s */ if (data_size > DECODE_BLOCK_SIZE) data_size = DECODE_BLOCK_SIZE; @@ -318,11 +318,11 @@ } t_pop(); - i_buffer_skip(inbuf, data_size); + i_stream_skip(input, data_size); pos -= data_size; } - i_buffer_set_read_limit(inbuf, old_limit); + i_stream_set_read_limit(input, old_limit); if (ctx->translation != NULL) charset_to_utf8_end(ctx->translation); @@ -355,7 +355,7 @@ return TRUE; } -static int message_body_search_ctx(BodySearchContext *ctx, IBuffer *inbuf, +static int message_body_search_ctx(BodySearchContext *ctx, IStream *input, MessagePart *part) { PartSearchContext part_ctx; @@ -363,9 +363,9 @@ found = FALSE; while (part != NULL && !found) { - i_assert(inbuf->v_offset <= part->physical_pos); + i_assert(input->v_offset <= part->physical_pos); - i_buffer_skip(inbuf, part->physical_pos - inbuf->v_offset); + i_stream_skip(input, part->physical_pos - input->v_offset); memset(&part_ctx, 0, sizeof(part_ctx)); part_ctx.body_ctx = ctx; @@ -374,14 +374,14 @@ t_push(); - if (message_search_header(&part_ctx, inbuf)) { + if (message_search_header(&part_ctx, input)) { found = TRUE; } else if (part->children != NULL) { /* multipart/xxx or message/rfc822 */ - if (message_body_search_ctx(ctx, inbuf, part->children)) + if (message_body_search_ctx(ctx, input, part->children)) found = TRUE; } else { - if (message_search_body(&part_ctx, inbuf, part)) + if (message_search_body(&part_ctx, input, part)) found = TRUE; } @@ -394,7 +394,7 @@ } int message_body_search(const char *key, const char *charset, - int *unknown_charset, IBuffer *inbuf, + int *unknown_charset, IStream *input, MessagePart *part, int search_header) { BodySearchContext ctx; @@ -403,5 +403,5 @@ search_header)) return -1; - return message_body_search_ctx(&ctx, inbuf, part); + return message_body_search_ctx(&ctx, input, part); }
--- a/src/lib-mail/message-body-search.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-mail/message-body-search.h Fri Dec 06 03:09:22 2002 +0200 @@ -6,7 +6,7 @@ is invalid. If charset is NULL, the key isn't assumed to be in any specific charset but is compared to message data without any translation. */ int message_body_search(const char *key, const char *charset, - int *unknown_charset, IBuffer *inbuf, + int *unknown_charset, IStream *input, MessagePart *part, int search_header); #endif
--- a/src/lib-mail/message-parser.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-mail/message-parser.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "rfc822-tokenize.h" #include "message-content-parser.h" #include "message-parser.h" @@ -27,12 +27,12 @@ void *context; } MessageParseContext; -static MessagePart *message_parse_part(IBuffer *inbuf, +static MessagePart *message_parse_part(IStream *input, MessageParseContext *parse_ctx); -static MessagePart *message_parse_body(IBuffer *inbuf, +static MessagePart *message_parse_body(IStream *input, MessageBoundary *boundaries, MessageSize *body_size); -static MessagePart *message_skip_boundary(IBuffer *inbuf, +static MessagePart *message_skip_boundary(IStream *input, MessageBoundary *boundaries, MessageSize *boundary_size); @@ -136,7 +136,7 @@ } } -static MessagePart *message_parse_multipart(IBuffer *inbuf, +static MessagePart *message_parse_multipart(IStream *input, MessageParseContext *parse_ctx) { MessagePart *parent_part, *next_part, *part; @@ -157,7 +157,7 @@ /* skip the data before the first boundary */ parent_part = parse_ctx->part; - next_part = message_skip_boundary(inbuf, parse_ctx->boundaries, + next_part = message_skip_boundary(input, parse_ctx->boundaries, &parent_part->body_size); /* now, parse the parts */ @@ -166,7 +166,7 @@ part = message_part_append(parse_ctx->pool, parent_part); parse_ctx->part = part; - next_part = message_parse_part(inbuf, parse_ctx); + next_part = message_parse_part(input, parse_ctx); /* update our size */ message_size_add_part(&parent_part->body_size, part); @@ -175,7 +175,7 @@ break; /* skip the boundary */ - next_part = message_skip_boundary(inbuf, parse_ctx->boundaries, + next_part = message_skip_boundary(input, parse_ctx->boundaries, &parent_part->body_size); } @@ -185,13 +185,13 @@ return next_part; } -static MessagePart *message_parse_part(IBuffer *inbuf, +static MessagePart *message_parse_part(IStream *input, MessageParseContext *parse_ctx) { MessagePart *next_part, *part; uoff_t hdr_size; - message_parse_header(parse_ctx->part, inbuf, + message_parse_header(parse_ctx->part, input, &parse_ctx->part->header_size, parse_header_field, parse_ctx); @@ -199,7 +199,7 @@ hdr_size = parse_ctx->part->header_size.physical_size; if (parse_ctx->last_boundary != NULL) - return message_parse_multipart(inbuf, parse_ctx); + return message_parse_multipart(input, parse_ctx); if (parse_ctx->last_content_type == NULL) { if (parse_ctx->part->parent != NULL && @@ -226,7 +226,7 @@ part = message_part_append(parse_ctx->pool, parse_ctx->part); parse_ctx->part = part; - next_part = message_parse_part(inbuf, parse_ctx); + next_part = message_parse_part(input, parse_ctx); parse_ctx->part = part->parent; /* our body size is the size of header+body in message/rfc822 */ @@ -234,14 +234,14 @@ } else { /* normal message, read until the next boundary */ part = parse_ctx->part; - next_part = message_parse_body(inbuf, parse_ctx->boundaries, + next_part = message_parse_body(input, parse_ctx->boundaries, &part->body_size); } return next_part; } -MessagePart *message_parse(Pool pool, IBuffer *inbuf, +MessagePart *message_parse(Pool pool, IStream *input, MessageHeaderFunc func, void *context) { MessagePart *part; @@ -254,20 +254,20 @@ parse_ctx.part = part = p_new(pool, MessagePart, 1); t_push(); - message_parse_part(inbuf, &parse_ctx); + message_parse_part(input, &parse_ctx); t_pop(); return part; } /* skip over to next line increasing message size */ -static void message_skip_line(IBuffer *inbuf, MessageSize *msg_size) +static void message_skip_line(IStream *input, MessageSize *msg_size) { const unsigned char *msg; size_t i, size, startpos; startpos = 0; - while (i_buffer_read_data(inbuf, &msg, &size, startpos) > 0) { + while (i_stream_read_data(input, &msg, &size, startpos) > 0) { for (i = startpos; i < size; i++) { if (msg[i] == '\n') { if (msg_size != NULL) { @@ -285,7 +285,7 @@ } /* leave the last character, it may be \r */ - i_buffer_skip(inbuf, i - 1); + i_stream_skip(input, i - 1); startpos = 1; if (msg_size != NULL) { @@ -294,7 +294,7 @@ } } - i_buffer_skip(inbuf, startpos); + i_stream_skip(input, startpos); if (msg_size != NULL) { msg_size->physical_size += startpos; @@ -302,7 +302,7 @@ } } -void message_parse_header(MessagePart *part, IBuffer *inbuf, +void message_parse_header(MessagePart *part, IStream *input, MessageSize *hdr_size, MessageHeaderFunc func, void *context) { @@ -317,12 +317,12 @@ missing_cr_count = startpos = line_start = 0; colon_pos = UINT_MAX; for (;;) { - ret = i_buffer_read_data(inbuf, &msg, &size, startpos+1); + ret = i_stream_read_data(input, &msg, &size, startpos+1); if (ret == -2) { /* overflow, line is too long. just skip it. */ i_assert(size > 2); - message_skip_line(inbuf, hdr_size); + message_skip_line(input, hdr_size); startpos = line_start = 0; colon_pos = UINT_MAX; continue; @@ -412,13 +412,13 @@ colon_pos -= line_start; if (hdr_size != NULL) hdr_size->physical_size += line_start; - i_buffer_skip(inbuf, line_start); + i_stream_skip(input, line_start); startpos = i-line_start; line_start = 0; } - i_buffer_skip(inbuf, startpos); + i_stream_skip(input, startpos); if (hdr_size != NULL) { hdr_size->physical_size += startpos; @@ -451,7 +451,7 @@ [\r]\n before the boundary, otherwise leave it right after the known boundary so the ending "--" can be checked. */ static MessageBoundary * -message_find_boundary(IBuffer *inbuf, MessageBoundary *boundaries, +message_find_boundary(IStream *input, MessageBoundary *boundaries, MessageSize *msg_size, int skip_over) { MessageBoundary *boundary; @@ -461,7 +461,7 @@ boundary = NULL; missing_cr_count = startpos = line_start = 0; - while (i_buffer_read_data(inbuf, &msg, &size, startpos) > 0) { + while (i_stream_read_data(input, &msg, &size, startpos) > 0) { for (i = startpos; i < size; i++) { if (msg[i] != '\n') continue; @@ -511,7 +511,7 @@ line_start -= i; } - i_buffer_skip(inbuf, i); + i_stream_skip(input, i); msg_size->physical_size += i; msg_size->virtual_size += i; @@ -535,7 +535,7 @@ startpos = line_start; } - i_buffer_skip(inbuf, startpos); + i_stream_skip(input, startpos); msg_size->physical_size += startpos; msg_size->virtual_size += startpos + missing_cr_count; @@ -544,17 +544,17 @@ return boundary; } -static MessagePart *message_parse_body(IBuffer *inbuf, +static MessagePart *message_parse_body(IStream *input, MessageBoundary *boundaries, MessageSize *body_size) { MessageBoundary *boundary; if (boundaries == NULL) { - message_get_body_size(inbuf, body_size, (uoff_t)-1); + message_get_body_size(input, body_size, (uoff_t)-1); return NULL; } else { - boundary = message_find_boundary(inbuf, boundaries, + boundary = message_find_boundary(input, boundaries, body_size, FALSE); return boundary == NULL ? NULL : boundary->part; } @@ -562,7 +562,7 @@ /* skip data until next boundary is found. if it's end boundary, skip the footer as well. */ -static MessagePart *message_skip_boundary(IBuffer *inbuf, +static MessagePart *message_skip_boundary(IStream *input, MessageBoundary *boundaries, MessageSize *boundary_size) { @@ -571,22 +571,22 @@ size_t size; int end_boundary; - boundary = message_find_boundary(inbuf, boundaries, + boundary = message_find_boundary(input, boundaries, boundary_size, TRUE); if (boundary == NULL) return NULL; /* now, see if it's end boundary */ end_boundary = FALSE; - if (i_buffer_read_data(inbuf, &msg, &size, 1) > 0) + if (i_stream_read_data(input, &msg, &size, 1) > 0) end_boundary = msg[0] == '-' && msg[1] == '-'; /* skip the rest of the line */ - message_skip_line(inbuf, boundary_size); + message_skip_line(input, boundary_size); if (end_boundary) { /* skip the footer */ - return message_parse_body(inbuf, boundaries, boundary_size); + return message_parse_body(input, boundaries, boundary_size); } return boundary == NULL ? NULL : boundary->part;
--- a/src/lib-mail/message-parser.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-mail/message-parser.h Fri Dec 06 03:09:22 2002 +0200 @@ -44,15 +44,15 @@ void *context); /* func is called for each field in message header. */ -MessagePart *message_parse(Pool pool, IBuffer *inbuf, +MessagePart *message_parse(Pool pool, IStream *input, MessageHeaderFunc func, void *context); /* Call func for each field in message header. Fills the hdr_size. part can be NULL, just make sure your header function works with it. This function doesn't use data stack so your header function may save - values to it. When finished, inbuf will point to beginning of message + values to it. When finished, input will point to beginning of message body. */ -void message_parse_header(MessagePart *part, IBuffer *inbuf, +void message_parse_header(MessagePart *part, IStream *input, MessageSize *hdr_size, MessageHeaderFunc func, void *context);
--- a/src/lib-mail/message-send.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-mail/message-send.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,12 +1,12 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "message-send.h" #include "message-size.h" -int message_send(OBuffer *outbuf, IBuffer *inbuf, MessageSize *msg_size, +int message_send(OStream *output, IStream *input, MessageSize *msg_size, uoff_t virtual_skip, uoff_t max_virtual_size) { const unsigned char *msg; @@ -23,21 +23,21 @@ if (msg_size->physical_size == msg_size->virtual_size) { /* no need to kludge with CRs, we can use sendfile() */ - i_buffer_skip(inbuf, virtual_skip); + i_stream_skip(input, virtual_skip); - old_limit = inbuf->v_limit; - limit = inbuf->v_offset + max_virtual_size; - i_buffer_set_read_limit(inbuf, I_MIN(limit, old_limit)); - ret = o_buffer_send_ibuffer(outbuf, inbuf) > 0; - i_buffer_set_read_limit(inbuf, old_limit); + old_limit = input->v_limit; + limit = input->v_offset + max_virtual_size; + i_stream_set_read_limit(input, I_MIN(limit, old_limit)); + ret = o_stream_send_istream(output, input) > 0; + i_stream_set_read_limit(input, old_limit); return ret; } - message_skip_virtual(inbuf, virtual_skip, NULL, &cr_skipped); + message_skip_virtual(input, virtual_skip, NULL, &cr_skipped); /* go through the message data and insert CRs where needed. */ - while (i_buffer_read_data(inbuf, &msg, &size, 0) > 0) { + while (i_stream_read_data(input, &msg, &size, 0) > 0) { add_cr = FALSE; for (i = 0; i < size; i++) { if (msg[i] == '\n') { @@ -60,11 +60,11 @@ } } - if (o_buffer_send(outbuf, msg, i) < 0) + if (o_stream_send(output, msg, i) < 0) return FALSE; if (add_cr) { - if (o_buffer_send(outbuf, "\r", 1) < 0) + if (o_stream_send(output, "\r", 1) < 0) return FALSE; cr_skipped = TRUE; } else { @@ -75,7 +75,7 @@ if (max_virtual_size == 0) break; - i_buffer_skip(inbuf, i); + i_stream_skip(input, i); } return TRUE;
--- a/src/lib-mail/message-send.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-mail/message-send.h Fri Dec 06 03:09:22 2002 +0200 @@ -5,9 +5,9 @@ /* Send message to client inserting CRs if needed. Only max_virtual_size bytes if sent (relative to virtual_skip), if you want it unlimited, - use (uoff_t)-1. Remember that if inbuf begins with LF, CR is inserted + use (uoff_t)-1. Remember that if input begins with LF, CR is inserted before it unless virtual_skip = 1. Returns TRUE if successful. */ -int message_send(OBuffer *outbuf, IBuffer *inbuf, MessageSize *msg_size, +int message_send(OStream *output, IStream *input, MessageSize *msg_size, uoff_t virtual_skip, uoff_t max_virtual_size); #endif
--- a/src/lib-mail/message-size.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-mail/message-size.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,11 +1,11 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "message-parser.h" #include "message-size.h" -void message_get_header_size(IBuffer *inbuf, MessageSize *hdr) +void message_get_header_size(IStream *input, MessageSize *hdr) { const unsigned char *msg; size_t i, size, startpos, missing_cr_count; @@ -13,7 +13,7 @@ memset(hdr, 0, sizeof(MessageSize)); missing_cr_count = 0; startpos = 0; - while (i_buffer_read_data(inbuf, &msg, &size, startpos) > 0) { + while (i_stream_read_data(input, &msg, &size, startpos) > 0) { for (i = startpos; i < size; i++) { if (msg[i] != '\n') continue; @@ -44,18 +44,18 @@ /* leave the last two characters, they may be \r\n */ startpos = size == 1 ? 1 : 2; - i_buffer_skip(inbuf, i - startpos); + i_stream_skip(input, i - startpos); hdr->physical_size += i - startpos; } - i_buffer_skip(inbuf, startpos); + 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); } -void message_get_body_size(IBuffer *inbuf, MessageSize *body, +void message_get_body_size(IStream *input, MessageSize *body, uoff_t max_virtual_size) { const unsigned char *msg; @@ -65,7 +65,7 @@ missing_cr_count = 0; startpos = 0; while (max_virtual_size != 0 && - i_buffer_read_data(inbuf, &msg, &size, startpos) > 0) { + i_stream_read_data(input, &msg, &size, startpos) > 0) { for (i = startpos; i < size && max_virtual_size != 0; i++) { if (max_virtual_size > 0) max_virtual_size--; @@ -91,19 +91,19 @@ } /* leave the last character, it may be \r */ - i_buffer_skip(inbuf, i - 1); + i_stream_skip(input, i - 1); startpos = 1; body->physical_size += i - 1; } - i_buffer_skip(inbuf, startpos); + i_stream_skip(input, startpos); body->physical_size += startpos; body->virtual_size = body->physical_size + missing_cr_count; i_assert(body->virtual_size >= body->physical_size); } -void message_skip_virtual(IBuffer *inbuf, uoff_t virtual_skip, +void message_skip_virtual(IStream *input, uoff_t virtual_skip, MessageSize *msg_size, int *cr_skipped) { const unsigned char *msg; @@ -114,7 +114,7 @@ return; startpos = 0; - while (i_buffer_read_data(inbuf, &msg, &size, startpos) > 0) { + while (i_stream_read_data(input, &msg, &size, startpos) > 0) { for (i = startpos; i < size && virtual_skip > 0; i++) { virtual_skip--; @@ -151,12 +151,12 @@ } if (i < size) { - i_buffer_skip(inbuf, i); + i_stream_skip(input, i); break; } /* leave the last character, it may be \r */ - i_buffer_skip(inbuf, i - 1); + i_stream_skip(input, i - 1); startpos = 1; } }
--- a/src/lib-mail/message-size.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-mail/message-size.h Fri Dec 06 03:09:22 2002 +0200 @@ -3,18 +3,18 @@ #include "message-parser.h" -/* Calculate size of message header. Leave the inbuf point to first +/* Calculate size of message header. Leave the input point to first character in body. */ -void message_get_header_size(IBuffer *inbuf, MessageSize *hdr); +void message_get_header_size(IStream *input, MessageSize *hdr); /* Calculate size of message body. Read only max_virtual_size virtual bytes, if you want it unlimited, use (uoff_t)-1. */ -void message_get_body_size(IBuffer *inbuf, MessageSize *body, +void message_get_body_size(IStream *input, MessageSize *body, uoff_t max_virtual_size); -/* Skip number of virtual bytes from buffer. If first character is \n, and +/* Skip number of virtual bytes from putfer. If first character is \n, and cr_skipped is FALSE, \r must be sent before it. msg_size is updated if it's not NULL. */ -void message_skip_virtual(IBuffer *inbuf, uoff_t virtual_skip, +void message_skip_virtual(IStream *input, uoff_t virtual_skip, MessageSize *msg_size, int *cr_skipped); /* Sum contents of src into dest. */
--- a/src/lib-storage/index/index-copy.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/index-copy.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "mail-custom-flags.h" #include "index-storage.h" #include "index-messageset.h" @@ -20,12 +20,12 @@ { CopyContext *ctx = context; IndexMailbox *dest_ibox = NULL; - IBuffer *inbuf; + IStream *input; time_t internal_date; int failed, deleted; - inbuf = index->open_mail(index, rec, &internal_date, &deleted); - if (inbuf == NULL) + input = index->open_mail(index, rec, &internal_date, &deleted); + if (input == NULL) return FALSE; if (ctx->copy_inside_mailbox) { @@ -37,12 +37,12 @@ /* save it in destination mailbox */ failed = !ctx->dest->save(ctx->dest, rec->msg_flags, ctx->custom_flags, internal_date, 0, - inbuf, inbuf->v_limit); + input, input->v_limit); if (ctx->copy_inside_mailbox) dest_ibox->delay_save_unlocking = FALSE; - i_buffer_unref(inbuf); + i_stream_unref(input); return !failed; }
--- a/src/lib-storage/index/index-fetch-section.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/index-fetch-section.c Fri Dec 06 03:09:22 2002 +0200 @@ -2,8 +2,8 @@ #include "lib.h" #include "temp-string.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "rfc822-tokenize.h" #include "message-send.h" #include "index-storage.h" @@ -43,13 +43,13 @@ FetchContext *ctx, const char *prefix, int fetch_header) { MessageSize size; - IBuffer *inbuf; + IStream *input; const char *str; int cr_skipped; if (!imap_msgcache_get_rfc822_partial(ctx->cache, sect->skip, sect->max_size, fetch_header, - &size, &inbuf, &cr_skipped)) { + &size, &input, &cr_skipped)) { i_error("Couldn't get BODY[] for UID %u (index %s)", rec->uid, ctx->index->filepath); return FALSE; @@ -57,13 +57,13 @@ str = t_strdup_printf("%s {%"PRIuUOFF_T"}\r\n", prefix, size.virtual_size); - if (o_buffer_send(ctx->outbuf, str, strlen(str)) < 0) + if (o_stream_send(ctx->output, str, strlen(str)) < 0) return FALSE; if (cr_skipped) size.virtual_size++; - return message_send(ctx->outbuf, inbuf, &size, + return message_send(ctx->output, input, &size, cr_skipped ? 1 : 0, sect->max_size); } @@ -139,7 +139,7 @@ typedef struct { TempString *dest; - OBuffer *outbuf; + OStream *output; uoff_t dest_size; uoff_t skip, max_size; @@ -170,8 +170,8 @@ t_string_append_n(ctx->dest, str, size); ctx->dest_size += size; - if (ctx->outbuf != NULL) { - if (o_buffer_send(ctx->outbuf, str, size) < 0) + if (ctx->output != NULL) { + if (o_stream_send(ctx->output, str, size) < 0) return FALSE; } return ctx->dest_size < ctx->max_size; @@ -220,7 +220,7 @@ (void)fetch_header_append(ctx, "\r\n", 2); } -static int fetch_header_fields(IBuffer *inbuf, const char *section, +static int fetch_header_fields(IStream *input, const char *section, FetchHeaderFieldContext *ctx) { if (strncasecmp(section, "HEADER.FIELDS ", 14) == 0) { @@ -238,7 +238,7 @@ } ctx->dest_size = 0; - message_parse_header(NULL, inbuf, NULL, fetch_header_field, ctx); + message_parse_header(NULL, input, NULL, fetch_header_field, ctx); i_assert(ctx->dest_size <= ctx->max_size); i_assert(ctx->dest == NULL || ctx->dest->len == ctx->dest_size); @@ -246,7 +246,7 @@ } /* fetch wanted headers from given data */ -static int fetch_header_from(IBuffer *inbuf, OBuffer *outbuf, +static int fetch_header_from(IStream *input, OStream *output, const char *prefix, MessageSize *size, const char *section, MailFetchBodyData *sect) { @@ -261,61 +261,61 @@ /* all headers */ str = t_strdup_printf("%s {%"PRIuUOFF_T"}\r\n", prefix, size->virtual_size); - if (o_buffer_send(outbuf, str, strlen(str)) < 0) + if (o_stream_send(output, str, strlen(str)) < 0) return FALSE; - return message_send(outbuf, inbuf, size, + return message_send(output, input, size, sect->skip, sect->max_size); } /* partial headers - copy the wanted fields into memory, inserting missing CRs on the way. If the header is too large, calculate - the size first and then send the data directly to output buffer. */ + the size first and then send the data directly to output stream. */ memset(&ctx, 0, sizeof(ctx)); ctx.skip = sect->skip; ctx.max_size = sect->max_size; failed = FALSE; - start_offset = inbuf->v_offset; + start_offset = input->v_offset; t_push(); /* first pass, we need at least the size */ if (size->virtual_size > MAX_HEADER_BUFFER_SIZE && sect->max_size > MAX_HEADER_BUFFER_SIZE) { - if (!fetch_header_fields(inbuf, section, &ctx)) + if (!fetch_header_fields(input, section, &ctx)) failed = TRUE; i_assert(ctx.dest_size <= size->virtual_size); } else { ctx.dest = t_string_new(size->virtual_size < 4096 ? size->virtual_size : 4096); - if (!fetch_header_fields(inbuf, section, &ctx)) + if (!fetch_header_fields(input, section, &ctx)) failed = TRUE; } if (!failed) { str = t_strdup_printf("%s {%"PRIuUOFF_T"}\r\n", prefix, ctx.dest_size); - if (o_buffer_send(outbuf, str, strlen(str)) < 0) + if (o_stream_send(output, str, strlen(str)) < 0) failed = TRUE; } if (!failed) { if (ctx.dest == NULL) { - /* second pass, write the data to output buffer */ + /* second pass, write the data to output stream */ uoff_t first_size = ctx.dest_size; - ctx.outbuf = outbuf; - i_buffer_seek(inbuf, start_offset); + ctx.output = output; + i_stream_seek(input, start_offset); if (!failed && - !fetch_header_fields(inbuf, section, &ctx)) + !fetch_header_fields(input, section, &ctx)) failed = TRUE; i_assert(first_size == ctx.dest_size); } else { - if (o_buffer_send(outbuf, ctx.dest->str, + if (o_stream_send(output, ctx.dest->str, ctx.dest->len) < 0) failed = TRUE; } @@ -330,12 +330,12 @@ const char *prefix) { MessageSize hdr_size; - IBuffer *inbuf; + IStream *input; - if (!imap_msgcache_get_rfc822(ctx->cache, &inbuf, &hdr_size, NULL)) + if (!imap_msgcache_get_rfc822(ctx->cache, &input, &hdr_size, NULL)) return FALSE; - return fetch_header_from(inbuf, ctx->outbuf, prefix, &hdr_size, + return fetch_header_from(input, ctx->output, prefix, &hdr_size, sect->section, sect); } @@ -389,25 +389,25 @@ static int fetch_part_body(MessagePart *part, MailFetchBodyData *sect, FetchContext *ctx, const char *prefix) { - IBuffer *inbuf; + IStream *input; const char *str; uoff_t skip_pos; - if (!imap_msgcache_get_data(ctx->cache, &inbuf)) + if (!imap_msgcache_get_data(ctx->cache, &input)) return FALSE; /* jump to beginning of wanted data */ skip_pos = part->physical_pos + part->header_size.physical_size; - i_buffer_skip(inbuf, skip_pos); + i_stream_skip(input, skip_pos); str = t_strdup_printf("%s {%"PRIuUOFF_T"}\r\n", prefix, part->body_size.virtual_size); - if (o_buffer_send(ctx->outbuf, str, strlen(str)) < 0) + if (o_stream_send(ctx->output, str, strlen(str)) < 0) return FALSE; /* FIXME: potential performance problem with big messages: FETCH BODY[1]<100000..1024>, hopefully no clients do this */ - return message_send(ctx->outbuf, inbuf, &part->body_size, + return message_send(ctx->output, input, &part->body_size, sect->skip, sect->max_size); } @@ -416,13 +416,13 @@ MailFetchBodyData *sect, FetchContext *ctx, const char *prefix) { - IBuffer *inbuf; + IStream *input; - if (!imap_msgcache_get_data(ctx->cache, &inbuf)) + if (!imap_msgcache_get_data(ctx->cache, &input)) return FALSE; - i_buffer_skip(inbuf, part->physical_pos); - return fetch_header_from(inbuf, ctx->outbuf, prefix, &part->header_size, + i_stream_skip(input, part->physical_pos); + return fetch_header_from(input, ctx->output, prefix, &part->header_size, section, sect); }
--- a/src/lib-storage/index/index-fetch.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/index-fetch.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "obuffer.h" +#include "ostream.h" #include "temp-string.h" #include "mail-custom-flags.h" #include "index-storage.h" @@ -119,10 +119,10 @@ static int index_fetch_send_rfc822(MailIndexRecord *rec, FetchContext *ctx) { MessageSize hdr_size, body_size; - IBuffer *inbuf; + IStream *input; const char *str; - if (!imap_msgcache_get_rfc822(ctx->cache, &inbuf, + if (!imap_msgcache_get_rfc822(ctx->cache, &input, &hdr_size, &body_size)) { mail_storage_set_critical(ctx->storage, "Couldn't get RFC822 for UID %u (index %s)", @@ -135,22 +135,22 @@ if (ctx->first) { str++; ctx->first = FALSE; } - if (o_buffer_send(ctx->outbuf, str, strlen(str)) < 0) + if (o_stream_send(ctx->output, str, strlen(str)) < 0) return FALSE; body_size.physical_size += hdr_size.physical_size; body_size.virtual_size += hdr_size.virtual_size; - return message_send(ctx->outbuf, inbuf, &body_size, 0, (uoff_t)-1); + return message_send(ctx->output, input, &body_size, 0, (uoff_t)-1); } static int index_fetch_send_rfc822_header(MailIndexRecord *rec, FetchContext *ctx) { MessageSize hdr_size; - IBuffer *inbuf; + IStream *input; const char *str; - if (!imap_msgcache_get_rfc822(ctx->cache, &inbuf, &hdr_size, NULL)) { + if (!imap_msgcache_get_rfc822(ctx->cache, &input, &hdr_size, NULL)) { mail_storage_set_critical(ctx->storage, "Couldn't get RFC822.HEADER for UID %u (index %s)", rec->uid, ctx->index->filepath); @@ -162,19 +162,19 @@ if (ctx->first) { str++; ctx->first = FALSE; } - if (o_buffer_send(ctx->outbuf, str, strlen(str)) < 0) + if (o_stream_send(ctx->output, str, strlen(str)) < 0) return FALSE; - return message_send(ctx->outbuf, inbuf, &hdr_size, 0, (uoff_t)-1); + return message_send(ctx->output, input, &hdr_size, 0, (uoff_t)-1); } static int index_fetch_send_rfc822_text(MailIndexRecord *rec, FetchContext *ctx) { MessageSize body_size; - IBuffer *inbuf; + IStream *input; const char *str; - if (!imap_msgcache_get_rfc822(ctx->cache, &inbuf, NULL, &body_size)) { + if (!imap_msgcache_get_rfc822(ctx->cache, &input, NULL, &body_size)) { mail_storage_set_critical(ctx->storage, "Couldn't get RFC822.TEXT for UID %u (index %s)", rec->uid, ctx->index->filepath); @@ -186,10 +186,10 @@ if (ctx->first) { str++; ctx->first = FALSE; } - if (o_buffer_send(ctx->outbuf, str, strlen(str)) < 0) + if (o_stream_send(ctx->output, str, strlen(str)) < 0) return FALSE; - return message_send(ctx->outbuf, inbuf, &body_size, 0, (uoff_t)-1); + return message_send(ctx->output, input, &body_size, 0, (uoff_t)-1); } static ImapCacheField index_get_cache(MailFetchData *fetch_data) @@ -303,7 +303,7 @@ if (!ctx->first) ctx->str->len--; - if (o_buffer_send(ctx->outbuf, ctx->str->str, + if (o_stream_send(ctx->output, ctx->str->str, ctx->str->len) < 0) break; } @@ -331,7 +331,7 @@ } while (0); if (data_written) { - if (o_buffer_send(ctx->outbuf, ")\r\n", 3) < 0) + if (o_stream_send(ctx->output, ")\r\n", 3) < 0) failed = TRUE; } @@ -340,7 +340,7 @@ } int index_storage_fetch(Mailbox *box, MailFetchData *fetch_data, - OBuffer *outbuf, int *all_found) + OStream *output, int *all_found) { IndexMailbox *ibox = (IndexMailbox *) box; FetchContext ctx; @@ -391,7 +391,7 @@ ctx.custom_flags_count = MAIL_CUSTOM_FLAGS_COUNT; ctx.fetch_data = fetch_data; - ctx.outbuf = outbuf; + ctx.output = output; ret = index_messageset_foreach(ibox, fetch_data->messageset, fetch_data->uidset,
--- a/src/lib-storage/index/index-fetch.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/index-fetch.h Fri Dec 06 03:09:22 2002 +0200 @@ -11,7 +11,7 @@ unsigned int custom_flags_count; MailFetchData *fetch_data; - OBuffer *outbuf; + OStream *output; TempString *str; int update_seen, failed; int first;
--- a/src/lib-storage/index/index-msgcache.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/index-msgcache.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "imap-date.h" #include "imap-message-cache.h" #include "message-part-serialize.h" @@ -71,7 +71,7 @@ full_virtual_size, ctx); } -static IBuffer *index_msgcache_open_mail(void *context) +static IStream *index_msgcache_open_mail(void *context) { IndexMsgcacheContext *ctx = context; int deleted; @@ -80,11 +80,11 @@ &ctx->internal_date, &deleted); } -static IBuffer *index_msgcache_inbuf_rewind(IBuffer *inbuf, - void *context __attr_unused__) +static IStream *index_msgcache_stream_rewind(IStream *input, + void *context __attr_unused__) { - i_buffer_seek(inbuf, 0); - return inbuf; + i_stream_seek(input, 0); + return input; } static const char *index_msgcache_get_cached_field(ImapCacheField field, @@ -169,7 +169,7 @@ ImapMessageCacheIface index_msgcache_iface = { index_msgcache_open_mail, - index_msgcache_inbuf_rewind, + index_msgcache_stream_rewind, index_msgcache_get_cached_field, index_msgcache_get_cached_parts, index_msgcache_get_internal_date
--- a/src/lib-storage/index/index-save.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/index-save.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,15 +1,15 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "write-full.h" #include "index-storage.h" #include <stdlib.h> #include <unistd.h> -static int write_with_crlf(OBuffer *outbuf, const unsigned char *data, +static int write_with_crlf(OStream *output, const unsigned char *data, size_t size) { size_t i, start; @@ -20,9 +20,9 @@ for (i = 0; i < size; i++) { if (data[i] == '\n' && (i == 0 || data[i-1] != '\r')) { /* missing CR */ - if (o_buffer_send(outbuf, data + start, i - start) < 0) + if (o_stream_send(output, data + start, i - start) < 0) return -1; - if (o_buffer_send(outbuf, "\r", 1) < 0) + if (o_stream_send(output, "\r", 1) < 0) return -1; /* \n is written next time */ @@ -34,13 +34,13 @@ if (data[size-1] == '\r') size--; - if (o_buffer_send(outbuf, data + start, size - start) < 0) + if (o_stream_send(output, data + start, size - start) < 0) return -1; return size; } -static int write_with_lf(OBuffer *outbuf, const unsigned char *data, +static int write_with_lf(OStream *output, const unsigned char *data, size_t size) { size_t i, start; @@ -51,7 +51,7 @@ for (i = 0; i < size; i++) { if (data[i] == '\n' && i > 0 && data[i-1] == '\r') { /* \r\n - skip \r */ - if (o_buffer_send(outbuf, data + start, + if (o_stream_send(output, data + start, i - start - 1) < 0) return -1; @@ -64,16 +64,16 @@ if (data[size-1] == '\r') size--; - if (o_buffer_send(outbuf, data + start, size - start) < 0) + if (o_stream_send(output, data + start, size - start) < 0) return -1; return size; } int index_storage_save(MailStorage *storage, const char *path, - IBuffer *inbuf, OBuffer *outbuf, uoff_t data_size) + IStream *input, OStream *output, uoff_t data_size) { - int (*write_func)(OBuffer *, const unsigned char *, size_t); + int (*write_func)(OStream *, const unsigned char *, size_t); const unsigned char *data; size_t size; ssize_t ret; @@ -83,9 +83,9 @@ failed = FALSE; while (data_size > 0) { - ret = i_buffer_read(inbuf); + ret = i_stream_read(input); if (ret < 0) { - errno = inbuf->buf_errno; + errno = input->stream_errno; if (errno == 0) { mail_storage_set_error(storage, "Client disconnected"); @@ -99,14 +99,14 @@ return FALSE; } - data = i_buffer_get_data(inbuf, &size); + data = i_stream_get_data(input, &size); if (size > data_size) size = (size_t)data_size; if (!failed) { - ret = write_func(outbuf, data, size); + ret = write_func(output, data, size); if (ret < 0) { - errno = outbuf->buf_errno; + errno = output->stream_errno; if (errno == ENOSPC) { mail_storage_set_error(storage, "Not enough disk space"); @@ -122,7 +122,7 @@ } data_size -= size; - i_buffer_skip(inbuf, size); + i_stream_skip(input, size); } return !failed;
--- a/src/lib-storage/index/index-search.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/index-search.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,8 +1,8 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "mmap-util.h" #include "rfc822-tokenize.h" #include "rfc822-date.h" @@ -50,7 +50,7 @@ typedef struct { SearchIndexContext *index_ctx; - IBuffer *inbuf; + IStream *input; MessagePart *part; } SearchBodyContext; @@ -533,10 +533,10 @@ return; if (arg->type == SEARCH_TEXT || arg->type == SEARCH_BODY) { - i_buffer_seek(ctx->inbuf, 0); + i_stream_seek(ctx->input, 0); ret = message_body_search(arg->value.str, ctx->index_ctx->charset, - &unknown_charset, ctx->inbuf, + &unknown_charset, ctx->input, ctx->part, arg->type == SEARCH_TEXT); if (ret < 0) { @@ -550,7 +550,7 @@ static int search_arg_match_text(MailSearchArg *args, SearchIndexContext *ctx) { - IBuffer *inbuf; + IStream *input; int have_headers, have_body, have_text; /* first check what we need to use */ @@ -561,7 +561,7 @@ if (have_headers || have_text) { SearchHeaderContext hdr_ctx; - if (!imap_msgcache_get_data(search_open_cache(ctx), &inbuf)) + if (!imap_msgcache_get_data(search_open_cache(ctx), &input)) return FALSE; memset(&hdr_ctx, 0, sizeof(hdr_ctx)); @@ -569,10 +569,10 @@ hdr_ctx.custom_header = TRUE; hdr_ctx.args = args; - message_parse_header(NULL, inbuf, NULL, + message_parse_header(NULL, input, NULL, search_header, &hdr_ctx); } else { - if (!imap_msgcache_get_rfc822(search_open_cache(ctx), &inbuf, + if (!imap_msgcache_get_rfc822(search_open_cache(ctx), &input, NULL, NULL)) return FALSE; } @@ -582,7 +582,7 @@ memset(&body_ctx, 0, sizeof(body_ctx)); body_ctx.index_ctx = ctx; - body_ctx.inbuf = inbuf; + body_ctx.input = input; body_ctx.part = imap_msgcache_get_parts(search_open_cache(ctx)); mail_search_args_foreach(args, search_body, &body_ctx); @@ -757,7 +757,7 @@ static int search_messages(IndexMailbox *ibox, const char *charset, MailSearchArg *args, MailSortContext *sort_ctx, - OBuffer *outbuf, int uid_result) + OStream *output, int uid_result) { SearchIndexContext ctx; MailIndexRecord *rec; @@ -831,7 +831,7 @@ len = i_snprintf(num, sizeof(num), " %u", uid_result ? rec->uid : client_seq); - o_buffer_send(outbuf, num, len); + o_stream_send(output, num, len); } else { mail_sort_input(sort_ctx, rec->uid); } @@ -850,7 +850,7 @@ } int index_storage_search(Mailbox *box, const char *charset, MailSearchArg *args, - MailSortType *sorting, OBuffer *outbuf, int uid_result) + MailSortType *sorting, OStream *output, int uid_result) { IndexMailbox *ibox = (IndexMailbox *) box; MailSortContext *sort_ctx; @@ -862,23 +862,23 @@ if (sorting == NULL) { sort_ctx = NULL; - o_buffer_send(outbuf, "* SEARCH", 8); + o_stream_send(output, "* SEARCH", 8); } else { memset(&index_sort_ctx, 0, sizeof(index_sort_ctx)); index_sort_ctx.ibox = ibox; - index_sort_ctx.outbuf = outbuf; + index_sort_ctx.output = output; sort_ctx = mail_sort_init(sort_unsorted, sorting, index_sort_funcs, &index_sort_ctx); - o_buffer_send(outbuf, "* SORT", 6); + o_stream_send(output, "* SORT", 6); } failed = !search_messages(ibox, charset, args, sort_ctx, - outbuf, uid_result); + output, uid_result); if (sort_ctx != NULL) mail_sort_deinit(sort_ctx); - o_buffer_send(outbuf, "\r\n", 2); + o_stream_send(output, "\r\n", 2); if (!index_storage_lock(ibox, MAIL_LOCK_UNLOCK)) return FALSE;
--- a/src/lib-storage/index/index-sort.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/index-sort.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "obuffer.h" +#include "ostream.h" #include "rfc822-date.h" #include "imap-envelope.h" #include "imap-message-cache.h" @@ -124,7 +124,7 @@ for (i = 0; i < count; i++) { len = i_snprintf(num, sizeof(num), " %u", data[i]); - o_buffer_send(ctx->outbuf, num, len); + o_stream_send(ctx->output, num, len); } }
--- a/src/lib-storage/index/index-sort.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/index-sort.h Fri Dec 06 03:09:22 2002 +0200 @@ -6,7 +6,7 @@ typedef struct { IndexMailbox *ibox; - OBuffer *outbuf; + OStream *output; unsigned int last_uid; MailIndexRecord *rec;
--- a/src/lib-storage/index/index-storage.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/index-storage.h Fri Dec 06 03:09:22 2002 +0200 @@ -59,7 +59,7 @@ unsigned int seq, int notify); int index_storage_save(MailStorage *storage, const char *path, - IBuffer *inbuf, OBuffer *outbuf, uoff_t data_size); + IStream *input, OStream *output, uoff_t data_size); int index_msgcache_open(ImapMessageCache *cache, MailIndex *index, MailIndexRecord *rec, ImapCacheField fields); @@ -82,9 +82,9 @@ ModifyType modify_type, int notify, int *all_found); int index_storage_fetch(Mailbox *box, MailFetchData *fetch_data, - OBuffer *outbuf, int *all_found); + OStream *output, int *all_found); int index_storage_search(Mailbox *box, const char *charset, MailSearchArg *args, - MailSortType *sorting, OBuffer *outbuf, + MailSortType *sorting, OStream *output, int uid_result); #endif
--- a/src/lib-storage/index/maildir/maildir-save.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/maildir/maildir-save.c Fri Dec 06 03:09:22 2002 +0200 @@ -3,7 +3,7 @@ #include "lib.h" #include "ioloop.h" #include "hostpid.h" -#include "obuffer.h" +#include "ostream.h" #include "maildir-index.h" #include "maildir-storage.h" @@ -48,10 +48,10 @@ } static const char *maildir_read_into_tmp(MailStorage *storage, const char *dir, - IBuffer *buf, uoff_t data_size) + IStream *input, uoff_t data_size) { const char *fname, *path; - OBuffer *outbuf; + OStream *output; int fd; fd = maildir_create_tmp(storage, dir, &fname); @@ -59,15 +59,15 @@ return NULL; t_push(); - outbuf = o_buffer_create_file(fd, data_stack_pool, 4096, + output = o_stream_create_file(fd, data_stack_pool, 4096, IO_PRIORITY_DEFAULT, FALSE); - o_buffer_set_blocking(outbuf, 60000, NULL, NULL); + o_stream_set_blocking(output, 60000, NULL, NULL); path = t_strconcat(dir, "/", fname, NULL); - if (!index_storage_save(storage, path, buf, outbuf, data_size)) + if (!index_storage_save(storage, path, input, output, data_size)) fname = NULL; - o_buffer_unref(outbuf); + o_stream_unref(output); if (close(fd) < 0) fname = NULL; @@ -80,7 +80,7 @@ int maildir_storage_save(Mailbox *box, MailFlags flags, const char *custom_flags[], time_t internal_date, int timezone_offset __attr_unused__, - IBuffer *data, uoff_t data_size) + IStream *data, uoff_t data_size) { IndexMailbox *ibox = (IndexMailbox *) box; struct utimbuf buf;
--- a/src/lib-storage/index/maildir/maildir-storage.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/maildir/maildir-storage.h Fri Dec 06 03:09:22 2002 +0200 @@ -8,7 +8,7 @@ int maildir_storage_save(Mailbox *box, MailFlags flags, const char *custom_flags[], time_t internal_date, int timezone_offset, - IBuffer *data, uoff_t data_size); + IStream *data, uoff_t data_size); int maildir_find_mailboxes(MailStorage *storage, const char *mask, MailboxFunc func, void *context);
--- a/src/lib-storage/index/mbox/mbox-expunge.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/mbox/mbox-expunge.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,8 +1,8 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "mbox-index.h" #include "mbox-storage.h" #include "mbox-lock.h" @@ -11,7 +11,7 @@ #include <unistd.h> static int expunge_real(IndexMailbox *ibox, MailIndexRecord *rec, - unsigned int seq, IBuffer *inbuf, OBuffer *outbuf, + unsigned int seq, IStream *input, OStream *output, int notify) { uoff_t offset, hdr_size, body_size; @@ -36,7 +36,7 @@ rec = ibox->index->next(ibox->index, rec); } - old_limit = inbuf->v_limit; + old_limit = input->v_limit; expunges = FALSE; while (rec != NULL) { @@ -55,33 +55,33 @@ if (!expunges) { /* first expunged record, seek to position where we want to begin writing */ - if (!o_buffer_seek(outbuf, from_offset)) + if (!o_stream_seek(output, from_offset)) return FALSE; expunges = TRUE; } } else if (expunges) { /* seek to wanted input position, and copy this messages */ - i_assert(inbuf->v_offset <= from_offset); - i_buffer_skip(inbuf, from_offset - inbuf->v_offset); + i_assert(input->v_offset <= from_offset); + i_stream_skip(input, from_offset - input->v_offset); - if (outbuf->offset == 0) { + if (output->offset == 0) { /* we're writing to beginning of mbox, so we don't want the [\r]\n there */ - (void)i_buffer_read_data(inbuf, &data, + (void)i_stream_read_data(input, &data, &size, 1); if (size > 0 && data[0] == '\n') - i_buffer_skip(inbuf, 1); + i_stream_skip(input, 1); else if (size > 1 && data[0] == '\r' && data[1] == '\n') - i_buffer_skip(inbuf, 2); + i_stream_skip(input, 2); } - i_buffer_set_read_limit(inbuf, end_offset); - failed = o_buffer_send_ibuffer(outbuf, inbuf) < 0; - i_buffer_set_read_limit(inbuf, old_limit); + i_stream_set_read_limit(input, end_offset); + failed = o_stream_send_istream(output, input) < 0; + i_stream_set_read_limit(input, old_limit); - if (failed || inbuf->v_offset != end_offset) + if (failed || input->v_offset != end_offset) return FALSE; } @@ -89,23 +89,23 @@ seq++; } - i_buffer_skip(inbuf, end_offset - inbuf->v_offset); + i_stream_skip(input, end_offset - input->v_offset); /* copy the rest as well, should be only \n but someone might as well just appended more data.. but if we've deleted all mail, don't write the only \n there. */ - copy_size = inbuf->v_size - inbuf->v_offset; - if (outbuf->offset == 0 && copy_size == 1) + copy_size = input->v_size - input->v_offset; + if (output->offset == 0 && copy_size == 1) return TRUE; - return o_buffer_send_ibuffer(outbuf, inbuf) >= 0; + return o_stream_send_istream(output, input) >= 0; } int mbox_expunge_locked(IndexMailbox *ibox, int notify) { MailIndexRecord *rec; - IBuffer *inbuf; - OBuffer *outbuf; + IStream *input; + OStream *output; unsigned int seq; int failed; @@ -118,35 +118,35 @@ } /* mbox must be already opened, synced and locked at this point. - we just want the IBuffer. */ - inbuf = mbox_get_inbuf(ibox->index, 0, MAIL_LOCK_EXCLUSIVE); - if (inbuf == NULL) + we just want the IStream. */ + input = mbox_get_stream(ibox->index, 0, MAIL_LOCK_EXCLUSIVE); + if (input == NULL) return FALSE; i_assert(ibox->index->mbox_sync_counter == ibox->index->mbox_lock_counter); t_push(); - outbuf = o_buffer_create_file(ibox->index->mbox_fd, data_stack_pool, + output = o_stream_create_file(ibox->index->mbox_fd, data_stack_pool, 4096, 0, FALSE); - o_buffer_set_blocking(outbuf, 60000, NULL, NULL); + o_stream_set_blocking(output, 60000, NULL, NULL); - failed = !expunge_real(ibox, rec, seq, inbuf, outbuf, notify); + failed = !expunge_real(ibox, rec, seq, input, output, notify); - if (failed && outbuf->offset > 0) { + if (failed && output->offset > 0) { /* we moved some of the data. move the rest as well so there won't be invalid holes in mbox file */ - (void)o_buffer_send_ibuffer(outbuf, inbuf); + (void)o_stream_send_istream(output, input); } - if (ftruncate(ibox->index->mbox_fd, (off_t)outbuf->offset) < 0) { + if (ftruncate(ibox->index->mbox_fd, (off_t)output->offset) < 0) { mail_storage_set_error(ibox->box.storage, "ftruncate() failed " "for mbox file %s: %m", ibox->index->mbox_path); failed = TRUE; } - o_buffer_unref(outbuf); + o_stream_unref(output); t_pop(); return !failed;
--- a/src/lib-storage/index/mbox/mbox-save.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/mbox/mbox-save.c Fri Dec 06 03:09:22 2002 +0200 @@ -2,7 +2,7 @@ #include "lib.h" #include "hostpid.h" -#include "obuffer.h" +#include "ostream.h" #include "write-full.h" #include "mbox-index.h" #include "mbox-lock.h" @@ -65,16 +65,16 @@ return TRUE; } -static int mbox_append_lf(MailStorage *storage, OBuffer *outbuf, +static int mbox_append_lf(MailStorage *storage, OStream *output, const char *mbox_path) { - if (o_buffer_send(outbuf, "\n", 1) < 0) + if (o_stream_send(output, "\n", 1) < 0) return write_error(storage, mbox_path); return TRUE; } -static int write_from_line(MailStorage *storage, OBuffer *outbuf, +static int write_from_line(MailStorage *storage, OStream *output, const char *mbox_path, time_t internal_date) { const char *sender, *line, *name; @@ -102,13 +102,13 @@ line = mbox_from_create(sender, internal_date); len = strlen(line); - if (o_buffer_send(outbuf, line, len) < 0) + if (o_stream_send(output, line, len) < 0) return write_error(storage, mbox_path); return TRUE; } -static int write_flags(MailStorage *storage, OBuffer *outbuf, +static int write_flags(MailStorage *storage, OStream *output, const char *mbox_path, MailFlags flags, const char *custom_flags[]) { @@ -120,7 +120,7 @@ return TRUE; if (flags & MAIL_SEEN) { - if (o_buffer_send(outbuf, "Status: R\n", 10) < 0) + if (o_stream_send(output, "Status: R\n", 10) < 0) return write_error(storage, mbox_path); } @@ -132,27 +132,27 @@ (flags & MAIL_DELETED) ? "T" : "", "\n", NULL); - if (o_buffer_send(outbuf, str, strlen(str)) < 0) + if (o_stream_send(output, str, strlen(str)) < 0) return write_error(storage, mbox_path); } if (flags & MAIL_CUSTOM_FLAGS_MASK) { - if (o_buffer_send(outbuf, "X-Keywords:", 11) < 0) + if (o_stream_send(output, "X-Keywords:", 11) < 0) return write_error(storage, mbox_path); field = 1 << MAIL_CUSTOM_FLAG_1_BIT; for (i = 0; i < MAIL_CUSTOM_FLAGS_COUNT; i++, field <<= 1) { if ((flags & field) && custom_flags[i] != NULL) { - if (o_buffer_send(outbuf, " ", 1) < 0) + if (o_stream_send(output, " ", 1) < 0) return write_error(storage, mbox_path); - if (o_buffer_send(outbuf, custom_flags[i], + if (o_stream_send(output, custom_flags[i], strlen(custom_flags[i])) < 0) return write_error(storage, mbox_path); } } - if (o_buffer_send(outbuf, "\n", 1) < 0) + if (o_stream_send(output, "\n", 1) < 0) return write_error(storage, mbox_path); } @@ -161,13 +161,13 @@ int mbox_storage_save(Mailbox *box, MailFlags flags, const char *custom_flags[], time_t internal_date, int timezone_offset __attr_unused__, - IBuffer *data, uoff_t data_size) + IStream *data, uoff_t data_size) { IndexMailbox *ibox = (IndexMailbox *) box; MailIndex *index; MailFlags real_flags; const char *mbox_path; - OBuffer *outbuf; + OStream *output; int failed; off_t pos; @@ -193,26 +193,26 @@ failed = FALSE; t_push(); - outbuf = o_buffer_create_file(index->mbox_fd, + output = o_stream_create_file(index->mbox_fd, data_stack_pool, 4096, 0, FALSE); - o_buffer_set_blocking(outbuf, 60000, NULL, NULL); + o_stream_set_blocking(output, 60000, NULL, NULL); - if (!write_from_line(box->storage, outbuf, mbox_path, + if (!write_from_line(box->storage, output, mbox_path, internal_date) || - !write_flags(box->storage, outbuf, mbox_path, flags, + !write_flags(box->storage, output, mbox_path, flags, custom_flags) || !index_storage_save(box->storage, mbox_path, - data, outbuf, data_size) || - !mbox_append_lf(box->storage, outbuf, mbox_path)) { + data, output, data_size) || + !mbox_append_lf(box->storage, output, mbox_path)) { /* failed, truncate file back to original size. - output buffer needs to be flushed before truncating + output stream needs to be flushed before truncating so unref() won't write anything. */ - o_buffer_flush(outbuf); + o_stream_flush(output); (void)ftruncate(index->mbox_fd, pos); failed = TRUE; } - o_buffer_unref(outbuf); + o_stream_unref(output); t_pop(); }
--- a/src/lib-storage/index/mbox/mbox-storage.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/index/mbox/mbox-storage.h Fri Dec 06 03:09:22 2002 +0200 @@ -7,7 +7,7 @@ const char *messageset, int uidset); int mbox_storage_save(Mailbox *box, MailFlags flags, const char *custom_flags[], time_t internal_date, int timezone_offset, - IBuffer *data, uoff_t data_size); + IStream *data, uoff_t data_size); int mbox_find_mailboxes(MailStorage *storage, const char *mask, MailboxFunc func, void *context);
--- a/src/lib-storage/mail-sort.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/mail-sort.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "obuffer.h" +#include "ostream.h" #include "mail-sort.h" #include <stdlib.h>
--- a/src/lib-storage/mail-storage.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib-storage/mail-storage.h Fri Dec 06 03:09:22 2002 +0200 @@ -152,24 +152,24 @@ int (*copy)(Mailbox *box, Mailbox *destbox, const char *messageset, int uidset); - /* Fetch wanted mail data. The results are written into outbuf + /* Fetch wanted mail data. The results are written into output stream in RFC2060 FETCH format. */ int (*fetch)(Mailbox *box, MailFetchData *fetch_data, - OBuffer *outbuf, int *all_found); + OStream *output, int *all_found); /* Search wanted mail data. args contains the search criteria. - Results are written into outbuf in RFC2060 SEARCH format. + Results are written into output stream in RFC2060 SEARCH format. If charset is NULL, the given search strings are matched without any conversion. */ int (*search)(Mailbox *box, const char *charset, MailSearchArg *args, - MailSortType *sorting, OBuffer *outbuf, int uid_result); + MailSortType *sorting, OStream *output, int uid_result); /* Save a new mail into mailbox. timezone_offset specifies the timezone in minutes which internal_date was originally given with. */ int (*save)(Mailbox *box, MailFlags flags, const char *custom_flags[], time_t internal_date, int timezone_offset, - IBuffer *data, uoff_t data_size); + IStream *data, uoff_t data_size); /* Returns TRUE if mailbox is now in inconsistent state, meaning that the message IDs etc. may have changed - only way to recover this
--- a/src/lib/Makefile.am Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib/Makefile.am Fri Dec 06 03:09:22 2002 +0200 @@ -15,11 +15,11 @@ hex-binary.c \ hostpid.c \ imem.c \ - iobuffer.c \ - ibuffer.c \ - ibuffer-data.c \ - ibuffer-file.c \ - ibuffer-mmap.c \ + iostream.c \ + istream.c \ + istream-data.c \ + istream-file.c \ + istream-mmap.c \ ioloop.c \ ioloop-poll.c \ ioloop-select.c \ @@ -33,8 +33,8 @@ mmap-anon.c \ mmap-util.c \ network.c \ - obuffer.c \ - obuffer-file.c \ + ostream.c \ + ostream-file.c \ primes.c \ process-title.c \ randgen.c \ @@ -64,9 +64,9 @@ hex-binary.h \ hostpid.h \ imem.h \ - iobuffer-internal.h \ - ibuffer.h \ - ibuffer-internal.h \ + iostream-internal.h \ + istream.h \ + istream-internal.h \ ioloop.h \ ioloop-internal.h \ lib.h \ @@ -76,8 +76,8 @@ mempool.h \ mmap-util.h \ network.h \ - obuffer.h \ - obuffer-internal.h \ + ostream.h \ + ostream-internal.h \ primes.h \ process-title.h \ randgen.h \
--- a/src/lib/ibuffer-data.c Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - ibuffer-data.c : Input buffer interface for reading from data buffer - - Copyright (c) 2002 Timo Sirainen - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "lib.h" -#include "ibuffer-internal.h" - -static void _close(_IOBuffer *buf __attr_unused__) -{ -} - -static void _destroy(_IOBuffer *buf __attr_unused__) -{ -} - -static void _set_max_size(_IOBuffer *buf __attr_unused__, - size_t max_size __attr_unused__) -{ -} - -static void _set_blocking(_IOBuffer *buf __attr_unused__, - int timeout_msecs __attr_unused__, - void (*timeout_func)(void *) __attr_unused__, - void *context __attr_unused__) -{ -} - -static ssize_t _read(_IBuffer *buf) -{ - return buf->pos - buf->skip; -} - -static void _seek(_IBuffer *buf, uoff_t v_offset) -{ - buf->skip = v_offset; - buf->ibuffer.v_offset = v_offset; -} - -static void _skip(_IBuffer *buf, uoff_t count) -{ - buf->skip += count; - buf->ibuffer.v_offset += count; -} - -IBuffer *i_buffer_create_from_data(Pool pool, const unsigned char *data, - size_t size) -{ - _IBuffer *buf; - - buf = p_new(pool, _IBuffer, 1); - buf->buffer = data; - buf->pos = size; - - buf->iobuf.close = _close; - buf->iobuf.destroy = _destroy; - buf->iobuf.set_max_size = _set_max_size; - buf->iobuf.set_blocking = _set_blocking; - - buf->read = _read; - buf->skip_count = _skip; - buf->seek = _seek; - - return _i_buffer_create(buf, pool, -1, 0, size); -}
--- a/src/lib/ibuffer-file.c Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,290 +0,0 @@ -/* - ibuffer-file.c : Input buffer handling for files - - Copyright (c) 2002 Timo Sirainen - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "lib.h" -#include "alarm-hup.h" -#include "ibuffer-internal.h" -#include "network.h" - -#include <time.h> -#include <unistd.h> -#include <sys/stat.h> - -#define I_BUFFER_MIN_SIZE 4096 - -#define BUFFER_IS_BLOCKING(fbuf) \ - ((fbuf)->timeout_msecs != 0) - -typedef struct { - _IBuffer ibuf; - - size_t max_buffer_size; - uoff_t skip_left; - - int timeout_msecs; - void (*timeout_func)(void *); - void *timeout_context; - - unsigned int file:1; - unsigned int autoclose_fd:1; -} FileIBuffer; - -static void _close(_IOBuffer *buf) -{ - FileIBuffer *fbuf = (FileIBuffer *) buf; - _IBuffer *_buf = (_IBuffer *) buf; - - if (fbuf->autoclose_fd && _buf->fd != -1) { - if (close(_buf->fd) < 0) - i_error("FileIBuffer.close() failed: %m"); - _buf->fd = -1; - } -} - -static void _destroy(_IOBuffer *buf) -{ - _IBuffer *_buf = (_IBuffer *) buf; - - p_free(_buf->iobuf.pool, _buf->w_buffer); -} - -static void _set_max_size(_IOBuffer *buf, size_t max_size) -{ - FileIBuffer *fbuf = (FileIBuffer *) buf; - - fbuf->max_buffer_size = max_size; -} - -static void _set_blocking(_IOBuffer *buf, int timeout_msecs, - void (*timeout_func)(void *), void *context) -{ - FileIBuffer *fbuf = (FileIBuffer *) buf; - - fbuf->timeout_msecs = timeout_msecs; - fbuf->timeout_func = timeout_func; - fbuf->timeout_context = context; - - net_set_nonblock(fbuf->ibuf.fd, timeout_msecs == 0); - - if (timeout_msecs != 0) - alarm_hup_init(); -} - -static void i_buffer_grow(_IBuffer *buf, size_t bytes) -{ - FileIBuffer *fbuf = (FileIBuffer *) buf; - - buf->buffer_size = buf->pos + bytes; - buf->buffer_size = - buf->buffer_size <= I_BUFFER_MIN_SIZE ? I_BUFFER_MIN_SIZE : - nearest_power(buf->buffer_size); - - if (fbuf->max_buffer_size > 0 && - buf->buffer_size > fbuf->max_buffer_size) - buf->buffer_size = fbuf->max_buffer_size; - - buf->buffer = buf->w_buffer = - p_realloc(buf->iobuf.pool, buf->w_buffer, buf->buffer_size); -} - -static void i_buffer_compress(_IBuffer *buf) -{ - memmove(buf->w_buffer, buf->w_buffer + buf->skip, buf->pos - buf->skip); - buf->pos -= buf->skip; - - if (buf->skip > buf->cr_lookup_pos) - buf->cr_lookup_pos = 0; - else - buf->cr_lookup_pos -= buf->skip; - - buf->skip = 0; -} - -static ssize_t _read(_IBuffer *buf) -{ - FileIBuffer *fbuf = (FileIBuffer *) buf; - time_t timeout_time; - uoff_t read_limit; - size_t size; - ssize_t ret; - - if (buf->ibuffer.closed) - return -1; - - if (fbuf->skip_left > 0) { - i_assert(buf->skip == buf->pos); - - if (fbuf->file) { - /* we're a file, so we can lseek() */ - i_buffer_seek(&buf->ibuffer, buf->ibuffer.v_offset); - if (buf->ibuffer.closed) - return -1; - } - } - - buf->ibuffer.buf_errno = 0; - - if (buf->pos == buf->buffer_size) { - if (buf->skip > 0) { - /* remove the unused bytes from beginning of buffer */ - i_buffer_compress(buf); - } else if (fbuf->max_buffer_size == 0 || - buf->buffer_size < fbuf->max_buffer_size) { - /* buffer is full - grow it */ - i_buffer_grow(buf, I_BUFFER_MIN_SIZE); - } - - if (buf->pos == buf->buffer_size) - return -2; /* buffer full */ - } - - size = buf->buffer_size - buf->pos; - if (buf->ibuffer.v_limit > 0) { - i_assert(buf->ibuffer.v_limit >= buf->ibuffer.v_offset); - - read_limit = buf->ibuffer.v_limit - - buf->ibuffer.v_offset + fbuf->skip_left; - if (read_limit <= buf->pos - buf->skip) { - /* virtual limit reached == EOF */ - return -1; - } - - read_limit -= buf->pos - buf->skip; - if (size > read_limit) - size = read_limit; - } - - timeout_time = GET_TIMEOUT_TIME(fbuf); - - ret = -1; - do { - if (ret == 0 && timeout_time > 0 && time(NULL) > timeout_time) { - /* timeouted */ - if (fbuf->timeout_func != NULL) - fbuf->timeout_func(fbuf->timeout_context); - buf->ibuffer.buf_errno = EAGAIN; - return -1; - } - - ret = read(buf->fd, buf->w_buffer + buf->pos, size); - if (ret == 0) { - /* EOF */ - buf->ibuffer.buf_errno = 0; - return -1; - } - - if (ret < 0) { - if (errno == EINTR || errno == EAGAIN) - ret = 0; - else { - buf->ibuffer.buf_errno = errno; - return -1; - } - } - - if (ret > 0 && fbuf->skip_left > 0) { - if (fbuf->skip_left >= (size_t)ret) { - fbuf->skip_left -= ret; - ret = 0; - } else { - ret -= fbuf->skip_left; - buf->pos += fbuf->skip_left; - buf->skip += fbuf->skip_left; - fbuf->skip_left = 0; - } - } - } while (ret == 0 && BUFFER_IS_BLOCKING(fbuf)); - - buf->pos += ret; - return ret; -} - -static void _skip(_IBuffer *buf, uoff_t count) -{ - FileIBuffer *fbuf = (FileIBuffer *) buf; - - fbuf->skip_left += count - (buf->pos - buf->skip); - buf->skip = buf->pos = 0; - buf->ibuffer.v_offset += count; -} - -static void _seek(_IBuffer *buf, uoff_t v_offset) -{ - FileIBuffer *fbuf = (FileIBuffer *) buf; - uoff_t real_offset; - off_t ret; - - real_offset = buf->ibuffer.start_offset + v_offset; - if (real_offset > OFF_T_MAX) { - buf->ibuffer.buf_errno = EOVERFLOW; - ret = -1; - } else { - ret = lseek(buf->fd, (off_t)real_offset, SEEK_SET); - if (ret < 0) - buf->ibuffer.buf_errno = errno; - else if (ret != (off_t)real_offset) { - buf->ibuffer.buf_errno = EINVAL; - ret = -1; - } else { - buf->skip = buf->pos = 0; - fbuf->skip_left = 0; - } - } - - if (ret < 0) - i_buffer_close(&buf->ibuffer); - else { - buf->ibuffer.buf_errno = 0; - buf->ibuffer.v_offset = v_offset; - } -} - -IBuffer *i_buffer_create_file(int fd, Pool pool, size_t max_buffer_size, - int autoclose_fd) -{ - FileIBuffer *fbuf; - struct stat st; - - fbuf = p_new(pool, FileIBuffer, 1); - fbuf->max_buffer_size = max_buffer_size; - fbuf->autoclose_fd = autoclose_fd; - - fbuf->ibuf.iobuf.close = _close; - fbuf->ibuf.iobuf.destroy = _destroy; - fbuf->ibuf.iobuf.set_max_size = _set_max_size; - fbuf->ibuf.iobuf.set_blocking = _set_blocking; - - fbuf->ibuf.read = _read; - fbuf->ibuf.skip_count = _skip; - fbuf->ibuf.seek = _seek; - - /* get size of fd if it's a file */ - if (fstat(fd, &st) < 0) - st.st_size = 0; - else if (S_ISREG(st.st_mode)) - fbuf->file = TRUE; - - return _i_buffer_create(&fbuf->ibuf, pool, fd, 0, (uoff_t)st.st_size); -}
--- a/src/lib/ibuffer-internal.h Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -#ifndef __IBUFFER_INTERNAL_H -#define __IBUFFER_INTERNAL_H - -#include "ibuffer.h" -#include "iobuffer-internal.h" - -typedef struct __IBuffer _IBuffer; - -struct __IBuffer { -/* inheritance: */ - _IOBuffer iobuf; - -/* methods: */ - ssize_t (*read)(_IBuffer *buf); - void (*skip_count)(_IBuffer *buf, uoff_t count); - void (*seek)(_IBuffer *buf, uoff_t v_offset); - -/* data: */ - IBuffer ibuffer; - - int fd; - const unsigned char *buffer; - unsigned char *w_buffer; /* may be NULL */ - size_t buffer_size; - - size_t skip, pos, cr_lookup_pos; -}; - -IBuffer *_i_buffer_create(_IBuffer *_buf, Pool pool, int fd, - uoff_t start_offset, uoff_t v_size); - -#endif
--- a/src/lib/ibuffer-mmap.c Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,240 +0,0 @@ -/* - ibuffer-mmap.c : Input buffer handling for mmap()ed files - - Copyright (c) 2002 Timo Sirainen - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "lib.h" -#include "mmap-util.h" -#include "ibuffer-internal.h" - -#include <unistd.h> -#include <sys/stat.h> - -typedef struct { - _IBuffer ibuf; - - int fd; - void *mmap_base; - off_t mmap_offset; - size_t mmap_block_size; - - unsigned int autoclose_fd:1; -} MmapIBuffer; - -static size_t mmap_pagesize = 0; -static size_t mmap_pagemask = 0; - -static void _close(_IOBuffer *buf) -{ - MmapIBuffer *mbuf = (MmapIBuffer *) buf; - - if (mbuf->autoclose_fd && mbuf->fd != -1) { - if (close(mbuf->fd) < 0) - i_error("MmapIBuffer.close() failed: %m"); - mbuf->fd = -1; - } -} - -static void i_buffer_munmap(MmapIBuffer *mbuf) -{ - _IBuffer *_buf = &mbuf->ibuf; - - if (_buf->buffer != NULL) { - if (munmap(mbuf->mmap_base, _buf->buffer_size) < 0) - i_error("MmapIBuffer.munmap() failed: %m"); - mbuf->mmap_base = NULL; - _buf->buffer = NULL; - _buf->buffer_size = 0; - mbuf->mmap_offset = 0; - } -} - -static void _destroy(_IOBuffer *buf) -{ - MmapIBuffer *mbuf = (MmapIBuffer *) buf; - - i_buffer_munmap(mbuf); -} - -static void _set_max_size(_IOBuffer *buf, size_t max_size) -{ - MmapIBuffer *mbuf = (MmapIBuffer *) buf; - - mbuf->mmap_block_size = max_size; -} - -static void _set_blocking(_IOBuffer *buf __attr_unused__, - int timeout_msecs __attr_unused__, - void (*timeout_func)(void *) __attr_unused__, - void *context __attr_unused__) -{ - /* we never block */ -} - -static ssize_t io_buffer_set_mmaped_pos(_IBuffer *buf) -{ - MmapIBuffer *mbuf = (MmapIBuffer *) buf; - - i_assert((uoff_t)mbuf->mmap_offset <= - buf->ibuffer.start_offset + buf->ibuffer.v_limit); - - buf->pos = buf->ibuffer.start_offset + buf->ibuffer.v_limit - - mbuf->mmap_offset; - if (buf->pos > buf->buffer_size) - buf->pos = buf->buffer_size; - - return buf->pos - buf->skip; -} - -static ssize_t _read(_IBuffer *buf) -{ - MmapIBuffer *mbuf = (MmapIBuffer *) buf; - size_t aligned_skip, limit_size; - - if (buf->ibuffer.start_offset + buf->ibuffer.v_limit <= - (uoff_t)mbuf->mmap_offset + buf->pos) { - /* end of file */ - buf->ibuffer.buf_errno = 0; - return -1; - } - - if (buf->pos < buf->buffer_size) { - /* more bytes available without needing to mmap() */ - return io_buffer_set_mmaped_pos(buf); - } - - aligned_skip = buf->skip & ~mmap_pagemask; - if (aligned_skip == 0 && mbuf->mmap_base != NULL) { - /* didn't skip enough bytes */ - return -2; - } - - buf->skip -= aligned_skip; - mbuf->mmap_offset += aligned_skip; - - if (mbuf->mmap_base != NULL) { - if (munmap(mbuf->mmap_base, buf->buffer_size) < 0) - i_error("io_buffer_read_mmaped(): munmap() failed: %m"); - } - - buf->buffer_size = buf->ibuffer.start_offset + buf->ibuffer.v_size - - mbuf->mmap_offset; - if (buf->buffer_size > mbuf->mmap_block_size) - buf->buffer_size = mbuf->mmap_block_size; - - i_assert((uoff_t)mbuf->mmap_offset + buf->buffer_size <= - buf->ibuffer.start_offset + buf->ibuffer.v_size); - - mbuf->mmap_base = mmap(NULL, buf->buffer_size, PROT_READ, MAP_PRIVATE, - mbuf->fd, mbuf->mmap_offset); - buf->buffer = mbuf->mmap_base; - if (mbuf->mmap_base == MAP_FAILED) { - buf->ibuffer.buf_errno = errno; - mbuf->mmap_base = NULL; - buf->buffer = NULL; - buf->buffer_size = 0; - buf->skip = buf->pos = 0; - i_error("MmapIBuffer.mmap() failed: %m"); - return -1; - } - - /* madvise() only if non-limited mmap()ed buffer area larger than - page size */ - limit_size = buf->ibuffer.start_offset + buf->ibuffer.v_limit - - mbuf->mmap_offset; - if (limit_size > mmap_pagesize) { - if (limit_size > buf->buffer_size) - limit_size = buf->buffer_size; - - if (madvise(mbuf->mmap_base, limit_size, MADV_SEQUENTIAL) < 0) - i_error("MmapIBuffer.madvise(): %m"); - } - - return io_buffer_set_mmaped_pos(buf); -} - -static void _seek(_IBuffer *buf, uoff_t v_offset) -{ - MmapIBuffer *mbuf = (MmapIBuffer *) buf; - uoff_t abs_offset; - - abs_offset = buf->ibuffer.start_offset + v_offset; - if (buf->buffer_size != 0 && - (uoff_t)mbuf->mmap_offset <= abs_offset && - (uoff_t)mbuf->mmap_offset + buf->buffer_size > abs_offset) { - /* already mmaped */ - buf->skip = buf->pos = abs_offset - mbuf->mmap_offset; - } else { - /* force reading next time */ - i_buffer_munmap(mbuf); - buf->skip = buf->pos = abs_offset; - } - - buf->ibuffer.v_offset = v_offset; -} - -static void _skip(_IBuffer *buf, uoff_t count) -{ - _seek(buf, buf->ibuffer.v_offset + count); -} - -IBuffer *i_buffer_create_mmap(int fd, Pool pool, size_t block_size, - uoff_t start_offset, uoff_t v_size, - int autoclose_fd) -{ - MmapIBuffer *mbuf; - struct stat st; - - if (mmap_pagesize == 0) { - mmap_pagesize = getpagesize(); - mmap_pagemask = mmap_pagesize-1; - } - - if (v_size == 0) { - if (fstat(fd, &st) < 0) { - i_error("i_buffer_create_mmap(): fstat() failed: %m"); - v_size = 0; - } else { - v_size = st.st_size; - if (start_offset > v_size) - start_offset = v_size; - v_size -= start_offset; - } - } - - mbuf = p_new(pool, MmapIBuffer, 1); - mbuf->fd = fd; - mbuf->mmap_block_size = block_size; - mbuf->autoclose_fd = autoclose_fd; - - mbuf->ibuf.iobuf.close = _close; - mbuf->ibuf.iobuf.destroy = _destroy; - mbuf->ibuf.iobuf.set_max_size = _set_max_size; - mbuf->ibuf.iobuf.set_blocking = _set_blocking; - - mbuf->ibuf.read = _read; - mbuf->ibuf.skip_count = _skip; - mbuf->ibuf.seek = _seek; - - return _i_buffer_create(&mbuf->ibuf, pool, fd, start_offset, v_size); -}
--- a/src/lib/ibuffer.c Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,243 +0,0 @@ -/* - ibuffer.c : Input buffer handling - - Copyright (c) 2002 Timo Sirainen - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "lib.h" -#include "ibuffer-internal.h" - -void i_buffer_ref(IBuffer *buf) -{ - _io_buffer_ref(buf->real_buffer); -} - -void i_buffer_unref(IBuffer *buf) -{ - _io_buffer_unref(buf->real_buffer); -} - -int i_buffer_get_fd(IBuffer *buf) -{ - _IBuffer *_buf = buf->real_buffer; - - return _buf->fd; -} - -void i_buffer_close(IBuffer *buf) -{ - _io_buffer_close(buf->real_buffer); - buf->closed = TRUE; -} - -void i_buffer_set_max_size(IBuffer *buf, size_t max_size) -{ - _io_buffer_set_max_size(buf->real_buffer, max_size); -} - -void i_buffer_set_blocking(IBuffer *buf, int timeout_msecs, - void (*timeout_func)(void *), void *context) -{ - _io_buffer_set_blocking(buf->real_buffer, timeout_msecs, - timeout_func, context); -} - -void i_buffer_set_start_offset(IBuffer *buf, uoff_t offset) -{ - _IBuffer *_buf = buf->real_buffer; - off_t diff; - - i_assert(buf->v_size == 0 || offset <= buf->start_offset + buf->v_size); - - if (offset == buf->start_offset) - return; - - diff = (off_t)buf->start_offset - (off_t)offset; - buf->start_offset = offset; - buf->v_offset += diff; - if (buf->v_size != 0) { - buf->v_size += diff; - buf->v_limit += diff; - } - - /* reset buffer data */ - _buf->skip = _buf->pos = _buf->cr_lookup_pos = 0; -} - -void i_buffer_set_read_limit(IBuffer *buf, uoff_t v_offset) -{ - _IBuffer *_buf = buf->real_buffer; - - i_assert(buf->v_size == 0 || v_offset <= buf->v_size); - - if (v_offset == 0) - buf->v_limit = buf->v_size; - else { - i_assert(v_offset >= buf->v_offset); - - buf->v_limit = v_offset; - if (_buf->pos > v_offset - buf->v_offset + _buf->skip) - _buf->pos = v_offset - buf->v_offset + _buf->skip; - } -} - -ssize_t i_buffer_read(IBuffer *buf) -{ - _IBuffer *_buf = buf->real_buffer; - - if (buf->closed) - return -1; - - return _buf->read(_buf); -} - -void i_buffer_skip(IBuffer *buf, uoff_t count) -{ - _IBuffer *_buf = buf->real_buffer; - size_t data_size; - - i_assert(buf->v_size == 0 || buf->v_offset + count <= buf->v_size); - - if (count <= _buf->pos - _buf->skip) { - buf->v_offset += count; - _buf->skip += count; - return; - } - - if (buf->closed) - return; - - data_size = _buf->pos - _buf->skip; - _buf->skip = _buf->pos; - - count -= data_size; - buf->v_offset += data_size; - - _buf->skip_count(_buf, count); -} - -void i_buffer_seek(IBuffer *buf, uoff_t v_offset) -{ - _IBuffer *_buf = buf->real_buffer; - - i_assert(v_offset <= buf->v_size); - - if (buf->closed) - return; - - _buf->seek(_buf, v_offset); -} - -char *i_buffer_next_line(IBuffer *buf) -{ - _IBuffer *_buf = buf->real_buffer; - char *ret_buf; - size_t i; - - i_assert(buf != NULL); - - if (_buf->skip >= _buf->pos) - return NULL; - - if (_buf->w_buffer == NULL) { - i_error("i_buffer_next_line() called for unmodifyable buffer"); - return NULL; - } - - ret_buf = NULL; - for (i = _buf->cr_lookup_pos; i < _buf->pos; i++) { - if (_buf->buffer[i] == 10) { - /* got it */ - if (i > 0 && _buf->buffer[i-1] == '\r') - _buf->w_buffer[i-1] = '\0'; - else - _buf->w_buffer[i] = '\0'; - ret_buf = (char *) _buf->w_buffer + _buf->skip; - - i++; - buf->v_offset += i - _buf->skip; - _buf->skip = i; - break; - } - } - - _buf->cr_lookup_pos = i; - return ret_buf; -} - -const unsigned char *i_buffer_get_data(IBuffer *buf, size_t *size) -{ - _IBuffer *_buf = buf->real_buffer; - - if (_buf->skip >= _buf->pos) { - *size = 0; - return NULL; - } - - *size = _buf->pos - _buf->skip; - return _buf->buffer + _buf->skip; -} - -unsigned char *i_buffer_get_modifyable_data(IBuffer *buf, size_t *size) -{ - _IBuffer *_buf = buf->real_buffer; - - if (_buf->skip >= _buf->pos || _buf->w_buffer == NULL) { - *size = 0; - return NULL; - } - - *size = _buf->pos - _buf->skip; - return _buf->w_buffer + _buf->skip; -} - -int i_buffer_read_data(IBuffer *buf, const unsigned char **data, - size_t *size, size_t threshold) -{ - _IBuffer *_buf = buf->real_buffer; - ssize_t ret = 0; - - while (_buf->pos - _buf->skip <= threshold) { - /* we need more data */ - ret = _buf->read(_buf); - if (ret < 0) - break; - } - - *data = i_buffer_get_data(buf, size); - return *size > threshold ? 1 : - ret == -2 ? -2 : - *size > 0 ? 0 : -1; -} - -IBuffer *_i_buffer_create(_IBuffer *_buf, Pool pool, int fd, - uoff_t start_offset, uoff_t v_size) -{ - _buf->fd = fd; - _buf->ibuffer.start_offset = start_offset; - _buf->ibuffer.v_size = v_size; - _buf->ibuffer.v_limit = v_size; - _buf->ibuffer.real_buffer = _buf; - - _io_buffer_init(pool, &_buf->iobuf); - return &_buf->ibuffer; -}
--- a/src/lib/ibuffer.h Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,74 +0,0 @@ -#ifndef __IBUFFER_H -#define __IBUFFER_H - -struct _IBuffer { - uoff_t start_offset; - uoff_t v_offset, v_size, v_limit; /* relative to start_offset */ - - int buf_errno; - unsigned int closed:1; - - void *real_buffer; -}; - -IBuffer *i_buffer_create_file(int fd, Pool pool, size_t max_buffer_size, - int autoclose_fd); -IBuffer *i_buffer_create_mmap(int fd, Pool pool, size_t block_size, - uoff_t start_offset, uoff_t v_size, - int autoclose_fd); -IBuffer *i_buffer_create_from_data(Pool pool, const unsigned char *data, - size_t size); - -/* Reference counting. References start from 1, so calling i_buffer_unref() - destroys the buffer if i_buffer_ref() is never used. */ -void i_buffer_ref(IBuffer *buf); -void i_buffer_unref(IBuffer *buf); - -/* Return file descriptor for buffer, or -1 if none is available. */ -int i_buffer_get_fd(IBuffer *buf); - -/* Mark the buffer closed. Any reads after this will return -1. The data - already in buffer can still be used. */ -void i_buffer_close(IBuffer *buf); - -/* Change the maximum size for buffer to grow. */ -void i_buffer_set_max_size(IBuffer *buf, size_t max_size); -/* Change the start_offset and drop all data in buffers. Doesn't do anything - if offset is the same as existing start_offset. */ -void i_buffer_set_start_offset(IBuffer *buf, uoff_t offset); -/* Input buffer won't be read past specified offset. Giving 0 as offset - removes the limit. The offset is */ -void i_buffer_set_read_limit(IBuffer *buf, uoff_t v_offset); -/* Makes reads blocking until at least one byte is read. timeout_func is - called if nothing is read in specified time. Setting timeout_msecs to 0 - makes it non-blocking. This call changes non-blocking state of file - descriptor. */ -void i_buffer_set_blocking(IBuffer *buf, int timeout_msecs, - void (*timeout_func)(void *), void *context); - -/* Returns number of bytes read if read was ok, -1 if EOF or error, -2 if the - buffer is full. */ -ssize_t i_buffer_read(IBuffer *buf); -/* Skip forward a number of bytes. Never fails, the next read tells if it - was successful. */ -void i_buffer_skip(IBuffer *buf, uoff_t count); -/* Seek to specified position from beginning of file. Never fails, the next - read tells if it was successful. This works only for files. */ -void i_buffer_seek(IBuffer *buf, uoff_t v_offset); -/* Returns the next line from input buffer, or NULL if more data is needed - to make a full line. NOTE: modifies the data in the buffer for the \0, so - it works only with ibuffers that allow it (currently only file). */ -char *i_buffer_next_line(IBuffer *buf); -/* Returns pointer to beginning of data in buffer, or NULL if there's - no data. */ -const unsigned char *i_buffer_get_data(IBuffer *buf, size_t *size); -/* Like i_buffer_get_data(), but returns non-const data. If modifying isn't - allowed to buffer, returns NULL. */ -unsigned char *i_buffer_get_modifyable_data(IBuffer *buf, size_t *size); -/* Like i_buffer_get_data(), but read it when needed. Returns 1 if more - than threshold bytes were stored into buffer, 0 if less, -1 if error or - EOF with no bytes in buffer or -2 if buffer is full. */ -int i_buffer_read_data(IBuffer *buf, const unsigned char **data, - size_t *size, size_t threshold); - -#endif
--- a/src/lib/iobuffer-internal.h Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -#ifndef __IOBUFFER_INTERNAL_H -#define __IOBUFFER_INTERNAL_H - -/* This file is private to IBuffer and OBuffer implementation */ - -typedef struct _IOBuffer _IOBuffer; - -struct _IOBuffer { - Pool pool; - int refcount; - - void (*close)(_IOBuffer *buf); - void (*destroy)(_IOBuffer *buf); - void (*set_max_size)(_IOBuffer *buf, size_t max_size); - void (*set_blocking)(_IOBuffer *buf, int timeout_msecs, - void (*timeout_func)(void *), void *context); -}; - -void _io_buffer_init(Pool pool, _IOBuffer *buf); -void _io_buffer_ref(_IOBuffer *buf); -void _io_buffer_unref(_IOBuffer *buf); -void _io_buffer_close(_IOBuffer *buf); -void _io_buffer_set_max_size(_IOBuffer *buf, size_t max_size); -void _io_buffer_set_blocking(_IOBuffer *buf, int timeout_msecs, - void (*timeout_func)(void *), void *context); - -#define GET_TIMEOUT_TIME(fbuf) \ - ((fbuf)->timeout_msecs == 0 ? 0 : \ - time(NULL) + ((fbuf)->timeout_msecs / 1000)) -#define BUFFER_IS_BLOCKING(fbuf) \ - ((fbuf)->timeout_msecs != 0) - -#endif
--- a/src/lib/iobuffer.c Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - iobuffer.c : Input/output buffer common handling - - Copyright (c) 2002 Timo Sirainen - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "lib.h" -#include "iobuffer-internal.h" - -void _io_buffer_init(Pool pool, _IOBuffer *buf) -{ - buf->pool = pool; - buf->refcount = 1; -} - -void _io_buffer_ref(_IOBuffer *buf) -{ - buf->refcount++; -} - -void _io_buffer_unref(_IOBuffer *buf) -{ - Pool pool; - - i_assert(buf->refcount > 0); - if (--buf->refcount != 0) - return; - - buf->close(buf); - buf->destroy(buf); - - pool = buf->pool; - p_free(pool, buf); - pool_unref(pool); -} - -void _io_buffer_close(_IOBuffer *buf) -{ - buf->close(buf); -} - -void _io_buffer_set_max_size(_IOBuffer *buf, size_t max_size) -{ - buf->set_max_size(buf, max_size); -} - -void _io_buffer_set_blocking(_IOBuffer *buf, int timeout_msecs, - void (*timeout_func)(void *), void *context) -{ - buf->set_blocking(buf, timeout_msecs, timeout_func, context); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/iostream-internal.h Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,33 @@ +#ifndef __IOSTREAM_INTERNAL_H +#define __IOSTREAM_INTERNAL_H + +/* This file is private to IStream and OStream implementation */ + +typedef struct _IOStream _IOStream; + +struct _IOStream { + Pool pool; + int refcount; + + void (*close)(_IOStream *stream); + void (*destroy)(_IOStream *stream); + void (*set_max_buffer_size)(_IOStream *stream, size_t max_size); + void (*set_blocking)(_IOStream *stream, int timeout_msecs, + void (*timeout_func)(void *), void *context); +}; + +void _io_stream_init(Pool pool, _IOStream *stream); +void _io_stream_ref(_IOStream *stream); +void _io_stream_unref(_IOStream *stream); +void _io_stream_close(_IOStream *stream); +void _io_stream_set_max_buffer_size(_IOStream *stream, size_t max_size); +void _io_stream_set_blocking(_IOStream *stream, int timeout_msecs, + void (*timeout_func)(void *), void *context); + +#define GET_TIMEOUT_TIME(fstream) \ + ((fstream)->timeout_msecs == 0 ? 0 : \ + time(NULL) + ((fstream)->timeout_msecs / 1000)) +#define STREAM_IS_BLOCKING(fstream) \ + ((fstream)->timeout_msecs != 0) + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/iostream.c Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,70 @@ +/* + iostream.c : Input/output stream common handling + + Copyright (c) 2002 Timo Sirainen + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "lib.h" +#include "iostream-internal.h" + +void _io_stream_init(Pool pool, _IOStream *stream) +{ + stream->pool = pool; + stream->refcount = 1; +} + +void _io_stream_ref(_IOStream *stream) +{ + stream->refcount++; +} + +void _io_stream_unref(_IOStream *stream) +{ + Pool pool; + + i_assert(stream->refcount > 0); + if (--stream->refcount != 0) + return; + + stream->close(stream); + stream->destroy(stream); + + pool = stream->pool; + p_free(pool, stream); + pool_unref(pool); +} + +void _io_stream_close(_IOStream *stream) +{ + stream->close(stream); +} + +void _io_stream_set_max_buffer_size(_IOStream *stream, size_t max_size) +{ + stream->set_max_buffer_size(stream, max_size); +} + +void _io_stream_set_blocking(_IOStream *stream, int timeout_msecs, + void (*timeout_func)(void *), void *context) +{ + stream->set_blocking(stream, timeout_msecs, timeout_func, context); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/istream-data.c Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,85 @@ +/* + istream-data.c : Input stream interface for reading from data buffer + + Copyright (c) 2002 Timo Sirainen + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "lib.h" +#include "istream-internal.h" + +static void _close(_IOStream *stream __attr_unused__) +{ +} + +static void _destroy(_IOStream *stream __attr_unused__) +{ +} + +static void _set_max_buffer_size(_IOStream *stream __attr_unused__, + size_t max_size __attr_unused__) +{ +} + +static void _set_blocking(_IOStream *stream __attr_unused__, + int timeout_msecs __attr_unused__, + void (*timeout_func)(void *) __attr_unused__, + void *context __attr_unused__) +{ +} + +static ssize_t _read(_IStream *stream) +{ + return stream->pos - stream->skip; +} + +static void _seek(_IStream *stream, uoff_t v_offset) +{ + stream->skip = v_offset; + stream->istream.v_offset = v_offset; +} + +static void _skip(_IStream *stream, uoff_t count) +{ + stream->skip += count; + stream->istream.v_offset += count; +} + +IStream *i_stream_create_from_data(Pool pool, const unsigned char *data, + size_t size) +{ + _IStream *stream; + + stream = p_new(pool, _IStream, 1); + stream->buffer = data; + stream->pos = size; + + stream->iostream.close = _close; + stream->iostream.destroy = _destroy; + stream->iostream.set_max_buffer_size = _set_max_buffer_size; + stream->iostream.set_blocking = _set_blocking; + + stream->read = _read; + stream->skip_count = _skip; + stream->seek = _seek; + + return _i_stream_create(stream, pool, -1, 0, size); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/istream-file.c Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,294 @@ +/* + istream-file.c : Input stream handling for files + + Copyright (c) 2002 Timo Sirainen + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "lib.h" +#include "alarm-hup.h" +#include "istream-internal.h" +#include "network.h" + +#include <time.h> +#include <unistd.h> +#include <sys/stat.h> + +#define I_STREAM_MIN_SIZE 4096 + +#define STREAM_IS_BLOCKING(fstream) \ + ((fstream)->timeout_msecs != 0) + +typedef struct { + _IStream istream; + + size_t max_buffer_size; + uoff_t skip_left; + + int timeout_msecs; + void (*timeout_func)(void *); + void *timeout_context; + + unsigned int file:1; + unsigned int autoclose_fd:1; +} FileIStream; + +static void _close(_IOStream *stream) +{ + FileIStream *fstream = (FileIStream *) stream; + _IStream *_stream = (_IStream *) stream; + + if (fstream->autoclose_fd && _stream->fd != -1) { + if (close(_stream->fd) < 0) + i_error("FileIStream.close() failed: %m"); + _stream->fd = -1; + } +} + +static void _destroy(_IOStream *stream) +{ + _IStream *_stream = (_IStream *) stream; + + p_free(_stream->iostream.pool, _stream->w_buffer); +} + +static void _set_max_buffer_size(_IOStream *stream, size_t max_size) +{ + FileIStream *fstream = (FileIStream *) stream; + + fstream->max_buffer_size = max_size; +} + +static void _set_blocking(_IOStream *stream, int timeout_msecs, + void (*timeout_func)(void *), void *context) +{ + FileIStream *fstream = (FileIStream *) stream; + + fstream->timeout_msecs = timeout_msecs; + fstream->timeout_func = timeout_func; + fstream->timeout_context = context; + + net_set_nonblock(fstream->istream.fd, timeout_msecs == 0); + + if (timeout_msecs != 0) + alarm_hup_init(); +} + +static void i_stream_grow_buffer(_IStream *stream, size_t bytes) +{ + FileIStream *fstream = (FileIStream *) stream; + + stream->buffer_size = stream->pos + bytes; + stream->buffer_size = + stream->buffer_size <= I_STREAM_MIN_SIZE ? I_STREAM_MIN_SIZE : + nearest_power(stream->buffer_size); + + if (fstream->max_buffer_size > 0 && + stream->buffer_size > fstream->max_buffer_size) + stream->buffer_size = fstream->max_buffer_size; + + stream->buffer = stream->w_buffer = + p_realloc(stream->iostream.pool, stream->w_buffer, + stream->buffer_size); +} + +static void i_stream_compress(_IStream *stream) +{ + memmove(stream->w_buffer, stream->w_buffer + stream->skip, + stream->pos - stream->skip); + stream->pos -= stream->skip; + + if (stream->skip > stream->cr_lookup_pos) + stream->cr_lookup_pos = 0; + else + stream->cr_lookup_pos -= stream->skip; + + stream->skip = 0; +} + +static ssize_t _read(_IStream *stream) +{ + FileIStream *fstream = (FileIStream *) stream; + time_t timeout_time; + uoff_t read_limit; + size_t size; + ssize_t ret; + + if (stream->istream.closed) + return -1; + + if (fstream->skip_left > 0) { + i_assert(stream->skip == stream->pos); + + if (fstream->file) { + /* we're a file, so we can lseek() */ + i_stream_seek(&stream->istream, + stream->istream.v_offset); + if (stream->istream.closed) + return -1; + } + } + + stream->istream.stream_errno = 0; + + if (stream->pos == stream->buffer_size) { + if (stream->skip > 0) { + /* remove the unused bytes from beginning of buffer */ + i_stream_compress(stream); + } else if (fstream->max_buffer_size == 0 || + stream->buffer_size < fstream->max_buffer_size) { + /* buffer is full - grow it */ + i_stream_grow_buffer(stream, I_STREAM_MIN_SIZE); + } + + if (stream->pos == stream->buffer_size) + return -2; /* buffer full */ + } + + size = stream->buffer_size - stream->pos; + if (stream->istream.v_limit > 0) { + i_assert(stream->istream.v_limit >= stream->istream.v_offset); + + read_limit = stream->istream.v_limit - + stream->istream.v_offset + fstream->skip_left; + if (read_limit <= stream->pos - stream->skip) { + /* virtual limit reached == EOF */ + return -1; + } + + read_limit -= stream->pos - stream->skip; + if (size > read_limit) + size = read_limit; + } + + timeout_time = GET_TIMEOUT_TIME(fstream); + + ret = -1; + do { + if (ret == 0 && timeout_time > 0 && time(NULL) > timeout_time) { + /* timeouted */ + if (fstream->timeout_func != NULL) + fstream->timeout_func(fstream->timeout_context); + stream->istream.stream_errno = EAGAIN; + return -1; + } + + ret = read(stream->fd, stream->w_buffer + stream->pos, size); + if (ret == 0) { + /* EOF */ + stream->istream.stream_errno = 0; + return -1; + } + + if (ret < 0) { + if (errno == EINTR || errno == EAGAIN) + ret = 0; + else { + stream->istream.stream_errno = errno; + return -1; + } + } + + if (ret > 0 && fstream->skip_left > 0) { + if (fstream->skip_left >= (size_t)ret) { + fstream->skip_left -= ret; + ret = 0; + } else { + ret -= fstream->skip_left; + stream->pos += fstream->skip_left; + stream->skip += fstream->skip_left; + fstream->skip_left = 0; + } + } + } while (ret == 0 && STREAM_IS_BLOCKING(fstream)); + + stream->pos += ret; + return ret; +} + +static void _skip(_IStream *stream, uoff_t count) +{ + FileIStream *fstream = (FileIStream *) stream; + + fstream->skip_left += count - (stream->pos - stream->skip); + stream->skip = stream->pos = 0; + stream->istream.v_offset += count; +} + +static void _seek(_IStream *stream, uoff_t v_offset) +{ + FileIStream *fstream = (FileIStream *) stream; + uoff_t real_offset; + off_t ret; + + real_offset = stream->istream.start_offset + v_offset; + if (real_offset > OFF_T_MAX) { + stream->istream.stream_errno = EOVERFLOW; + ret = -1; + } else { + ret = lseek(stream->fd, (off_t)real_offset, SEEK_SET); + if (ret < 0) + stream->istream.stream_errno = errno; + else if (ret != (off_t)real_offset) { + stream->istream.stream_errno = EINVAL; + ret = -1; + } else { + stream->skip = stream->pos = 0; + fstream->skip_left = 0; + } + } + + if (ret < 0) + i_stream_close(&stream->istream); + else { + stream->istream.stream_errno = 0; + stream->istream.v_offset = v_offset; + } +} + +IStream *i_stream_create_file(int fd, Pool pool, size_t max_buffer_size, + int autoclose_fd) +{ + FileIStream *fstream; + struct stat st; + + fstream = p_new(pool, FileIStream, 1); + fstream->max_buffer_size = max_buffer_size; + fstream->autoclose_fd = autoclose_fd; + + fstream->istream.iostream.close = _close; + fstream->istream.iostream.destroy = _destroy; + fstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size; + fstream->istream.iostream.set_blocking = _set_blocking; + + fstream->istream.read = _read; + fstream->istream.skip_count = _skip; + fstream->istream.seek = _seek; + + /* get size of fd if it's a file */ + if (fstat(fd, &st) < 0) + st.st_size = 0; + else if (S_ISREG(st.st_mode)) + fstream->file = TRUE; + + return _i_stream_create(&fstream->istream, pool, fd, 0, + (uoff_t)st.st_size); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/istream-internal.h Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,32 @@ +#ifndef __ISTREAM_INTERNAL_H +#define __ISTREAM_INTERNAL_H + +#include "istream.h" +#include "iostream-internal.h" + +typedef struct __IStream _IStream; + +struct __IStream { +/* inheritance: */ + _IOStream iostream; + +/* methods: */ + ssize_t (*read)(_IStream *stream); + void (*skip_count)(_IStream *stream, uoff_t count); + void (*seek)(_IStream *stream, uoff_t v_offset); + +/* data: */ + IStream istream; + + int fd; + const unsigned char *buffer; + unsigned char *w_buffer; /* may be NULL */ + size_t buffer_size; + + size_t skip, pos, cr_lookup_pos; +}; + +IStream *_i_stream_create(_IStream *_buf, Pool pool, int fd, + uoff_t start_offset, uoff_t v_size); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/istream-mmap.c Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,241 @@ +/* + istream-mmap.c : Input stream handling for mmap()ed files + + Copyright (c) 2002 Timo Sirainen + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "lib.h" +#include "mmap-util.h" +#include "istream-internal.h" + +#include <unistd.h> +#include <sys/stat.h> + +typedef struct { + _IStream istream; + + int fd; + void *mmap_base; + off_t mmap_offset; + size_t mmap_block_size; + + unsigned int autoclose_fd:1; +} MmapIStream; + +static size_t mmap_pagesize = 0; +static size_t mmap_pagemask = 0; + +static void _close(_IOStream *stream) +{ + MmapIStream *mstream = (MmapIStream *) stream; + + if (mstream->autoclose_fd && mstream->fd != -1) { + if (close(mstream->fd) < 0) + i_error("MmapIStream.close() failed: %m"); + mstream->fd = -1; + } +} + +static void i_stream_munmap(MmapIStream *mstream) +{ + _IStream *_stream = &mstream->istream; + + if (_stream->buffer != NULL) { + if (munmap(mstream->mmap_base, _stream->buffer_size) < 0) + i_error("MmapIStream.munmap() failed: %m"); + mstream->mmap_base = NULL; + _stream->buffer = NULL; + _stream->buffer_size = 0; + mstream->mmap_offset = 0; + } +} + +static void _destroy(_IOStream *stream) +{ + MmapIStream *mstream = (MmapIStream *) stream; + + i_stream_munmap(mstream); +} + +static void _set_max_buffer_size(_IOStream *stream, size_t max_size) +{ + MmapIStream *mstream = (MmapIStream *) stream; + + mstream->mmap_block_size = max_size; +} + +static void _set_blocking(_IOStream *stream __attr_unused__, + int timeout_msecs __attr_unused__, + void (*timeout_func)(void *) __attr_unused__, + void *context __attr_unused__) +{ + /* we never block */ +} + +static ssize_t io_stream_set_mmaped_pos(_IStream *stream) +{ + MmapIStream *mstream = (MmapIStream *) stream; + + i_assert((uoff_t)mstream->mmap_offset <= + stream->istream.start_offset + stream->istream.v_limit); + + stream->pos = stream->istream.start_offset + stream->istream.v_limit - + mstream->mmap_offset; + if (stream->pos > stream->buffer_size) + stream->pos = stream->buffer_size; + + return stream->pos - stream->skip; +} + +static ssize_t _read(_IStream *stream) +{ + MmapIStream *mstream = (MmapIStream *) stream; + size_t aligned_skip, limit_size; + + if (stream->istream.start_offset + stream->istream.v_limit <= + (uoff_t)mstream->mmap_offset + stream->pos) { + /* end of file */ + stream->istream.stream_errno = 0; + return -1; + } + + if (stream->pos < stream->buffer_size) { + /* more bytes available without needing to mmap() */ + return io_stream_set_mmaped_pos(stream); + } + + aligned_skip = stream->skip & ~mmap_pagemask; + if (aligned_skip == 0 && mstream->mmap_base != NULL) { + /* didn't skip enough bytes */ + return -2; + } + + stream->skip -= aligned_skip; + mstream->mmap_offset += aligned_skip; + + if (mstream->mmap_base != NULL) { + if (munmap(mstream->mmap_base, stream->buffer_size) < 0) + i_error("io_stream_read_mmaped(): munmap() failed: %m"); + } + + stream->buffer_size = stream->istream.start_offset + + stream->istream.v_size - mstream->mmap_offset; + if (stream->buffer_size > mstream->mmap_block_size) + stream->buffer_size = mstream->mmap_block_size; + + i_assert((uoff_t)mstream->mmap_offset + stream->buffer_size <= + stream->istream.start_offset + stream->istream.v_size); + + mstream->mmap_base = mmap(NULL, stream->buffer_size, + PROT_READ, MAP_PRIVATE, + mstream->fd, mstream->mmap_offset); + stream->buffer = mstream->mmap_base; + if (mstream->mmap_base == MAP_FAILED) { + stream->istream.stream_errno = errno; + mstream->mmap_base = NULL; + stream->buffer = NULL; + stream->buffer_size = 0; + stream->skip = stream->pos = 0; + i_error("MmapIStream.mmap() failed: %m"); + return -1; + } + + /* madvise() only if non-limited mmap()ed buffer area larger than + page size */ + limit_size = stream->istream.start_offset + stream->istream.v_limit - + mstream->mmap_offset; + if (limit_size > mmap_pagesize) { + if (limit_size > stream->buffer_size) + limit_size = stream->buffer_size; + + if (madvise(mstream->mmap_base, limit_size, MADV_SEQUENTIAL) < 0) + i_error("MmapIStream.madvise(): %m"); + } + + return io_stream_set_mmaped_pos(stream); +} + +static void _seek(_IStream *stream, uoff_t v_offset) +{ + MmapIStream *mstream = (MmapIStream *) stream; + uoff_t abs_offset; + + abs_offset = stream->istream.start_offset + v_offset; + if (stream->buffer_size != 0 && + (uoff_t)mstream->mmap_offset <= abs_offset && + (uoff_t)mstream->mmap_offset + stream->buffer_size > abs_offset) { + /* already mmaped */ + stream->skip = stream->pos = abs_offset - mstream->mmap_offset; + } else { + /* force reading next time */ + i_stream_munmap(mstream); + stream->skip = stream->pos = abs_offset; + } + + stream->istream.v_offset = v_offset; +} + +static void _skip(_IStream *stream, uoff_t count) +{ + _seek(stream, stream->istream.v_offset + count); +} + +IStream *i_stream_create_mmap(int fd, Pool pool, size_t block_size, + uoff_t start_offset, uoff_t v_size, + int autoclose_fd) +{ + MmapIStream *mstream; + struct stat st; + + if (mmap_pagesize == 0) { + mmap_pagesize = getpagesize(); + mmap_pagemask = mmap_pagesize-1; + } + + if (v_size == 0) { + if (fstat(fd, &st) < 0) { + i_error("i_stream_create_mmap(): fstat() failed: %m"); + v_size = 0; + } else { + v_size = st.st_size; + if (start_offset > v_size) + start_offset = v_size; + v_size -= start_offset; + } + } + + mstream = p_new(pool, MmapIStream, 1); + mstream->fd = fd; + mstream->mmap_block_size = block_size; + mstream->autoclose_fd = autoclose_fd; + + mstream->istream.iostream.close = _close; + mstream->istream.iostream.destroy = _destroy; + mstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size; + mstream->istream.iostream.set_blocking = _set_blocking; + + mstream->istream.read = _read; + mstream->istream.skip_count = _skip; + mstream->istream.seek = _seek; + + return _i_stream_create(&mstream->istream, pool, fd, start_offset, v_size); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/istream.c Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,247 @@ +/* + istream.c : Input stream handling + + Copyright (c) 2002 Timo Sirainen + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "lib.h" +#include "istream-internal.h" + +void i_stream_ref(IStream *stream) +{ + _io_stream_ref(stream->real_stream); +} + +void i_stream_unref(IStream *stream) +{ + _io_stream_unref(stream->real_stream); +} + +int i_stream_get_fd(IStream *stream) +{ + _IStream *_stream = stream->real_stream; + + return _stream->fd; +} + +void i_stream_close(IStream *stream) +{ + _io_stream_close(stream->real_stream); + stream->closed = TRUE; +} + +void i_stream_set_max_buffer_size(IStream *stream, size_t max_size) +{ + _io_stream_set_max_buffer_size(stream->real_stream, max_size); +} + +void i_stream_set_blocking(IStream *stream, int timeout_msecs, + void (*timeout_func)(void *), void *context) +{ + _io_stream_set_blocking(stream->real_stream, timeout_msecs, + timeout_func, context); +} + +void i_stream_set_start_offset(IStream *stream, uoff_t offset) +{ + _IStream *_stream = stream->real_stream; + off_t diff; + + i_assert(stream->v_size == 0 || + offset <= stream->start_offset + stream->v_size); + + if (offset == stream->start_offset) + return; + + diff = (off_t)stream->start_offset - (off_t)offset; + stream->start_offset = offset; + stream->v_offset += diff; + if (stream->v_size != 0) { + stream->v_size += diff; + stream->v_limit += diff; + } + + /* reset buffer data */ + _stream->skip = _stream->pos = _stream->cr_lookup_pos = 0; +} + +void i_stream_set_read_limit(IStream *stream, uoff_t v_offset) +{ + _IStream *_stream = stream->real_stream; + uoff_t max_pos; + + i_assert(stream->v_size == 0 || v_offset <= stream->v_size); + + if (v_offset == 0) + stream->v_limit = stream->v_size; + else { + i_assert(v_offset >= stream->v_offset); + + stream->v_limit = v_offset; + max_pos = v_offset - stream->v_offset + _stream->skip; + if (_stream->pos > max_pos) + _stream->pos = max_pos; + } +} + +ssize_t i_stream_read(IStream *stream) +{ + _IStream *_stream = stream->real_stream; + + if (stream->closed) + return -1; + + return _stream->read(_stream); +} + +void i_stream_skip(IStream *stream, uoff_t count) +{ + _IStream *_stream = stream->real_stream; + size_t data_size; + + i_assert(stream->v_size == 0 || + stream->v_offset + count <= stream->v_size); + + if (count <= _stream->pos - _stream->skip) { + stream->v_offset += count; + _stream->skip += count; + return; + } + + if (stream->closed) + return; + + data_size = _stream->pos - _stream->skip; + _stream->skip = _stream->pos; + + count -= data_size; + stream->v_offset += data_size; + + _stream->skip_count(_stream, count); +} + +void i_stream_seek(IStream *stream, uoff_t v_offset) +{ + _IStream *_stream = stream->real_stream; + + i_assert(v_offset <= stream->v_size); + + if (stream->closed) + return; + + _stream->seek(_stream, v_offset); +} + +char *i_stream_next_line(IStream *stream) +{ + _IStream *_stream = stream->real_stream; + char *ret_buf; + size_t i; + + i_assert(stream != NULL); + + if (_stream->skip >= _stream->pos) + return NULL; + + if (_stream->w_buffer == NULL) { + i_error("i_stream_next_line() called for unmodifyable stream"); + return NULL; + } + + ret_buf = NULL; + for (i = _stream->cr_lookup_pos; i < _stream->pos; i++) { + if (_stream->buffer[i] == 10) { + /* got it */ + if (i > 0 && _stream->buffer[i-1] == '\r') + _stream->w_buffer[i-1] = '\0'; + else + _stream->w_buffer[i] = '\0'; + ret_buf = (char *) _stream->w_buffer + _stream->skip; + + i++; + stream->v_offset += i - _stream->skip; + _stream->skip = i; + break; + } + } + + _stream->cr_lookup_pos = i; + return ret_buf; +} + +const unsigned char *i_stream_get_data(IStream *stream, size_t *size) +{ + _IStream *_stream = stream->real_stream; + + if (_stream->skip >= _stream->pos) { + *size = 0; + return NULL; + } + + *size = _stream->pos - _stream->skip; + return _stream->buffer + _stream->skip; +} + +unsigned char *i_stream_get_modifyable_data(IStream *stream, size_t *size) +{ + _IStream *_stream = stream->real_stream; + + if (_stream->skip >= _stream->pos || _stream->w_buffer == NULL) { + *size = 0; + return NULL; + } + + *size = _stream->pos - _stream->skip; + return _stream->w_buffer + _stream->skip; +} + +int i_stream_read_data(IStream *stream, const unsigned char **data, + size_t *size, size_t threshold) +{ + _IStream *_stream = stream->real_stream; + ssize_t ret = 0; + + while (_stream->pos - _stream->skip <= threshold) { + /* we need more data */ + ret = _stream->read(_stream); + if (ret < 0) + break; + } + + *data = i_stream_get_data(stream, size); + return *size > threshold ? 1 : + ret == -2 ? -2 : + *size > 0 ? 0 : -1; +} + +IStream *_i_stream_create(_IStream *_stream, Pool pool, int fd, + uoff_t start_offset, uoff_t v_size) +{ + _stream->fd = fd; + _stream->istream.start_offset = start_offset; + _stream->istream.v_size = v_size; + _stream->istream.v_limit = v_size; + _stream->istream.real_stream = _stream; + + _io_stream_init(pool, &_stream->iostream); + return &_stream->istream; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/istream.h Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,75 @@ +#ifndef __ISTREAM_H +#define __ISTREAM_H + +struct _IStream { + uoff_t start_offset; + uoff_t v_offset, v_size, v_limit; /* relative to start_offset */ + + int stream_errno; + unsigned int closed:1; + + void *real_stream; +}; + +IStream *i_stream_create_file(int fd, Pool pool, size_t max_buffer_size, + int autoclose_fd); +IStream *i_stream_create_mmap(int fd, Pool pool, size_t block_size, + uoff_t start_offset, uoff_t v_size, + int autoclose_fd); +IStream *i_stream_create_from_data(Pool pool, const unsigned char *data, + size_t size); + +/* Reference counting. References start from 1, so calling i_stream_unref() + destroys the stream if i_stream_ref() is never used. */ +void i_stream_ref(IStream *stream); +void i_stream_unref(IStream *stream); + +/* Return file descriptor for stream, or -1 if none is available. */ +int i_stream_get_fd(IStream *stream); + +/* Mark the stream closed. Any reads after this will return -1. The data + already read can still be used. */ +void i_stream_close(IStream *stream); + +/* Change the maximum size for stream's input buffer to grow. Useful only + for buffered streams (currently only file). */ +void i_stream_set_max_buffer_size(IStream *stream, size_t max_size); +/* Change the start_offset and drop all data in buffers. Doesn't do anything + if offset is the same as existing start_offset. */ +void i_stream_set_start_offset(IStream *stream, uoff_t offset); +/* Stream won't be read past specified offset. Giving 0 as offset + removes the limit. */ +void i_stream_set_read_limit(IStream *stream, uoff_t v_offset); +/* Makes reads blocking until at least one byte is read. timeout_func is + called if nothing is read in specified time. Setting timeout_msecs to 0 + makes it non-blocking. This call changes non-blocking state of file + descriptor. */ +void i_stream_set_blocking(IStream *stream, int timeout_msecs, + void (*timeout_func)(void *), void *context); + +/* Returns number of bytes read if read was ok, -1 if EOF or error, -2 if the + input buffer is full. */ +ssize_t i_stream_read(IStream *stream); +/* Skip forward a number of bytes. Never fails, the next read tells if it + was successful. */ +void i_stream_skip(IStream *stream, uoff_t count); +/* Seek to specified position from beginning of file. Never fails, the next + read tells if it was successful. This works only for files. */ +void i_stream_seek(IStream *stream, uoff_t v_offset); +/* Reads the next line from stream and returns it, or NULL if more data is + needed to make a full line. NOTE: modifies the data in buffer for the \0, + so it works only with buffered streams (currently only file). */ +char *i_stream_next_line(IStream *stream); +/* Returns pointer to beginning of read data, or NULL if there's no data + buffered. */ +const unsigned char *i_stream_get_data(IStream *stream, size_t *size); +/* Like i_stream_get_data(), but returns non-const data. This only works with + buffered streams (currently only file), others return NULL. */ +unsigned char *i_stream_get_modifyable_data(IStream *stream, size_t *size); +/* Like i_stream_get_data(), but read more when needed. Returns 1 if more + than threshold bytes are available, 0 if less, -1 if error or EOF with no + bytes available, or -2 if stream's input buffer is full. */ +int i_stream_read_data(IStream *stream, const unsigned char **data, + size_t *size, size_t threshold); + +#endif
--- a/src/lib/lib.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/lib/lib.h Fri Dec 06 03:09:22 2002 +0200 @@ -22,8 +22,8 @@ typedef struct _Timeout *Timeout; typedef struct _IPADDR IPADDR; -typedef struct _IBuffer IBuffer; -typedef struct _OBuffer OBuffer; +typedef struct _IStream IStream; +typedef struct _OStream OStream; typedef struct _TempString TempString; #include "compat.h"
--- a/src/lib/obuffer-file.c Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,678 +0,0 @@ -/* - obuffer-file.c : Output buffer handling for files - - Copyright (c) 2002 Timo Sirainen - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "lib.h" -#include "alarm-hup.h" -#include "ioloop.h" -#include "network.h" -#include "sendfile-util.h" -#include "ibuffer.h" -#include "obuffer-internal.h" - -#include <unistd.h> -#ifdef HAVE_SYS_UIO_H -# include <sys/uio.h> -#endif - -#define O_BUFFER_MIN_SIZE 4096 - -#define IS_BUFFER_EMPTY(fbuf) \ - (!(fbuf)->full && (fbuf)->head == (fbuf)->tail) - -#define MAX_SSIZE_T(size) \ - ((size) < SSIZE_T_MAX ? (size_t)(size) : SSIZE_T_MAX) - -typedef struct { - _OBuffer obuf; - - int fd; - int priority; - IO io; - - unsigned char *buffer; /* ring-buffer */ - size_t buffer_size, max_buffer_size; - size_t head, tail; /* first unsent/unused byte */ - - int timeout_msecs; - void (*timeout_func)(void *); - void *timeout_context; - - unsigned int full:1; /* if head == tail, is buffer empty or full? */ - unsigned int corked:1; - unsigned int no_socket_cork:1; - unsigned int autoclose_fd:1; -} FileOBuffer; - -static void buffer_closed(FileOBuffer *fbuf) -{ - if (fbuf->autoclose_fd && fbuf->fd != -1) { - if (close(fbuf->fd) < 0) - i_error("FileOBuffer.close() failed: %m"); - fbuf->fd = -1; - } - - if (fbuf->io != NULL) { - io_remove(fbuf->io); - fbuf->io = NULL; - } - - fbuf->obuf.obuffer.closed = TRUE; -} - -static void _close(_IOBuffer *buf) -{ - FileOBuffer *fbuf = (FileOBuffer *) buf; - - /* flush output before really closing it */ - o_buffer_flush(&fbuf->obuf.obuffer); - - buffer_closed(fbuf); -} - -static void _destroy(_IOBuffer *buf) -{ - FileOBuffer *fbuf = (FileOBuffer *) buf; - - p_free(fbuf->obuf.iobuf.pool, fbuf->buffer); -} - -static void _set_max_size(_IOBuffer *buf, size_t max_size) -{ - FileOBuffer *fbuf = (FileOBuffer *) buf; - - fbuf->max_buffer_size = max_size; -} - -static void _set_blocking(_IOBuffer *buf, int timeout_msecs, - void (*timeout_func)(void *), void *context) -{ - FileOBuffer *fbuf = (FileOBuffer *) buf; - - fbuf->timeout_msecs = timeout_msecs; - fbuf->timeout_func = timeout_func; - fbuf->timeout_context = context; - - net_set_nonblock(fbuf->fd, timeout_msecs == 0); - - if (timeout_msecs != 0) - alarm_hup_init(); -} - -static void _cork(_OBuffer *buf) -{ - FileOBuffer *fbuf = (FileOBuffer *) buf; - - if (!fbuf->corked) { - if (!fbuf->no_socket_cork) { - if (net_set_cork(fbuf->fd, TRUE) < 0) - fbuf->no_socket_cork = TRUE; - } - fbuf->corked = TRUE; - } -} - -static void update_iovec(struct iovec *iov, unsigned int iov_size, size_t size) -{ - while (size > 0) { - i_assert(iov_size > 0); - - if ((size_t)iov->iov_len <= size) { - size -= iov->iov_len; - iov->iov_base = NULL; - iov->iov_len = 0; - } else { - iov->iov_base = (char *) iov->iov_base + size; - iov->iov_len -= size; - size = 0; - } - iov++; iov_size--; - } -} - -static void update_buffer(FileOBuffer *fbuf, size_t size) -{ - size_t used; - - if (IS_BUFFER_EMPTY(fbuf)) - return; - - if (fbuf->head < fbuf->tail) { - /* ...HXXXT... */ - used = fbuf->tail - fbuf->head; - fbuf->head += I_MIN(used, size); - } else { - /* XXXT...HXXX */ - used = fbuf->buffer_size - fbuf->head; - if (size > used) { - size -= used; - if (size < fbuf->tail) - fbuf->head = size; - else { - /* whole buffer is sent */ - fbuf->head = fbuf->tail = 0; - } - } else { - fbuf->head += I_MIN(used, size); - } - - fbuf->full = FALSE; - } - - if (fbuf->head == fbuf->tail) - fbuf->head = fbuf->tail = 0; - - if (fbuf->head == fbuf->buffer_size) - fbuf->head = 0; -} - -/* NOTE: modifies iov */ -static ssize_t -o_buffer_writev(FileOBuffer *fbuf, struct iovec *iov, int iov_size) -{ - ssize_t ret; - - while (iov->iov_len == 0 && iov_size > 0) { - iov++; - iov_size--; - } - - i_assert(iov_size > 0); - - ret = writev(fbuf->fd, iov, iov_size); - if (ret < 0) { - if (errno == EAGAIN || errno == EINTR) - return 0; - buffer_closed(fbuf); - return -1; - } - - update_iovec(iov, iov_size, ret); - update_buffer(fbuf, ret); - fbuf->obuf.obuffer.offset += ret; - - return ret; -} - -/* returns how much of vector was used */ -static int o_buffer_fill_iovec(FileOBuffer *fbuf, struct iovec iov[2]) -{ - if (IS_BUFFER_EMPTY(fbuf)) - return 0; - - if (fbuf->head < fbuf->tail) { - iov[0].iov_base = fbuf->buffer + fbuf->head; - iov[0].iov_len = fbuf->tail - fbuf->head; - return 1; - } else { - iov[0].iov_base = fbuf->buffer + fbuf->head; - iov[0].iov_len = fbuf->buffer_size - fbuf->head; - if (fbuf->tail == 0) - return 1; - else { - iov[1].iov_base = fbuf->buffer; - iov[1].iov_len = fbuf->tail; - return 2; - } - } -} - -static int o_buffer_send_blocking(FileOBuffer *fbuf, const void *data, - size_t size) -{ - time_t timeout_time; - struct iovec iov[3]; - int iov_len, first; - - iov_len = o_buffer_fill_iovec(fbuf, iov); - if (size > 0) { - iov[iov_len].iov_base = (void *) data; - iov[iov_len].iov_len = size; - iov_len++; - } - - first = TRUE; - - timeout_time = GET_TIMEOUT_TIME(fbuf); - while (iov[iov_len-1].iov_len != 0) { - if (first) - first = FALSE; - else if (timeout_time > 0 && time(NULL) > timeout_time) { - /* timeouted */ - if (fbuf->timeout_func != NULL) - fbuf->timeout_func(fbuf->timeout_context); - fbuf->obuf.obuffer.buf_errno = EAGAIN; - return -1; - } - - if (o_buffer_writev(fbuf, iov, iov_len) < 0) - return -1; - } - - return 1; -} - -static int buffer_flush(FileOBuffer *fbuf) -{ - struct iovec iov[2]; - int iov_len; - - if (!IS_BUFFER_EMPTY(fbuf)) { - iov_len = o_buffer_fill_iovec(fbuf, iov); - if (o_buffer_writev(fbuf, iov, iov_len) < 0) - return -1; - - if (!IS_BUFFER_EMPTY(fbuf)) { - if (o_buffer_send_blocking(fbuf, NULL, 0) < 0) - return -1; - } - } - - return 1; -} - -static int _flush(_OBuffer *buf) -{ - FileOBuffer *fbuf = (FileOBuffer *) buf; - int ret; - - ret = buffer_flush(fbuf); - - if (fbuf->corked) { - /* remove cork */ - if (!fbuf->no_socket_cork) { - if (net_set_cork(fbuf->fd, FALSE) < 0) - i_error("net_set_cork() failed: %m"); - } - fbuf->corked = FALSE; - } - - return ret; -} - -static size_t get_unused_space(FileOBuffer *fbuf) -{ - if (fbuf->head > fbuf->tail) { - /* XXXT...HXXX */ - return fbuf->head - fbuf->tail; - } else if (fbuf->head < fbuf->tail) { - /* ...HXXXT... */ - return (fbuf->buffer_size - fbuf->tail) + fbuf->head; - } else { - /* either fully unused or fully used */ - return fbuf->full ? 0 : fbuf->buffer_size; - } -} - -static int _have_space(_OBuffer *buf, size_t size) -{ - FileOBuffer *fbuf = (FileOBuffer *) buf; - size_t unused; - - if (fbuf->max_buffer_size == 0) - return 1; - - unused = get_unused_space(fbuf); - if (size <= unused) - return 1; - - unused += (fbuf->max_buffer_size - fbuf->buffer_size); - return size <= unused ? 1 : 0; -} - -static int _seek(_OBuffer *buf, uoff_t offset) -{ - FileOBuffer *fbuf = (FileOBuffer *) buf; - off_t ret; - - if (offset > OFF_T_MAX) { - buf->obuffer.buf_errno = EINVAL; - return -1; - } - - ret = lseek(fbuf->fd, (off_t)offset, SEEK_SET); - if (ret < 0) { - buf->obuffer.buf_errno = errno; - return -1; - } - - if (ret != (off_t)offset) { - buf->obuffer.buf_errno = EINVAL; - return -1; - } - - buf->obuffer.buf_errno = 0; - buf->obuffer.offset = offset; - return 1; -} - -static void o_buffer_grow(FileOBuffer *fbuf, size_t bytes) -{ - size_t size, head_size; - - size = nearest_power(fbuf->buffer_size + bytes); - if (fbuf->max_buffer_size != 0) { - if (size > fbuf->max_buffer_size) { - /* limit the size */ - size = fbuf->max_buffer_size; - } else if (fbuf->corked) { - /* use the largest possible buffer with corking */ - size = fbuf->max_buffer_size; - } - } - - if (size == fbuf->buffer_size) - return; - - fbuf->buffer = p_realloc(fbuf->obuf.iobuf.pool, fbuf->buffer, size); - - if (fbuf->tail <= fbuf->head && !IS_BUFFER_EMPTY(fbuf)) { - head_size = I_MIN(fbuf->head, size - fbuf->buffer_size); - memcpy(fbuf->buffer + fbuf->buffer_size, fbuf->buffer, - head_size); - - if (head_size == fbuf->head) - fbuf->tail = fbuf->buffer_size + head_size; - else { - memmove(fbuf->buffer, fbuf->buffer + head_size, - fbuf->head - head_size); - fbuf->tail = fbuf->head - head_size; - } - } - - fbuf->full = FALSE; - fbuf->buffer_size = size; -} - -static void buffer_send_io(void *context, int fd __attr_unused__, - IO io __attr_unused__) -{ - FileOBuffer *fbuf = context; - struct iovec iov[2]; - int iov_len; - - iov_len = o_buffer_fill_iovec(fbuf, iov); - - if (iov_len == 0 || o_buffer_writev(fbuf, iov, iov_len) < 0 || - iov[iov_len-1].iov_len == 0) { - /* error / all sent */ - io_remove(fbuf->io); - fbuf->io = NULL; - } -} - -static size_t o_buffer_add(FileOBuffer *fbuf, const void *data, size_t size) -{ - size_t unused, sent; - int i; - - unused = get_unused_space(fbuf); - if (unused < size) - o_buffer_grow(fbuf, size-unused); - - sent = 0; - for (i = 0; i < 2 && sent < size && !fbuf->full; i++) { - unused = fbuf->tail >= fbuf->head ? - fbuf->buffer_size - fbuf->tail : - fbuf->head - fbuf->tail; - - if (unused > size-sent) - unused = size-sent; - memcpy(fbuf->buffer + fbuf->tail, data, unused); - sent += unused; - - fbuf->tail += unused; - if (fbuf->tail == fbuf->buffer_size) - fbuf->tail = 0; - - if (fbuf->head == fbuf->tail) - fbuf->full = TRUE; - } - - if (sent != 0 && fbuf->io == NULL && !fbuf->corked) { - fbuf->io = io_add_priority(fbuf->fd, fbuf->priority, IO_WRITE, - buffer_send_io, fbuf); - } - - i_assert(!BUFFER_IS_BLOCKING(fbuf) || sent == size); - return sent; -} - -static ssize_t _send(_OBuffer *buf, const void *data, size_t size) -{ - FileOBuffer *fbuf = (FileOBuffer *) buf; - struct iovec iov; - ssize_t ret; - - i_assert(size <= SSIZE_T_MAX); - - if (buf->obuffer.closed) - return -1; - - buf->obuffer.buf_errno = 0; - - /* never try sending buffer immediately if we're block, - so we don't need to deal with timeout issues here */ - if (IS_BUFFER_EMPTY(fbuf) && !BUFFER_IS_BLOCKING(fbuf) && - (!fbuf->corked || !_have_space(buf, size))) { - iov.iov_base = (void *) data; - iov.iov_len = size; - ret = o_buffer_writev(fbuf, &iov, 1); - if (ret < 0 || (size_t)ret == size) - return ret; - - data = (const char *) data + ret; - size -= ret; - } - - if (!_have_space(buf, size) && BUFFER_IS_BLOCKING(fbuf)) { - /* send it blocking */ - if (o_buffer_send_blocking(fbuf, data, size) < 0) - return -1; - return (ssize_t)size; - } else { - /* buffer it, at least partly */ - return (ssize_t)o_buffer_add(fbuf, data, size); - } -} - -static off_t io_buffer_sendfile(_OBuffer *outbuf, IBuffer *inbuf) -{ - FileOBuffer *foutbuf = (FileOBuffer *) outbuf; - time_t timeout_time; - uoff_t start_offset; - uoff_t offset, send_size; - ssize_t ret; - int in_fd, first; - - in_fd = i_buffer_get_fd(inbuf); - if (in_fd == -1) { - outbuf->obuffer.buf_errno = EINVAL; - return -1; - } - - /* set timeout time before flushing existing buffer which may block */ - timeout_time = GET_TIMEOUT_TIME(foutbuf); - start_offset = inbuf->v_offset; - - /* flush out any data in buffer */ - if (buffer_flush(foutbuf) < 0) - return -1; - - first = TRUE; - for (;;) { - if (first) - first = FALSE; - else if (timeout_time > 0 && time(NULL) > timeout_time) { - /* timeouted */ - if (foutbuf->timeout_func != NULL) - foutbuf->timeout_func(foutbuf->timeout_context); - outbuf->obuffer.buf_errno = EAGAIN; - return -1; - } - - offset = inbuf->start_offset + inbuf->v_offset; - send_size = inbuf->v_limit - inbuf->v_offset; - - ret = safe_sendfile(foutbuf->fd, in_fd, &offset, - MAX_SSIZE_T(send_size)); - if (ret < 0) { - if (errno != EINTR && errno != EAGAIN) { - outbuf->obuffer.buf_errno = errno; - if (errno != EINVAL) { - /* close only if error wasn't because - sendfile() isn't supported */ - buffer_closed(foutbuf); - } - return -1; - } - - if (!BUFFER_IS_BLOCKING(foutbuf)) { - /* don't block */ - break; - } - ret = 0; - } - - i_buffer_skip(inbuf, (size_t)ret); - outbuf->obuffer.offset += ret; - - if ((uoff_t)ret == send_size) { - /* yes, all sent */ - break; - } - } - - return (off_t) (inbuf->v_offset - start_offset); -} - -static off_t io_buffer_copy(_OBuffer *outbuf, IBuffer *inbuf) -{ - FileOBuffer *foutbuf = (FileOBuffer *) outbuf; - time_t timeout_time; - uoff_t start_offset; - struct iovec iov[3]; - int iov_len; - const unsigned char *data; - size_t size; - ssize_t ret; - int pos; - - timeout_time = GET_TIMEOUT_TIME(foutbuf); - iov_len = o_buffer_fill_iovec(foutbuf, iov); - - start_offset = inbuf->v_offset; - for (;;) { - (void)i_buffer_read_data(inbuf, &data, &size, - O_BUFFER_MIN_SIZE-1); - - if (size == 0) { - /* all sent */ - break; - } - - pos = iov_len++; - iov[pos].iov_base = (void *) data; - iov[pos].iov_len = size; - - ret = o_buffer_writev(foutbuf, iov, iov_len); - if (ret < 0) { - /* error */ - return -1; - } - - if (ret == 0 && !BUFFER_IS_BLOCKING(foutbuf)) { - /* don't block */ - break; - } - - if (timeout_time > 0 && time(NULL) > timeout_time) { - /* timeouted */ - if (foutbuf->timeout_func != NULL) - foutbuf->timeout_func(foutbuf->timeout_context); - outbuf->obuffer.buf_errno = EAGAIN; - return -1; - } - - i_buffer_skip(inbuf, size - iov[pos].iov_len); - iov_len--; - - /* if we already sent the iov[0] and iov[1], we - can just remove them from future calls */ - while (iov_len > 0 && iov[0].iov_len == 0) { - iov[0] = iov[1]; - if (iov_len > 1) iov[1] = iov[2]; - iov_len--; - } - } - - return (off_t) (inbuf->v_offset - start_offset); -} - -static off_t _send_ibuffer(_OBuffer *outbuf, IBuffer *inbuf) -{ - off_t ret; - - i_assert(inbuf->v_limit <= OFF_T_MAX); - i_assert(inbuf->v_offset <= inbuf->v_limit); - - if (inbuf->v_offset == inbuf->v_limit) - return 0; - - ret = io_buffer_sendfile(outbuf, inbuf); - if (ret >= 0 || outbuf->obuffer.buf_errno != EINVAL) - return ret; - - /* sendfile() not supported (with this fd), fallback to - regular sending */ - - outbuf->obuffer.buf_errno = 0; - return io_buffer_copy(outbuf, inbuf); -} - -OBuffer *o_buffer_create_file(int fd, Pool pool, size_t max_buffer_size, - int priority, int autoclose_fd) -{ - FileOBuffer *fbuf; - - fbuf = p_new(pool, FileOBuffer, 1); - fbuf->fd = fd; - fbuf->priority = priority; - fbuf->max_buffer_size = max_buffer_size; - fbuf->autoclose_fd = autoclose_fd; - - fbuf->obuf.iobuf.close = _close; - fbuf->obuf.iobuf.destroy = _destroy; - fbuf->obuf.iobuf.set_max_size = _set_max_size; - fbuf->obuf.iobuf.set_blocking = _set_blocking; - - fbuf->obuf.cork = _cork; - fbuf->obuf.flush = _flush; - fbuf->obuf.have_space = _have_space; - fbuf->obuf.seek = _seek; - fbuf->obuf.send = _send; - fbuf->obuf.send_ibuffer = _send_ibuffer; - - return _o_buffer_create(&fbuf->obuf, pool); -}
--- a/src/lib/obuffer-internal.h Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -#ifndef __OBUFFER_INTERNAL_H -#define __OBUFFER_INTERNAL_H - -#include "obuffer.h" -#include "iobuffer-internal.h" - -typedef struct __OBuffer _OBuffer; - -struct __OBuffer { -/* inheritance: */ - _IOBuffer iobuf; - -/* methods: */ - void (*cork)(_OBuffer *buf); - int (*flush)(_OBuffer *buf); - int (*have_space)(_OBuffer *buf, size_t size); - int (*seek)(_OBuffer *buf, uoff_t offset); - ssize_t (*send)(_OBuffer *buf, const void *data, size_t size); - off_t (*send_ibuffer)(_OBuffer *outbuf, IBuffer *inbuf); - -/* data: */ - OBuffer obuffer; -}; - -OBuffer *_o_buffer_create(_OBuffer *_buf, Pool pool); - -#endif
--- a/src/lib/obuffer.c Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -/* - obuffer.c : Output buffer handling - - Copyright (c) 2002 Timo Sirainen - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -#include "lib.h" -#include "ibuffer.h" -#include "obuffer-internal.h" - -void o_buffer_ref(OBuffer *buf) -{ - _io_buffer_ref(buf->real_buffer); -} - -void o_buffer_unref(OBuffer *buf) -{ - _io_buffer_unref(buf->real_buffer); -} - -void o_buffer_close(OBuffer *buf) -{ - _io_buffer_close(buf->real_buffer); - buf->closed = TRUE; -} - -void o_buffer_set_max_size(OBuffer *buf, size_t max_size) -{ - _io_buffer_set_max_size(buf->real_buffer, max_size); -} - -void o_buffer_set_blocking(OBuffer *buf, int timeout_msecs, - void (*timeout_func)(void *), void *context) -{ - _io_buffer_set_blocking(buf->real_buffer, timeout_msecs, - timeout_func, context); -} - -void o_buffer_cork(OBuffer *buf) -{ - _OBuffer *_buf = buf->real_buffer; - - if (buf->closed) - return; - - _buf->cork(_buf); -} - -int o_buffer_flush(OBuffer *buf) -{ - _OBuffer *_buf = buf->real_buffer; - - if (buf->closed) - return -1; - - return _buf->flush(_buf); -} - -int o_buffer_have_space(OBuffer *buf, size_t size) -{ - _OBuffer *_buf = buf->real_buffer; - - return _buf->have_space(_buf, size); -} - -int o_buffer_seek(OBuffer *buf, uoff_t offset) -{ - _OBuffer *_buf = buf->real_buffer; - - if (buf->closed) - return -1; - - return _buf->seek(_buf, offset); -} - -ssize_t o_buffer_send(OBuffer *buf, const void *data, size_t size) -{ - _OBuffer *_buf = buf->real_buffer; - - if (buf->closed) - return -1; - - if (size == 0) - return 0; - - return _buf->send(_buf, data, size); -} - -off_t o_buffer_send_ibuffer(OBuffer *outbuf, IBuffer *inbuf) -{ - _OBuffer *_outbuf = outbuf->real_buffer; - - if (outbuf->closed || inbuf->closed) - return -1; - - return _outbuf->send_ibuffer(_outbuf, inbuf); -} - -OBuffer *_o_buffer_create(_OBuffer *_buf, Pool pool) -{ - _buf->obuffer.real_buffer = _buf; - - _io_buffer_init(pool, &_buf->iobuf); - return &_buf->obuffer; -}
--- a/src/lib/obuffer.h Fri Dec 06 00:37:33 2002 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -#ifndef __OBUFFER_H -#define __OBUFFER_H - -struct _OBuffer { - uoff_t offset; - - int buf_errno; - unsigned int closed:1; - - void *real_buffer; -}; - -OBuffer *o_buffer_create_file(int fd, Pool pool, size_t max_buffer_size, - int priority, int autoclose_fd); - -/* Reference counting. References start from 1, so calling o_buffer_unref() - destroys the buffer if o_buffer_ref() is never used. */ -void o_buffer_ref(OBuffer *buf); -void o_buffer_unref(OBuffer *buf); - -/* Mark the buffer closed. Nothing will be sent after this call. */ -void o_buffer_close(OBuffer *buf); - -/* Change the maximum size for buffer to grow. */ -void o_buffer_set_max_size(OBuffer *buf, size_t max_size); -/* Buffer is made to be flushed out whenever it gets full (assumes max_size - is already set), ie. writes will never be partial. Also makes any blocking - writes to fail after specified timeout, calling timeout_func if it's - set. This call changes non-blocking state of file descriptor. */ -void o_buffer_set_blocking(OBuffer *buf, int timeout_msecs, - void (*timeout_func)(void *), void *context); - -/* Delays sending as far as possible, writing only full buffers. Also sets - TCP_CORK on if supported. o_buffer_flush() removes the cork. */ -void o_buffer_cork(OBuffer *buf); -/* Flush the output buffer, blocks until everything is sent. - Returns 1 if ok, -1 if error. */ -int o_buffer_flush(OBuffer *buf); -/* Returns 1 if specified amount of data fits into buffer before reaching - max_size, 0 if not. */ -int o_buffer_have_space(OBuffer *buf, size_t size); - -/* Seek to specified position from beginning of file. This works only for - files. Returns 1 if successful, -1 if error. */ -int o_buffer_seek(OBuffer *buf, uoff_t offset); -/* Returns number of bytes sent or buffered, or -1 if disconnected */ -ssize_t o_buffer_send(OBuffer *buf, const void *data, size_t size); -/* Send data from input buffer to output buffer using the fastest - possible method. Returns number of bytes sent, or -1 if error. - Note that this function may block if either inbuf or outbuf is blocking. */ -off_t o_buffer_send_ibuffer(OBuffer *outbuf, IBuffer *inbuf); - -#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/ostream-file.c Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,684 @@ +/* + ostream-file.c : Output stream handling for files + + Copyright (c) 2002 Timo Sirainen + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "lib.h" +#include "alarm-hup.h" +#include "ioloop.h" +#include "network.h" +#include "sendfile-util.h" +#include "istream.h" +#include "ostream-internal.h" + +#include <unistd.h> +#ifdef HAVE_SYS_UIO_H +# include <sys/uio.h> +#endif + +#define O_STREAM_MIN_SIZE 4096 + +#define IS_STREAM_EMPTY(fstream) \ + (!(fstream)->full && (fstream)->head == (fstream)->tail) + +#define MAX_SSIZE_T(size) \ + ((size) < SSIZE_T_MAX ? (size_t)(size) : SSIZE_T_MAX) + +typedef struct { + _OStream ostream; + + int fd; + int priority; + IO io; + + unsigned char *buffer; /* ring-buffer */ + size_t buffer_size, max_buffer_size; + size_t head, tail; /* first unsent/unused byte */ + + int timeout_msecs; + void (*timeout_func)(void *); + void *timeout_context; + + unsigned int full:1; /* if head == tail, is buffer empty or full? */ + unsigned int corked:1; + unsigned int no_socket_cork:1; + unsigned int autoclose_fd:1; +} FileOStream; + +static void stream_closed(FileOStream *fstream) +{ + if (fstream->autoclose_fd && fstream->fd != -1) { + if (close(fstream->fd) < 0) + i_error("FileOStream.close() failed: %m"); + fstream->fd = -1; + } + + if (fstream->io != NULL) { + io_remove(fstream->io); + fstream->io = NULL; + } + + fstream->ostream.ostream.closed = TRUE; +} + +static void _close(_IOStream *stream) +{ + FileOStream *fstream = (FileOStream *) stream; + + /* flush output before really closing it */ + o_stream_flush(&fstream->ostream.ostream); + + stream_closed(fstream); +} + +static void _destroy(_IOStream *stream) +{ + FileOStream *fstream = (FileOStream *) stream; + + p_free(fstream->ostream.iostream.pool, fstream->buffer); +} + +static void _set_max_buffer_size(_IOStream *stream, size_t max_size) +{ + FileOStream *fstream = (FileOStream *) stream; + + fstream->max_buffer_size = max_size; +} + +static void _set_blocking(_IOStream *stream, int timeout_msecs, + void (*timeout_func)(void *), void *context) +{ + FileOStream *fstream = (FileOStream *) stream; + + fstream->timeout_msecs = timeout_msecs; + fstream->timeout_func = timeout_func; + fstream->timeout_context = context; + + net_set_nonblock(fstream->fd, timeout_msecs == 0); + + if (timeout_msecs != 0) + alarm_hup_init(); +} + +static void _cork(_OStream *stream) +{ + FileOStream *fstream = (FileOStream *) stream; + + if (!fstream->corked) { + if (!fstream->no_socket_cork) { + if (net_set_cork(fstream->fd, TRUE) < 0) + fstream->no_socket_cork = TRUE; + } + fstream->corked = TRUE; + } +} + +static void update_iovec(struct iovec *iov, unsigned int iov_size, size_t size) +{ + while (size > 0) { + i_assert(iov_size > 0); + + if ((size_t)iov->iov_len <= size) { + size -= iov->iov_len; + iov->iov_base = NULL; + iov->iov_len = 0; + } else { + iov->iov_base = (char *) iov->iov_base + size; + iov->iov_len -= size; + size = 0; + } + iov++; iov_size--; + } +} + +static void update_buffer(FileOStream *fstream, size_t size) +{ + size_t used; + + if (IS_STREAM_EMPTY(fstream)) + return; + + if (fstream->head < fstream->tail) { + /* ...HXXXT... */ + used = fstream->tail - fstream->head; + fstream->head += I_MIN(used, size); + } else { + /* XXXT...HXXX */ + used = fstream->buffer_size - fstream->head; + if (size > used) { + size -= used; + if (size < fstream->tail) + fstream->head = size; + else { + /* whole buffer is sent */ + fstream->head = fstream->tail = 0; + } + } else { + fstream->head += I_MIN(used, size); + } + + fstream->full = FALSE; + } + + if (fstream->head == fstream->tail) + fstream->head = fstream->tail = 0; + + if (fstream->head == fstream->buffer_size) + fstream->head = 0; +} + +/* NOTE: modifies iov */ +static ssize_t +o_stream_writev(FileOStream *fstream, struct iovec *iov, int iov_size) +{ + ssize_t ret; + + while (iov->iov_len == 0 && iov_size > 0) { + iov++; + iov_size--; + } + + i_assert(iov_size > 0); + + ret = writev(fstream->fd, iov, iov_size); + if (ret < 0) { + if (errno == EAGAIN || errno == EINTR) + return 0; + stream_closed(fstream); + return -1; + } + + update_iovec(iov, iov_size, ret); + update_buffer(fstream, ret); + fstream->ostream.ostream.offset += ret; + + return ret; +} + +/* returns how much of vector was used */ +static int o_stream_fill_iovec(FileOStream *fstream, struct iovec iov[2]) +{ + if (IS_STREAM_EMPTY(fstream)) + return 0; + + if (fstream->head < fstream->tail) { + iov[0].iov_base = fstream->buffer + fstream->head; + iov[0].iov_len = fstream->tail - fstream->head; + return 1; + } else { + iov[0].iov_base = fstream->buffer + fstream->head; + iov[0].iov_len = fstream->buffer_size - fstream->head; + if (fstream->tail == 0) + return 1; + else { + iov[1].iov_base = fstream->buffer; + iov[1].iov_len = fstream->tail; + return 2; + } + } +} + +static int o_stream_send_blocking(FileOStream *fstream, const void *data, + size_t size) +{ + time_t timeout_time; + struct iovec iov[3]; + int iov_len, first; + + iov_len = o_stream_fill_iovec(fstream, iov); + if (size > 0) { + iov[iov_len].iov_base = (void *) data; + iov[iov_len].iov_len = size; + iov_len++; + } + + first = TRUE; + + timeout_time = GET_TIMEOUT_TIME(fstream); + while (iov[iov_len-1].iov_len != 0) { + if (first) + first = FALSE; + else if (timeout_time > 0 && time(NULL) > timeout_time) { + /* timeouted */ + if (fstream->timeout_func != NULL) + fstream->timeout_func(fstream->timeout_context); + fstream->ostream.ostream.stream_errno = EAGAIN; + return -1; + } + + if (o_stream_writev(fstream, iov, iov_len) < 0) + return -1; + } + + return 1; +} + +static int buffer_flush(FileOStream *fstream) +{ + struct iovec iov[2]; + int iov_len; + + if (!IS_STREAM_EMPTY(fstream)) { + iov_len = o_stream_fill_iovec(fstream, iov); + if (o_stream_writev(fstream, iov, iov_len) < 0) + return -1; + + if (!IS_STREAM_EMPTY(fstream)) { + if (o_stream_send_blocking(fstream, NULL, 0) < 0) + return -1; + } + } + + return 1; +} + +static int _flush(_OStream *stream) +{ + FileOStream *fstream = (FileOStream *) stream; + int ret; + + ret = buffer_flush(fstream); + + if (fstream->corked) { + /* remove cork */ + if (!fstream->no_socket_cork) { + if (net_set_cork(fstream->fd, FALSE) < 0) + i_error("net_set_cork() failed: %m"); + } + fstream->corked = FALSE; + } + + return ret; +} + +static size_t get_unused_space(FileOStream *fstream) +{ + if (fstream->head > fstream->tail) { + /* XXXT...HXXX */ + return fstream->head - fstream->tail; + } else if (fstream->head < fstream->tail) { + /* ...HXXXT... */ + return (fstream->buffer_size - fstream->tail) + fstream->head; + } else { + /* either fully unused or fully used */ + return fstream->full ? 0 : fstream->buffer_size; + } +} + +static int _have_space(_OStream *stream, size_t size) +{ + FileOStream *fstream = (FileOStream *) stream; + size_t unused; + + if (fstream->max_buffer_size == 0) + return 1; + + unused = get_unused_space(fstream); + if (size <= unused) + return 1; + + unused += (fstream->max_buffer_size - fstream->buffer_size); + return size <= unused ? 1 : 0; +} + +static int _seek(_OStream *stream, uoff_t offset) +{ + FileOStream *fstream = (FileOStream *) stream; + off_t ret; + + if (offset > OFF_T_MAX) { + stream->ostream.stream_errno = EINVAL; + return -1; + } + + ret = lseek(fstream->fd, (off_t)offset, SEEK_SET); + if (ret < 0) { + stream->ostream.stream_errno = errno; + return -1; + } + + if (ret != (off_t)offset) { + stream->ostream.stream_errno = EINVAL; + return -1; + } + + stream->ostream.stream_errno = 0; + stream->ostream.offset = offset; + return 1; +} + +static void o_stream_grow_buffer(FileOStream *fstream, size_t bytes) +{ + size_t size, head_size; + + size = nearest_power(fstream->buffer_size + bytes); + if (fstream->max_buffer_size != 0) { + if (size > fstream->max_buffer_size) { + /* limit the size */ + size = fstream->max_buffer_size; + } else if (fstream->corked) { + /* use the largest possible buffer with corking */ + size = fstream->max_buffer_size; + } + } + + if (size == fstream->buffer_size) + return; + + fstream->buffer = p_realloc(fstream->ostream.iostream.pool, + fstream->buffer, size); + + if (fstream->tail <= fstream->head && !IS_STREAM_EMPTY(fstream)) { + head_size = I_MIN(fstream->head, size - fstream->buffer_size); + memcpy(fstream->buffer + fstream->buffer_size, fstream->buffer, + head_size); + + if (head_size == fstream->head) + fstream->tail = fstream->buffer_size + head_size; + else { + memmove(fstream->buffer, fstream->buffer + head_size, + fstream->head - head_size); + fstream->tail = fstream->head - head_size; + } + } + + fstream->full = FALSE; + fstream->buffer_size = size; +} + +static void stream_send_io(void *context, int fd __attr_unused__, + IO io __attr_unused__) +{ + FileOStream *fstream = context; + struct iovec iov[2]; + int iov_len; + + iov_len = o_stream_fill_iovec(fstream, iov); + + if (iov_len == 0 || o_stream_writev(fstream, iov, iov_len) < 0 || + iov[iov_len-1].iov_len == 0) { + /* error / all sent */ + io_remove(fstream->io); + fstream->io = NULL; + } +} + +static size_t o_stream_add(FileOStream *fstream, const void *data, size_t size) +{ + size_t unused, sent; + int i; + + unused = get_unused_space(fstream); + if (unused < size) + o_stream_grow_buffer(fstream, size-unused); + + sent = 0; + for (i = 0; i < 2 && sent < size && !fstream->full; i++) { + unused = fstream->tail >= fstream->head ? + fstream->buffer_size - fstream->tail : + fstream->head - fstream->tail; + + if (unused > size-sent) + unused = size-sent; + memcpy(fstream->buffer + fstream->tail, data, unused); + sent += unused; + + fstream->tail += unused; + if (fstream->tail == fstream->buffer_size) + fstream->tail = 0; + + if (fstream->head == fstream->tail) + fstream->full = TRUE; + } + + if (sent != 0 && fstream->io == NULL && !fstream->corked) { + fstream->io = io_add_priority(fstream->fd, fstream->priority, + IO_WRITE, stream_send_io, + fstream); + } + + i_assert(!STREAM_IS_BLOCKING(fstream) || sent == size); + return sent; +} + +static ssize_t _send(_OStream *stream, const void *data, size_t size) +{ + FileOStream *fstream = (FileOStream *) stream; + struct iovec iov; + ssize_t ret; + + i_assert(size <= SSIZE_T_MAX); + + if (stream->ostream.closed) + return -1; + + stream->ostream.stream_errno = 0; + + /* never try sending immediately if fd is blocking, + so we don't need to deal with timeout issues here */ + if (IS_STREAM_EMPTY(fstream) && !STREAM_IS_BLOCKING(fstream) && + (!fstream->corked || !_have_space(stream, size))) { + iov.iov_base = (void *) data; + iov.iov_len = size; + ret = o_stream_writev(fstream, &iov, 1); + if (ret < 0 || (size_t)ret == size) + return ret; + + data = (const char *) data + ret; + size -= ret; + } + + if (!_have_space(stream, size) && STREAM_IS_BLOCKING(fstream)) { + /* send it blocking */ + if (o_stream_send_blocking(fstream, data, size) < 0) + return -1; + return (ssize_t)size; + } else { + /* buffer it, at least partly */ + return (ssize_t)o_stream_add(fstream, data, size); + } +} + +static off_t io_stream_sendfile(_OStream *outstream, IStream *instream) +{ + FileOStream *foutstream = (FileOStream *) outstream; + time_t timeout_time; + uoff_t start_offset; + uoff_t offset, send_size; + ssize_t ret; + int in_fd, first; + + in_fd = i_stream_get_fd(instream); + if (in_fd == -1) { + outstream->ostream.stream_errno = EINVAL; + return -1; + } + + /* set timeout time before flushing existing buffer which may block */ + timeout_time = GET_TIMEOUT_TIME(foutstream); + start_offset = instream->v_offset; + + /* flush out any data in buffer */ + if (buffer_flush(foutstream) < 0) + return -1; + + first = TRUE; + for (;;) { + if (first) + first = FALSE; + else if (timeout_time > 0 && time(NULL) > timeout_time) { + /* timeouted */ + if (foutstream->timeout_func != NULL) { + foutstream->timeout_func( + foutstream->timeout_context); + } + outstream->ostream.stream_errno = EAGAIN; + return -1; + } + + offset = instream->start_offset + instream->v_offset; + send_size = instream->v_limit - instream->v_offset; + + ret = safe_sendfile(foutstream->fd, in_fd, &offset, + MAX_SSIZE_T(send_size)); + if (ret < 0) { + if (errno != EINTR && errno != EAGAIN) { + outstream->ostream.stream_errno = errno; + if (errno != EINVAL) { + /* close only if error wasn't because + sendfile() isn't supported */ + stream_closed(foutstream); + } + return -1; + } + + if (!STREAM_IS_BLOCKING(foutstream)) { + /* don't block */ + break; + } + ret = 0; + } + + i_stream_skip(instream, (size_t)ret); + outstream->ostream.offset += ret; + + if ((uoff_t)ret == send_size) { + /* yes, all sent */ + break; + } + } + + return (off_t) (instream->v_offset - start_offset); +} + +static off_t io_stream_copy(_OStream *outstream, IStream *instream) +{ + FileOStream *foutstream = (FileOStream *) outstream; + time_t timeout_time; + uoff_t start_offset; + struct iovec iov[3]; + int iov_len; + const unsigned char *data; + size_t size; + ssize_t ret; + int pos; + + timeout_time = GET_TIMEOUT_TIME(foutstream); + iov_len = o_stream_fill_iovec(foutstream, iov); + + start_offset = instream->v_offset; + for (;;) { + (void)i_stream_read_data(instream, &data, &size, + O_STREAM_MIN_SIZE-1); + + if (size == 0) { + /* all sent */ + break; + } + + pos = iov_len++; + iov[pos].iov_base = (void *) data; + iov[pos].iov_len = size; + + ret = o_stream_writev(foutstream, iov, iov_len); + if (ret < 0) { + /* error */ + return -1; + } + + if (ret == 0 && !STREAM_IS_BLOCKING(foutstream)) { + /* don't block */ + break; + } + + if (timeout_time > 0 && time(NULL) > timeout_time) { + /* timeouted */ + if (foutstream->timeout_func != NULL) { + foutstream->timeout_func( + foutstream->timeout_context); + } + outstream->ostream.stream_errno = EAGAIN; + return -1; + } + + i_stream_skip(instream, size - iov[pos].iov_len); + iov_len--; + + /* if we already sent the iov[0] and iov[1], we + can just remove them from future calls */ + while (iov_len > 0 && iov[0].iov_len == 0) { + iov[0] = iov[1]; + if (iov_len > 1) iov[1] = iov[2]; + iov_len--; + } + } + + return (off_t) (instream->v_offset - start_offset); +} + +static off_t _send_istream(_OStream *outstream, IStream *instream) +{ + off_t ret; + + i_assert(instream->v_limit <= OFF_T_MAX); + i_assert(instream->v_offset <= instream->v_limit); + + if (instream->v_offset == instream->v_limit) + return 0; + + ret = io_stream_sendfile(outstream, instream); + if (ret >= 0 || outstream->ostream.stream_errno != EINVAL) + return ret; + + /* sendfile() not supported (with this fd), fallback to + regular sending */ + + outstream->ostream.stream_errno = 0; + return io_stream_copy(outstream, instream); +} + +OStream *o_stream_create_file(int fd, Pool pool, size_t max_buffer_size, + int priority, int autoclose_fd) +{ + FileOStream *fstream; + + fstream = p_new(pool, FileOStream, 1); + fstream->fd = fd; + fstream->priority = priority; + fstream->max_buffer_size = max_buffer_size; + fstream->autoclose_fd = autoclose_fd; + + fstream->ostream.iostream.close = _close; + fstream->ostream.iostream.destroy = _destroy; + fstream->ostream.iostream.set_max_buffer_size = _set_max_buffer_size; + fstream->ostream.iostream.set_blocking = _set_blocking; + + fstream->ostream.cork = _cork; + fstream->ostream.flush = _flush; + fstream->ostream.have_space = _have_space; + fstream->ostream.seek = _seek; + fstream->ostream.send = _send; + fstream->ostream.send_istream = _send_istream; + + return _o_stream_create(&fstream->ostream, pool); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/ostream-internal.h Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,27 @@ +#ifndef __OSTREAM_INTERNAL_H +#define __OSTREAM_INTERNAL_H + +#include "ostream.h" +#include "iostream-internal.h" + +typedef struct __OStream _OStream; + +struct __OStream { +/* inheritance: */ + _IOStream iostream; + +/* methods: */ + void (*cork)(_OStream *stream); + int (*flush)(_OStream *stream); + int (*have_space)(_OStream *stream, size_t size); + int (*seek)(_OStream *stream, uoff_t offset); + ssize_t (*send)(_OStream *stream, const void *data, size_t size); + off_t (*send_istream)(_OStream *outstream, IStream *instream); + +/* data: */ + OStream ostream; +}; + +OStream *_o_stream_create(_OStream *_stream, Pool pool); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/ostream.c Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,124 @@ +/* + ostream.c : Output stream handling + + Copyright (c) 2002 Timo Sirainen + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "lib.h" +#include "istream.h" +#include "ostream-internal.h" + +void o_stream_ref(OStream *stream) +{ + _io_stream_ref(stream->real_stream); +} + +void o_stream_unref(OStream *stream) +{ + _io_stream_unref(stream->real_stream); +} + +void o_stream_close(OStream *stream) +{ + _io_stream_close(stream->real_stream); + stream->closed = TRUE; +} + +void o_stream_set_max_buffer_size(OStream *stream, size_t max_size) +{ + _io_stream_set_max_buffer_size(stream->real_stream, max_size); +} + +void o_stream_set_blocking(OStream *stream, int timeout_msecs, + void (*timeout_func)(void *), void *context) +{ + _io_stream_set_blocking(stream->real_stream, timeout_msecs, + timeout_func, context); +} + +void o_stream_cork(OStream *stream) +{ + _OStream *_stream = stream->real_stream; + + if (stream->closed) + return; + + _stream->cork(_stream); +} + +int o_stream_flush(OStream *stream) +{ + _OStream *_stream = stream->real_stream; + + if (stream->closed) + return -1; + + return _stream->flush(_stream); +} + +int o_stream_have_space(OStream *stream, size_t size) +{ + _OStream *_stream = stream->real_stream; + + return _stream->have_space(_stream, size); +} + +int o_stream_seek(OStream *stream, uoff_t offset) +{ + _OStream *_stream = stream->real_stream; + + if (stream->closed) + return -1; + + return _stream->seek(_stream, offset); +} + +ssize_t o_stream_send(OStream *stream, const void *data, size_t size) +{ + _OStream *_stream = stream->real_stream; + + if (stream->closed) + return -1; + + if (size == 0) + return 0; + + return _stream->send(_stream, data, size); +} + +off_t o_stream_send_istream(OStream *outstream, IStream *instream) +{ + _OStream *_outstream = outstream->real_stream; + + if (outstream->closed || instream->closed) + return -1; + + return _outstream->send_istream(_outstream, instream); +} + +OStream *_o_stream_create(_OStream *_stream, Pool pool) +{ + _stream->ostream.real_stream = _stream; + + _io_stream_init(pool, &_stream->iostream); + return &_stream->ostream; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/ostream.h Fri Dec 06 03:09:22 2002 +0200 @@ -0,0 +1,53 @@ +#ifndef __OSTREAM_H +#define __OSTREAM_H + +struct _OStream { + uoff_t offset; + + int stream_errno; + unsigned int closed:1; + + void *real_stream; +}; + +OStream *o_stream_create_file(int fd, Pool pool, size_t max_buffer_size, + int priority, int autoclose_fd); + +/* Reference counting. References start from 1, so calling o_stream_unref() + destroys the stream if o_stream_ref() is never used. */ +void o_stream_ref(OStream *stream); +void o_stream_unref(OStream *stream); + +/* Mark the stream closed. Nothing will be sent after this call. */ +void o_stream_close(OStream *stream); + +/* Change the maximum size for stream's output buffer to grow. */ +void o_stream_set_max_buffer_size(OStream *stream, size_t max_size); +/* Stream is made to be flushed out whenever it gets full (assumes max_size + is already set), ie. writes will never be partial. Also makes any blocking + writes to fail after specified timeout, calling timeout_func if it's + set. This call changes non-blocking state of file descriptor. */ +void o_stream_set_blocking(OStream *stream, int timeout_msecs, + void (*timeout_func)(void *), void *context); + +/* Delays sending as far as possible, writing only full buffers. Also sets + TCP_CORK on if supported. o_stream_flush() removes the cork. */ +void o_stream_cork(OStream *stream); +/* Flush the output stream, blocks until everything is sent. + Returns 1 if ok, -1 if error. */ +int o_stream_flush(OStream *stream); +/* Returns 1 if specified amount of data currently fits into stream's output + buffer, 0 if not. */ +int o_stream_have_space(OStream *stream, size_t size); + +/* Seek to specified position from beginning of file. This works only for + files. Returns 1 if successful, -1 if error. */ +int o_stream_seek(OStream *stream, uoff_t offset); +/* Returns number of bytes sent or buffered, or -1 if disconnected */ +ssize_t o_stream_send(OStream *stream, const void *data, size_t size); +/* Send data from input stream. Returns number of bytes sent, or -1 if error. + Note that this function may block if either instream or outstream is + blocking. */ +off_t o_stream_send_istream(OStream *outstream, IStream *instream); + +#endif
--- a/src/login/auth-connection.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/login/auth-connection.c Fri Dec 06 03:09:22 2002 +0200 @@ -4,8 +4,8 @@ #include "hash.h" #include "ioloop.h" #include "network.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "auth-connection.h" #include <unistd.h> @@ -22,8 +22,8 @@ char *path; int fd; IO io; - IBuffer *inbuf; - OBuffer *outbuf; + IStream *input; + OStream *output; int auth_process; AuthMethod available_auth_methods; @@ -73,9 +73,9 @@ conn->path = i_strdup(path); conn->fd = fd; conn->io = io_add(fd, IO_READ, auth_input, conn); - conn->inbuf = i_buffer_create_file(fd, default_pool, MAX_INBUF_SIZE, + conn->input = i_stream_create_file(fd, default_pool, MAX_INBUF_SIZE, FALSE); - conn->outbuf = o_buffer_create_file(fd, default_pool, MAX_OUTBUF_SIZE, + conn->output = o_stream_create_file(fd, default_pool, MAX_OUTBUF_SIZE, IO_PRIORITY_DEFAULT, FALSE); conn->requests = hash_create(default_pool, 100, NULL, NULL); @@ -121,8 +121,8 @@ (void)close(conn->fd); io_remove(conn->io); - i_buffer_unref(conn->inbuf); - o_buffer_unref(conn->outbuf); + i_stream_unref(conn->input); + o_stream_unref(conn->output); i_free(conn->path); i_free(conn); } @@ -136,7 +136,7 @@ found = FALSE; for (conn = auth_connections; conn != NULL; conn = conn->next) { if ((conn->available_auth_methods & method)) { - if (o_buffer_have_space(conn->outbuf, size) > 0) + if (o_stream_have_space(conn->output, size) > 0) return conn; found = TRUE; @@ -210,7 +210,7 @@ const unsigned char *data; size_t size; - switch (i_buffer_read(conn->inbuf)) { + switch (i_stream_read(conn->input)) { case 0: return; case -1: @@ -226,12 +226,12 @@ return; } - data = i_buffer_get_data(conn->inbuf, &size); + data = i_stream_get_data(conn->input, &size); if (!conn->init_received) { if (size == sizeof(AuthInitData)) { memcpy(&init_data, data, sizeof(AuthInitData)); - i_buffer_skip(conn->inbuf, sizeof(AuthInitData)); + i_stream_skip(conn->input, sizeof(AuthInitData)); auth_handle_init(conn, &init_data); } else if (size > sizeof(AuthInitData)) { @@ -245,14 +245,14 @@ } if (!conn->in_reply_received) { - data = i_buffer_get_data(conn->inbuf, &size); + data = i_stream_get_data(conn->input, &size); if (size < sizeof(AuthReplyData)) return; memcpy(&conn->in_reply, data, sizeof(AuthReplyData)); data += sizeof(AuthReplyData); size -= sizeof(AuthReplyData); - i_buffer_skip(conn->inbuf, sizeof(AuthReplyData)); + i_stream_skip(conn->input, sizeof(AuthReplyData)); conn->in_reply_received = TRUE; } @@ -262,7 +262,7 @@ /* we've got a full reply */ conn->in_reply_received = FALSE; auth_handle_reply(conn, &conn->in_reply, data); - i_buffer_skip(conn->inbuf, conn->in_reply.data_size); + i_stream_skip(conn->input, conn->in_reply.data_size); } int auth_init_request(AuthMethod method, AuthCallback callback, @@ -293,7 +293,7 @@ request_data.type = AUTH_REQUEST_INIT; request_data.method = request->method; request_data.id = request->id; - if (o_buffer_send(request->conn->outbuf, &request_data, + if (o_stream_send(request->conn->output, &request_data, sizeof(request_data)) < 0) auth_connection_destroy(request->conn); return TRUE; @@ -310,10 +310,10 @@ request_data.id = request->id; request_data.data_size = data_size; - if (o_buffer_send(request->conn->outbuf, &request_data, + if (o_stream_send(request->conn->output, &request_data, sizeof(request_data)) < 0) auth_connection_destroy(request->conn); - else if (o_buffer_send(request->conn->outbuf, data, data_size) < 0) + else if (o_stream_send(request->conn->output, data, data_size) < 0) auth_connection_destroy(request->conn); }
--- a/src/login/client-authenticate.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/login/client-authenticate.c Fri Dec 06 03:09:22 2002 +0200 @@ -3,8 +3,8 @@ #include "common.h" #include "base64.h" #include "ioloop.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "temp-string.h" #include "auth-connection.h" #include "client.h" @@ -73,7 +73,7 @@ client_send_tagline(client, msg != NULL ? msg : "NO Authentication failed."); - o_buffer_flush(client->outbuf); + o_stream_flush(client->output); /* get back to normal client input */ if (client->io != NULL) @@ -110,11 +110,11 @@ t_push(); base64_data = base64_encode(data, size); - o_buffer_send(client->outbuf, "+ ", 2); - o_buffer_send(client->outbuf, base64_data, strlen(base64_data)); - o_buffer_send(client->outbuf, "\r\n", 2); + o_stream_send(client->output, "+ ", 2); + o_stream_send(client->output, base64_data, strlen(base64_data)); + o_stream_send(client->output, "\r\n", 2); - o_buffer_flush(client->outbuf); + o_stream_flush(client->output); t_pop(); } @@ -244,7 +244,7 @@ if (!client_read(client)) return; - line = i_buffer_next_line(client->inbuf); + line = i_stream_next_line(client->input); if (line == NULL) return;
--- a/src/login/client.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/login/client.c Fri Dec 06 03:09:22 2002 +0200 @@ -3,8 +3,8 @@ #include "common.h" #include "hash.h" #include "ioloop.h" -#include "ibuffer.h" -#include "obuffer.h" +#include "istream.h" +#include "ostream.h" #include "process-title.h" #include "client.h" #include "client-authenticate.h" @@ -66,7 +66,7 @@ } client_send_tagline(client, "OK Begin TLS negotiation now."); - o_buffer_flush(client->outbuf); + o_stream_flush(client->output); /* must be removed before ssl_proxy_new(), since it may io_add() the same fd. */ @@ -82,12 +82,12 @@ client->fd = fd_ssl; - i_buffer_unref(client->inbuf); - o_buffer_unref(client->outbuf); + i_stream_unref(client->input); + o_stream_unref(client->output); - client->inbuf = i_buffer_create_file(fd_ssl, default_pool, + client->input = i_stream_create_file(fd_ssl, default_pool, 8192, FALSE); - client->outbuf = o_buffer_create_file(fd_ssl, default_pool, + client->output = o_stream_create_file(fd_ssl, default_pool, 1024, IO_PRIORITY_DEFAULT, FALSE); } else { @@ -115,7 +115,7 @@ int client_read(Client *client) { - switch (i_buffer_read(client->inbuf)) { + switch (i_stream_read(client->input)) { case -2: /* buffer full */ client_send_line(client, "* BYE Input buffer full, aborting"); @@ -211,9 +211,9 @@ return; client_ref(client); - o_buffer_cork(client->outbuf); + o_stream_cork(client->output); - while ((line = i_buffer_next_line(client->inbuf)) != NULL) { + while ((line = i_stream_next_line(client->input)) != NULL) { /* split the arguments, make sure we have at least tag + command */ i_free(client->tag); @@ -228,7 +228,7 @@ } if (client_unref(client)) - o_buffer_flush(client->outbuf); + o_stream_flush(client->output); } static void client_hash_destroy_oldest(void *key, void *value __attr_unused__, @@ -286,8 +286,8 @@ memcpy(&client->ip, ip, sizeof(IPADDR)); client->fd = fd; client->io = io_add(fd, IO_READ, client_input, client); - client->inbuf = i_buffer_create_file(fd, default_pool, 8192, FALSE); - client->outbuf = o_buffer_create_file(fd, default_pool, 1024, + client->input = i_stream_create_file(fd, default_pool, 8192, FALSE); + client->output = o_stream_create_file(fd, default_pool, 1024, IO_PRIORITY_DEFAULT, FALSE); client->last_input = ioloop_time; hash_insert(clients, client, client); @@ -306,8 +306,8 @@ hash_remove(clients, client); - i_buffer_close(client->inbuf); - o_buffer_close(client->outbuf); + i_stream_close(client->input); + o_stream_close(client->output); if (client->io != NULL) { io_remove(client->io); @@ -330,8 +330,8 @@ if (--client->refcount > 0) return TRUE; - i_buffer_unref(client->inbuf); - o_buffer_unref(client->outbuf); + i_stream_unref(client->input); + o_stream_unref(client->output); i_free(client->tag); i_free(client->plain_login); @@ -343,8 +343,8 @@ void client_send_line(Client *client, const char *line) { - o_buffer_send(client->outbuf, line, strlen(line)); - o_buffer_send(client->outbuf, "\r\n", 2); + o_stream_send(client->output, line, strlen(line)); + o_stream_send(client->output, "\r\n", 2); } void client_send_tagline(Client *client, const char *line)
--- a/src/login/client.h Fri Dec 06 00:37:33 2002 +0200 +++ b/src/login/client.h Fri Dec 06 03:09:22 2002 +0200 @@ -10,8 +10,8 @@ int fd; IO io; - IBuffer *inbuf; - OBuffer *outbuf; + IStream *input; + OStream *output; time_t last_input; char *tag;
--- a/src/master/auth-process.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/master/auth-process.c Fri Dec 06 03:09:22 2002 +0200 @@ -5,7 +5,7 @@ #include "env-util.h" #include "fd-close-on-exec.h" #include "network.h" -#include "obuffer.h" +#include "ostream.h" #include "restrict-access.h" #include "restrict-process-size.h" #include "auth-process.h" @@ -24,7 +24,7 @@ pid_t pid; int fd; IO io; - OBuffer *outbuf; + OStream *output; unsigned int reply_pos; char reply_buf[sizeof(AuthCookieReplyData)]; @@ -127,7 +127,7 @@ p->pid = pid; p->fd = fd; p->io = io_add(fd, IO_READ, auth_process_input, p); - p->outbuf = o_buffer_create_file(fd, default_pool, + p->output = o_stream_create_file(fd, default_pool, sizeof(AuthCookieRequestData)*100, IO_PRIORITY_DEFAULT, FALSE); @@ -159,7 +159,7 @@ (void)unlink(t_strconcat(set_login_dir, "/", p->name, NULL)); - o_buffer_unref(p->outbuf); + o_stream_unref(p->output); io_remove(p->io); (void)close(p->fd); i_free(p->name); @@ -285,7 +285,7 @@ req.id = id; memcpy(req.cookie, cookie, AUTH_COOKIE_SIZE); - if (o_buffer_send(process->outbuf, &req, sizeof(req)) < 0) + if (o_stream_send(process->output, &req, sizeof(req)) < 0) auth_process_destroy(process); push_request(process, id, callback, context);
--- a/src/master/login-process.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/master/login-process.c Fri Dec 06 03:09:22 2002 +0200 @@ -3,7 +3,7 @@ #include "common.h" #include "ioloop.h" #include "network.h" -#include "obuffer.h" +#include "ostream.h" #include "fdpass.h" #include "fd-close-on-exec.h" #include "env-util.h" @@ -25,7 +25,7 @@ pid_t pid; int fd; IO io; - OBuffer *outbuf; + OStream *output; unsigned int listening:1; unsigned int destroyed:1; }; @@ -81,7 +81,7 @@ reply.id = request->login_id; process = request->process; - if (o_buffer_send(process->outbuf, &reply, sizeof(reply)) < 0) + if (o_stream_send(process->output, &reply, sizeof(reply)) < 0) login_process_destroy(process); (void)close(request->fd); @@ -182,7 +182,7 @@ p->fd = fd; p->listening = TRUE; p->io = io_add(fd, IO_READ, login_process_input, p); - p->outbuf = o_buffer_create_file(fd, default_pool, + p->output = o_stream_create_file(fd, default_pool, sizeof(MasterReply)*10, IO_PRIORITY_DEFAULT, FALSE); @@ -215,7 +215,7 @@ if (p->listening) listening_processes--; - o_buffer_close(p->outbuf); + o_stream_close(p->output); io_remove(p->io); (void)close(p->fd); @@ -232,7 +232,7 @@ if (--p->refcount > 0) return; - o_buffer_unref(p->outbuf); + o_stream_unref(p->output); i_free(p); }
--- a/src/master/settings.c Fri Dec 06 00:37:33 2002 +0200 +++ b/src/master/settings.c Fri Dec 06 03:09:22 2002 +0200 @@ -1,7 +1,7 @@ /* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" -#include "ibuffer.h" +#include "istream.h" #include "settings.h" #include <stdio.h> @@ -433,7 +433,7 @@ void settings_read(const char *path) { - IBuffer *inbuf; + IStream *input; const char *errormsg; char *line, *key, *p; int fd, linenum; @@ -445,11 +445,11 @@ i_fatal("Can't open configuration file %s: %m", path); linenum = 0; - inbuf = i_buffer_create_file(fd, default_pool, 2048, TRUE); + input = i_stream_create_file(fd, default_pool, 2048, TRUE); for (;;) { - line = i_buffer_next_line(inbuf); + line = i_stream_next_line(input); if (line == NULL) { - if (i_buffer_read(inbuf) <= 0) + if (i_stream_read(input) <= 0) break; continue; } @@ -494,7 +494,7 @@ } }; - i_buffer_unref(inbuf); + i_stream_unref(input); settings_verify(); }