static void imap_hibernate_client_destroy(struct connection *conn) { struct imap_hibernate_client *client = (struct imap_hibernate_client *)conn; if (!client->imap_client_created) master_service_client_connection_destroyed(master_service); else if (client->finished) imap_client_create_finish(client->imap_client); connection_deinit(conn); i_free(conn); }
static int imap_hibernate_client_input_line(struct connection *conn, const char *line) { struct imap_hibernate_client *client = (struct imap_hibernate_client *)conn; int fd = -1, ret; if (!conn->version_received) { if (connection_verify_version(conn, t_strsplit_tabescaped(line)) < 0) return -1; conn->version_received = TRUE; return 1; } if (client->imap_client == NULL) { char *const *args; pool_t pool; fd = i_stream_unix_get_read_fd(conn->input); if (fd == -1) { i_error("IMAP client fd not received"); return -1; } pool = pool_alloconly_create("client cmd", 1024); args = p_strsplit_tabescaped(pool, line); ret = imap_hibernate_client_input_args(conn, (void *)args, fd, pool); if (ret >= 0 && client->debug) i_debug("Create client with input: %s", line); pool_unref(&pool); } else { fd = i_stream_unix_get_read_fd(conn->input); if (fd == -1) { i_error("IMAP notify fd not received (input: %s)", line); ret = -1; } else if (line[0] != '\0') { i_error("Expected empty notify fd line from client, but got: %s", line); o_stream_send_str(conn->output, "Expected empty notify fd line"); ret = -1; } else { imap_client_add_notify_fd(client->imap_client, fd); ret = 1; } } if (ret < 0) { if (client->imap_client != NULL) imap_client_destroy(&client->imap_client, NULL); if (fd != -1) i_close_fd(&fd); return -1; } else if (ret == 0) { /* still need to read another fd */ i_stream_unix_set_read_fd(conn->input); o_stream_send_str(conn->output, "+\n"); return 1; } else { /* finished - always disconnect the hibernate client afterwards */ o_stream_send_str(conn->output, "+\n"); imap_client_create_finish(client->imap_client); return -1; } }