AmendHub

jcs

/

wallops

/

amendments

/

14

irc: Handle /me and CTCP VERSION, move vers resource handling to util

Also try to properly send a QUIT message when we cmd+q

jcs made amendment 14 6 months ago
--- chatter.c Mon Feb 7 16:51:10 2022 +++ chatter.c Mon Feb 7 17:36:58 2022 @@ -31,6 +31,7 @@ void chatter_idle(struct focusable *focusable, EventRe void chatter_update(struct focusable *focusable, EventRecord *event); void chatter_resume(struct focusable *focusable, EventRecord *event); void chatter_close(struct focusable *focusable, EventRecord *event); +bool chatter_quit(struct focusable *focusable); void chatter_atexit(struct focusable *focusable); void @@ -89,6 +90,7 @@ chatter_init(const char *server, const unsigned short focusable->update = chatter_update; focusable->close = chatter_close; focusable->atexit = chatter_atexit; + focusable->quit = chatter_quit; focusable->menu = chatter_menu; focusable->resume = chatter_resume; add_focusable(focusable); @@ -198,6 +200,20 @@ chatter_close(struct focusable *focusable, EventRecord close_focusable(focusable); } else hide_focusable(focusable); +} + +bool +chatter_quit(struct focusable *focusable) +{ + struct chatter *chatter = (struct chatter *)(focusable->cookie); + + if (chatter->irc_state < IRC_STATE_CONNECTED) + irc_abort(chatter); + else + irc_close(chatter); + + close_focusable(focusable); + return true; } void --- chatter.h Mon Feb 7 12:57:14 2022 +++ chatter.h Mon Feb 7 17:33:39 2022 @@ -23,7 +23,7 @@ #include "tcp.h" #include "util.h" -#define PROGRAM_NAME "wallops" +#define PROGRAM_NAME "Wallops" #define CHATTER_FONT geneva #define CHATTER_FONT_SIZE 10 @@ -79,6 +79,7 @@ struct focusable { void (*close)(struct focusable *focusable, EventRecord *event); void (*suspend)(struct focusable *focusable, EventRecord *event); void (*resume)(struct focusable *focusable, EventRecord *event); + bool (*quit)(struct focusable *focusable); void (*atexit)(struct focusable *focusable); }; extern struct focusable **focusables; --- irc.c Mon Feb 7 16:52:11 2022 +++ irc.c Mon Feb 7 22:21:06 2022 @@ -150,7 +150,9 @@ irc_close(struct chatter *chatter) if (chatter->irc_state == IRC_STATE_DISCONNECTED) return; - chatter_printf(chatter, "$B*!*$0 Disconnecting"); + chatter_printf(chatter, "$B***$0 Disconnecting"); + if (chatter->irc_state == IRC_STATE_IDLE) + irc_printf(chatter, "QUIT :Cmd+Q\r\n"); irc_abort(chatter); } @@ -425,10 +427,34 @@ done_parsing: } if (strcmp(msg.cmd, "PRIVMSG") == 0) { user = irc_parse_user(msg.source); - if (strcmp(msg.dest, chatter->irc_nick) == 0) + size = strlen(msg.msg); + + if (msg.msg[0] == '\1' && msg.msg[size - 1] == '\1') { + /* CTCP or a /me action */ + msg.msg[size - 1] = '\0'; + if (strncmp(msg.msg + 1, "ACTION", 6) == 0) { + chatter_printf(chatter, "* %s$/ %s", user->nick, + msg.msg + 8); + } else if (strncmp(msg.msg + 1, "VERSION", 7) == 0) { + chatter_printf(chatter, "$B*** %s ($0%s@%s$B)$0 " + "requested CTCP $BVERSION$0 from $B%s$0", + user->nick, user->username, user->hostname, + msg.dest); + + /* only respond if it was sent directly to us */ + if (strcmp(msg.dest, chatter->irc_nick) == 0) { + irc_printf(chatter, + "NOTICE %s :\1VERSION %s %s on a %s\1\r\n", + user->nick, PROGRAM_NAME, get_version(false), + gestalt_machine_type()); + } + } else { + goto unknown; + } + } else if (strcmp(msg.dest, chatter->irc_nick) == 0) { chatter_printf(chatter, "$B[$0%s$B($0%s@%s$B)]$0$/ %s", user->nick, user->username, user->hostname, msg.msg); - else if (chatter->irc_channel && + } else if (chatter->irc_channel && strcmp(msg.dest, chatter->irc_channel->name) == 0) { size = strlen(chatter->irc_nick); if (strncmp(msg.msg, chatter->irc_nick, size) == 0 && @@ -627,10 +653,8 @@ irc_process_input(struct chatter *chatter, char *str) size_t n; if (str[0] != '/') { - if (chatter->irc_channel == NULL) { - chatter_printf(chatter, "$B*** Cannot send (not in channel)$0"); - return; - } + if (chatter->irc_channel == NULL) + goto not_in_channel; irc_printf(chatter, "PRIVMSG %s :%s\r\n", chatter->irc_channel->name, str); chatter_printf(chatter, "<$B%s$0>$/ %s", chatter->irc_nick, str); @@ -650,14 +674,22 @@ irc_process_input(struct chatter *chatter, char *str) irc_printf(chatter, "PRIVMSG %s :%s\r\n", arg1, str); return; } - + if (strcmp(arg0, "me") == 0) { + if (str == NULL) + goto not_enough_params; + if (chatter->irc_channel == NULL) + goto not_in_channel; + chatter_printf(chatter, "* %s$/ %s", chatter->irc_nick, str); + irc_printf(chatter, "PRIVMSG %s :\1ACTION %s\1\r\n", + chatter->irc_channel->name, str); + return; + } if (strcmp(arg0, "join") == 0) { if (str == NULL) goto not_enough_params; irc_printf(chatter, "JOIN %s\r\n", str); return; } - if (strcmp(arg0, "part") == 0) { if (str == NULL && chatter->irc_channel) irc_printf(chatter, "PART %s\r\n", chatter->irc_channel->name); @@ -665,19 +697,16 @@ irc_process_input(struct chatter *chatter, char *str) irc_printf(chatter, "PART %s\r\n", str); return; } - if (strcmp(arg0, "quit") == 0) { irc_printf(chatter, "QUIT :%s\r\n", str == NULL ? "&" : str); return; } - if (strcmp(arg0, "nick") == 0) { if (str == NULL) goto not_enough_params; irc_printf(chatter, "NICK %s\r\n", str); return; } - if (strcmp(arg0, "quote") == 0) { if (str == NULL) goto not_enough_params; @@ -690,6 +719,10 @@ irc_process_input(struct chatter *chatter, char *str) not_enough_params: chatter_printf(chatter, "$B***$0 Not enough parameters given"); + return; +not_in_channel: + chatter_printf(chatter, "$B*** Cannot send (not in channel)$0"); + return; } void --- main.c Mon Feb 7 16:49:02 2022 +++ main.c Mon Feb 7 21:18:50 2022 @@ -353,32 +353,18 @@ verify: bool handle_menu(long menu_id) { + size_t n; bool ret = false; + bool quit = true; switch (HiWord(menu_id)) { case APPLE_MENU_ID: switch (LoWord(menu_id)) { case APPLE_MENU_ABOUT_ID: { - VersRecHndl vers; char vers_s[255]; - char short_vers[255] = { 0 }; - short vlen; - if ((vers = (VersRecHndl)GetResource('vers', 128))) { - /* - * vers "long version string" is a pascal string after the - * short version pascal string - */ - HLock(vers); - vlen = (*vers)->shortVersion[0]; - memcpy(short_vers, (*vers)->shortVersion + vlen + 1, - sizeof((*vers)->shortVersion) - vlen - 1); - PtoCstr(short_vers); - sprintf(vers_s, "%s %s", PROGRAM_NAME, short_vers); - ReleaseResource(vers); - note("%s", vers_s); - } else - warn("Can't find version number!"); + sprintf(vers_s, "%s %s", PROGRAM_NAME, get_version(true)); + note("%s", vers_s); ret = true; break; @@ -393,7 +379,17 @@ handle_menu(long menu_id) break; case FILE_MENU_QUIT_ID: ret = true; - ExitToShell(); + quit = true; + for (n = 0; n < nfocusables; n++) { + if (focusables[n] && focusables[n]->quit && + !focusables[n]->quit(focusables[n])) { + quit = false; + break; + } + } + if (quit) + ExitToShell(); + break; } break; default: --- util.c Mon Feb 7 16:06:20 2022 +++ util.c Mon Feb 7 22:03:03 2022 @@ -896,6 +896,32 @@ gestalt_machine_type(void) return NULL; } +char * +get_version(bool long_version) +{ + static char vers_s[256] = { 0 }; + char *v; + VersRecHndl vers; + short len; + + vers = (VersRecHndl)GetResource('vers', 128); + if (!vers) + return NULL; + + HLock(vers); + v = (char *)&(*vers)->shortVersion; + len = v[0]; + if (long_version) { + v += len + 1; + len = v[0]; + } + memcpy(vers_s, v, len + 1); + ReleaseResource(vers); + + PtoCstr(vers_s); + return vers_s; +} + /* * General Mac-specific GUI functions */ --- util.h Mon Feb 7 16:05:45 2022 +++ util.h Mon Feb 7 21:18:17 2022 @@ -113,6 +113,7 @@ OSErr copy_file_contents(short source_ref, short dest_ OSErr FSReadLine(short frefnum, char *buf, size_t buflen); char * gestalt_machine_type(void); +char * get_version(bool long_version); short FontHeight(short font_id, short size); void DrawGrowIconOnly(WindowPtr win);