AmendHub

Download:

jcs

/

wallops

/

amendments

/

73

irc: Pass count of nicks in batch to irc_add_nick_to_channel

This lets it do a malloc of the full count of the line, rather than
having to realloc it 5 at a time.
 
Also implement 333 and 475 and show non-server notices properly.

jcs made amendment 73 2 months ago
--- irc.c Sun Sep 8 22:01:55 2024 +++ irc.c Mon Sep 9 16:13:58 2024 @@ -39,7 +39,7 @@ void irc_dealloc_channel(struct irc_channel *channel); void irc_set_active_channel(struct irc_connection *conn, char *channame); void irc_parse_names(struct irc_channel *channel, char *line); void irc_add_nick_to_channel(struct irc_channel *channel, char *nick, - short flags); + short flags, short count_hint); void irc_remove_nick_from_channel(struct irc_channel *channel, char *nick); bool irc_nick_is_in_channel(struct irc_channel *channel, char *nick); void irc_change_user_nick(struct irc_channel *channel, @@ -86,7 +86,8 @@ irc_connect(struct chatter *chatter, const char *serve conn->channel_autojoin = xstrdup(channel); chatter_printf(conn->chatter, conn, NULL, - "$B***$0 Connecting to $B%s:%d$0...", conn->hostname, conn->port); + "$B***$0 Connecting to $B%s$0 port $B%d$0...", conn->hostname, + conn->port); if ((err = _TCPCreate(&conn->send_pb, &conn->stream, (Ptr)conn->tcp_buf, sizeof(conn->tcp_buf), nil, nil, nil, false)) != noErr) { @@ -114,8 +115,8 @@ irc_connect(struct chatter *chatter, const char *serve } chatter_printf(conn->chatter, conn, NULL, - "$B***$0 Connected to $B%s$0 (%s) port %d", conn->hostname, ip_str, - conn->port); + "$B***$0 Connected to $B%s$0 (%s) port $B%d$0", conn->hostname, + ip_str, conn->port); conn->state = IRC_STATE_CONNECTED; @@ -536,7 +537,7 @@ irc_process_server(struct irc_connection *conn) else { channel = irc_find_channel(conn, msg.arg[0]); if (channel) - irc_add_nick_to_channel(channel, user->nick, 0); + irc_add_nick_to_channel(channel, user->nick, 0, 0); } chatter_printf(channel->chatter, conn, msg.arg[0], "$B*** %s ($0%s@%s$B)$0 has joined $B%s$0", @@ -626,14 +627,23 @@ irc_process_server(struct irc_connection *conn) return true; } if (strcmp(msg.cmd, "NOTICE") == 0) { - if (strncmp(msg.msg, "*** ", 4) == 0) - chatter_printf(conn->chatter, conn, NULL, - "$B***$0 $/%s", - msg.msg + 4); - else - chatter_printf(conn->chatter, conn, NULL, - "$/%s", - msg.msg); + if (strchr(msg.source, '@') == NULL) { + /* server notice */ + if (strncmp(msg.msg, "*** ", 4) == 0) + chatter_printf(conn->chatter, conn, NULL, + "$B***$0 $/%s", + msg.msg + 4); + else + chatter_printf(conn->chatter, conn, NULL, + "$/%s", + msg.msg); + } else { + /* user notice */ + user = irc_parse_user(msg.source); + chatter_printf(conn->chatter, conn, user->nick, + "$Bnotice:[%s($0%s@%s$B)]$0$/ %s", + user->nick, user->username, user->hostname, msg.msg); + } return true; } if (strcmp(msg.cmd, "PART") == 0) { @@ -775,6 +785,9 @@ irc_process_server(struct irc_connection *conn) return true; case 333: /* TOPIC creator */ + chatter_printf(conn->chatter, conn, msg.arg[1], + "$B***$0 Topic set by $B%s$0", + msg.arg[1]); return true; case 338: case 378: @@ -842,6 +855,12 @@ irc_process_server(struct irc_connection *conn) irc_send(conn, conn->line, len); return true; } + case 475: + /* can't join channel */ + chatter_printf(conn->chatter, conn, NULL, + "$B***$0 Cannot join $B%s$0$/: %s", + msg.arg[1], msg.msg); + return true; case 671: /* WHOIS server */ chatter_printf(conn->chatter, conn, conn->current_whois, @@ -853,7 +872,7 @@ irc_process_server(struct irc_connection *conn) chatter_printf(conn->chatter, conn, NULL, "$B***$0$/ %s", msg.msg); - break; + return true; default: goto unknown; } @@ -1118,11 +1137,26 @@ irc_dealloc_channel(struct irc_channel *channel) void irc_parse_names(struct irc_channel *channel, char *line) { - char *nick; - short flags; + char *nick, *tline; + short flags, count; - channel->parsing_nicks = true; + if (!channel->parsing_nicks) { + /* new names output, clear previous */ + if (channel->nicks_size) { + memset(&channel->nicks, 0, + sizeof(struct irc_channel_nick) * channel->nicks_size); + } + + channel->nnicks = 0; + channel->parsing_nicks = true; + } + /* get a count of nicks to pass as a hint to malloc */ + count = 1; + for (tline = line; *tline != '\0'; tline++) + if (*tline == ' ') + count++; + for (;;) { nick = strsep(&line, " "); @@ -1138,7 +1172,7 @@ irc_parse_names(struct irc_channel *channel, char *lin } else flags = 0; - irc_add_nick_to_channel(channel, nick, flags); + irc_add_nick_to_channel(channel, nick, flags, count); if (line == NULL) break; @@ -1147,17 +1181,23 @@ irc_parse_names(struct irc_channel *channel, char *lin void irc_add_nick_to_channel(struct irc_channel *channel, char *nick, - short flags) + short flags, short count_hint) { struct irc_channel_nick *anick, *cnick, *pnick; short aidx, cidx, ret; if (channel->nnicks >= channel->nicks_size) { /* allocate a chunk at a time so we don't do this every iteration */ - channel->nicks_size += 5; + if (count_hint) + channel->nicks_size += count_hint; + else + channel->nicks_size += 5; channel->nicks = xreallocarray(channel->nicks, sizeof(struct irc_channel_nick), channel->nicks_size); + if (channel->nicks == NULL) + panic("out of memory allocating for %ld nicks", + sizeof(struct irc_channel_nick) * channel->nicks_size); memset(&channel->nicks[channel->nnicks], 0, sizeof(struct irc_channel_nick) * (channel->nicks_size - channel->nnicks)); @@ -1308,7 +1348,7 @@ irc_change_user_nick(struct irc_channel *channel, stru } irc_remove_nick_from_channel(channel, user->nick); - irc_add_nick_to_channel(channel, nick, flags); + irc_add_nick_to_channel(channel, nick, flags, 0); } if (strcmp(channel->connection->nick, user->nick) == 0) { @@ -1369,7 +1409,7 @@ irc_parse_channel_mode_change(struct irc_channel *chan irc_remove_nick_from_channel(channel, cnick->nick); /* cnick is probably invalid now */ - irc_add_nick_to_channel(channel, user, flags); + irc_add_nick_to_channel(channel, user, flags, 0); break; }