From: Timo Sirainen Date: Sun, 30 May 2004 01:40:47 +0000 (+0300) Subject: Allow using more easily outside dovecot. X-Git-Tag: 1.1.alpha1~4024 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=acf3b7bf3a8891b118a71c45e6c48d17bc90b259;p=thirdparty%2Fdovecot%2Fcore.git Allow using more easily outside dovecot. --HG-- branch : HEAD --- diff --git a/src/lib-auth/auth-client.c b/src/lib-auth/auth-client.c index cac6b43b53..0fbdf73324 100644 --- a/src/lib-auth/auth-client.c +++ b/src/lib-auth/auth-client.c @@ -11,14 +11,26 @@ #include struct auth_client *auth_client_new(unsigned int client_pid) +{ + return auth_client_new_external(client_pid, NULL, NULL, NULL); +} + +struct auth_client *auth_client_new_external(unsigned int client_pid, + const char *socket_paths, + input_func_add_t *add_func, + input_func_remove_t *remove_func) { struct auth_client *client; client = i_new(struct auth_client, 1); client->pid = client_pid; + client->socket_paths = i_strdup(socket_paths); client->available_auth_mechs = buffer_create_dynamic(default_pool, 128, (size_t)-1); + client->ext_input_add = add_func; + client->ext_input_remove = remove_func; + auth_client_connect_missing_servers(client); return client; } @@ -43,6 +55,7 @@ void auth_client_free(struct auth_client *client) if (client->to_reconnect != NULL) timeout_remove(client->to_reconnect); + i_free(client->socket_paths); i_free(client); } @@ -76,7 +89,7 @@ auth_client_find_mech(struct auth_client *client, const char *name) int auth_client_is_connected(struct auth_client *client) { - return client->to_reconnect == NULL && + return !client->reconnect && client->conn_waiting_handshake_count == 0; } @@ -95,42 +108,68 @@ static void reconnect_timeout(void *context) auth_client_connect_missing_servers(client); } +static void auth_client_connect_missing_servers_list(struct auth_client *client, + const char *list) +{ + const char *const *path; + + client->reconnect = FALSE; + + t_push(); + path = t_strsplit(list, ":"); + for (; *path != NULL; path++) { + if (auth_server_connection_find_path(client, *path) == NULL) { + if (auth_server_connection_new(client, *path) == NULL) + client->reconnect = TRUE; + } + } + t_pop(); +} + void auth_client_connect_missing_servers(struct auth_client *client) { DIR *dirp; struct dirent *dp; struct stat st; - int reconnect; - /* we're chrooted into */ - dirp = opendir("."); - if (dirp == NULL) { - i_fatal("opendir(.) failed when trying to get list of " - "authentication servers: %m"); - } + if (client->socket_paths != NULL) { + auth_client_connect_missing_servers_list(client, + client->socket_paths); + } else { + /* we're chrooted */ + dirp = opendir("."); + if (dirp == NULL) { + i_fatal("opendir(.) failed when trying to get list of " + "authentication servers: %m"); + } - reconnect = FALSE; - while ((dp = readdir(dirp)) != NULL) { - if (dp->d_name[0] == '.') - continue; + client->reconnect = FALSE; + while ((dp = readdir(dirp)) != NULL) { + const char *name = dp->d_name; - if (auth_server_connection_find_path(client, dp->d_name) != NULL) { - /* already connected */ - continue; - } + if (name[0] == '.') + continue; + + if (auth_server_connection_find_path(client, + name) != NULL) { + /* already connected */ + continue; + } - if (stat(dp->d_name, &st) == 0 && S_ISSOCK(st.st_mode)) { - if (auth_server_connection_new(client, - dp->d_name) == NULL) - reconnect = TRUE; + if (stat(name, &st) == 0 && S_ISSOCK(st.st_mode)) { + if (auth_server_connection_new(client, + name) == NULL) + client->reconnect = TRUE; + } } - } - if (closedir(dirp) < 0) - i_error("closedir() failed: %m"); + if (closedir(dirp) < 0) + i_error("closedir() failed: %m"); + } - if (reconnect || client->connections == NULL) { - if (client->to_reconnect == NULL) { + if (client->reconnect || client->connections == NULL) { + if (client->to_reconnect == NULL && + client->ext_input_add == NULL) { client->to_reconnect = timeout_add(5000, reconnect_timeout, client); } diff --git a/src/lib-auth/auth-client.h b/src/lib-auth/auth-client.h index 73c7a097f3..d75e2caef9 100644 --- a/src/lib-auth/auth-client.h +++ b/src/lib-auth/auth-client.h @@ -34,8 +34,6 @@ auth_client_get_available_mechs(struct auth_client *client, const struct auth_mech_desc * auth_client_find_mech(struct auth_client *client, const char *name); -void auth_client_connect_missing_servers(struct auth_client *client); - /* Create a new authentication request. callback is called whenever something happens for the request. */ struct auth_request * @@ -61,4 +59,16 @@ unsigned int auth_client_request_get_id(struct auth_request *request); /* Return the PID of the server that handled this request. */ unsigned int auth_client_request_get_server_pid(struct auth_request *request); +/* -- Using lib-auth with external I/O loop -- */ + +typedef void *input_func_add_t(int fd, void (*cb)(void *), void *context); +typedef void *input_func_remove_t(void *io); + +struct auth_client *auth_client_new_external(unsigned int client_pid, + const char *socket_paths, + input_func_add_t *add_func, + input_func_remove_t *remove_func); +/* Call every few seconds. */ +void auth_client_connect_missing_servers(struct auth_client *client); + #endif diff --git a/src/lib-auth/auth-server-connection.c b/src/lib-auth/auth-server-connection.c index d39357bf50..b9cf6f3994 100644 --- a/src/lib-auth/auth-server-connection.c +++ b/src/lib-auth/auth-server-connection.c @@ -49,12 +49,6 @@ static void auth_handle_handshake(struct auth_server_connection *conn, buffer_t *buf; unsigned int i; - if (handshake->server_pid == 0) { - i_error("BUG: Auth server said it's PID 0"); - auth_server_connection_destroy(conn, FALSE); - return; - } - if (handshake->data_size == 0 || data[handshake->data_size-1] != '\0' || handshake->mech_count * sizeof(handshake_mech_desc) >= handshake->data_size) { @@ -191,7 +185,12 @@ auth_server_connection_new(struct auth_client *client, const char *path) conn->client = client; conn->path = p_strdup(pool, path); conn->fd = fd; - conn->io = io_add(fd, IO_READ, auth_client_input, conn); + if (client->ext_input_add == NULL) + conn->io = io_add(fd, IO_READ, auth_client_input, conn); + else { + conn->ext_input_io = + client->ext_input_add(fd, auth_client_input, conn); + } conn->input = i_stream_create_file(fd, default_pool, MAX_INBUF_SIZE, FALSE); conn->output = o_stream_create_file(fd, default_pool, MAX_OUTBUF_SIZE, @@ -235,8 +234,14 @@ void auth_server_connection_destroy(struct auth_server_connection *conn, if (!conn->handshake_received) client->conn_waiting_handshake_count--; - io_remove(conn->io); - conn->io = NULL; + if (conn->ext_input_io != NULL) { + client->ext_input_remove(conn->ext_input_io); + conn->ext_input_io = NULL; + } + if (conn->io != NULL) { + io_remove(conn->io); + conn->io = NULL; + } i_stream_close(conn->input); o_stream_close(conn->output); @@ -294,7 +299,7 @@ auth_server_connection_find_mech(struct auth_client *client, for (conn = client->connections; conn != NULL; conn = conn->next) { mech = conn->available_auth_mechs; for (i = 0; i < conn->available_auth_mechs_count; i++) { - if (strcmp(mech[i].name, name) == 0) + if (strcasecmp(mech[i].name, name) == 0) return conn; } } diff --git a/src/lib-auth/auth-server-connection.h b/src/lib-auth/auth-server-connection.h index 5ba25b2c7f..fbfb17f5b7 100644 --- a/src/lib-auth/auth-server-connection.h +++ b/src/lib-auth/auth-server-connection.h @@ -3,6 +3,10 @@ struct auth_client { unsigned int pid; + char *socket_paths; + + input_func_add_t *ext_input_add; + input_func_remove_t *ext_input_remove; struct auth_server_connection *connections; struct timeout *to_reconnect; @@ -14,6 +18,8 @@ struct auth_client { auth_connect_notify_callback_t *connect_notify_callback; void *connect_notify_context; + + unsigned int reconnect:1; }; struct auth_server_connection { @@ -27,6 +33,7 @@ struct auth_server_connection { int fd; struct io *io; + void *ext_input_io; struct istream *input; struct ostream *output;