From 687ec880201e4872a9abf72f5efe135164fc349b Mon Sep 17 00:00:00 2001 From: dequis Date: Sat, 12 Sep 2015 05:25:33 -0300 Subject: IRCv3 multi-prefix... but mostly just adding prefixes to WHO We can't actually have multiple prefixes internally, so the only thing missing for multi-prefix compliance is actually having the prefix in the WHO reply, which is a rfc1459 thing. Note to future self: check irc logs for the implementation I threw away. The one that actually handled multiple prefixes. I hope that's useful. --- irc.h | 4 ++-- irc_cap.c | 3 +-- irc_channel.c | 12 ++++++++++++ irc_send.c | 32 +++++++++++++++++++------------- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/irc.h b/irc.h index c7d1aa85..4be7ce7e 100644 --- a/irc.h +++ b/irc.h @@ -66,8 +66,7 @@ typedef enum { } irc_status_t; typedef enum { - CAP_FOO = (1 << 0), - CAP_BAR = (1 << 1), + CAP_MULTI_PREFIX = (1 << 1), } irc_cap_flag_t; struct irc_user; @@ -308,6 +307,7 @@ int irc_channel_name_cmp(const char *a_, const char *b_); char *irc_channel_name_gen(irc_t *irc, const char *name); gboolean irc_channel_name_hint(irc_channel_t *ic, const char *name); void irc_channel_update_ops(irc_channel_t *ic, char *value); +char irc_channel_user_get_prefix(irc_channel_user_t *icu); char *set_eval_irc_channel_ops(struct set *set, char *value); gboolean irc_channel_wants_user(irc_channel_t *ic, irc_user_t *iu); diff --git a/irc_cap.c b/irc_cap.c index 3b139c94..79732409 100644 --- a/irc_cap.c +++ b/irc_cap.c @@ -37,8 +37,7 @@ typedef struct { } cap_info_t; static const cap_info_t supported_caps[] = { - {"foo", CAP_FOO}, - {"bar", CAP_BAR}, + {"multi-prefix", CAP_MULTI_PREFIX}, {NULL}, }; diff --git a/irc_channel.c b/irc_channel.c index cbd306a3..714e974a 100644 --- a/irc_channel.c +++ b/irc_channel.c @@ -428,6 +428,18 @@ void irc_channel_set_mode(irc_channel_t *ic, const char *s) } } +char irc_channel_user_get_prefix(irc_channel_user_t *icu) +{ + if (icu->flags & IRC_CHANNEL_USER_OP) { + return '@'; + } else if (icu->flags & IRC_CHANNEL_USER_HALFOP) { + return '%'; + } else if (icu->flags & IRC_CHANNEL_USER_VOICE) { + return '+'; + } + return 0; +} + void irc_channel_auto_joins(irc_t *irc, account_t *acc) { GSList *l; diff --git a/irc_send.c b/irc_send.c index a76b5bb1..4dbc82d5 100644 --- a/irc_send.c +++ b/irc_send.c @@ -213,13 +213,8 @@ void irc_send_names(irc_channel_t *ic) *namelist = 0; } - if (icu->flags & IRC_CHANNEL_USER_OP) { - strcat(namelist, "@"); - } else if (icu->flags & IRC_CHANNEL_USER_HALFOP) { - strcat(namelist, "%"); - } else if (icu->flags & IRC_CHANNEL_USER_VOICE) { - strcat(namelist, "+"); - } + namelist[strlen(namelist) + 1] = '\0'; + namelist[strlen(namelist)] = irc_channel_user_get_prefix(icu); strcat(namelist, iu->nick); strcat(namelist, " "); @@ -293,15 +288,26 @@ void irc_send_who(irc_t *irc, GSList *l, const char *channel) gboolean is_channel = strchr(CTYPES, channel[0]) != NULL; while (l) { - irc_user_t *iu = l->data; + irc_user_t *iu; + + /* Null terminated string with three chars, respectively: + * { , <@|%|+|\0>, \0 } */ + char status_prefix[3] = {0}; + + /* rfc1459 doesn't mention this: G means gone, H means here */ + status_prefix[0] = iu->flags & IRC_USER_AWAY ? 'G' : 'H'; + if (is_channel) { - iu = ((irc_channel_user_t *) iu)->iu; + irc_channel_user_t *icu = l->data; + status_prefix[1] = irc_channel_user_get_prefix(icu); + iu = icu->iu; + } else { + iu = l->data; } - /* TODO(wilmer): Restore away/channel information here */ - irc_send_num(irc, 352, "%s %s %s %s %s %c :0 %s", + + irc_send_num(irc, 352, "%s %s %s %s %s %s :0 %s", is_channel ? channel : "*", iu->user, iu->host, irc->root->host, - iu->nick, iu->flags & IRC_USER_AWAY ? 'G' : 'H', - iu->fullname); + iu->nick, status_prefix, iu->fullname); l = l->next; } -- cgit v1.2.3