static void client_add_input(struct client *client, const buffer_t *buf) { struct ostream *output; if (buf != NULL && buf->used > 0) { if (!i_stream_add_data(client->input, buf->data, buf->used)) i_panic("Couldn't add client input to stream"); } output = client->output; o_stream_ref(output); o_stream_cork(output); (void)client_handle_input(client); o_stream_uncork(output); o_stream_unref(&output); }
static void client_add_input(struct client *client, const buffer_t *buf) { struct ostream *output; struct client_input input; if (buf != NULL && buf->used > 0) { client_parse_input(buf->data, buf->used, &input); if (input.input_size > 0 && !i_stream_add_data(client->input, input.input, input.input_size)) i_panic("Couldn't add client input to stream"); } else { /* IMAPLOGINTAG environment is compatible with mailfront */ memset(&input, 0, sizeof(input)); input.tag = getenv("IMAPLOGINTAG"); } output = client->output; o_stream_ref(output); o_stream_cork(output); if (input.tag == NULL) { client_send_line(client, t_strconcat( "* PREAUTH [CAPABILITY ", str_c(client->capability_string), "] " "Logged in as ", client->user->username, NULL)); } else if (input.send_untagged_capability) { /* client doesn't seem to understand tagged capabilities. send untagged instead and hope that it works. */ client_send_line(client, t_strconcat("* CAPABILITY ", str_c(client->capability_string), NULL)); client_send_line(client, t_strconcat(input.tag, " OK Logged in", NULL)); } else { client_send_line(client, t_strconcat( input.tag, " OK [CAPABILITY ", str_c(client->capability_string), "] Logged in", NULL)); } (void)client_handle_input(client); o_stream_uncork(output); o_stream_unref(&output); }
static int imap_master_client_input_args(struct connection *conn, const char *const *args, int fd_client, pool_t pool) { struct imap_master_client *client = (struct imap_master_client *)conn; struct client *imap_client; struct mail_storage_service_input input; struct imap_master_input master_input; const char *error; int ret; if (imap_master_client_parse_input(args, pool, &input, &master_input, &error) < 0) { i_error("imap-master: Failed to parse client input: %s", error); o_stream_nsend_str(conn->output, t_strdup_printf( "-Failed to parse client input: %s\n", error)); i_close_fd(&fd_client); return -1; } if (imap_master_client_verify(&master_input, fd_client, &error) < 0) { i_error("imap-master: Failed to verify client input: %s", error); o_stream_nsend_str(conn->output, t_strdup_printf( "-Failed to verify client input: %s\n", error)); i_close_fd(&fd_client); return -1; } /* Send a success notification before we start anything that lasts potentially a long time. imap-hibernate process is waiting for us to answer. Even if we fail later, we log the error anyway. */ o_stream_nsend_str(conn->output, "+\n"); (void)o_stream_flush(conn->output); /* NOTE: before client_create_from_input() on failures we need to close fd_client, but afterward it gets closed by client_destroy() */ ret = client_create_from_input(&input, fd_client, fd_client, &imap_client, &error); if (ret < 0) { i_error("imap-master(%s): Failed to create client: %s", input.username, error); i_close_fd(&fd_client); return -1; } client->imap_client_created = TRUE; if (client_create_finish(imap_client, &error) < 0) { i_error("imap-master(%s): %s", input.username, error); client_destroy(imap_client, error); return -1; } /* log prefix is set at this point, so we don't need to add the username anymore to the log messages */ o_stream_nsend(imap_client->output, master_input.client_output->data, master_input.client_output->used); if (master_input.client_input->used > 0 && !i_stream_add_data(imap_client->input, master_input.client_input->data, master_input.client_input->used)) { i_error("imap-master: Couldn't add %"PRIuSIZE_T " bytes to client's input stream", master_input.client_input->used); client_destroy(imap_client, "Client initialization failed"); return -1; } imap_client->state_import_bad_idle_done = master_input.state_import_bad_idle_done; imap_client->state_import_idle_continue = master_input.state_import_idle_continue; if (imap_client->user->mail_debug) { if (imap_client->state_import_bad_idle_done) i_debug("imap-master: Unhibernated because IDLE was stopped with BAD command"); else if (imap_client->state_import_idle_continue) i_debug("imap-master: Unhibernated to send mailbox changes"); else i_debug("imap-master: Unhibernated because IDLE was stopped with DONE"); } ret = imap_state_import_internal(imap_client, master_input.state->data, master_input.state->used, &error); if (ret <= 0) { i_error("imap-master: Failed to import client state: %s", error); client_destroy(imap_client, "Client state initialization failed"); return -1; } if (master_input.tag != NULL) imap_state_import_idle_cmd_tag(imap_client, master_input.tag); /* make sure all pending input gets handled */ i_assert(imap_client->to_delayed_input == NULL); if (master_input.client_input->used > 0) { if (imap_client->user->mail_debug) { i_debug("imap-master: Pending client input: '%s'", str_sanitize(str_c(master_input.client_input), 128)); } imap_client->to_delayed_input = timeout_add(0, client_input, imap_client); } imap_refresh_proctitle(); /* we'll always disconnect the client afterwards */ return -1; }