degesch: finish implementation of rehashing
I can only hope it works.
This commit is contained in:
		
							parent
							
								
									e39bb976cb
								
							
						
					
					
						commit
						fafe1fde90
					
				
							
								
								
									
										99
									
								
								degesch.c
									
									
									
									
									
								
							
							
						
						
									
										99
									
								
								degesch.c
									
									
									
									
									
								
							| @ -2925,6 +2925,58 @@ irc_left_channel (struct channel *channel) | ||||
| 
 | ||||
| // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 | ||||
| 
 | ||||
| static void | ||||
| remove_conflicting_buffer (struct server *s, struct buffer *buffer) | ||||
| { | ||||
| 	buffer_send_status (s->ctx, NULL, | ||||
| 		"Removed buffer %s because of casemapping conflict", buffer->name); | ||||
| 	if (s->ctx->current_buffer == buffer) | ||||
| 		buffer_activate (s->ctx, s->buffer); | ||||
| 	buffer_remove (s->ctx, buffer); | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| irc_try_readd_user (struct server *s, | ||||
| 	struct user *user, struct buffer *buffer) | ||||
| { | ||||
| 	if (str_map_find (&s->irc_users, user->nickname)) | ||||
| 	{ | ||||
| 		// Remove user from all channels and destroy any PM buffer
 | ||||
| 		user_ref (user); | ||||
| 		LIST_FOR_EACH (struct user_channel, iter, user->channels) | ||||
| 			irc_remove_user_from_channel (user, iter->channel); | ||||
| 		if (buffer) | ||||
| 			remove_conflicting_buffer (s, buffer); | ||||
| 		user_unref (user); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		str_map_set (&s->irc_users, user->nickname, user); | ||||
| 		str_map_set (&s->irc_buffer_map, user->nickname, buffer); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| irc_try_readd_channel (struct server *s, | ||||
| 	struct channel *channel, struct buffer *buffer) | ||||
| { | ||||
| 	if (str_map_find (&s->irc_channels, channel->name)) | ||||
| 	{ | ||||
| 		// Remove all users from channel and destroy any channel buffer
 | ||||
| 		channel_ref (channel); | ||||
| 		LIST_FOR_EACH (struct channel_user, iter, channel->users) | ||||
| 			irc_channel_unlink_user (channel, iter); | ||||
| 		if (buffer) | ||||
| 			remove_conflicting_buffer (s, buffer); | ||||
| 		channel_unref (channel); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		str_map_set (&s->irc_channels, channel->name, channel); | ||||
| 		str_map_set (&s->irc_buffer_map, channel->name, buffer); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| irc_rehash_and_fix_conflicts (struct server *s) | ||||
| { | ||||
| @ -2937,10 +2989,6 @@ irc_rehash_and_fix_conflicts (struct server *s) | ||||
| 	str_map_init (&s->irc_channels); | ||||
| 	str_map_init (&s->irc_buffer_map); | ||||
| 
 | ||||
| 	s->irc_users     .free = old_users     .free; | ||||
| 	s->irc_channels  .free = old_channels  .free; | ||||
| 	s->irc_buffer_map.free = old_buffer_map.free; | ||||
| 
 | ||||
| 	s->irc_users     .key_xfrm = s->irc_strxfrm; | ||||
| 	s->irc_channels  .key_xfrm = s->irc_strxfrm; | ||||
| 	s->irc_buffer_map.key_xfrm = s->irc_strxfrm; | ||||
| @ -2949,46 +2997,27 @@ irc_rehash_and_fix_conflicts (struct server *s) | ||||
| 	// from server maps upon removing the last reference to them
 | ||||
| 	s->rehashing = true; | ||||
| 
 | ||||
| 	// TODO: "Removed similarly named buffer %s because of casemapping conflict"
 | ||||
| 	// XXX: to be perfectly sure, we should also check
 | ||||
| 	//   whether any users collide with channels and vice versa
 | ||||
| 
 | ||||
| 	// Our own user always takes priority, add him first
 | ||||
| 	if (s->irc_user) | ||||
| 		irc_try_readd_user (s, s->irc_user, | ||||
| 			str_map_find (&old_buffer_map, s->irc_user->nickname)); | ||||
| 
 | ||||
| 	struct str_map_iter iter; | ||||
| 	str_map_iter_init (&iter, &old_users); | ||||
| 	struct user *user; | ||||
| 	struct channel *channel; | ||||
| 
 | ||||
| 	str_map_iter_init (&iter, &old_users); | ||||
| 	while ((user = str_map_iter_next (&iter))) | ||||
| 	{ | ||||
| 		// FIXME: don't remove ourselves!
 | ||||
| 		if (str_map_find (&s->irc_users, user->nickname)) | ||||
| 		{ | ||||
| 			// TODO: move or merge any PM buffer and remove
 | ||||
| 			//   the user from channels and altogether
 | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			str_map_set (&s->irc_users, user->nickname, user); | ||||
| 			str_map_set (&s->irc_buffer_map, user->nickname, | ||||
| 				str_map_find (&old_buffer_map, user->nickname)); | ||||
| 		} | ||||
| 	} | ||||
| 		irc_try_readd_user (s, user, | ||||
| 			str_map_find (&old_buffer_map, user->nickname)); | ||||
| 
 | ||||
| 	str_map_iter_init (&iter, &old_channels); | ||||
| 	struct channel *channel; | ||||
| 	while ((channel = str_map_iter_next (&iter))) | ||||
| 	{ | ||||
| 		if (str_map_find (&s->irc_channels, channel->name)) | ||||
| 		{ | ||||
| 			// TODO: remove all users from the buffer
 | ||||
| 			//   and probably issue NAMES if registered and on the channel,
 | ||||
| 			//   and of course remove the colliding channel
 | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			str_map_set (&s->irc_channels, channel->name, user); | ||||
| 			str_map_set (&s->irc_buffer_map, user->nickname, | ||||
| 				str_map_find (&old_buffer_map, user->nickname)); | ||||
| 		} | ||||
| 	} | ||||
| 		irc_try_readd_channel (s, channel, | ||||
| 			str_map_find (&old_buffer_map, channel->name)); | ||||
| 
 | ||||
| 	// Hopefully we've either moved or destroyed all the old content
 | ||||
| 	s->rehashing = false; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user