degesch: parse more of RPL_ISUPPORT
This commit is contained in:
		
							parent
							
								
									81aff58f73
								
							
						
					
					
						commit
						2242724c34
					
				
							
								
								
									
										132
									
								
								degesch.c
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								degesch.c
									
									
									
									
									
								
							| @ -1035,11 +1035,6 @@ struct server | ||||
| 
 | ||||
| 	// IRC:
 | ||||
| 
 | ||||
| 	// TODO: casemapping-specific strxfrm and/or tolower (CASEMAPPING=rfc1459)
 | ||||
| 	// TODO: channel name prefixes (CHANTYPES=#& + IDCHAN)
 | ||||
| 	char *irc_channel_prefixes;         ///< Channel user prefixes
 | ||||
| 	char *irc_channel_modes;            ///< Channel user modes
 | ||||
| 
 | ||||
| 	struct str_map irc_users;           ///< IRC user data
 | ||||
| 	struct str_map irc_channels;        ///< IRC channel data
 | ||||
| 	struct str_map irc_buffer_map;      ///< Maps IRC identifiers to buffers
 | ||||
| @ -1048,6 +1043,22 @@ struct server | ||||
| 	char *irc_user_mode;                ///< Our current user mode
 | ||||
| 	char *irc_user_host;                ///< Our current user@host
 | ||||
| 
 | ||||
| 	// Server-specific information (from RPL_ISUPPORT):
 | ||||
| 
 | ||||
| 	// TODO: implement a generic strcmp() on top of "irc_tolower"
 | ||||
| 	/// 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); | ||||
| 
 | ||||
| 	char *irc_chantypes;                ///< Channel types (name prefixes)
 | ||||
| 	char *irc_idchan_prefixes;          ///< Prefixes for "safe channels"
 | ||||
| 	char *irc_statusmsg;                ///< Prefixes for channel targets
 | ||||
| 
 | ||||
| 	char *irc_chanuser_prefixes;        ///< Channel user prefixes
 | ||||
| 	char *irc_chanuser_modes;           ///< Channel user modes
 | ||||
| 
 | ||||
| 	// Events:
 | ||||
| 
 | ||||
| 	struct poller_timer ping_tmr;       ///< We should send a ping
 | ||||
| @ -1068,9 +1079,16 @@ server_init (struct server *self, struct poller *poller) | ||||
| 	str_init (&self->read_buffer); | ||||
| 	self->state = IRC_DISCONNECTED; | ||||
| 
 | ||||
| 	// RFC 1459 as per the RPL_ISUPPORT draft
 | ||||
| 	self->irc_channel_prefixes = xstrdup ("@+"); | ||||
| 	self->irc_channel_modes    = xstrdup ("ov"); | ||||
| 	// Defaults as per the RPL_ISUPPORT draft
 | ||||
| 	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_chanuser_prefixes = xstrdup ("@+"); | ||||
| 	self->irc_chanuser_modes    = xstrdup ("ov"); | ||||
| 
 | ||||
| 	str_map_init (&self->irc_users); | ||||
| 	self->irc_users.key_xfrm = irc_strxfrm; | ||||
| @ -1119,8 +1137,12 @@ server_free (struct server *self) | ||||
| 	free (self->irc_user_mode); | ||||
| 	free (self->irc_user_host); | ||||
| 
 | ||||
| 	free (self->irc_channel_prefixes); | ||||
| 	free (self->irc_channel_modes); | ||||
| 	free (self->irc_chantypes); | ||||
| 	free (self->irc_idchan_prefixes); | ||||
| 	free (self->irc_statusmsg); | ||||
| 
 | ||||
| 	free (self->irc_chanuser_prefixes); | ||||
| 	free (self->irc_chanuser_modes); | ||||
| 
 | ||||
| 	str_map_free (&self->irc_users); | ||||
| 	str_map_free (&self->irc_channels); | ||||
| @ -3731,7 +3753,6 @@ irc_is_highlight (struct server *s, const char *message) | ||||
| // --- Input handling ----------------------------------------------------------
 | ||||
| 
 | ||||
| // TODO: we will need a proper mode parser; to be shared with kike
 | ||||
| // TODO: we alse definitely need to parse server capability messages
 | ||||
| 
 | ||||
| static void | ||||
| irc_handle_join (struct server *s, const struct irc_message *msg) | ||||
| @ -4430,7 +4451,7 @@ irc_process_names (struct server *s, struct channel *channel) | ||||
| 	for (size_t i = 0; i < updates->len; i++) | ||||
| 	{ | ||||
| 		const char *item = updates->vector[i]; | ||||
| 		const char *nick = item + strspn (item, s->irc_channel_modes); | ||||
| 		const char *nick = item + strspn (item, s->irc_chanuser_modes); | ||||
| 		struct channel_user *channel_user = str_map_find (&map, nick); | ||||
| 		if (!channel_user) | ||||
| 		{ | ||||
| @ -4479,11 +4500,72 @@ irc_handle_isupport_prefix (struct server *s, char *value) | ||||
| 	if (*modes++ != '(' || !prefixes++ || strlen (value) != 2 * n_prefixes--) | ||||
| 		return; | ||||
| 
 | ||||
| 	free (s->irc_channel_modes); | ||||
| 	free (s->irc_channel_prefixes); | ||||
| 	free (s->irc_chanuser_modes); | ||||
| 	free (s->irc_chanuser_prefixes); | ||||
| 
 | ||||
| 	s->irc_channel_modes    = xstrndup (modes,    n_prefixes); | ||||
| 	s->irc_channel_prefixes = xstrndup (prefixes, n_prefixes); | ||||
| 	s->irc_chanuser_modes    = xstrndup (modes,    n_prefixes); | ||||
| 	s->irc_chanuser_prefixes = xstrndup (prefixes, n_prefixes); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| irc_handle_isupport_casemapping (struct server *s, char *value) | ||||
| { | ||||
| 	// TODO: reinitialize hashtables with the new tolower() and strxfrm(),
 | ||||
| 	//   note that collisions may arise on reconnecting
 | ||||
| 
 | ||||
| 	if      (!strcmp (value, "ascii")) | ||||
| 	{ | ||||
| 		s->irc_tolower = tolower_ascii; | ||||
| 		s->irc_strxfrm = tolower_ascii_strxfrm; | ||||
| 	} | ||||
| 	else if (!strcmp (value, "rfc1459")) | ||||
| 	{ | ||||
| 		s->irc_tolower = irc_tolower; | ||||
| 		s->irc_strxfrm = irc_strxfrm; | ||||
| 	} | ||||
| 	else if (!strcmp (value, "rfc1459-strict")) | ||||
| 	{ | ||||
| 		// TODO: implement
 | ||||
| 		s->irc_tolower = irc_tolower; | ||||
| 		s->irc_strxfrm = irc_strxfrm; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| irc_handle_isupport_chantypes (struct server *s, char *value) | ||||
| { | ||||
| 	free (s->irc_chantypes); | ||||
| 	s->irc_chantypes = xstrdup (value); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| irc_handle_isupport_idchan (struct server *s, char *value) | ||||
| { | ||||
| 	struct str prefixes; | ||||
| 	str_init (&prefixes); | ||||
| 
 | ||||
| 	struct str_vector v; | ||||
| 	str_vector_init (&v); | ||||
| 	split_str_ignore_empty (value, ',', &v); | ||||
| 	for (size_t i = 0; i < v.len; i++) | ||||
| 	{ | ||||
| 		// Not using or validating the numeric part
 | ||||
| 		const char *pair = v.vector[i]; | ||||
| 		const char *colon = strchr (pair, ':'); | ||||
| 		if (colon) | ||||
| 			str_append_data (&prefixes, pair, colon - pair); | ||||
| 	} | ||||
| 	str_vector_free (&v); | ||||
| 
 | ||||
| 	free (s->irc_idchan_prefixes); | ||||
| 	s->irc_idchan_prefixes = str_steal (&prefixes); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| irc_handle_isupport_statusmsg (struct server *s, char *value) | ||||
| { | ||||
| 	free (s->irc_statusmsg); | ||||
| 	s->irc_statusmsg = xstrdup (value); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| @ -4522,14 +4604,22 @@ irc_handle_rpl_isupport (struct server *s, const struct irc_message *msg) | ||||
| 		str_init (&value_unescaped); | ||||
| 		unescape_isupport_value (value, &value_unescaped); | ||||
| 
 | ||||
| 		if (!strcmp (param, "PREFIX")) | ||||
| 			irc_handle_isupport_prefix (s, value_unescaped.str); | ||||
| 		if      (!strcmp (param, "PREFIX")) | ||||
| 			irc_handle_isupport_prefix      (s, value_unescaped.str); | ||||
| 		else if (!strcmp (param, "CASEMAPPING")) | ||||
| 			irc_handle_isupport_casemapping (s, value_unescaped.str); | ||||
| 		else if (!strcmp (param, "CHANTYPES")) | ||||
| 			irc_handle_isupport_chantypes   (s, value_unescaped.str); | ||||
| 		else if (!strcmp (param, "IDCHAN")) | ||||
| 			irc_handle_isupport_idchan      (s, value_unescaped.str); | ||||
| 		else if (!strcmp (param, "STATUSMSG")) | ||||
| 			irc_handle_isupport_statusmsg   (s, value_unescaped.str); | ||||
| 
 | ||||
| 		// TODO: also parse MODES, TARGMAX, CHANMODES and make use of them
 | ||||
| 		//   to split client commands as necessary
 | ||||
| 
 | ||||
| 		str_free (&value_unescaped); | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: initialize key_strxfrm according to server properties;
 | ||||
| 	//   note that collisions may arise on reconnecting
 | ||||
| } | ||||
| 
 | ||||
| static void | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user