degesch: some basic RPL_ISUPPORT parsing
This commit is contained in:
		
							parent
							
								
									36185ddeee
								
							
						
					
					
						commit
						0b91604acd
					
				
							
								
								
									
										60
									
								
								degesch.c
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								degesch.c
									
									
									
									
									
								
							| @ -1035,6 +1035,11 @@ 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
 | ||||
| @ -1063,6 +1068,10 @@ 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"); | ||||
| 
 | ||||
| 	str_map_init (&self->irc_users); | ||||
| 	self->irc_users.key_xfrm = irc_strxfrm; | ||||
| 	str_map_init (&self->irc_channels); | ||||
| @ -1110,6 +1119,9 @@ 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); | ||||
| 
 | ||||
| 	str_map_free (&self->irc_users); | ||||
| 	str_map_free (&self->irc_channels); | ||||
| 	str_map_free (&self->irc_buffer_map); | ||||
| @ -4418,8 +4430,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]; | ||||
| 		// FIXME: use server-specific chanmode characters
 | ||||
| 		const char *nick = item + strspn (item, "@+"); | ||||
| 		const char *nick = item + strspn (item, s->irc_channel_modes); | ||||
| 		struct channel_user *channel_user = str_map_find (&map, nick); | ||||
| 		if (!channel_user) | ||||
| 		{ | ||||
| @ -4459,6 +4470,43 @@ irc_handle_rpl_endofnames (struct server *s, const struct irc_message *msg) | ||||
| 		irc_process_names (s, channel); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| irc_handle_isupport_prefix (struct server *s, char *value) | ||||
| { | ||||
| 	char *modes = value; | ||||
| 	char *prefixes = strchr (value, ')'); | ||||
| 	size_t n_prefixes = prefixes - modes; | ||||
| 	if (*modes++ != '(' || !prefixes++ || strlen (value) != 2 * n_prefixes--) | ||||
| 		return; | ||||
| 
 | ||||
| 	free (s->irc_channel_modes); | ||||
| 	free (s->irc_channel_prefixes); | ||||
| 
 | ||||
| 	s->irc_channel_modes    = xstrndup (modes,    n_prefixes); | ||||
| 	s->irc_channel_prefixes = xstrndup (prefixes, n_prefixes); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| irc_handle_rpl_isupport (struct server *s, const struct irc_message *msg) | ||||
| { | ||||
| 	if (msg->params.len < 2) | ||||
| 		return; | ||||
| 
 | ||||
| 	for (size_t i = 1; i < msg->params.len - 1; i++) | ||||
| 	{ | ||||
| 		// TODO: if the parameter starts with "-", it resets to default
 | ||||
| 		char *param = msg->params.vector[i]; | ||||
| 		char *value = param + strcspn (param, "="); | ||||
| 		if (*value) *value++ = '\0'; | ||||
| 
 | ||||
| 		if (!strcmp (param, "PREFIX")) | ||||
| 			irc_handle_isupport_prefix (s, value); | ||||
| 	} | ||||
| 
 | ||||
| 	// TODO: initialize key_strxfrm according to server properties;
 | ||||
| 	//   note that collisions may arise on reconnecting
 | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| irc_process_numeric (struct server *s, | ||||
| 	const struct irc_message *msg, unsigned long numeric) | ||||
| @ -4491,14 +4539,8 @@ irc_process_numeric (struct server *s, | ||||
| 		if (msg->params.len == 2) | ||||
| 			irc_try_parse_welcome_for_userhost (s, msg->params.vector[1]); | ||||
| 		break; | ||||
| 	case IRC_RPL_ISUPPORT: | ||||
| 		// TODO: parse this, mainly PREFIX; see
 | ||||
| 		//   http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt
 | ||||
| 
 | ||||
| 		// TODO: initialize key_strxfrm according to server properties;
 | ||||
| 		//   note that collisions may arise on reconnecting
 | ||||
| 		break; | ||||
| 
 | ||||
| 	case IRC_RPL_ISUPPORT:   irc_handle_rpl_isupport   (s, msg); break; | ||||
| 	case IRC_RPL_USERHOST:   irc_handle_rpl_userhost   (s, msg); break; | ||||
| 	case IRC_RPL_NAMREPLY:   irc_handle_rpl_namreply   (s, msg); break; | ||||
| 	case IRC_RPL_ENDOFNAMES: irc_handle_rpl_endofnames (s, msg); break; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user