diff options
| author | dequis <dx@dxzone.com.ar> | 2015-09-12 05:25:33 -0300 | 
|---|---|---|
| committer | dequis <dx@dxzone.com.ar> | 2015-10-08 02:25:56 -0300 | 
| commit | 687ec880201e4872a9abf72f5efe135164fc349b (patch) | |
| tree | 4e49f1d713799ff679954978f4c8bd94b096282c | |
| parent | 0b0bb4c68a1c87b8f77f266ea8e836758203f53e (diff) | |
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.
| -rw-r--r-- | irc.h | 4 | ||||
| -rw-r--r-- | irc_cap.c | 3 | ||||
| -rw-r--r-- | irc_channel.c | 12 | ||||
| -rw-r--r-- | irc_send.c | 32 | 
4 files changed, 34 insertions, 17 deletions
| @@ -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); @@ -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; @@ -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: +		 * { <H|G>, <@|%|+|\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;  	} | 
