bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen#define DOVEADM_HANDSHAKE "VERSION\tdoveadm-server\t1\t0\n"
36757b426f4761dbd837bdddc8998e22d09dc869Timo Sirainendsync_client_init(const char *path, const char *dsync_params)
36757b426f4761dbd837bdddc8998e22d09dc869Timo Sirainen client->dsync_params = i_strdup(dsync_params);
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainenstatic void dsync_callback(struct dsync_client *client,
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen dsync_callback_t *callback = client->callback;
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen /* make sure callback doesn't try to reuse this connection, since
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen we can't currently handle it */
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainenstatic void dsync_close(struct dsync_client *client)
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainenstatic void dsync_disconnect(struct dsync_client *client)
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainenvoid dsync_client_deinit(struct dsync_client **_client)
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainenstatic int dsync_input_line(struct dsync_client *client, const char *line)
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen i_error("%s: Unexpected input: %s", client->path, line);
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen client->state = i_strdup(t_strcut(line, '\t'));
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen dsync_callback(client, state, DSYNC_REPLY_OK);
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen dsync_callback(client, "", DSYNC_REPLY_NOUSER);
c62d29c66b504ad3676deaefdf9e95f54e4f8eecAki Tuomi dsync_callback(client, "", DSYNC_REPLY_NOREPLICATE);
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen i_error("%s: Invalid input: %s", client->path, line);
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen /* FIXME: disconnect after each request for now.
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen doveadm server's getopt() handling seems to break otherwise.
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen also with multiple UIDs doveadm-server fails because setid() fails */
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainenstatic void dsync_input(struct dsync_client *client)
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen while ((line = i_stream_read_next_line(client->input)) != NULL) {
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainenstatic int dsync_connect(struct dsync_client *client)
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen if (client->last_connect_failure == ioloop_time)
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen i_error("net_connect_unix(%s) failed: %m", client->path);
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen client->io = io_add(client->fd, IO_READ, dsync_input, client);
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi client->input = i_stream_create_fd(client->fd, (size_t)-1);
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvi client->output = o_stream_create_fd(client->fd, (size_t)-1);
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen o_stream_set_no_error_handling(client->output, TRUE);
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen o_stream_nsend_str(client->output, DOVEADM_HANDSHAKE);
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainenstatic void dsync_fail_timeout(struct dsync_client *client)
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainenvoid dsync_client_sync(struct dsync_client *client,
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen const char *username, const char *state, bool full,
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen client->to = timeout_add(DSYNC_FAIL_TIMEOUT_MSECS,
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen /* <flags> <username> <command> [<args>] */
36757b426f4761dbd837bdddc8998e22d09dc869Timo Sirainen /* insert the parameters. we can do it simply by converting
36757b426f4761dbd837bdddc8998e22d09dc869Timo Sirainen spaces into tabs, it's unlikely we'll ever need anything
36757b426f4761dbd837bdddc8998e22d09dc869Timo Sirainen more complex here. */
36757b426f4761dbd837bdddc8998e22d09dc869Timo Sirainen for (; *p != '\0'; p++) {
36757b426f4761dbd837bdddc8998e22d09dc869Timo Sirainen if (*p == ' ')
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainen o_stream_nsend(client->output, str_data(cmd), str_len(cmd));
cc116e6d7a2515f0089a449c22a3d61d9ec14642Timo Sirainenbool dsync_client_is_busy(struct dsync_client *client)
2e08b126fd1a168c993b1c8c0d1211da236ff604Timo Sirainenconst char *dsync_client_get_username(struct dsync_client *conn)
2e08b126fd1a168c993b1c8c0d1211da236ff604Timo Sirainenenum dsync_type dsync_client_get_type(struct dsync_client *conn)
2e08b126fd1a168c993b1c8c0d1211da236ff604Timo Sirainenconst char *dsync_client_get_state(struct dsync_client *conn)
2e08b126fd1a168c993b1c8c0d1211da236ff604Timo Sirainen return "Not connected";
2e08b126fd1a168c993b1c8c0d1211da236ff604Timo Sirainen return t_strdup_printf("Failed to connect to '%s' - last attempt %ld secs ago", conn->path,
2e08b126fd1a168c993b1c8c0d1211da236ff604Timo Sirainen (long)(ioloop_time - conn->last_connect_failure));
2e08b126fd1a168c993b1c8c0d1211da236ff604Timo Sirainen return "Idle";
2e08b126fd1a168c993b1c8c0d1211da236ff604Timo Sirainen return "Waiting for handshake";
2e08b126fd1a168c993b1c8c0d1211da236ff604Timo Sirainen return "Waiting for dsync to finish";
2e08b126fd1a168c993b1c8c0d1211da236ff604Timo Sirainen return "Waiting for dsync to finish (second line)";