AmendHub

Download:

jcs

/

subtext

/

amendments

/

531

*: Do config changes on the fly, restarting modules as needed

Annotate each config option with which component it needs restarted
when it changes and do those after saving from the sysop menu. This
also provides the ability to log each changed config option with its
old and new values.

jcs made amendment 531 5 months ago
--- binkp.c Mon Apr 24 09:42:55 2023 +++ binkp.c Thu Nov 9 09:48:19 2023 @@ -59,6 +59,8 @@ binkp_init(void) { Str255 base_dir; + binkp_ready = false; + binkp_mkdir(base_dir, NULL); binkp_mkdir(binkp_inbox_dir, "inbox"); binkp_mkdir(binkp_done_dir, "processed"); @@ -76,6 +78,13 @@ binkp_init(void) } binkp_ready = true; +} + +bool +binkp_reinit(void) +{ + binkp_init(); + return true; } void --- binkp.h Tue Mar 14 15:24:38 2023 +++ binkp.h Thu Nov 9 09:47:58 2023 @@ -72,6 +72,7 @@ extern bool binkp_ready; extern time_t binkp_next_poll; void binkp_init(void); +bool binkp_reinit(void); void binkp_atexit(void); void binkp_poll(void); bool binkp_scan_message(struct fidopkt_message *msg); --- db.c Wed Nov 8 21:02:07 2023 +++ db.c Thu Nov 9 09:07:14 2023 @@ -53,30 +53,38 @@ struct struct_field config_fields[] = { 1, member_size(struct config, hostname) }, { "Telnet Port", CONFIG_TYPE_SHORT, offsetof(struct config, telnet_port), - 0, 65535 }, + 0, 65535, + CONFIG_REQUIRES_TELNET_REINIT }, { "Telnet Trusted Proxy IP", CONFIG_TYPE_IP, offsetof(struct config, trusted_proxy_ip), - 0, 1 }, + 0, 1, + CONFIG_REQUIRES_TELNET_REINIT }, { "Telnet Trusted Proxy UDP Port", CONFIG_TYPE_SHORT, offsetof(struct config, trusted_proxy_udp_port), - 0, 65535 }, + 0, 65535, + CONFIG_REQUIRES_TELNET_REINIT }, { "IP Geolocation Database Path", CONFIG_TYPE_STRING, offsetof(struct config, ipdb_path), - 0, member_size(struct config, ipdb_path) }, + 0, member_size(struct config, ipdb_path), + CONFIG_REQUIRES_IPDB_REINIT }, { "Modem Port", CONFIG_TYPE_SHORT, offsetof(struct config, modem_port), - 0, 2 }, + 0, 2, + CONFIG_REQUIRES_SERIAL_REINIT }, { "Modem Port Speed", CONFIG_TYPE_LONG, offsetof(struct config, modem_speed), - 300, 115200 }, + 300, 115200, + CONFIG_REQUIRES_SERIAL_REINIT }, { "Modem Bits/Parity/Stop", CONFIG_TYPE_STRING, offsetof(struct config, modem_parity), - 1, member_size(struct config, modem_parity) }, + 1, member_size(struct config, modem_parity), + CONFIG_REQUIRES_SERIAL_REINIT }, { "Modem Init String", CONFIG_TYPE_STRING, offsetof(struct config, modem_init), - 1, member_size(struct config, modem_init) }, + 1, member_size(struct config, modem_init), + CONFIG_REQUIRES_SERIAL_REINIT }, { "Modem Answer After Rings", CONFIG_TYPE_SHORT, offsetof(struct config, modem_rings), 1, 100 }, @@ -107,19 +115,23 @@ struct struct_field config_fields[] = { { "FTN Network Name", CONFIG_TYPE_STRING, offsetof(struct config, ftn_network), - 0, member_size(struct config, ftn_network) }, + 0, member_size(struct config, ftn_network), + CONFIG_REQUIRES_BINKP_REINIT }, { "FTN Local Node Address", CONFIG_TYPE_STRING, offsetof(struct config, ftn_node_addr), - 0, member_size(struct config, ftn_node_addr) }, + 0, member_size(struct config, ftn_node_addr), + CONFIG_REQUIRES_BINKP_REINIT }, { "FTN Hub Node Address", CONFIG_TYPE_STRING, offsetof(struct config, ftn_hub_addr), - 0, member_size(struct config, ftn_hub_addr) }, + 0, member_size(struct config, ftn_hub_addr), + CONFIG_REQUIRES_BINKP_REINIT }, { "FTN Hub Packet Password", CONFIG_TYPE_PASSWORD, offsetof(struct config, ftn_hub_pkt_password), 0, member_size(struct config, ftn_hub_pkt_password) }, { "FTN Hub Binkp Hostname", CONFIG_TYPE_STRING, offsetof(struct config, binkp_hostname), - 0, member_size(struct config, binkp_hostname) }, + 0, member_size(struct config, binkp_hostname), + CONFIG_REQUIRES_BINKP_REINIT }, { "FTN Hub Binkp Port", CONFIG_TYPE_SHORT, offsetof(struct config, binkp_port), 0, 65535 }, --- main.c Wed Jun 14 22:39:59 2023 +++ main.c Thu Nov 9 09:53:43 2023 @@ -119,24 +119,20 @@ main(void) logger_printf("[db] Updating username cache"); user_cache_usernames(); - binkp_init(); - if (db->config.telnet_port) - telnet_init(); - if (db->config.modem_port) - serial_init(); if (db->config.ipdb_path[0]) db->ipdb = ipdb_open(db->config.ipdb_path); + + binkp_init(); + telnet_init(); + serial_init(); blanker_last_blank = Time; periodic_job_thread = uthread_add(periodic_jobs, NULL); while (!quitting) { - if (db->config.telnet_port) - telnet_idle(); - if (db->config.modem_port) - serial_idle(); - + telnet_idle(); + serial_idle(); uthread_coordinate(); SystemTask(); --- serial.c Wed Nov 8 20:49:54 2023 +++ serial.c Thu Nov 9 09:53:36 2023 @@ -63,7 +63,7 @@ static char serial_input_internal_buf[1024]; static char serial_input_buf[128]; static size_t serial_input_buf_len = 0; static short serial_rings = 0; -static unsigned long serial_last_ring = 0; +static time_t serial_last_ring = 0; static ParamBlockRec serial_write_pbr = { 0 }; enum { @@ -106,6 +106,17 @@ serial_init(void) char *resp; long m; + if (serial_in_refnum) { + SerSetBuf(serial_in_refnum, (Ptr)&serial_input_internal_buf, 0); + CloseDriver(serial_in_refnum); + serial_in_refnum = 0; + } + + if (serial_out_refnum) { + CloseDriver(serial_out_refnum); + serial_out_refnum = 0; + } + if (db->config.modem_port == 0) return; @@ -115,14 +126,6 @@ serial_init(void) out_port[2] = 'B'; } - if (serial_in_refnum || serial_out_refnum) { - SerSetBuf(serial_in_refnum, (Ptr)&serial_input_internal_buf, 0); - if (serial_in_refnum) - CloseDriver(serial_in_refnum); - if (serial_out_refnum) - CloseDriver(serial_out_refnum); - } - if ((error = OpenDriver(in_port, &serial_in_refnum)) != 0) panic("OpenDriver(%s) failed: %d", PtoCstr(in_port), error); if ((error = OpenDriver(out_port, &serial_out_refnum)) != 0) @@ -230,12 +233,27 @@ serial_init(void) serial_last_ring = 0; } +bool +serial_reinit(void) +{ + if (the_serial_node.state != SERIAL_STATE_IDLE) { + logger_printf("[modem] In use, not re-initializing"); + return false; + } + + logger_printf("[modem] Re-initializing"); + serial_hangup(); + serial_init(); + + return true; +} + void serial_hangup(void) { long m; - if (db->config.modem_port == 0) + if (serial_out_refnum == 0) return; logger_printf("[modem] Hanging up"); @@ -400,11 +418,12 @@ serial_atexit(void) { serial_init(); - SerSetBuf(serial_in_refnum, (Ptr)&serial_input_internal_buf, 0); - if (serial_in_refnum) + if (serial_in_refnum) { + SerSetBuf(serial_in_refnum, (Ptr)&serial_input_internal_buf, 0); CloseDriver(serial_in_refnum); - if (serial_out_refnum) - CloseDriver(serial_out_refnum); + } + if (serial_out_refnum) + CloseDriver(serial_out_refnum); } void @@ -430,6 +449,9 @@ serial_idle(void) SerStaRec status; char *line; + if (db->config.modem_port == 0) + return; + SerStatus(serial_in_refnum, &status); #if 0 if (status.ctsHold != 0) --- serial_local.h Sun Mar 6 16:40:03 2022 +++ serial_local.h Thu Nov 9 09:26:32 2023 @@ -19,6 +19,7 @@ void serial_init(void); void serial_idle(void); +bool serial_reinit(void); void serial_atexit(void); void serial_hangup(void); --- settings.h Fri Mar 17 16:15:31 2023 +++ settings.h Thu Nov 9 09:22:06 2023 @@ -28,12 +28,21 @@ enum { CONFIG_TYPE_PASSWORD }; +enum { + CONFIG_NO_RESTART, + CONFIG_REQUIRES_SERIAL_REINIT, + CONFIG_REQUIRES_TELNET_REINIT, + CONFIG_REQUIRES_BINKP_REINIT, + CONFIG_REQUIRES_IPDB_REINIT +}; + struct struct_field { char name[50]; short type; unsigned short off; long min; long max; + short reinit; }; short struct_editor(struct session *s, const struct struct_field *fields, --- sysop.c Mon Aug 28 11:35:51 2023 +++ sysop.c Thu Nov 9 17:25:12 2023 @@ -24,6 +24,7 @@ #include "serial_local.h" #include "session.h" #include "sysop.h" +#include "telnet.h" #define USERS_PER_PAGE 20 @@ -138,7 +139,11 @@ void sysop_edit_settings(struct session *s) { struct config *new_config, old_config; - short ret; + const struct struct_field *sf; + char *new_config_data, *old_config_data; + short ret, n, nsval, osval; + unsigned long nlval, olval; + unsigned short reinits = 0; if (!s->user || !s->user->is_sysop) return; @@ -152,15 +157,116 @@ sysop_edit_settings(struct session *s) } memcpy(&old_config, &db->config, sizeof(db->config)); - memcpy(&db->config, new_config, sizeof(db->config)); + + for (n = 0; n < nconfig_fields; n++) { + sf = &config_fields[n]; + + old_config_data = (char *)&db->config + sf->off; + new_config_data = (char *)new_config + sf->off; + + switch (sf->type) { + case CONFIG_TYPE_STRING: + case CONFIG_TYPE_PASSWORD: + if (memcmp(old_config_data, new_config_data, sf->max) == 0) + goto next_field; + + if (sf->type == CONFIG_TYPE_PASSWORD) + session_logf(s, "Changed BBS setting \"%s\" (password)", + sf->name); + else + session_logf(s, "Changed BBS setting \"%s\" from \"%s\" " + "to \"%s\"", sf->name, old_config_data, new_config_data); + + memcpy(old_config_data, new_config_data, sf->max); + break; + case CONFIG_TYPE_SHORT: + osval = CHARS_TO_SHORT(old_config_data[0], old_config_data[1]); + nsval = CHARS_TO_SHORT(new_config_data[0], new_config_data[1]); + + if (nsval == osval) + goto next_field; + + session_logf(s, "Changed BBS setting \"%s\" from %d to %d", + sf->name, osval, nsval); + + memcpy(old_config_data, new_config_data, sizeof(short)); + break; + case CONFIG_TYPE_LONG: + olval = CHARS_TO_LONG(old_config_data[0], old_config_data[1], + old_config_data[2], old_config_data[3]); + nlval = CHARS_TO_LONG(new_config_data[0], new_config_data[1], + new_config_data[2], new_config_data[3]); + if (olval == nlval) + goto next_field; + + session_logf(s, "Changed BBS setting \"%s\" from %lu to %lu", + sf->name, olval, nlval); + + memcpy(old_config_data, new_config_data, sizeof(long)); + break; + case CONFIG_TYPE_BOOLEAN: + if (old_config_data[0] == new_config_data[0]) + goto next_field; + + session_logf(s, "Changed BBS setting \"%s\" from %s to %s", + sf->name, old_config_data[0] ? "true" : "false", + new_config_data[0] ? "true" : "false"); + + memcpy(old_config_data, new_config_data, 1); + break; + case CONFIG_TYPE_IP: { + char old_ip_str[16], new_ip_str[16]; + + olval = CHARS_TO_LONG(old_config_data[0], old_config_data[1], + old_config_data[2], old_config_data[3]); + nlval = CHARS_TO_LONG(new_config_data[0], new_config_data[1], + new_config_data[2], new_config_data[3]); + if (olval == nlval) + goto next_field; + + if (olval == 0) + snprintf(old_ip_str, sizeof(old_ip_str), "(None)"); + else + long2ip(olval, old_ip_str); + + if (nlval == 0) + snprintf(new_ip_str, sizeof(new_ip_str), "(None)"); + else + long2ip(nlval, new_ip_str); + + session_logf(s, "Changed BBS setting \"%s\" from %s to %s", + sf->name, old_ip_str, new_ip_str); + + memcpy(old_config_data, new_config_data, sizeof(long)); + break; + } + } + + reinits |= (1 << sf->reinit); + +next_field: + continue; + } + db_config_save(db); bile_flush(db->bile, true); - memcpy(&db->config, &old_config, sizeof(db->config)); + + if (reinits & (1 << CONFIG_REQUIRES_SERIAL_REINIT)) + serial_reinit(); + if (reinits & (1 << CONFIG_REQUIRES_TELNET_REINIT)) + telnet_reinit(); + if (reinits & (1 << CONFIG_REQUIRES_BINKP_REINIT)) + binkp_reinit(); + if (reinits & (1 << CONFIG_REQUIRES_IPDB_REINIT)) { + if (db->ipdb) + ipdb_close(&db->ipdb); + if (db->config.ipdb_path) + db->ipdb = ipdb_open(db->config.ipdb_path); + } - session_logf(s, "Changed BBS settings"); - session_printf(s, "Successfully saved changes to BBS Settings, " - "restart to take effect\r\n"); xfree(&new_config); + + session_printf(s, "Successfully saved changes to BBS Settings\r\n"); } void --- telnet.c Wed Jun 14 23:02:09 2023 +++ telnet.c Thu Nov 9 15:47:33 2023 @@ -122,7 +122,7 @@ static TCPiopb telnet_exit_pb; static TCPStatusPB telnet_status_pb; static bool did_initial_log = false; static UDPiopb udp_ban_pb; -static StreamPtr udp_ban_stream; +static StreamPtr udp_ban_stream = 0; static char *udp_ban_rcv_buf; #define UDP_BAN_RCV_BUF_SIZE 2048 static wdsEntry udp_ban_wds[2]; @@ -139,6 +139,7 @@ static const char * vt100_terms[] = { NULL, }; +void telnet_deinit(void); void telnet_setup(struct session *session); void telnet_listen_on_node(struct telnet_node *node); void telnet_output_iac(struct session *session, const char *iacs, @@ -160,20 +161,20 @@ telnet_init(void) if (!db->config.telnet_port) return; - logger_printf("[telnet] Initializing MacTCP"); + if (!did_initial_log) + logger_printf("[telnet] Initializing MacTCP"); if (_TCPInit() != noErr) panic("Failed initializing MacTCP"); /* pre-allocate nodes */ for (n = 0; n < MAX_TELNET_NODES; n++) { - telnet_nodes[n] = xmalloczero(sizeof(struct telnet_node)); - if (telnet_nodes[n] == NULL) - panic("Failed allocating telnet node %d", n); + if (telnet_nodes[n] == NULL) { + telnet_nodes[n] = xmalloczero(sizeof(struct telnet_node)); + if (telnet_nodes[n] == NULL) + panic("Failed allocating telnet node %d", n); + } telnet_nodes[n]->id = n; - - if (n == 0) - telnet_listen_on_node(telnet_nodes[n]); } if (db->config.trusted_proxy_ip != 0 && @@ -189,7 +190,35 @@ telnet_init(void) } } +bool +telnet_reinit(void) +{ + telnet_deinit(); + telnet_init(); + did_initial_log = false; + return true; +} + void +telnet_deinit(void) +{ + if (telnet_listener_node) { + _TCPRelease(&telnet_exit_pb, telnet_listener_node->stream, nil, + nil, false); + telnet_listener_node->state = TELNET_PB_STATE_UNUSED; + telnet_listener_node = NULL; + } + + if (udp_ban_stream) { + _UDPRelease(&udp_ban_pb, udp_ban_stream, NULL, NULL, false); + udp_ban_stream = 0; + } + + if (udp_ban_rcv_buf) + xfree(&udp_ban_rcv_buf); +} + +void telnet_atexit(void) { struct telnet_node *node; @@ -207,11 +236,7 @@ telnet_atexit(void) telnet_nodes[n] = NULL; } - telnet_listener_node = NULL; - - if (db->config.trusted_proxy_ip != 0 && - db->config.trusted_proxy_udp_port != 0) - _UDPRelease(&udp_ban_pb, udp_ban_stream, NULL, NULL, false); + telnet_deinit(); } void --- telnet.h Sun Jul 17 20:13:43 2022 +++ telnet.h Thu Nov 9 09:44:24 2023 @@ -20,6 +20,7 @@ #include "session.h" void telnet_init(void); +bool telnet_reinit(void); void telnet_idle(void); void telnet_atexit(void);