kike: shuffle things around
Pseudorandomly. There are more than one way the program could be laid out. Some of them make more sense than others.
This commit is contained in:
parent
9927956104
commit
23cd9521d4
11
src/common.c
11
src/common.c
|
@ -1815,6 +1815,17 @@ irc_strcmp (const char *a, const char *b)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
irc_fnmatch (const char *pattern, const char *string)
|
||||||
|
{
|
||||||
|
size_t pattern_size = strlen (pattern) + 1;
|
||||||
|
size_t string_size = strlen (string) + 1;
|
||||||
|
char x_pattern[pattern_size], x_string[string_size];
|
||||||
|
irc_strxfrm (x_pattern, pattern, pattern_size);
|
||||||
|
irc_strxfrm (x_string, string, string_size);
|
||||||
|
return fnmatch (x_pattern, x_string, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// --- Configuration -----------------------------------------------------------
|
// --- Configuration -----------------------------------------------------------
|
||||||
|
|
||||||
// The keys are stripped of surrounding whitespace, the values are not.
|
// The keys are stripped of surrounding whitespace, the values are not.
|
||||||
|
|
317
src/kike.c
317
src/kike.c
|
@ -236,7 +236,7 @@ irc_is_valid_fingerprint (const char *fp)
|
||||||
return irc_regex_match ("^[a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){19}$", fp);
|
return irc_regex_match ("^[a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){19}$", fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Application data --------------------------------------------------------
|
// --- Clients (equals users) --------------------------------------------------
|
||||||
|
|
||||||
#define IRC_SUPPORTED_USER_MODES "aiwros"
|
#define IRC_SUPPORTED_USER_MODES "aiwros"
|
||||||
|
|
||||||
|
@ -307,26 +307,14 @@ client_free (struct client *self)
|
||||||
free (self->away_message);
|
free (self->away_message);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void client_close_link (struct client *, const char *);
|
||||||
client_mode_to_str (unsigned m, struct str *out)
|
static void client_send (struct client *, const char *, ...)
|
||||||
{
|
ATTRIBUTE_PRINTF (2, 3);
|
||||||
if (m & IRC_USER_MODE_INVISIBLE) str_append_c (out, 'i');
|
static void client_cancel_timers (struct client *);
|
||||||
if (m & IRC_USER_MODE_RX_WALLOPS) str_append_c (out, 'w');
|
static void client_set_kill_timer (struct client *);
|
||||||
if (m & IRC_USER_MODE_RESTRICTED) str_append_c (out, 'r');
|
static void client_update_poller (struct client *, const struct pollfd *);
|
||||||
if (m & IRC_USER_MODE_OPERATOR) str_append_c (out, 'o');
|
|
||||||
if (m & IRC_USER_MODE_RX_SERVER_NOTICES) str_append_c (out, 's');
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
// --- Channels ----------------------------------------------------------------
|
||||||
client_get_mode (struct client *self)
|
|
||||||
{
|
|
||||||
struct str mode;
|
|
||||||
str_init (&mode);
|
|
||||||
if (self->away_message)
|
|
||||||
str_append_c (&mode, 'a');
|
|
||||||
client_mode_to_str (self->mode, &mode);
|
|
||||||
return str_steal (&mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define IRC_SUPPORTED_CHAN_MODES "ov" "beI" "imnqpst" "kl"
|
#define IRC_SUPPORTED_CHAN_MODES "ov" "beI" "imnqpst" "kl"
|
||||||
|
|
||||||
|
@ -434,6 +422,42 @@ channel_get_mode (struct channel *self, bool disclose_secrets)
|
||||||
return str_steal (&mode);
|
return str_steal (&mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct channel_user *
|
||||||
|
channel_get_user (const struct channel *chan, const struct client *c)
|
||||||
|
{
|
||||||
|
for (struct channel_user *iter = chan->users; iter; iter = iter->next)
|
||||||
|
if (iter->c == c)
|
||||||
|
return iter;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct channel_user *
|
||||||
|
channel_add_user (struct channel *chan, struct client *c)
|
||||||
|
{
|
||||||
|
struct channel_user *link = xcalloc (1, sizeof *link);
|
||||||
|
link->c = c;
|
||||||
|
LIST_PREPEND (chan->users, link);
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
channel_remove_user (struct channel *chan, struct channel_user *user)
|
||||||
|
{
|
||||||
|
LIST_UNLINK (chan->users, user);
|
||||||
|
free (user);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t
|
||||||
|
channel_user_count (const struct channel *chan)
|
||||||
|
{
|
||||||
|
size_t result = 0;
|
||||||
|
for (struct channel_user *iter = chan->users; iter; iter = iter->next)
|
||||||
|
result++;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- IRC server context ------------------------------------------------------
|
||||||
|
|
||||||
struct server_context
|
struct server_context
|
||||||
{
|
{
|
||||||
int listen_fds[1]; ///< Listening socket FD's
|
int listen_fds[1]; ///< Listening socket FD's
|
||||||
|
@ -523,13 +547,6 @@ server_context_free (struct server_context *self)
|
||||||
str_map_free (&self->operators);
|
str_map_free (&self->operators);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
irc_try_finish_quit (struct server_context *ctx)
|
|
||||||
{
|
|
||||||
if (!ctx->n_clients && ctx->quitting)
|
|
||||||
ctx->polling = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
irc_get_text (struct server_context *ctx, int id, const char *def)
|
irc_get_text (struct server_context *ctx, int id, const char *def)
|
||||||
{
|
{
|
||||||
|
@ -540,55 +557,37 @@ irc_get_text (struct server_context *ctx, int id, const char *def)
|
||||||
return catgets (ctx->catalog, 1, id, def);
|
return catgets (ctx->catalog, 1, id, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
irc_fnmatch (const char *pattern, const char *string)
|
irc_try_finish_quit (struct server_context *ctx)
|
||||||
{
|
{
|
||||||
size_t pattern_size = strlen (pattern) + 1;
|
if (!ctx->n_clients && ctx->quitting)
|
||||||
size_t string_size = strlen (string) + 1;
|
ctx->polling = false;
|
||||||
char x_pattern[pattern_size], x_string[string_size];
|
|
||||||
irc_strxfrm (x_pattern, pattern, pattern_size);
|
|
||||||
irc_strxfrm (x_string, string, string_size);
|
|
||||||
return fnmatch (x_pattern, x_string, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// --- Channels ----------------------------------------------------------------
|
|
||||||
|
|
||||||
static struct channel_user *
|
|
||||||
channel_get_user (const struct channel *chan, const struct client *c)
|
|
||||||
{
|
|
||||||
for (struct channel_user *iter = chan->users; iter; iter = iter->next)
|
|
||||||
if (iter->c == c)
|
|
||||||
return iter;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct channel_user *
|
|
||||||
channel_add_user (struct channel *chan, struct client *c)
|
|
||||||
{
|
|
||||||
struct channel_user *link = xcalloc (1, sizeof *link);
|
|
||||||
link->c = c;
|
|
||||||
LIST_PREPEND (chan->users, link);
|
|
||||||
return link;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
channel_remove_user (struct channel *chan, struct channel_user *user)
|
irc_initiate_quit (struct server_context *ctx)
|
||||||
{
|
{
|
||||||
LIST_UNLINK (chan->users, user);
|
print_status ("shutting down");
|
||||||
free (user);
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t
|
for (struct client *iter = ctx->clients; iter; iter = iter->next)
|
||||||
channel_user_count (const struct channel *chan)
|
if (!iter->closing_link)
|
||||||
{
|
client_close_link (iter, "Shutting down");
|
||||||
size_t result = 0;
|
|
||||||
for (struct channel_user *iter = chan->users; iter; iter = iter->next)
|
for (size_t i = 0; i < ctx->n_listen_fds; i++)
|
||||||
result++;
|
{
|
||||||
return result;
|
ssize_t index = poller_find_by_fd (&ctx->poller, ctx->listen_fds[i]);
|
||||||
|
if (soft_assert (index != -1))
|
||||||
|
poller_remove_at_index (&ctx->poller, index);
|
||||||
|
xclose (ctx->listen_fds[i]);
|
||||||
|
}
|
||||||
|
ctx->n_listen_fds = 0;
|
||||||
|
|
||||||
|
ctx->quitting = true;
|
||||||
|
irc_try_finish_quit (ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct channel *
|
static struct channel *
|
||||||
channel_create (struct server_context *ctx, const char *name)
|
irc_channel_create (struct server_context *ctx, const char *name)
|
||||||
{
|
{
|
||||||
struct channel *chan = channel_new ();
|
struct channel *chan = channel_new ();
|
||||||
chan->ctx = ctx;
|
chan->ctx = ctx;
|
||||||
|
@ -598,52 +597,14 @@ channel_create (struct server_context *ctx, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
channel_destroy_if_empty (struct server_context *ctx, struct channel *chan)
|
irc_channel_destroy_if_empty (struct server_context *ctx, struct channel *chan)
|
||||||
{
|
{
|
||||||
if (!chan->users)
|
if (!chan->users)
|
||||||
str_map_set (&ctx->channels, chan->name, NULL);
|
str_map_set (&ctx->channels, chan->name, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Clients -----------------------------------------------------------------
|
|
||||||
|
|
||||||
static void client_cancel_timers (struct client *);
|
|
||||||
static void client_set_kill_timer (struct client *);
|
|
||||||
static void client_update_poller (struct client *, const struct pollfd *);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irc_send_str (struct client *c, const struct str *s)
|
irc_send_to_roommates (struct client *c, const char *message)
|
||||||
{
|
|
||||||
hard_assert (c->initialized && !c->closing_link);
|
|
||||||
|
|
||||||
// TODO: kill the connection above some "SendQ" threshold (careful!)
|
|
||||||
str_append_data (&c->write_buffer, s->str,
|
|
||||||
s->len > IRC_MAX_MESSAGE_LENGTH ? IRC_MAX_MESSAGE_LENGTH : s->len);
|
|
||||||
str_append (&c->write_buffer, "\r\n");
|
|
||||||
// XXX: we might want to move this elsewhere, so that it doesn't get called
|
|
||||||
// as often; it's going to cause a lot of syscalls with epoll.
|
|
||||||
client_update_poller (c, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void irc_send (struct client *c,
|
|
||||||
const char *format, ...) ATTRIBUTE_PRINTF (2, 3);
|
|
||||||
|
|
||||||
static void
|
|
||||||
irc_send (struct client *c, const char *format, ...)
|
|
||||||
{
|
|
||||||
struct str tmp;
|
|
||||||
str_init (&tmp);
|
|
||||||
|
|
||||||
va_list ap;
|
|
||||||
va_start (ap, format);
|
|
||||||
str_append_vprintf (&tmp, format, ap);
|
|
||||||
va_end (ap);
|
|
||||||
|
|
||||||
irc_send_str (c, &tmp);
|
|
||||||
str_free (&tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
client_send_to_roommates (struct client *c, const char *message)
|
|
||||||
{
|
{
|
||||||
struct str_map targets;
|
struct str_map targets;
|
||||||
str_map_init (&targets);
|
str_map_init (&targets);
|
||||||
|
@ -668,7 +629,59 @@ client_send_to_roommates (struct client *c, const char *message)
|
||||||
str_map_iter_init (&iter, &targets);
|
str_map_iter_init (&iter, &targets);
|
||||||
struct client *target;
|
struct client *target;
|
||||||
while ((target = str_map_iter_next (&iter)))
|
while ((target = str_map_iter_next (&iter)))
|
||||||
irc_send (target, "%s", message);
|
client_send (target, "%s", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Clients (continued) -----------------------------------------------------
|
||||||
|
|
||||||
|
static void
|
||||||
|
client_mode_to_str (unsigned m, struct str *out)
|
||||||
|
{
|
||||||
|
if (m & IRC_USER_MODE_INVISIBLE) str_append_c (out, 'i');
|
||||||
|
if (m & IRC_USER_MODE_RX_WALLOPS) str_append_c (out, 'w');
|
||||||
|
if (m & IRC_USER_MODE_RESTRICTED) str_append_c (out, 'r');
|
||||||
|
if (m & IRC_USER_MODE_OPERATOR) str_append_c (out, 'o');
|
||||||
|
if (m & IRC_USER_MODE_RX_SERVER_NOTICES) str_append_c (out, 's');
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
client_get_mode (struct client *self)
|
||||||
|
{
|
||||||
|
struct str mode;
|
||||||
|
str_init (&mode);
|
||||||
|
if (self->away_message)
|
||||||
|
str_append_c (&mode, 'a');
|
||||||
|
client_mode_to_str (self->mode, &mode);
|
||||||
|
return str_steal (&mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
client_send_str (struct client *c, const struct str *s)
|
||||||
|
{
|
||||||
|
hard_assert (c->initialized && !c->closing_link);
|
||||||
|
|
||||||
|
// TODO: kill the connection above some "SendQ" threshold (careful!)
|
||||||
|
str_append_data (&c->write_buffer, s->str,
|
||||||
|
s->len > IRC_MAX_MESSAGE_LENGTH ? IRC_MAX_MESSAGE_LENGTH : s->len);
|
||||||
|
str_append (&c->write_buffer, "\r\n");
|
||||||
|
// XXX: we might want to move this elsewhere, so that it doesn't get called
|
||||||
|
// as often; it's going to cause a lot of syscalls with epoll.
|
||||||
|
client_update_poller (c, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
client_send (struct client *c, const char *format, ...)
|
||||||
|
{
|
||||||
|
struct str tmp;
|
||||||
|
str_init (&tmp);
|
||||||
|
|
||||||
|
va_list ap;
|
||||||
|
va_start (ap, format);
|
||||||
|
str_append_vprintf (&tmp, format, ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
client_send_str (c, &tmp);
|
||||||
|
str_free (&tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -682,7 +695,7 @@ client_unregister (struct client *c, const char *reason)
|
||||||
|
|
||||||
char *message = xstrdup_printf (":%s!%s@%s QUIT :%s",
|
char *message = xstrdup_printf (":%s!%s@%s QUIT :%s",
|
||||||
c->nickname, c->username, c->hostname, reason);
|
c->nickname, c->username, c->hostname, reason);
|
||||||
client_send_to_roommates (c, message);
|
irc_send_to_roommates (c, message);
|
||||||
free (message);
|
free (message);
|
||||||
|
|
||||||
struct str_map_iter iter;
|
struct str_map_iter iter;
|
||||||
|
@ -695,7 +708,7 @@ client_unregister (struct client *c, const char *reason)
|
||||||
if (!(user = channel_get_user (chan, c)))
|
if (!(user = channel_get_user (chan, c)))
|
||||||
continue;
|
continue;
|
||||||
channel_remove_user (chan, user);
|
channel_remove_user (chan, user);
|
||||||
channel_destroy_if_empty (c->ctx, chan);
|
irc_channel_destroy_if_empty (c->ctx, chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (c->nickname);
|
free (c->nickname);
|
||||||
|
@ -727,7 +740,7 @@ client_kill (struct client *c, const char *reason)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
irc_close_link (struct client *c, const char *reason)
|
client_close_link (struct client *c, const char *reason)
|
||||||
{
|
{
|
||||||
if (!soft_assert (!c->closing_link))
|
if (!soft_assert (!c->closing_link))
|
||||||
return;
|
return;
|
||||||
|
@ -736,7 +749,7 @@ irc_close_link (struct client *c, const char *reason)
|
||||||
// it, with some arbitrary timeout. The `closing_link' state makes sure
|
// it, with some arbitrary timeout. The `closing_link' state makes sure
|
||||||
// that a/ we ignore any successive messages, and b/ that the connection
|
// that a/ we ignore any successive messages, and b/ that the connection
|
||||||
// is killed after the write buffer is transferred and emptied.
|
// is killed after the write buffer is transferred and emptied.
|
||||||
irc_send (c, "ERROR :Closing Link: %s[%s] (%s)", c->nickname,
|
client_send (c, "ERROR :Closing Link: %s[%s] (%s)", c->nickname,
|
||||||
c->hostname /* TODO host IP? */, reason);
|
c->hostname /* TODO host IP? */, reason);
|
||||||
c->closing_link = true;
|
c->closing_link = true;
|
||||||
|
|
||||||
|
@ -760,28 +773,6 @@ client_in_mask_list (const struct client *c, const struct str_vector *mask)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
irc_initiate_quit (struct server_context *ctx)
|
|
||||||
{
|
|
||||||
print_status ("shutting down");
|
|
||||||
|
|
||||||
for (struct client *iter = ctx->clients; iter; iter = iter->next)
|
|
||||||
if (!iter->closing_link)
|
|
||||||
irc_close_link (iter, "Shutting down");
|
|
||||||
|
|
||||||
for (size_t i = 0; i < ctx->n_listen_fds; i++)
|
|
||||||
{
|
|
||||||
ssize_t index = poller_find_by_fd (&ctx->poller, ctx->listen_fds[i]);
|
|
||||||
if (soft_assert (index != -1))
|
|
||||||
poller_remove_at_index (&ctx->poller, index);
|
|
||||||
xclose (ctx->listen_fds[i]);
|
|
||||||
}
|
|
||||||
ctx->n_listen_fds = 0;
|
|
||||||
|
|
||||||
ctx->quitting = true;
|
|
||||||
irc_try_finish_quit (ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
client_get_ssl_cert_fingerprint (struct client *c)
|
client_get_ssl_cert_fingerprint (struct client *c)
|
||||||
{
|
{
|
||||||
|
@ -830,7 +821,7 @@ client_set_timer (struct client *c, poller_timer_func fn, unsigned interval)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_irc_client_kill_timer (void *user_data)
|
on_client_kill_timer (void *user_data)
|
||||||
{
|
{
|
||||||
struct client *c = user_data;
|
struct client *c = user_data;
|
||||||
hard_assert (!c->initialized || c->closing_link);
|
hard_assert (!c->initialized || c->closing_link);
|
||||||
|
@ -840,32 +831,32 @@ on_irc_client_kill_timer (void *user_data)
|
||||||
static void
|
static void
|
||||||
client_set_kill_timer (struct client *c)
|
client_set_kill_timer (struct client *c)
|
||||||
{
|
{
|
||||||
client_set_timer (c, on_irc_client_kill_timer, c->ctx->ping_interval);
|
client_set_timer (c, on_client_kill_timer, c->ctx->ping_interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_irc_client_timeout_timer (void *user_data)
|
on_client_timeout_timer (void *user_data)
|
||||||
{
|
{
|
||||||
struct client *c = user_data;
|
struct client *c = user_data;
|
||||||
char *reason = xstrdup_printf
|
char *reason = xstrdup_printf
|
||||||
("Ping timeout: >%u seconds", c->ctx->ping_interval);
|
("Ping timeout: >%u seconds", c->ctx->ping_interval);
|
||||||
irc_close_link (c, reason);
|
client_close_link (c, reason);
|
||||||
free (reason);
|
free (reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_irc_client_ping_timer (void *user_data)
|
on_client_ping_timer (void *user_data)
|
||||||
{
|
{
|
||||||
struct client *c = user_data;
|
struct client *c = user_data;
|
||||||
hard_assert (!c->closing_link);
|
hard_assert (!c->closing_link);
|
||||||
irc_send (c, "PING :%s", c->ctx->server_name);
|
client_send (c, "PING :%s", c->ctx->server_name);
|
||||||
client_set_timer (c, on_irc_client_timeout_timer, c->ctx->ping_interval);
|
client_set_timer (c, on_client_timeout_timer, c->ctx->ping_interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
client_set_ping_timer (struct client *c)
|
client_set_ping_timer (struct client *c)
|
||||||
{
|
{
|
||||||
client_set_timer (c, on_irc_client_ping_timer, c->ctx->ping_interval);
|
client_set_timer (c, on_client_ping_timer, c->ctx->ping_interval);
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- IRC command handling ----------------------------------------------------
|
// --- IRC command handling ----------------------------------------------------
|
||||||
|
@ -1045,7 +1036,7 @@ irc_send_reply (struct client *c, int id, ...)
|
||||||
irc_get_text (c->ctx, id, g_default_replies[id]), ap);
|
irc_get_text (c->ctx, id, g_default_replies[id]), ap);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
|
|
||||||
irc_send_str (c, &tmp);
|
client_send_str (c, &tmp);
|
||||||
str_free (&tmp);
|
str_free (&tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1132,12 +1123,12 @@ irc_try_finish_registration (struct client *c)
|
||||||
|
|
||||||
char *mode = client_get_mode (c);
|
char *mode = client_get_mode (c);
|
||||||
if (*mode)
|
if (*mode)
|
||||||
irc_send (c, ":%s MODE %s :+%s", c->nickname, c->nickname, mode);
|
client_send (c, ":%s MODE %s :+%s", c->nickname, c->nickname, mode);
|
||||||
free (mode);
|
free (mode);
|
||||||
|
|
||||||
hard_assert (c->ssl_cert_fingerprint == NULL);
|
hard_assert (c->ssl_cert_fingerprint == NULL);
|
||||||
if ((c->ssl_cert_fingerprint = client_get_ssl_cert_fingerprint (c)))
|
if ((c->ssl_cert_fingerprint = client_get_ssl_cert_fingerprint (c)))
|
||||||
irc_send (c, ":%s NOTICE %s :"
|
client_send (c, ":%s NOTICE %s :"
|
||||||
"Your SSL client certificate fingerprint is %s",
|
"Your SSL client certificate fingerprint is %s",
|
||||||
ctx->server_name, c->nickname, c->ssl_cert_fingerprint);
|
ctx->server_name, c->nickname, c->ssl_cert_fingerprint);
|
||||||
}
|
}
|
||||||
|
@ -1173,7 +1164,7 @@ irc_handle_nick (const struct irc_message *msg, struct client *c)
|
||||||
{
|
{
|
||||||
char *message = xstrdup_printf (":%s!%s@%s NICK :%s",
|
char *message = xstrdup_printf (":%s!%s@%s NICK :%s",
|
||||||
c->nickname, c->username, c->hostname, nickname);
|
c->nickname, c->username, c->hostname, nickname);
|
||||||
client_send_to_roommates (c, message);
|
irc_send_to_roommates (c, message);
|
||||||
free (message);
|
free (message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1276,7 +1267,7 @@ irc_handle_ping (const struct irc_message *msg, struct client *c)
|
||||||
else if (msg->params.len < 1)
|
else if (msg->params.len < 1)
|
||||||
irc_send_reply (c, IRC_ERR_NOORIGIN);
|
irc_send_reply (c, IRC_ERR_NOORIGIN);
|
||||||
else
|
else
|
||||||
irc_send (c, ":%s PONG :%s",
|
client_send (c, ":%s PONG :%s",
|
||||||
c->ctx->server_name, msg->params.vector[0]);
|
c->ctx->server_name, msg->params.vector[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1296,7 +1287,7 @@ irc_handle_quit (const struct irc_message *msg, struct client *c)
|
||||||
{
|
{
|
||||||
char *reason = xstrdup_printf ("Quit: %s",
|
char *reason = xstrdup_printf ("Quit: %s",
|
||||||
msg->params.len > 0 ? msg->params.vector[0] : c->nickname);
|
msg->params.len > 0 ? msg->params.vector[0] : c->nickname);
|
||||||
irc_close_link (c, reason);
|
client_close_link (c, reason);
|
||||||
free (reason);
|
free (reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1330,7 +1321,7 @@ irc_channel_multicast (struct channel *chan, const char *message,
|
||||||
for (struct channel_user *iter = chan->users; iter; iter = iter->next)
|
for (struct channel_user *iter = chan->users; iter; iter = iter->next)
|
||||||
{
|
{
|
||||||
if (iter->c != except)
|
if (iter->c != except)
|
||||||
irc_send (iter->c, "%s", message);
|
client_send (iter->c, "%s", message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1369,7 +1360,7 @@ irc_update_user_mode (struct client *c, unsigned new_mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diff.len)
|
if (diff.len)
|
||||||
irc_send (c, ":%s MODE %s :%s",
|
client_send (c, ":%s MODE %s :%s",
|
||||||
c->nickname, c->nickname, diff.str);
|
c->nickname, c->nickname, diff.str);
|
||||||
str_free (&diff);
|
str_free (&diff);
|
||||||
}
|
}
|
||||||
|
@ -1407,7 +1398,7 @@ irc_handle_user_mode_change (struct client *c, const char *mode_string)
|
||||||
&& str_map_find (&c->ctx->operators, c->ssl_cert_fingerprint))
|
&& str_map_find (&c->ctx->operators, c->ssl_cert_fingerprint))
|
||||||
new_mode |= IRC_USER_MODE_OPERATOR;
|
new_mode |= IRC_USER_MODE_OPERATOR;
|
||||||
else
|
else
|
||||||
irc_send (c, ":%s NOTICE %s :Either you're not using an SSL"
|
client_send (c, ":%s NOTICE %s :Either you're not using an SSL"
|
||||||
" client certificate, or the fingerprint doesn't match",
|
" client certificate, or the fingerprint doesn't match",
|
||||||
c->ctx->server_name, c->nickname);
|
c->ctx->server_name, c->nickname);
|
||||||
break;
|
break;
|
||||||
|
@ -1736,7 +1727,7 @@ irc_handle_user_message (const struct irc_message *msg, struct client *c,
|
||||||
struct client *client = str_map_find (&c->ctx->users, target);
|
struct client *client = str_map_find (&c->ctx->users, target);
|
||||||
if (client)
|
if (client)
|
||||||
{
|
{
|
||||||
irc_send (client, ":%s!%s@%s %s %s :%s",
|
client_send (client, ":%s!%s@%s %s %s :%s",
|
||||||
c->nickname, c->username, c->hostname, command, target, text);
|
c->nickname, c->username, c->hostname, command, target, text);
|
||||||
if (allow_away_reply && client->away_message)
|
if (allow_away_reply && client->away_message)
|
||||||
irc_send_reply (c, IRC_RPL_AWAY, target, client->away_message);
|
irc_send_reply (c, IRC_RPL_AWAY, target, client->away_message);
|
||||||
|
@ -2143,11 +2134,11 @@ irc_try_part (struct client *c, const char *channel_name, const char *reason)
|
||||||
if (!(chan->modes & IRC_CHAN_MODE_QUIET))
|
if (!(chan->modes & IRC_CHAN_MODE_QUIET))
|
||||||
irc_channel_multicast (chan, message, NULL);
|
irc_channel_multicast (chan, message, NULL);
|
||||||
else
|
else
|
||||||
irc_send (c, "%s", message);
|
client_send (c, "%s", message);
|
||||||
free (message);
|
free (message);
|
||||||
|
|
||||||
channel_remove_user (chan, user);
|
channel_remove_user (chan, user);
|
||||||
channel_destroy_if_empty (c->ctx, chan);
|
irc_channel_destroy_if_empty (c->ctx, chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2205,11 +2196,11 @@ irc_try_kick (struct client *c, const char *channel_name, const char *nick,
|
||||||
if (!(chan->modes & IRC_CHAN_MODE_QUIET))
|
if (!(chan->modes & IRC_CHAN_MODE_QUIET))
|
||||||
irc_channel_multicast (chan, message, NULL);
|
irc_channel_multicast (chan, message, NULL);
|
||||||
else
|
else
|
||||||
irc_send (c, "%s", message);
|
client_send (c, "%s", message);
|
||||||
free (message);
|
free (message);
|
||||||
|
|
||||||
channel_remove_user (chan, user);
|
channel_remove_user (chan, user);
|
||||||
channel_destroy_if_empty (c->ctx, chan);
|
irc_channel_destroy_if_empty (c->ctx, chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2249,7 +2240,7 @@ irc_try_join (struct client *c, const char *channel_name, const char *key)
|
||||||
{
|
{
|
||||||
if (irc_validate_channel_name (channel_name) != VALIDATION_OK)
|
if (irc_validate_channel_name (channel_name) != VALIDATION_OK)
|
||||||
RETURN_WITH_REPLY (c, IRC_ERR_BADCHANMASK, channel_name);
|
RETURN_WITH_REPLY (c, IRC_ERR_BADCHANMASK, channel_name);
|
||||||
chan = channel_create (c->ctx, channel_name);
|
chan = irc_channel_create (c->ctx, channel_name);
|
||||||
user_mode = IRC_CHAN_MODE_OPERATOR;
|
user_mode = IRC_CHAN_MODE_OPERATOR;
|
||||||
}
|
}
|
||||||
else if (channel_get_user (chan, c))
|
else if (channel_get_user (chan, c))
|
||||||
|
@ -2275,7 +2266,7 @@ irc_try_join (struct client *c, const char *channel_name, const char *key)
|
||||||
if (!(chan->modes & IRC_CHAN_MODE_QUIET))
|
if (!(chan->modes & IRC_CHAN_MODE_QUIET))
|
||||||
irc_channel_multicast (chan, message, NULL);
|
irc_channel_multicast (chan, message, NULL);
|
||||||
else
|
else
|
||||||
irc_send (c, "%s", message);
|
client_send (c, "%s", message);
|
||||||
free (message);
|
free (message);
|
||||||
|
|
||||||
irc_send_rpl_topic (c, chan);
|
irc_send_rpl_topic (c, chan);
|
||||||
|
@ -2383,7 +2374,7 @@ irc_handle_kill (const struct irc_message *msg, struct client *c)
|
||||||
RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHNICK, msg->params.vector[0]);
|
RETURN_WITH_REPLY (c, IRC_ERR_NOSUCHNICK, msg->params.vector[0]);
|
||||||
char *reason = xstrdup_printf ("Killed by %s: %s",
|
char *reason = xstrdup_printf ("Killed by %s: %s",
|
||||||
c->nickname, msg->params.vector[1]);
|
c->nickname, msg->params.vector[1]);
|
||||||
irc_close_link (target, reason);
|
client_close_link (target, reason);
|
||||||
free (reason);
|
free (reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2684,7 +2675,7 @@ error_ssl_1:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_irc_client_ready (const struct pollfd *pfd, void *user_data)
|
on_client_ready (const struct pollfd *pfd, void *user_data)
|
||||||
{
|
{
|
||||||
struct client *c = user_data;
|
struct client *c = user_data;
|
||||||
if (!c->initialized)
|
if (!c->initialized)
|
||||||
|
@ -2735,7 +2726,7 @@ client_update_poller (struct client *c, const struct pollfd *pfd)
|
||||||
hard_assert (new_events != 0);
|
hard_assert (new_events != 0);
|
||||||
if (!pfd || pfd->events != new_events)
|
if (!pfd || pfd->events != new_events)
|
||||||
poller_set (&c->ctx->poller, c->socket_fd, new_events,
|
poller_set (&c->ctx->poller, c->socket_fd, new_events,
|
||||||
(poller_dispatcher_func) on_irc_client_ready, c);
|
(poller_dispatcher_func) on_client_ready, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2794,7 +2785,7 @@ on_irc_client_available (const struct pollfd *pfd, void *user_data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// --- Application setup -------------------------------------------------------
|
||||||
|
|
||||||
static int
|
static int
|
||||||
irc_ssl_verify_callback (int verify_ok, X509_STORE_CTX *ctx)
|
irc_ssl_verify_callback (int verify_ok, X509_STORE_CTX *ctx)
|
||||||
|
@ -3107,6 +3098,8 @@ irc_setup_listen_fds (struct server_context *ctx, struct error **e)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Main --------------------------------------------------------------------
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_signal_pipe_readable (const struct pollfd *fd, struct server_context *ctx)
|
on_signal_pipe_readable (const struct pollfd *fd, struct server_context *ctx)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue