master.c revision cd94aeaa294f7cc507206b4b2075852f00e14d61
76b43e4417bab52e913da39b5f5bc2a130d3f149Timo Sirainen/* Copyright (c) 2002-2008 Dovecot authors, see the included COPYING file */
d6af1e63bc7824f1cc5b9b73a1c5f8f8789788d6Timo Sirainenstatic unsigned int master_tag_counter;
d6af1e63bc7824f1cc5b9b73a1c5f8f8789788d6Timo Sirainenstatic unsigned int master_pos;
d6af1e63bc7824f1cc5b9b73a1c5f8f8789788d6Timo Sirainenstatic char master_buf[sizeof(struct master_login_reply)];
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainenstatic void client_call_master_callback(struct client *client,
d6af1e63bc7824f1cc5b9b73a1c5f8f8789788d6Timo Sirainenstatic void request_handle(struct master_login_reply *reply)
d6af1e63bc7824f1cc5b9b73a1c5f8f8789788d6Timo Sirainen if (reply->tag == 0 && !process_per_connection) {
d6af1e63bc7824f1cc5b9b73a1c5f8f8789788d6Timo Sirainen /* this means we have to start listening again.
d6af1e63bc7824f1cc5b9b73a1c5f8f8789788d6Timo Sirainen we've reached maximum number of login processes. */
6a9f9a5101b665fd2ef80c9e048a5eace78e01efTimo Sirainen client = hash_lookup(master_requests, POINTER_CAST(reply->tag));
0f66f12eb4cdbf47670975044c88d8f388bf92dfTimo Sirainen i_fatal("Master sent reply with unknown tag %u", reply->tag);
6a9f9a5101b665fd2ef80c9e048a5eace78e01efTimo Sirainen hash_remove(master_requests, POINTER_CAST(reply->tag));
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen client_call_master_callback(client, reply->status);
4b058f90f9e8a2c6b2eed275de4eb8cc5195a71dTimo Sirainen /* NOTE: client may be destroyed now */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid master_request_login(struct client *client, master_callback_t *callback,
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen const unsigned char *data;
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen data = i_stream_get_data(client->input, &size);
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen buf = buffer_create_dynamic(pool_datastack_create(),
1f57716285d4c5bc9bf2fd5569e3c85fd496afd9Timo Sirainen req = buffer_get_space_unsafe(buf, 0, sizeof(*req));
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen#if LOGIN_MAX_INBUF_SIZE != MASTER_LOGIN_MAX_DATA_SIZE
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainen i_assert(req->data_size <= LOGIN_MAX_INBUF_SIZE);
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen ret = fd_send(master_fd, client->fd, buf->data, buf->used);
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen i_fatal("fd_send(%d) failed: %m", client->fd);
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen hash_insert(master_requests, POINTER_CAST(req->tag), client);
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainenvoid master_request_abort(struct client *client)
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen /* we're still going to get the reply from the master, so just
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen remember that we want to ignore it */
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen hash_update(master_requests, POINTER_CAST(client->master_tag),
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainenvoid master_notify_state_change(enum master_login_state state)
b09be485e9373be4288f5615bbce6ebed65a425aTimo Sirainen /* sending -1 as fd does the notification */
b09be485e9373be4288f5615bbce6ebed65a425aTimo Sirainen if (fd_send(master_fd, -1, &req, sizeof(req)) != sizeof(req))
b09be485e9373be4288f5615bbce6ebed65a425aTimo Sirainen /* may call this function again through main_unref() */
33ca6b017b6ebbd048651b5e3d16915001dbc291Timo Sirainen i_fatal("master_exec: dup2(%d, 0) failed: %m", fd);
const char *line;
env_clean();
path);
return fd;
int ret;
if (ret < 0) {
master_close();
master_pos = 0;
main_ref();
master_pos = 0;
void master_deinit(void)