aboutsummaryrefslogtreecommitdiff
path: root/degesch.c
diff options
context:
space:
mode:
Diffstat (limited to 'degesch.c')
-rw-r--r--degesch.c94
1 files changed, 60 insertions, 34 deletions
diff --git a/degesch.c b/degesch.c
index 49b5ab6..5b514c5 100644
--- a/degesch.c
+++ b/degesch.c
@@ -1020,6 +1020,12 @@ enum server_state
IRC_REGISTERED ///< We can chat now
};
+/// Convert an IRC identifier character to lower-case
+typedef int (*irc_tolower_fn) (int);
+
+/// Key conversion function for hashmap lookups
+typedef size_t (*irc_strxfrm_fn) (char *, const char *, size_t);
+
struct server
{
struct app_context *ctx; ///< Application context
@@ -1064,11 +1070,8 @@ struct server
// Server-specific information (from RPL_ISUPPORT):
- /// Convert an IRC identifier character to lower-case
- int (*irc_tolower) (int);
-
- /// Key conversion function for hashmap lookups
- size_t (*irc_strxfrm) (char *, const char *, size_t);
+ irc_tolower_fn irc_tolower; ///< Server tolower()
+ irc_strxfrm_fn irc_strxfrm; ///< Server strxfrm()
char *irc_chantypes; ///< Channel types (name prefixes)
char *irc_idchan_prefixes; ///< Prefixes for "safe channels"
@@ -1090,6 +1093,45 @@ static void on_irc_ping_timeout (void *user_data);
static void irc_initiate_connect (struct server *s);
static void
+server_init_specifics (struct server *self)
+{
+ // Defaults as per the RPL_ISUPPORT drafts, or RFC 1459
+
+ self->irc_tolower = irc_tolower;
+ self->irc_strxfrm = irc_strxfrm;
+
+ self->irc_chantypes = xstrdup ("#&");
+ self->irc_idchan_prefixes = xstrdup ("");
+ self->irc_statusmsg = xstrdup ("");
+
+ self->irc_chanmodes_list = xstrdup ("b");
+ self->irc_chanmodes_param_always = xstrdup ("k");
+ self->irc_chanmodes_param_when_set = xstrdup ("l");
+ self->irc_chanmodes_param_never = xstrdup ("imnpst");
+
+ self->irc_chanuser_prefixes = xstrdup ("@+");
+ self->irc_chanuser_modes = xstrdup ("ov");
+
+ self->irc_max_modes = 3;
+}
+
+static void
+server_free_specifics (struct server *self)
+{
+ free (self->irc_chantypes);
+ free (self->irc_idchan_prefixes);
+ free (self->irc_statusmsg);
+
+ free (self->irc_chanmodes_list);
+ free (self->irc_chanmodes_param_always);
+ free (self->irc_chanmodes_param_when_set);
+ free (self->irc_chanmodes_param_never);
+
+ free (self->irc_chanuser_prefixes);
+ free (self->irc_chanuser_modes);
+}
+
+static void
server_init (struct server *self, struct poller *poller)
{
memset (self, 0, sizeof *self);
@@ -1119,23 +1161,8 @@ server_init (struct server *self, struct poller *poller)
str_init (&self->irc_user_mode);
- // Defaults as per the RPL_ISUPPORT drafts, or RFC 1459
- self->irc_tolower = irc_tolower;
- self->irc_strxfrm = irc_strxfrm;
-
- self->irc_chantypes = xstrdup ("#&");
- self->irc_idchan_prefixes = xstrdup ("");
- self->irc_statusmsg = xstrdup ("");
-
- self->irc_chanmodes_list = xstrdup ("b");
- self->irc_chanmodes_param_always = xstrdup ("k");
- self->irc_chanmodes_param_when_set = xstrdup ("l");
- self->irc_chanmodes_param_never = xstrdup ("imnpst");
-
- self->irc_chanuser_prefixes = xstrdup ("@+");
- self->irc_chanuser_modes = xstrdup ("ov");
-
- self->irc_max_modes = 3;
+ server_free_specifics (self);
+ server_init_specifics (self);
}
static void
@@ -1169,17 +1196,7 @@ server_free (struct server *self)
str_free (&self->irc_user_mode);
free (self->irc_user_host);
- free (self->irc_chantypes);
- free (self->irc_idchan_prefixes);
- free (self->irc_statusmsg);
-
- free (self->irc_chanmodes_list);
- free (self->irc_chanmodes_param_always);
- free (self->irc_chanmodes_param_when_set);
- free (self->irc_chanmodes_param_never);
-
- free (self->irc_chanuser_prefixes);
- free (self->irc_chanuser_modes);
+ server_free_specifics (self);
}
static void
@@ -3208,9 +3225,18 @@ on_irc_disconnected (struct server *s)
free (s->irc_user_host);
s->irc_user_host = NULL;
- // TODO: reset RPL_ISUPPORT information
s->cap_echo_message = false;
+ irc_tolower_fn old_tolower = s->irc_tolower;
+ irc_strxfrm_fn old_strxfrm = s->irc_strxfrm;
+ server_free_specifics (s);
+ server_init_specifics (s);
+ // TODO: compare with the original functions and merge users and their
+ // buffers as necessary; ideally we would never have to do this but
+ // I can't think of any good workaround
+ s->irc_tolower = old_tolower;
+ s->irc_strxfrm = old_strxfrm;
+
// Take any relevant actions
if (s->ctx->quitting)
try_finish_quit (s->ctx);