diff --git a/src/kike.c b/src/kike.c index 9a744c2..d9b8291 100644 --- a/src/kike.c +++ b/src/kike.c @@ -423,7 +423,6 @@ server_context_free (struct server_context *self) if (self->ssl_ctx) SSL_CTX_free (self->ssl_ctx); - // TODO: terminate the connections properly before this is called struct client *link, *tmp; for (link = self->clients; link; link = tmp) { @@ -464,6 +463,13 @@ client_unregister (struct client *c, const char *reason) c->registered = false; } +static void +irc_try_finish_quit (struct server_context *ctx) +{ + if (!ctx->n_clients && ctx->quitting) + ctx->polling = false; +} + static void client_kill (struct client *c, const char *reason) { @@ -483,6 +489,8 @@ client_kill (struct client *c, const char *reason) LIST_UNLINK (ctx->clients, c); ctx->n_clients--; free (c); + + irc_try_finish_quit (ctx); } static void @@ -1266,8 +1274,7 @@ on_irc_client_available (const struct pollfd *pfd, void *user_data) exit_fatal ("%s: %s", "accept", strerror (errno)); } - if (ctx->max_connections != 0 - && ctx->n_clients >= ctx->max_connections) + if (ctx->max_connections != 0 && ctx->n_clients >= ctx->max_connections) { print_debug ("connection limit reached, refusing connection"); close (fd); @@ -1580,13 +1587,23 @@ on_signal_pipe_readable (const struct pollfd *fd, struct server_context *ctx) char *dummy; (void) read (fd->fd, &dummy, 1); - // TODO: send ERROR messages to anyone, wait for the messages to get - // dispatched for a few seconds, RST the rest and quit. if (g_termination_requested && !ctx->quitting) { -#if 0 - initiate_quit (ctx); -#endif + print_status ("shutting down"); + + for (struct client *iter = ctx->clients; iter; iter = iter->next) + if (!iter->closing_link) + irc_close_link (iter, "Shutting down"); + + ssize_t i = poller_find_by_fd (&ctx->poller, ctx->listen_fd); + if (soft_assert (i != -1)) + poller_remove_at_index (&ctx->poller, i); + if (ctx->listen_fd != -1) + xclose (ctx->listen_fd); + ctx->listen_fd = -1; + + ctx->quitting = true; + irc_try_finish_quit (ctx); } }