refactor nick management code
- drop struct nick. - follow nick changes in a basic way. right now it does not work if one changes nick and somebody else takes the old unused nick.
This commit is contained in:
parent
4d231e8ddc
commit
e8bb841e5f
181
src/irc.c
181
src/irc.c
@ -78,7 +78,7 @@ struct channel *channel_new(const char *name)
|
|||||||
struct channel *chan;
|
struct channel *chan;
|
||||||
chan = bip_calloc(sizeof(struct channel), 1);
|
chan = bip_calloc(sizeof(struct channel), 1);
|
||||||
chan->name = bip_strdup(name);
|
chan->name = bip_strdup(name);
|
||||||
hash_init(&chan->nicks, HASH_NOCASE);
|
hash_init(&chan->ovmasks, HASH_NOCASE);
|
||||||
return chan;
|
return chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,23 +108,21 @@ list_t *channel_name_list(struct channel *c)
|
|||||||
{
|
{
|
||||||
list_t *ret;
|
list_t *ret;
|
||||||
hash_iterator_t hi;
|
hash_iterator_t hi;
|
||||||
size_t s = NAMESIZE;
|
|
||||||
ret = list_new(NULL);
|
|
||||||
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
char *str = bip_malloc(NAMESIZE);
|
char *str = bip_malloc(NAMESIZE + 1);
|
||||||
|
|
||||||
|
ret = list_new(NULL);
|
||||||
*str = 0;
|
*str = 0;
|
||||||
for (hash_it_init(&c->nicks, &hi); hash_it_item(&hi);
|
for (hash_it_init(&c->ovmasks, &hi); hash_it_item(&hi);
|
||||||
hash_it_next(&hi)){
|
hash_it_next(&hi)){
|
||||||
struct nick *n = hash_it_item(&hi);
|
const char *nick = hash_it_key(&hi);
|
||||||
|
long int ovmask = (long int)hash_it_item(&hi);
|
||||||
|
|
||||||
if (strlen(n->name) + 2 >= NAMESIZE)
|
assert(strlen(nick) + 2 < NAMESIZE);
|
||||||
fatal("nick too big for me"); /* FIXME */
|
|
||||||
|
|
||||||
if (len + strlen(n->name) + 2 + (n->ovmask ? 1 : 0)
|
if (len + strlen(nick) + 2 + (ovmask ? 1 : 0) >= NAMESIZE) {
|
||||||
>= NAMESIZE) {
|
|
||||||
list_add_last(ret, str);
|
list_add_last(ret, str);
|
||||||
str = bip_malloc(s);
|
str = bip_malloc(NAMESIZE + 1);
|
||||||
*str = 0;
|
*str = 0;
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
@ -132,20 +130,17 @@ list_t *channel_name_list(struct channel *c)
|
|||||||
strncat(str, " ", NAMESIZE);
|
strncat(str, " ", NAMESIZE);
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
if (n->ovmask & NICKOP) {
|
if (ovmask & NICKOP)
|
||||||
strncat(str, "@", NAMESIZE);
|
strncat(str, "@", NAMESIZE);
|
||||||
len++;
|
else if (ovmask & NICKHALFOP)
|
||||||
} else if (n->ovmask & NICKHALFOP) {
|
|
||||||
strncat(str, "%", NAMESIZE);
|
strncat(str, "%", NAMESIZE);
|
||||||
len++;
|
else if (ovmask & NICKVOICED)
|
||||||
} else if (n->ovmask & NICKVOICED) {
|
|
||||||
strncat(str, "+", NAMESIZE);
|
strncat(str, "+", NAMESIZE);
|
||||||
len++;
|
len++;
|
||||||
}
|
|
||||||
strncat(str, n->name, NAMESIZE);
|
strncat(str, nick, NAMESIZE);
|
||||||
len += strlen(n->name);
|
len += strlen(nick);
|
||||||
if (len >= NAMESIZE)
|
assert(len < NAMESIZE);
|
||||||
fatal("internal error 5");
|
|
||||||
}
|
}
|
||||||
list_add_last(ret, str);
|
list_add_last(ret, str);
|
||||||
return ret;
|
return ret;
|
||||||
@ -542,7 +537,6 @@ static void irc_send_join(struct link_client *ic, struct channel *chan)
|
|||||||
|
|
||||||
WRITE_LINE3(CONN(ic), P_SERV, "366", LINK(ic)->l_server->nick,
|
WRITE_LINE3(CONN(ic), P_SERV, "366", LINK(ic)->l_server->nick,
|
||||||
chan->name, "End of /NAMES list.");
|
chan->name, "End of /NAMES list.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void write_init_string(connection_t *c, struct line *line, char *nick)
|
static void write_init_string(connection_t *c, struct line *line, char *nick)
|
||||||
@ -666,7 +660,7 @@ static void irc_cli_backlog(struct link_client *ic)
|
|||||||
|
|
||||||
user = LINK(ic)->user;
|
user = LINK(ic)->user;
|
||||||
if (!user)
|
if (!user)
|
||||||
fatal("irc_send_join: No user associated");
|
fatal("irc_cli_backlog: No user associated");
|
||||||
if (!user->backlog) {
|
if (!user->backlog) {
|
||||||
mylog(LOG_DEBUG, "Backlog disabled for %s, not backlogging",
|
mylog(LOG_DEBUG, "Backlog disabled for %s, not backlogging",
|
||||||
user->name);
|
user->name);
|
||||||
@ -1254,7 +1248,6 @@ static int irc_join(struct link_server *server, struct line *line)
|
|||||||
char *s_nick;
|
char *s_nick;
|
||||||
const char *s_chan;
|
const char *s_chan;
|
||||||
struct channel *channel;
|
struct channel *channel;
|
||||||
struct nick *nick;
|
|
||||||
|
|
||||||
if (irc_line_count(line) != 2 && irc_line_count(line) != 3)
|
if (irc_line_count(line) != 2 && irc_line_count(line) != 3)
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
@ -1278,9 +1271,7 @@ static int irc_join(struct link_server *server, struct line *line)
|
|||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
s_nick = nick_from_ircmask(line->origin);
|
s_nick = nick_from_ircmask(line->origin);
|
||||||
|
|
||||||
nick = bip_calloc(sizeof(struct nick), 1);
|
hash_insert(&channel->ovmasks, s_nick, 0);
|
||||||
nick->name = s_nick; /* not freeing s_nick */
|
|
||||||
hash_insert(&channel->nicks, s_nick, nick);
|
|
||||||
return OK_COPY;
|
return OK_COPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1329,20 +1320,12 @@ static int irc_333(struct link_server *server, struct line *line)
|
|||||||
return OK_COPY;
|
return OK_COPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nick_free(struct nick *nick)
|
|
||||||
{
|
|
||||||
if (nick->name)
|
|
||||||
free(nick->name);
|
|
||||||
free(nick);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int irc_353(struct link_server *server, struct line *line)
|
static int irc_353(struct link_server *server, struct line *line)
|
||||||
{
|
{
|
||||||
struct channel *channel;
|
struct channel *channel;
|
||||||
struct nick *nick;
|
|
||||||
const char *names, *eon;
|
const char *names, *eon;
|
||||||
size_t len;
|
size_t len;
|
||||||
char *tmp;
|
char *nick;
|
||||||
|
|
||||||
if (irc_line_count(line) != 5)
|
if (irc_line_count(line) != 5)
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
@ -1354,12 +1337,7 @@ static int irc_353(struct link_server *server, struct line *line)
|
|||||||
|
|
||||||
if (!channel->running_names) {
|
if (!channel->running_names) {
|
||||||
channel->running_names = 1;
|
channel->running_names = 1;
|
||||||
hash_iterator_t hi;
|
hash_clean(&channel->ovmasks);
|
||||||
for (hash_it_init(&channel->nicks, &hi); hash_it_item(&hi);
|
|
||||||
hash_it_next(&hi)) {
|
|
||||||
nick_free(hash_it_item(&hi));
|
|
||||||
}
|
|
||||||
hash_clean(&channel->nicks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO check that type is one of "=" / "*" / "@" */
|
/* TODO check that type is one of "=" / "*" / "@" */
|
||||||
@ -1368,7 +1346,7 @@ static int irc_353(struct link_server *server, struct line *line)
|
|||||||
names = irc_line_elem(line, 4);
|
names = irc_line_elem(line, 4);
|
||||||
|
|
||||||
while (*names) {
|
while (*names) {
|
||||||
int ovmask = 0;
|
long int ovmask = 0;
|
||||||
int flagchars = 1;
|
int flagchars = 1;
|
||||||
/* some ircds (e.g. unreal) may display several flags for the
|
/* some ircds (e.g. unreal) may display several flags for the
|
||||||
same nick */
|
same nick */
|
||||||
@ -1400,15 +1378,14 @@ static int irc_353(struct link_server *server, struct line *line)
|
|||||||
eon++;
|
eon++;
|
||||||
|
|
||||||
len = eon - names;
|
len = eon - names;
|
||||||
tmp = bip_malloc(len + 1);
|
nick = bip_malloc(len + 1);
|
||||||
memcpy(tmp, names, len);
|
memcpy(nick, names, len);
|
||||||
tmp[len] = 0;
|
nick[len] = 0;
|
||||||
|
|
||||||
nick = bip_malloc(sizeof(struct nick));
|
/* we just ignore names for nicks that are crazy long */
|
||||||
nick->name = tmp;
|
if (len + 2 < NAMESIZE)
|
||||||
nick->ovmask = ovmask;
|
hash_insert(&channel->ovmasks, nick, (void *)ovmask);
|
||||||
|
|
||||||
hash_insert(&channel->nicks, nick->name, nick);
|
|
||||||
while (*eon && *eon == ' ')
|
while (*eon && *eon == ' ')
|
||||||
eon++;
|
eon++;
|
||||||
names = eon;
|
names = eon;
|
||||||
@ -1475,10 +1452,7 @@ static void channel_free(struct channel *c)
|
|||||||
if (c->create_ts)
|
if (c->create_ts)
|
||||||
free(c->create_ts);
|
free(c->create_ts);
|
||||||
|
|
||||||
hash_iterator_t hi;
|
hash_clean(&c->ovmasks);
|
||||||
for (hash_it_init(&c->nicks, &hi); hash_it_item(&hi); hash_it_next(&hi))
|
|
||||||
nick_free(hash_it_item(&hi));
|
|
||||||
hash_clean(&c->nicks);
|
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1487,7 +1461,6 @@ static int irc_part(struct link_server *server, struct line *line)
|
|||||||
char *s_nick;
|
char *s_nick;
|
||||||
const char *s_chan;
|
const char *s_chan;
|
||||||
struct channel *channel;
|
struct channel *channel;
|
||||||
struct nick *nick;
|
|
||||||
|
|
||||||
if (irc_line_count(line) != 2 && irc_line_count(line) != 3)
|
if (irc_line_count(line) != 2 && irc_line_count(line) != 3)
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
@ -1512,18 +1485,14 @@ static int irc_part(struct link_server *server, struct line *line)
|
|||||||
if (!line->origin)
|
if (!line->origin)
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
s_nick = nick_from_ircmask(line->origin);
|
s_nick = nick_from_ircmask(line->origin);
|
||||||
nick = hash_get(&channel->nicks, s_nick);
|
if (!hash_includes(&channel->ovmasks, s_nick))
|
||||||
if (!nick) {
|
|
||||||
free(s_nick);
|
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
}
|
hash_remove(&channel->ovmasks, s_nick);
|
||||||
nick = hash_remove(&channel->nicks, s_nick);
|
|
||||||
free(s_nick);
|
|
||||||
|
|
||||||
log_part(LINK(server)->log, line->origin, s_chan,
|
log_part(LINK(server)->log, line->origin, s_chan,
|
||||||
irc_line_count(line) == 3 ? irc_line_elem(line, 2) : NULL);
|
irc_line_count(line) == 3 ?
|
||||||
|
irc_line_elem(line, 2) : NULL);
|
||||||
|
|
||||||
nick_free(nick);
|
|
||||||
return OK_COPY;
|
return OK_COPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1579,10 +1548,8 @@ static int irc_mode(struct link_server *server, struct line *line)
|
|||||||
const char *mode;
|
const char *mode;
|
||||||
int add = 1;
|
int add = 1;
|
||||||
unsigned cur_arg = 0;
|
unsigned cur_arg = 0;
|
||||||
struct nick *nick;
|
|
||||||
array_t *mode_args = NULL;
|
array_t *mode_args = NULL;
|
||||||
|
|
||||||
|
|
||||||
if (!irc_line_includes(line, 2))
|
if (!irc_line_includes(line, 2))
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
|
|
||||||
@ -1621,6 +1588,8 @@ static int irc_mode(struct link_server *server, struct line *line)
|
|||||||
* ^ ^
|
* ^ ^
|
||||||
* mode cur_arg
|
* mode cur_arg
|
||||||
*/
|
*/
|
||||||
|
const char *nick;
|
||||||
|
long int ovmask;
|
||||||
for (mode = irc_line_elem(line, 2); *mode; mode++) {
|
for (mode = irc_line_elem(line, 2); *mode; mode++) {
|
||||||
switch (*mode) {
|
switch (*mode) {
|
||||||
case '-':
|
case '-':
|
||||||
@ -1637,43 +1606,48 @@ static int irc_mode(struct link_server *server, struct line *line)
|
|||||||
case 'o':
|
case 'o':
|
||||||
if (!irc_line_includes(line, cur_arg + 3))
|
if (!irc_line_includes(line, cur_arg + 3))
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
|
nick = irc_line_elem(line, cur_arg + 3);
|
||||||
|
|
||||||
nick = hash_get(&channel->nicks,
|
if (!hash_includes(&channel->ovmasks, nick))
|
||||||
irc_line_elem(line, cur_arg + 3));
|
|
||||||
if (!nick)
|
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
|
ovmask = (long int)hash_remove(&channel->ovmasks, nick);
|
||||||
if (add)
|
if (add)
|
||||||
nick->ovmask |= NICKOP;
|
ovmask |= NICKOP;
|
||||||
else
|
else
|
||||||
nick->ovmask &= ~NICKOP;
|
ovmask &= ~NICKOP;
|
||||||
|
hash_insert(&channel->ovmasks, nick, (void *)ovmask);
|
||||||
cur_arg++;
|
cur_arg++;
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
if (!irc_line_includes(line, cur_arg + 3))
|
if (!irc_line_includes(line, cur_arg + 3))
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
|
nick = irc_line_elem(line, cur_arg + 3);
|
||||||
|
|
||||||
nick = hash_get(&channel->nicks,
|
if (!hash_includes(&channel->ovmasks, nick))
|
||||||
irc_line_elem(line, cur_arg + 3));
|
|
||||||
if (!nick)
|
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
|
|
||||||
|
ovmask = (long int)hash_get(&channel->ovmasks, nick);
|
||||||
if (add)
|
if (add)
|
||||||
nick->ovmask |= NICKHALFOP;
|
ovmask |= NICKHALFOP;
|
||||||
else
|
else
|
||||||
nick->ovmask &= ~NICKHALFOP;
|
ovmask &= ~NICKHALFOP;
|
||||||
|
hash_insert(&channel->ovmasks, nick, (void *)ovmask);
|
||||||
cur_arg++;
|
cur_arg++;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
if (!irc_line_includes(line, cur_arg + 3))
|
if (!irc_line_includes(line, cur_arg + 3))
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
|
nick = irc_line_elem(line, cur_arg + 3);
|
||||||
|
|
||||||
nick = hash_get(&channel->nicks,
|
if (!hash_includes(&channel->ovmasks, nick))
|
||||||
irc_line_elem(line, cur_arg + 3));
|
|
||||||
if (!nick)
|
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
|
|
||||||
|
ovmask = (long int)hash_get(&channel->ovmasks, nick);
|
||||||
if (add)
|
if (add)
|
||||||
nick->ovmask |= NICKVOICED;
|
ovmask |= NICKVOICED;
|
||||||
else
|
else
|
||||||
nick->ovmask &= ~NICKVOICED;
|
ovmask &= ~NICKVOICED;
|
||||||
|
hash_insert(&channel->ovmasks, nick, (void *)ovmask);
|
||||||
cur_arg++;
|
cur_arg++;
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
@ -1749,14 +1723,14 @@ static int irc_topic(struct link_server *server, struct line *line)
|
|||||||
free(channel->create_ts);
|
free(channel->create_ts);
|
||||||
channel->create_ts = irc_timestamp();
|
channel->create_ts = irc_timestamp();
|
||||||
|
|
||||||
log_topic(LINK(server)->log, line->origin, irc_line_elem(line, 1), topic);
|
log_topic(LINK(server)->log, line->origin, irc_line_elem(line, 1),
|
||||||
|
topic);
|
||||||
return OK_COPY;
|
return OK_COPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int irc_kick(struct link_server *server, struct line *line)
|
static int irc_kick(struct link_server *server, struct line *line)
|
||||||
{
|
{
|
||||||
struct channel *channel;
|
struct channel *channel;
|
||||||
struct nick *nick;
|
|
||||||
|
|
||||||
if (irc_line_count(line) != 3 && irc_line_count(line) != 4)
|
if (irc_line_count(line) != 3 && irc_line_count(line) != 4)
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
@ -1766,22 +1740,21 @@ static int irc_kick(struct link_server *server, struct line *line)
|
|||||||
if (!channel)
|
if (!channel)
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
|
|
||||||
nick = hash_get(&channel->nicks, irc_line_elem(line, 2));
|
if (!hash_includes(&channel->ovmasks, irc_line_elem(line, 2)))
|
||||||
if (!nick)
|
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
|
|
||||||
if (strcmp(nick->name, server->nick) == 0) {
|
if (strcasecmp(irc_line_elem(line, 2), server->nick) == 0) {
|
||||||
log_kick(LINK(server)->log, line->origin, channel->name,
|
log_kick(LINK(server)->log, line->origin, channel->name,
|
||||||
nick->name,
|
irc_line_elem(line, 2),
|
||||||
irc_line_count(line) == 4 ? irc_line_elem(line, 3) : NULL);
|
irc_line_count(line) == 4 ?
|
||||||
|
irc_line_elem(line, 3) : NULL);
|
||||||
|
|
||||||
hash_remove(&server->channels, channel->name);
|
hash_remove(&server->channels, channel->name);
|
||||||
channel_free(channel);
|
channel_free(channel);
|
||||||
return OK_COPY;
|
return OK_COPY;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_remove(&channel->nicks, nick->name);
|
hash_remove(&channel->ovmasks, irc_line_elem(line, 2));
|
||||||
nick_free(nick);
|
|
||||||
log_kick(LINK(server)->log, line->origin, irc_line_elem(line, 1),
|
log_kick(LINK(server)->log, line->origin, irc_line_elem(line, 1),
|
||||||
irc_line_elem(line, 2),
|
irc_line_elem(line, 2),
|
||||||
irc_line_count(line) == 4 ? irc_line_elem(line, 3) : NULL);
|
irc_line_count(line) == 4 ? irc_line_elem(line, 3) : NULL);
|
||||||
@ -1834,9 +1807,9 @@ static int irc_quit(struct link_server *server, struct line *line)
|
|||||||
static int irc_nick(struct link_server *server, struct line *line)
|
static int irc_nick(struct link_server *server, struct line *line)
|
||||||
{
|
{
|
||||||
struct channel *channel;
|
struct channel *channel;
|
||||||
struct nick *nick;
|
|
||||||
hash_iterator_t hi;
|
hash_iterator_t hi;
|
||||||
char *org_nick;
|
char *org_nick;
|
||||||
|
const char *dst_nick;
|
||||||
|
|
||||||
if (irc_line_count(line) != 2)
|
if (irc_line_count(line) != 2)
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
@ -1845,24 +1818,20 @@ static int irc_nick(struct link_server *server, struct line *line)
|
|||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
|
|
||||||
org_nick = nick_from_ircmask(line->origin);
|
org_nick = nick_from_ircmask(line->origin);
|
||||||
|
dst_nick = irc_line_elem(line, 1);
|
||||||
|
|
||||||
for (hash_it_init(&server->channels, &hi); hash_it_item(&hi);
|
for (hash_it_init(&server->channels, &hi); hash_it_item(&hi);
|
||||||
hash_it_next(&hi)) {
|
hash_it_next(&hi)) {
|
||||||
channel = hash_it_item(&hi);
|
channel = hash_it_item(&hi);
|
||||||
nick = hash_get(&channel->nicks, org_nick);
|
if (!hash_includes(&channel->ovmasks, org_nick))
|
||||||
if (!nick)
|
|
||||||
continue;
|
continue;
|
||||||
hash_remove(&channel->nicks, org_nick);
|
hash_rename_key(&channel->ovmasks, org_nick, dst_nick);
|
||||||
free(nick->name);
|
log_nick(LINK(server)->log, org_nick, channel->name, dst_nick);
|
||||||
nick->name = bip_strdup(irc_line_elem(line, 1));
|
|
||||||
hash_insert(&channel->nicks, nick->name, nick);
|
|
||||||
log_nick(LINK(server)->log, org_nick, channel->name,
|
|
||||||
irc_line_elem(line, 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (origin_is_me(line, server)) {
|
if (origin_is_me(line, server)) {
|
||||||
free(server->nick);
|
free(server->nick);
|
||||||
server->nick = bip_strdup(irc_line_elem(line, 1));
|
server->nick = bip_strdup(dst_nick);
|
||||||
if (LINK(server)->follow_nick &&
|
if (LINK(server)->follow_nick &&
|
||||||
(LINK(server)->away_nick == NULL ||
|
(LINK(server)->away_nick == NULL ||
|
||||||
strcmp(server->nick, LINK(server)->away_nick))
|
strcmp(server->nick, LINK(server)->away_nick))
|
||||||
@ -1879,7 +1848,6 @@ static int irc_nick(struct link_server *server, struct line *line)
|
|||||||
static int irc_generic_quit(struct link_server *server, struct line *line)
|
static int irc_generic_quit(struct link_server *server, struct line *line)
|
||||||
{
|
{
|
||||||
struct channel *channel;
|
struct channel *channel;
|
||||||
struct nick *nick;
|
|
||||||
hash_iterator_t hi;
|
hash_iterator_t hi;
|
||||||
char *s_nick;
|
char *s_nick;
|
||||||
|
|
||||||
@ -1889,18 +1857,15 @@ static int irc_generic_quit(struct link_server *server, struct line *line)
|
|||||||
if (!line->origin)
|
if (!line->origin)
|
||||||
return ERR_PROTOCOL;
|
return ERR_PROTOCOL;
|
||||||
s_nick = nick_from_ircmask(line->origin);
|
s_nick = nick_from_ircmask(line->origin);
|
||||||
|
|
||||||
for (hash_it_init(&server->channels, &hi); hash_it_item(&hi);
|
for (hash_it_init(&server->channels, &hi); hash_it_item(&hi);
|
||||||
hash_it_next(&hi)) {
|
hash_it_next(&hi)) {
|
||||||
channel = hash_it_item(&hi);
|
channel = hash_it_item(&hi);
|
||||||
nick = hash_get(&channel->nicks, s_nick);
|
if (!hash_includes(&channel->ovmasks, s_nick))
|
||||||
if (!nick)
|
|
||||||
continue;
|
continue;
|
||||||
hash_remove(&channel->nicks, s_nick);
|
hash_remove(&channel->ovmasks, s_nick);
|
||||||
nick_free(nick);
|
|
||||||
|
|
||||||
log_quit(LINK(server)->log, line->origin, channel->name,
|
log_quit(LINK(server)->log, line->origin, channel->name,
|
||||||
irc_line_includes(line, 1) ? irc_line_elem(line, 1) : NULL);
|
irc_line_includes(line, 1) ?
|
||||||
|
irc_line_elem(line, 1) : NULL);
|
||||||
}
|
}
|
||||||
free(s_nick);
|
free(s_nick);
|
||||||
return OK_COPY;
|
return OK_COPY;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#define IRC_H
|
#define IRC_H
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "line.h"
|
#include "line.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
#define ERR_PROTOCOL (-1)
|
#define ERR_PROTOCOL (-1)
|
||||||
#define ERR_AUTH (-2)
|
#define ERR_AUTH (-2)
|
||||||
@ -40,11 +40,6 @@ struct server {
|
|||||||
#define NICKHALFOP (1<<1)
|
#define NICKHALFOP (1<<1)
|
||||||
#define NICKVOICED (1<<2)
|
#define NICKVOICED (1<<2)
|
||||||
|
|
||||||
struct nick {
|
|
||||||
char *name;
|
|
||||||
int ovmask;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct channel {
|
struct channel {
|
||||||
char *name;
|
char *name;
|
||||||
char *mode;
|
char *mode;
|
||||||
@ -54,7 +49,7 @@ struct channel {
|
|||||||
char type;
|
char type;
|
||||||
char *creator;
|
char *creator;
|
||||||
char *create_ts;
|
char *create_ts;
|
||||||
hash_t nicks;
|
hash_t ovmasks;
|
||||||
int running_names;
|
int running_names;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -415,6 +415,9 @@ void log_quit(log_t *logdata, const char *ircmask, const char *channel,
|
|||||||
void log_nick(log_t *logdata, const char *ircmask, const char *channel,
|
void log_nick(log_t *logdata, const char *ircmask, const char *channel,
|
||||||
const char *newnick)
|
const char *newnick)
|
||||||
{
|
{
|
||||||
|
char *oldnick = nick_from_ircmask(ircmask);
|
||||||
|
if (hash_includes(&logdata->logfgs, oldnick))
|
||||||
|
hash_rename_key(&logdata->logfgs, oldnick, newnick);
|
||||||
snprintf(logdata->buffer, LOGLINE_MAXLEN,
|
snprintf(logdata->buffer, LOGLINE_MAXLEN,
|
||||||
"%s -!- %s is now known as %s",
|
"%s -!- %s is now known as %s",
|
||||||
timestamp(), ircmask, newnick);
|
timestamp(), ircmask, newnick);
|
||||||
@ -559,6 +562,7 @@ void log_mode(log_t *logdata, const char *ircmask, const char *channel,
|
|||||||
|
|
||||||
snprintf(tmpbuf, LOGLINE_MAXLEN, "%s -!- mode/%s [%s", timestamp(),
|
snprintf(tmpbuf, LOGLINE_MAXLEN, "%s -!- mode/%s [%s", timestamp(),
|
||||||
channel, modes);
|
channel, modes);
|
||||||
|
if (mode_args) {
|
||||||
for (i = 0; i < array_count(mode_args); i++) {
|
for (i = 0; i < array_count(mode_args); i++) {
|
||||||
snprintf(tmpbuf2, LOGLINE_MAXLEN, "%s %s", tmpbuf,
|
snprintf(tmpbuf2, LOGLINE_MAXLEN, "%s %s", tmpbuf,
|
||||||
(char *)array_get(mode_args, i));
|
(char *)array_get(mode_args, i));
|
||||||
@ -566,9 +570,9 @@ void log_mode(log_t *logdata, const char *ircmask, const char *channel,
|
|||||||
tmpbuf = tmpbuf2;
|
tmpbuf = tmpbuf2;
|
||||||
tmpbuf2 = tmp;
|
tmpbuf2 = tmp;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(logdata->buffer, LOGLINE_MAXLEN, "%s] by %s", tmpbuf,
|
snprintf(logdata->buffer, LOGLINE_MAXLEN, "%s] by %s", tmpbuf, ircmask);
|
||||||
ircmask);
|
|
||||||
log_write(logdata, channel, logdata->buffer);
|
log_write(logdata, channel, logdata->buffer);
|
||||||
|
|
||||||
free(tmpbuf);
|
free(tmpbuf);
|
||||||
|
13
src/util.c
13
src/util.c
@ -550,6 +550,14 @@ void hash_insert(hash_t *hash, const char *key, void *ptr)
|
|||||||
list_add_first(&hash->lists[hash_func(key)], it);
|
list_add_first(&hash->lists[hash_func(key)], it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int hash_includes(hash_t *hash, const char *key)
|
||||||
|
{
|
||||||
|
struct hash_item *hi;
|
||||||
|
list_t *list = &hash->lists[hash_func(key)];
|
||||||
|
hi = list_get(list, key);
|
||||||
|
return hi != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void *hash_get(hash_t *hash, const char *key)
|
void *hash_get(hash_t *hash, const char *key)
|
||||||
{
|
{
|
||||||
struct hash_item *hi;
|
struct hash_item *hi;
|
||||||
@ -667,6 +675,11 @@ list_t *hash_keys(hash_t *hash)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void hash_rename_key(hash_t *h, const char *oldk, const char *newk)
|
||||||
|
{
|
||||||
|
hash_insert(h, newk, hash_remove(h, oldk));
|
||||||
|
}
|
||||||
|
|
||||||
char *bip_strmaydup(char *s)
|
char *bip_strmaydup(char *s)
|
||||||
{
|
{
|
||||||
if (!s)
|
if (!s)
|
||||||
|
@ -122,6 +122,7 @@ void hash_free(hash_t *h);
|
|||||||
void hash_clean(hash_t *h);
|
void hash_clean(hash_t *h);
|
||||||
hash_t *hash_new(int options);
|
hash_t *hash_new(int options);
|
||||||
void hash_insert(hash_t *hash, const char *key, void *ptr);
|
void hash_insert(hash_t *hash, const char *key, void *ptr);
|
||||||
|
int hash_includes(hash_t *hash, const char *key);
|
||||||
void *hash_get(hash_t *, const char *key);
|
void *hash_get(hash_t *, const char *key);
|
||||||
void *hash_remove(hash_t *hash, const char *key);
|
void *hash_remove(hash_t *hash, const char *key);
|
||||||
void *hash_remove_if_exists(hash_t *hash, const char *key);
|
void *hash_remove_if_exists(hash_t *hash, const char *key);
|
||||||
@ -132,6 +133,7 @@ void *hash_it_item(hash_iterator_t *h);
|
|||||||
const char *hash_it_key(hash_iterator_t *h);
|
const char *hash_it_key(hash_iterator_t *h);
|
||||||
void *hash_it_remove(hash_iterator_t *li);
|
void *hash_it_remove(hash_iterator_t *li);
|
||||||
list_t *hash_keys(hash_t *hash);
|
list_t *hash_keys(hash_t *hash);
|
||||||
|
void hash_rename_key(hash_t *h, const char *oldk, const char *newk);
|
||||||
|
|
||||||
int is_valid_nick(char *str);
|
int is_valid_nick(char *str);
|
||||||
int is_valid_username(char *str);
|
int is_valid_username(char *str);
|
||||||
@ -183,8 +185,10 @@ static inline void *array_get(array_t *a, int index)
|
|||||||
|
|
||||||
static inline void array_push(array_t *a, void *ptr)
|
static inline void array_push(array_t *a, void *ptr)
|
||||||
{
|
{
|
||||||
array_ensure(a, a->elemc + 1);
|
int idx = a->elemc;
|
||||||
a->elemv[a->elemc - 1] = ptr;
|
|
||||||
|
array_ensure(a, idx);
|
||||||
|
a->elemv[idx] = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void *array_pop(array_t *a)
|
static inline void *array_pop(array_t *a)
|
||||||
|
Loading…
Reference in New Issue
Block a user