]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Allow using more easily outside dovecot.
authorTimo Sirainen <tss@iki.fi>
Sun, 30 May 2004 01:40:47 +0000 (04:40 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 30 May 2004 01:40:47 +0000 (04:40 +0300)
--HG--
branch : HEAD

src/lib-auth/auth-client.c
src/lib-auth/auth-client.h
src/lib-auth/auth-server-connection.c
src/lib-auth/auth-server-connection.h

index cac6b43b535d07ca8031f1bd5d444d94467fa177..0fbdf733248eec9eca2322a97c655c419e5689cb 100644 (file)
 #include <sys/stat.h>
 
 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);
                }
index 73c7a097f3a1e61bb8b8cd641a2b1048a7dcbdb6..d75e2caef9c089e36e37b56f876eec235d1a5c79 100644 (file)
@@ -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
index d39357bf50452decaf14898d55508be58f7cbfcd..b9cf6f39946d50bd911ea8bb9faec6133e3d2b99 100644 (file)
@@ -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;
                }
        }
index 5ba25b2c7f142806fa7b12a400d0d4480b89c95d..fbfb17f5b7e2f4b1f2c72576c3c043ae2704b710 100644 (file)
@@ -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;