Seems some icbirc users started having : prefixed nicks after updating weechat. Even though weechat added a workaround, I think it would be best to fix the IRC protocol parsing in icbirc to conform to the RFC.
I special cased RAWICB to bypass the correct parsing; I assumed people manually typed those commands and I shouldn't break finger memory. I don't use ICB, so this has only been compile tested. Once tested, this should go upstream rather than living in the tree. - Matthew Martin diff --git Makefile Makefile index d7bb3f1160b..a7b292d43da 100644 --- Makefile +++ Makefile @@ -3,7 +3,7 @@ COMMENT= proxy IRC client with ICB server DISTNAME= icbirc-2.1 -REVISION= 2 +REVISION= 3 CATEGORIES= net MASTER_SITES= http://www.benzedrine.ch/ diff --git patches/patch-irc_c patches/patch-irc_c new file mode 100644 index 00000000000..ceb5f0172a0 --- /dev/null +++ patches/patch-irc_c @@ -0,0 +1,200 @@ +$OpenBSD$ + +Index: irc.c +--- irc.c.orig ++++ irc.c +@@ -42,7 +42,7 @@ extern void scan(const char **, char *, size_t, const + const char *); + extern int sync_write(int, const char *, int); + +-static void irc_cmd(const char *, int, int); ++static void irc_cmd(char *, int, int); + + static void irc_send_pong(int, const char *); + +@@ -93,44 +93,55 @@ irc_recv(const char *buf, unsigned len, int client_fd, + } + + static void +-irc_cmd(const char *cmd, int client_fd, int server_fd) ++irc_cmd(char *cmd, int client_fd, int server_fd) + { +- if (!strncasecmp(cmd, "PASS ", 5)) { +- cmd += 5; +- scan(&cmd, irc_pass, sizeof(irc_pass), " ", " "); +- } else if (!strncasecmp(cmd, "USER ", 5)) { +- cmd += 5; +- scan(&cmd, irc_ident, sizeof(irc_ident), " ", " "); ++ if (!strncasecmp(cmd, "RAWICB ", 7)) { ++ icb_send_raw(server_fd, cmd + 7); ++ return; ++ } ++ ++ char *argv[10], *p; ++ int argc = 1; ++ ++ for (p = cmd, argv[0] = p; argc < 10 && (p = strchr(p, ' ')) != NULL; ++ argc++) { ++ *p = 0; ++ p++; ++ while (*p == ' ') ++ p++; ++ if (*p == ':') { ++ argv[argc] = p + 1; ++ argc++; ++ break; ++ } ++ argv[argc] = p; ++ } ++ ++ if (!strcasecmp(argv[0], "PASS")) { ++ strlcpy(irc_pass, argv[1], sizeof(irc_pass)); ++ } else if (!strcasecmp(argv[0], "USER")) { ++ strlcpy(irc_ident, argv[1], sizeof(irc_ident)); + if (!icb_logged_in && irc_nick[0] && irc_ident[0]) + icb_send_login(server_fd, irc_nick, + irc_ident, irc_pass); +- } else if (!strncasecmp(cmd, "NICK ", 5)) { +- cmd += 5; +- scan(&cmd, irc_nick, sizeof(irc_nick), " ", " "); ++ } else if (!strcasecmp(argv[0], "NICK")) { ++ strlcpy(irc_nick, argv[1], sizeof(irc_nick)); + if (icb_logged_in) + icb_send_name(server_fd, irc_nick); + else if (irc_nick[0] && irc_ident[0]) + icb_send_login(server_fd, irc_nick, + irc_ident, irc_pass); +- } else if (!strncasecmp(cmd, "JOIN ", 5)) { +- char group[128]; +- +- cmd += 5; +- if (*cmd == '#') +- cmd++; +- scan(&cmd, group, sizeof(group), " ", " "); +- icb_send_group(server_fd, group); +- } else if (!strncasecmp(cmd, "PART ", 5)) { ++ } else if (!strcasecmp(argv[0], "JOIN")) { ++ icb_send_group(server_fd, ++ argv[1] + (argv[1][0] == '#' ? 1 : 0)); ++ } else if (!strcasecmp(argv[0], "PART")) { + in_irc_channel = 0; +- } else if (!strncasecmp(cmd, "PRIVMSG ", 8) || +- !strncasecmp(cmd, "NOTICE ", 7)) { +- char dst[128]; ++ } else if (!strcasecmp(argv[0], "PRIVMSG") || ++ !strcasecmp(argv[0], "NOTICE")) { + char msg[8192]; + unsigned i, j; + +- cmd += strncasecmp(cmd, "NOTICE ", 7) ? 8 : 7; +- scan(&cmd, dst, sizeof(dst), " ", " "); +- scan(&cmd, msg, sizeof(msg), " ", ""); ++ strlcpy(msg, argv[2], sizeof(msg)); + /* strip \001 found in CTCP messages */ + i = 0; + while (msg[i]) { +@@ -141,73 +152,52 @@ irc_cmd(const char *cmd, int client_fd, int server_fd) + } else + i++; + } +- if (!strcmp(dst, irc_channel)) +- icb_send_openmsg(server_fd, +- msg + (msg[0] == ':' ? 1 : 0)); ++ if (!strcmp(argv[1], irc_channel)) ++ icb_send_openmsg(server_fd, msg); + else +- icb_send_privmsg(server_fd, dst, +- msg + (msg[0] == ':' ? 1 : 0)); +- } else if (!strncasecmp(cmd, "MODE ", 5)) { +- cmd += 5; +- if (!strcmp(cmd, irc_channel)) ++ icb_send_privmsg(server_fd, argv[1], msg); ++ } else if (!strcasecmp(argv[0], "MODE")) { ++ if (strcmp(argv[1], irc_channel)) ++ return; ++ if (argc == 2) + icb_send_names(server_fd, irc_channel); +- else if (!strncmp(cmd, irc_channel, strlen(irc_channel))) { +- cmd += strlen(irc_channel); +- if (strncmp(cmd, " +o ", 4)) { ++ else { ++ if (strcmp(argv[2], "+o")) { + printf("irc_cmd: invalid MODE args '%s'\n", +- cmd); ++ argv[2]); + return; + } +- cmd += 4; +- icb_send_pass(server_fd, cmd); ++ icb_send_pass(server_fd, argv[3]); + } +- } else if (!strncasecmp(cmd, "TOPIC ", 6)) { +- cmd += 6; +- if (strncmp(cmd, irc_channel, strlen(irc_channel))) { +- printf("irc_cmd: invalid TOPIC args '%s'\n", cmd); ++ } else if (!strcasecmp(argv[0], "TOPIC")) { ++ if (strcmp(argv[1], irc_channel)) { ++ printf("irc_cmd: invalid TOPIC channel '%s'\n", ++ argv[1]); + return; + } +- cmd += strlen(irc_channel); +- if (strncmp(cmd, " :", 2)) { +- printf("irc_cmd: invalid TOPIC args '%s'\n", cmd); +- return; +- } +- cmd += 2; +- icb_send_topic(server_fd, cmd); +- } else if (!strcasecmp(cmd, "LIST")) { ++ icb_send_topic(server_fd, argv[2]); ++ } else if (!strcasecmp(argv[0], "LIST")) { + icb_send_list(server_fd); +- } else if (!strncasecmp(cmd, "NAMES ", 6)) { +- cmd += 6; +- icb_send_names(server_fd, cmd); +- } else if (!strncasecmp(cmd, "WHOIS ", 6)) { +- cmd += 6; +- icb_send_whois(server_fd, cmd); +- } else if (!strncasecmp(cmd, "WHO ", 4)) { +- cmd += 4; +- icb_send_who(server_fd, cmd); +- } else if (!strncasecmp(cmd, "KICK ", 5)) { +- char channel[128], nick[128]; +- +- cmd += 5; +- scan(&cmd, channel, sizeof(channel), " ", " "); +- scan(&cmd, nick, sizeof(nick), " ", " "); +- if (strcmp(channel, irc_channel)) { +- printf("irc_cmd: invalid KICK args '%s'\n", cmd); ++ } else if (!strcasecmp(argv[0], "NAMES")) { ++ icb_send_names(server_fd, argv[1]); ++ } else if (!strcasecmp(argv[0], "WHOIS")) { ++ icb_send_whois(server_fd, argv[1]); ++ } else if (!strcasecmp(argv[0], "WHO")) { ++ icb_send_who(server_fd, argv[1]); ++ } else if (!strcasecmp(argv[0], "KICK")) { ++ if (strcmp(argv[1], irc_channel)) { ++ printf("irc_cmd: invalid KICK args '%s'\n", argv[1]); + return; + } +- icb_send_boot(server_fd, nick); +- } else if (!strncasecmp(cmd, "PING ", 5)) { ++ icb_send_boot(server_fd, argv[2]); ++ } else if (!strcasecmp(argv[0], "PING")) { + icb_send_noop(server_fd); +- cmd += 5; +- irc_send_pong(client_fd, cmd); +- } else if (!strncasecmp(cmd, "RAWICB ", 7)) { +- cmd += 7; +- icb_send_raw(server_fd, cmd); +- } else if (!strncasecmp(cmd, "QUIT ", 5)) { ++ irc_send_pong(client_fd, argv[1]); ++ } else if (!strcasecmp(argv[0], "QUIT")) { + printf("client QUIT\n"); + terminate_client = 1; + } else +- printf("irc_cmd: unknown cmd '%s'\n", cmd); ++ printf("irc_cmd: unknown command '%s'\n", argv[0]); + } + + void
