]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
ipc: Fixes when sending commands to an empty group.
authorTimo Sirainen <tss@iki.fi>
Mon, 23 May 2011 12:04:36 +0000 (15:04 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 23 May 2011 12:04:36 +0000 (15:04 +0300)
src/ipc/client.c
src/ipc/ipc-group.c
src/ipc/ipc-group.h

index 22bdb5ac4df9a6aa8396b6004bb8947e0d3087f0..de014b0bc183ef4dd82915f4fde7c8c71ec47dd7 100644 (file)
@@ -48,8 +48,7 @@ client_cmd_input(enum ipc_cmd_status status, const char *line, void *context)
                                  t_strdup_printf("%c%s\n", chr, line));
        } T_END;
 
-       if (status != IPC_CMD_STATUS_REPLY) {
-               i_assert(client->io == NULL);
+       if (status != IPC_CMD_STATUS_REPLY && client->io == NULL) {
                client->io = io_add(client->fd, IO_READ, client_input, client);
                client_input(client);
        }
@@ -61,6 +60,7 @@ static void client_input(struct client *client)
        struct ipc_connection *conn;
        char *line, *id, *data;
        unsigned int id_num;
+       bool ret;
 
        while ((line = i_stream_read_next_line(client->input)) != NULL) {
                /* <ipc name> *|<id> <command> */
@@ -78,31 +78,39 @@ static void client_input(struct client *client)
                *data++ = '\0';
 
                group = ipc_group_lookup_name(line);
-               if (group == NULL) {
-                       o_stream_send_str(client->output,
-                               t_strdup_printf("-Unknown IPC group: %s\n", line));
-                       continue;
-               }
 
+               ret = FALSE;
                if (strcmp(id, "*") == 0) {
                        /* send to everyone */
-                       ipc_group_cmd(group, data, client_cmd_input, client);
+                       if (group == NULL) {
+                               client_cmd_input(IPC_CMD_STATUS_OK,
+                                                NULL, client);
+                       } else {
+                               ret = ipc_group_cmd(group, data,
+                                                   client_cmd_input, client);
+                       }
                } else if (str_to_uint(id, &id_num) < 0) {
                        o_stream_send_str(client->output,
                                t_strdup_printf("-Invalid IPC connection id: %s\n", id));
                        continue;
+               } else if (group == NULL) {
+                       o_stream_send_str(client->output,
+                               t_strdup_printf("-Unknown IPC group: %s\n", line));
                } else if ((conn = ipc_connection_lookup_id(group, id_num)) == NULL) {
                        o_stream_send_str(client->output,
                                t_strdup_printf("-Unknown IPC connection id: %u\n", id_num));
                        continue;
                } else {
                        ipc_connection_cmd(conn, data, client_cmd_input, client);
+                       ret = TRUE;
                }
 
-               /* we'll handle commands one at a time. stop reading input
-                  until this command is finished. */
-               io_remove(&client->io);
-               break;
+               if (ret) {
+                       /* we'll handle commands one at a time. stop reading
+                          input until this command is finished. */
+                       io_remove(&client->io);
+                       break;
+               }
        }
        if (client->input->eof || client->input->stream_errno != 0)
                client_destroy(&client);
index cbfeb14343bafc70554aff8af67bf40bc89b4e0a..2f3c25b2938bfad43f3fc57dfa2388ce702e4610 100644 (file)
@@ -113,7 +113,7 @@ static void ipc_group_cmd_callback(enum ipc_cmd_status status,
 
 }
 
-void ipc_group_cmd(struct ipc_group *group, const char *cmd,
+bool ipc_group_cmd(struct ipc_group *group, const char *cmd,
                   ipc_cmd_callback_t *callback, void *context)
 {
        struct ipc_connection *conn, *next;
@@ -121,7 +121,7 @@ void ipc_group_cmd(struct ipc_group *group, const char *cmd,
 
        if (group->connections == NULL) {
                callback(IPC_CMD_STATUS_OK, NULL, context);
-               return;
+               return FALSE;
        }
 
        group_cmd = i_new(struct ipc_group_cmd, 1);
@@ -135,6 +135,7 @@ void ipc_group_cmd(struct ipc_group *group, const char *cmd,
                ipc_connection_cmd(conn, cmd,
                                   ipc_group_cmd_callback, group_cmd);
        }
+       return TRUE;
 }
 
 void ipc_groups_init(void)
index 56d41d804f41324698c7585adfd1f17b4b5e5bfe..13a673f43131974f289e964c19a0af8cdaac2990 100644 (file)
@@ -33,8 +33,9 @@ struct ipc_group *ipc_group_lookup_name(const char *name);
 int ipc_group_update_name(struct ipc_group *group, const char *name);
 
 /* Send a command to all connections in a group. All connections are expected
-   to answer something. All replies are  */
-void ipc_group_cmd(struct ipc_group *group, const char *cmd,
+   to answer something. If there are no connections, callback() is called
+   immediately and FALSE is returned. */
+bool ipc_group_cmd(struct ipc_group *group, const char *cmd,
                   ipc_cmd_callback_t *callback, void *context);
 
 void ipc_groups_init(void);