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…
Reference in New Issue