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
|
static void
|
||||||
irc_rehash_and_fix_conflicts (struct server *s)
|
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_channels);
|
||||||
str_map_init (&s->irc_buffer_map);
|
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_users .key_xfrm = s->irc_strxfrm;
|
||||||
s->irc_channels .key_xfrm = s->irc_strxfrm;
|
s->irc_channels .key_xfrm = s->irc_strxfrm;
|
||||||
s->irc_buffer_map.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
|
// from server maps upon removing the last reference to them
|
||||||
s->rehashing = true;
|
s->rehashing = true;
|
||||||
|
|
||||||
// TODO: "Removed similarly named buffer %s because of casemapping conflict"
|
|
||||||
// XXX: to be perfectly sure, we should also check
|
// XXX: to be perfectly sure, we should also check
|
||||||
// whether any users collide with channels and vice versa
|
// 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;
|
struct str_map_iter iter;
|
||||||
str_map_iter_init (&iter, &old_users);
|
|
||||||
struct user *user;
|
struct user *user;
|
||||||
|
struct channel *channel;
|
||||||
|
|
||||||
|
str_map_iter_init (&iter, &old_users);
|
||||||
while ((user = str_map_iter_next (&iter)))
|
while ((user = str_map_iter_next (&iter)))
|
||||||
{
|
irc_try_readd_user (s, user,
|
||||||
// FIXME: don't remove ourselves!
|
str_map_find (&old_buffer_map, user->nickname));
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
str_map_iter_init (&iter, &old_channels);
|
str_map_iter_init (&iter, &old_channels);
|
||||||
struct channel *channel;
|
|
||||||
while ((channel = str_map_iter_next (&iter)))
|
while ((channel = str_map_iter_next (&iter)))
|
||||||
{
|
irc_try_readd_channel (s, channel,
|
||||||
if (str_map_find (&s->irc_channels, channel->name))
|
str_map_find (&old_buffer_map, 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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hopefully we've either moved or destroyed all the old content
|
// Hopefully we've either moved or destroyed all the old content
|
||||||
s->rehashing = false;
|
s->rehashing = false;
|
||||||
|
|
Loading…
Reference in New Issue