server-connection.c revision 7d359c1719bf6ff228a96c66d27f5cfa239cb31d
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2010-2012 Dovecot authors, see the included COPYING file */
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainenstatic struct server_connection *printing_conn = NULL;
e5fd6dfd0a492e4708d4dbb7971d7fc5d7b8fd85Timo Sirainenstatic void server_connection_input(struct server_connection *conn);
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen struct doveadm_server *server = printing_conn->server;
dfaefeabae939803ceb8c503101e86b5496541d1Timo Sirainen unsigned int i, count;
57a8c6a95e4bce3eeaba36985adb81c07dd683ffTimo Sirainen conns = array_get(&server->connections, &count);
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainen for (i = 0; i < count; i++) {
563273bdac80393af63b9520cbf4d24cc0efd028Timo Sirainenserver_connection_callback(struct server_connection *conn,
ff7056842f14fd3b30a2d327dfab165b9d15dd30Timo Sirainen server_cmd_callback_t *callback = conn->callback;
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainenstatic void stream_data(string_t *str, const unsigned char *data, size_t size)
c5ab90cfad9cc3e33bcb1baeb30ffc82a7b7053aTimo Sirainen text = str_tabunescape(str_c_modifiable(str));
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void server_flush_field(struct server_connection *conn, string_t *str,
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen text = str_tabunescape(str_c_modifiable(str));
17ad2164c747cedbf81dae1893063e71a3df0356Timo Sirainenserver_handle_input(struct server_connection *conn,
51327f2489a4e0e615eb9f7d921473cf8512bb79Timo Sirainen /* continue printing */
d3442384ca53d4b18a493db7dd0b000f470419cfTimo Sirainen /* someone else is printing. don't continue until it
c0d069950af1dbc6a4e5c3de3bf2e437796e3ae0Timo Sirainen /* last character is an escape */
5137d2d80255938a0f5fb8f3c1a21b34cf11ada3Timo Sirainen server_flush_field(conn, str, data + start, i - start);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstatic void server_connection_authenticated(struct server_connection *conn)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen o_stream_send_str(conn->output, conn->delayed_cmd);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenserver_connection_authenticate(struct server_connection *conn)
e3aeeb634245e80d4f643f8d2eea11d6b72336d8Timo Sirainen "can't authenticate to remote server");
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen str_append(plain, conn->set->doveadm_password);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen o_stream_send(conn->output, cmd->data, cmd->used);
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainenstatic void server_connection_input(struct server_connection *conn)
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen const unsigned char *data;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if ((line = i_stream_read_next_line(conn->input)) == NULL) {
1d2b188f0eedc3cab6e27ceac5425a037f38042eTimo Sirainen if (conn->input->eof || conn->input->stream_errno != 0)
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if (server_connection_authenticate(conn) < 0) {
ca98892a6b8a30ffc1fe26fcf02c7d59e3204e7eTimo Sirainen i_error("doveadm server sent invalid handshake: %s",
df00412606a00714a6e85383fa87fbdc7cc1fb5bTimo Sirainen /* disconnected */
f81f4bc282cd1944cec187bae89c0701a416ed2aTimo Sirainen if ((line = i_stream_next_line(conn->input)) == NULL)
3dd0679b6f24be0287cc42d7a60bbf59cdf8b637Timo Sirainen i_error("doveadm authentication failed (%s)", line+1);
3f91e60401495a4046c73992fabaa5e77200a451Timo Sirainen i_error("doveadm server sent unexpected input");
eb64c3586d854cddd693f0b811d897399076a441Timo Sirainen /* fall through */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen server_connection_callback(conn, SERVER_CMD_REPLY_OK);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* we're finished, close the connection */
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainenstatic int server_connection_read_settings(struct server_connection *conn)
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen const struct setting_parser_info *set_roots[] = {
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen unsigned int port;
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (void)net_getsockname(conn->fd, &input.local_ip, &port);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen (void)net_getpeername(conn->fd, &input.remote_ip, &port);
83bb013a99f0936995f9c7a1077822662d8fefdbTimo Sirainen if (master_service_settings_read(master_service, &input,
9af6cc9ebc9986c1275ebdfa29c39e152af1557eTimo Sirainen i_error("Error reading configuration: %s", error);
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen set = master_service_settings_get_others(master_service)[0];
73b50eecfc31750a312e2f940023f522eb07178cTimo Sirainen conn->set = settings_dup(&doveadm_setting_parser_info, set, conn->pool);
838e367716bbd5e44b4a1691db9cbf72af53e9f0Timo Sirainenserver_connection_create(struct doveadm_server *server)
6564208826b0f46a00f010d1b5711d85944c3c88Timo Sirainen#define DOVEADM_SERVER_HANDSHAKE "VERSION\tdoveadm-server\t1\t0\n"
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen pool = pool_alloconly_create("doveadm server connection", 1024*16);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen conn = p_new(pool, struct server_connection, 1);
539977f9257bd8985be5a8093658da266ae9cd19Timo Sirainen conn->io = io_add(conn->fd, IO_READ, server_connection_input, conn);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen conn->input = i_stream_create_fd(conn->fd, MAX_INBUF_SIZE, FALSE);
310767ca33e7636d40ec45dee68a2c319a5fa3c0Timo Sirainen conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE);
310767ca33e7636d40ec45dee68a2c319a5fa3c0Timo Sirainen o_stream_send_str(conn->output, DOVEADM_SERVER_HANDSHAKE);
8e371a3ce32bd64288786855b8ce0cb63f19f7d1Timo Sirainen array_append(&conn->server->connections, &conn, 1);
e29f8a6a52ca72fc6010132fb86dd00e9d96432aTimo Sirainenvoid server_connection_destroy(struct server_connection **_conn)
b0a901f1dbe9e05ac1c92a0974af6bce0274f31aTimo Sirainen unsigned int i, count;
b0a901f1dbe9e05ac1c92a0974af6bce0274f31aTimo Sirainen conns = array_get(&conn->server->connections, &count);
b0a901f1dbe9e05ac1c92a0974af6bce0274f31aTimo Sirainen for (i = 0; i < count; i++) {
b0a901f1dbe9e05ac1c92a0974af6bce0274f31aTimo Sirainen array_delete(&conn->server->connections, i, 1);
c04f9a724a7b3cc649485a61b0a540868d25d71bTimo Sirainenserver_connection_get_server(struct server_connection *conn)
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainenvoid server_connection_cmd(struct server_connection *conn, const char *line,
cd83124e5d070a016c590bb0b1096d7828c7b6adTimo Sirainen server_cmd_callback_t *callback, void *context)
eb0816090cf5a549280ad783b9aa6fec199d36baTimo Sirainen conn->delayed_cmd = p_strdup(conn->pool, line);