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 over 2 years 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);