Skip to content
Snippets Groups Projects
Commit 4f84221d authored by rswindell's avatar rswindell
Browse files

SBBSecho v3.02:

Most of the changes are in EchoCfg:
- SBBSecho and EchoCfg will now maintain auto-backups of the sbbsecho.ini file
- AutoAddSubs now defaults to true/enabled: this setting is harmless without
  further configuring linked nodes (Uplink for Groups / GroupHub)
- Global Settings are now a separate sub-menu in EchoCfg
- EchoCfg remembers current selection on (more) sub-menus
- Sub-menus have been rearranged and resized
- Numerous Online Help text updates in EchoCfg
- Adding missing/new settings to EchoCfg:
  Log Timestamp Format
  Strict Packet Passwords
  Use FTN Domain/Zone Map
  BSY Mutex File Timeout
  BSO Lock Attempt Delay
  BSO Lock Attempt Limit
  Config File Backups
  Linked Nodes->Uplink for Message Groups
  Echo Statistics File
  Outgoing Semaphore File
  Automatically Add New Subs to Area File
  Maximum Backups to Maintain of Area File
  Relay Filtered Messages
  (everything you can set in sbbsecho.ini should now be editable via EchoCfg)
parent cd4c1501
No related branches found
No related tags found
No related merge requests found
......@@ -65,6 +65,144 @@ void bail(int code)
static char* logLevelStringList[]
= {"Emergency", "Alert", "Critical", "Error", "Warning", "Notice", "Informational", "Debugging", NULL};
void global_settings(void)
{
static int global_opt;
while(1) {
int i = 0;
char str[128];
char duration[64];
sprintf(opt[i++], "%-25s %s", "Mailer Type"
,cfg.flo_mailer ? "Binkley/FLO":"ArcMail/Attach");
sprintf(opt[i++], "%-25s %s", "Log Level", logLevelStringList[cfg.log_level]);
sprintf(opt[i++], "%-25s %s", "Log Timestamp Format", cfg.logtime);
sprintf(opt[i++], "%-25s %s", "Strict Packet Passwords", cfg.strict_packet_passwords ? "Enabled" : "Disabled");
sprintf(opt[i++], "%-25s %s", "Use FTN Domain/Zone Map", cfg.use_ftn_domains ? "Enabled" : "Disabled");
sprintf(opt[i++], "%-25s %s", "BSY Mutex File Timeout", duration_to_vstr(cfg.bsy_timeout, duration, sizeof(duration)));
sprintf(opt[i++], "%-25s %s", "BSO Lock Attempt Delay", duration_to_vstr(cfg.bso_lock_delay, duration, sizeof(duration)));
sprintf(opt[i++], "%-25s %u", "BSO Lock Attempt Limit", cfg.bso_lock_attempts);
sprintf(opt[i++], "%-25s %u", "Config File Backups", cfg.cfgfile_backups);
opt[i][0] = 0;
uifc.helpbuf=
"~ Global Settings ~\n"
"\n"
"`Mailer Type` should normally be set to `Binkley/FLO` to enable SBBSecho's\n"
" \"Binkley-Style Outbound\" operating mode (a.k.a. `BSO` or `FLO` mode).\n"
" If you are using an `Attach`, `ArcMail`, or `FrontDoor` style FidoNet\n"
" mailer, then set this setting to `ArcMail/Attach`, but know that most\n"
" modern FidoNet mailers are Binkley-Style and therefore that mode of\n"
" operation in SBBSecho is more widely tested and supported.\n"
"\n"
"`Log Level` should normally be set to `Informational` but if you're\n"
" experiencing problems with SBBSecho and would like more verbose log\n"
" output, set this to `Debugging`. If you want less verbose logging,\n"
" set to higher-severity levels to reduce the number of log messages.\n"
"\n"
"`Log Timestmap Format` defines the format of the date/time-stamps added\n"
" along with each log message to the log file (e.g. sbbsecho.log).\n"
" The timestamp format is defined using standard C `strftime` notation.\n"
" The default format is: `" DEFAULT_LOG_TIME_FMT "`\n"
" For SBBSecho v2 timestamp format, use `%m/%d/%y %H:%M:%S`\n"
"\n"
"`Strict Packet Passwords`, when enabled, requires that Packet Passwords\n"
" must match the password for the linked-node from which the packet\n"
" was received, even if that linked-node has no password configured.\n"
" If you wish to revert to the SBBSecho v2 behavior with less strict\n"
" enforcement of matching packet passwords, disable this option.\n"
" Default: Enabled\n"
"\n"
"`Use FTN Domain/Zone Map`, when enabled, uses the configuration file\n"
" `ctrl/ftn_domains.ini` to determine the mapping between FTN domains\n"
" and FTN zones and the relevant BSO outbound directory.\n"
" Default: Disabled\n"
"\n"
"`BSY Mutex File Timeout` determines the maximum age of an existing\n"
" mutex file (`*.bsy`) before SBBSecho will act as though the mutex\n"
" file was not present. This setting applies to the global\n"
" `sbbsecho.bsy` file as well as the BSO lock (`*.bsy`) files for\n"
" individual nodes.\n"
" Default: 12 hours\n"
"\n"
"`BSO Lock Attempt Delay` determines the amount of time between BSO\n"
" node lock attempts (via `*.bsy` files in the relevant outbound\n"
" directory).\n"
" Default: 10 seconds\n"
"\n"
"`BSO Lock Attempt Limit` determines the maximum number of BSO node lock\n"
" attempts before SBBSecho will give-up and move on to another node\n"
" to process mail. This value multiplied by the `BSO Lock Attempt\n"
" Delay` should be much less than the `BSY Mutex File Timeout` value.\n"
" Default: 60 attempts\n"
"\n"
"`Config File Backups` determines the number of automatic backups of your\n"
" SBBSecho configuration file (e.g. `sbbsecho.ini`) that will be\n"
" maintained by SBBSecho Config and SBBSecho AreaFix.\n"
;
int key = uifc.list(WIN_BOT|WIN_L2R|WIN_ACT|WIN_SAV, 0, 0, 0, &global_opt,0, "Global Settings", opt);
switch(key) {
case -1:
return;
case 0:
cfg.flo_mailer = !cfg.flo_mailer;
break;
case 1:
uifc.helpbuf=
"~ Log Level ~\n"
"\n"
"Select the minimum severity of log entries to be logged to the log file.\n"
"The default/normal setting is `Informational`.";
int i = cfg.log_level;
i = uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Log Level",logLevelStringList);
if(i>=0 && i<=LOG_DEBUG)
cfg.log_level=i;
break;
case 2:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Log Timestamp Format", cfg.logtime, sizeof(cfg.logtime)-1, K_EDIT);
break;
case 3:
cfg.strict_packet_passwords = !cfg.strict_packet_passwords;
break;
case 4:
cfg.use_ftn_domains = !cfg.use_ftn_domains;
break;
case 5:
duration_to_vstr(cfg.bsy_timeout, duration, sizeof(duration));
if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "BSY Mutex File Timeout", duration, 10, K_EDIT) > 0)
cfg.bsy_timeout = (ulong)parse_duration(duration);
break;
case 6:
duration_to_vstr(cfg.bso_lock_delay, duration, sizeof(duration));
if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Delay Between BSO Lock Attempts", duration, 10, K_EDIT) > 0)
cfg.bso_lock_delay = (ulong)parse_duration(duration);
break;
case 7:
sprintf(str, "%u", cfg.bso_lock_attempts);
if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum BSO Lock Attempts", str, 5, K_EDIT|K_NUMBER) > 0)
cfg.bso_lock_attempts = atoi(str);
break;
case 8:
sprintf(str, "%u", cfg.cfgfile_backups);
if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Configuration File Backups", str, 5, K_EDIT|K_NUMBER) > 0)
cfg.cfgfile_backups = atoi(str);
break;
}
}
}
int main(int argc, char **argv)
{
char str[256],*p;
......@@ -91,7 +229,7 @@ int main(int argc, char **argv)
if(argv[i][0]=='-')
switch(toupper(argv[i][1])) {
case 'D':
printf("NOTICE: The -d option is deprecated, use -id instead\r\n");
printf("NOTICE: The -d option is deprecated, use -id instead\n");
SLEEP(2000);
door_mode=TRUE;
break;
......@@ -110,7 +248,7 @@ int main(int argc, char **argv)
ciolib_mode=CIOLIB_MODE_CURSES;
break;
case 0:
printf("NOTICE: The -i option is deprecated, use -if instead\r\n");
printf("NOTICE: The -i option is deprecated, use -if instead\n");
SLEEP(2000);
case 'F':
ciolib_mode=CIOLIB_MODE_CURSES_IBM;
......@@ -142,24 +280,24 @@ int main(int argc, char **argv)
break;
default:
USAGE:
printf("\nusage: echocfg [path/to/sbbsecho.ini] [options]"
printf("usage: echocfg [path/to/sbbsecho.ini] [options]"
"\n\noptions:\n\n"
"-k = keyboard mode only (no mouse support)\r\n"
"-c = force color mode\r\n"
"-m = force monochrome mode\r\n"
"-e# = set escape delay to #msec\r\n"
"-iX = set interface mode to X (default=auto) where X is one of:\r\n"
"-k = keyboard mode only (no mouse support)\n"
"-c = force color mode\n"
"-m = force monochrome mode\n"
"-e# = set escape delay to #msec\n"
"-iX = set interface mode to X (default=auto) where X is one of:\n"
#ifdef __unix__
" X = X11 mode\r\n"
" C = Curses mode\r\n"
" F = Curses mode with forced IBM charset\r\n"
" X = X11 mode\n"
" C = Curses mode\n"
" F = Curses mode with forced IBM charset\n"
#else
" W = Win32 native mode\r\n"
" W = Win32 native mode\n"
#endif
" A = ANSI mode\r\n"
" D = standard input/output/door mode\r\n"
"-v# = set video mode to # (default=auto)\r\n"
"-l# = set screen lines to # (default=auto-detect)\r\n"
" A = ANSI mode\n"
" D = standard input/output/door mode\n"
"-v# = set video mode to # (default=auto)\n"
"-l# = set screen lines to # (default=auto-detect)\n"
);
exit(0);
}
......@@ -227,94 +365,79 @@ int main(int argc, char **argv)
p=getfname(cfg.cfgfile);
uifc.printf(uifc.scrn_width-(strlen(p)+1),1,uifc.bclr|(uifc.cclr<<4),p);
/* Remember current menu item selections using these vars: */
int netmail_opt = 0;
int echomail_opt = 0;
int path_opt = 0;
int node_opt = 0;
int archive_opt = 0;
int echolist_opt = 0;
dflt=0;
while(1) {
if(memcmp(&cfg, &orig_cfg, sizeof(cfg)) != 0)
uifc.changes = TRUE;
uifc.helpbuf=
"~ SBBSecho Configuration ~\r\n\r\n"
"This program allows you to easily configure the Synchronet BBS\r\n"
"FidoNet-style EchoMail program known as `SBBSecho`. Alternatively, you\r\n"
"may edit the SBBSecho configuration file (e.g. `ctrl/sbbsecho.ini`) using\r\n"
"an ASCII/plain-text editor.\r\n"
"\r\n"
"For detailed documentation, see `http://wiki.synchro.net/util:sbbsecho`\r\n"
"\r\n"
"`Mailer Type` should normally be set to `Binkley/FLO` to enable SBBSecho's\r\n"
"\"Binkley-Style Outbound\" operating mode (a.k.a. `BSO` or `FLO` mode).\r\n"
"If you are using an `Attach`, `ArcMail`, or `FrontDoor` style FidoNet\r\n"
"mailer, then set this setting to `ArcMail/Attach`, but know that most\r\n"
"modern FidoNet mailers are Binkley-Style and therefore that mode of\r\n"
"operation in SBBSecho is more widely tested and supported.\r\n"
"\r\n"
"`Log Level` should normally be set to `Informational` but if you're\r\n"
"experiencing problems with SBBSecho and would like more verbose log\r\n"
"output, set this to `Debugging`. If you want less verbose logging,\r\n"
"set to higher-severity levels to reduce the number of log messages.\r\n"
"\r\n"
"The `Linked Nodes` sub-menu is where you configure your FidoNet-style\r\n"
"links: other FidoNet-style nodes/systems you directly connect with.\r\n"
"\r\n"
"The `Archive Types` sub-menu is where you configure your archive\r\n"
"programs (a.k.a. \"packers\") used for the packing and unpacking of\r\n"
"EchoMail bundle files (usually in 'zip' format).\r\n"
"\r\n"
"The `NetMail Settings` sub-menu is where you configure NetMail-specific\r\n"
"settings.\r\n"
"\r\n"
"The `EchoMail Settings` sub-menu is where you configure EchoMail-specific\r\n"
"settings.\r\n"
"\r\n"
"The `Paths and Filenames` sub-menu is where you configure your system's\r\n"
"directory and file paths used by SBBSecho.\r\n"
"\r\n"
"The `Additional EchoLists` sub-menu is for configuring additional\r\n"
"(optional) lists of FidoNet-style message areas in `BACKBONE.NA` format.\r\n"
"These lists, if configured, are used in addition to your main\r\n"
"~ SBBSecho Configuration ~\n\n"
"This program allows you to easily configure the Synchronet BBS\n"
"FidoNet-style EchoMail program known as `SBBSecho`. Alternatively, you\n"
"may edit the SBBSecho configuration file (e.g. `ctrl/sbbsecho.ini`) using\n"
"an ASCII/plain-text editor.\n"
"\n"
"For detailed documentation, see `http://wiki.synchro.net/util:sbbsecho`\n"
"\n"
"The `Global Settings` sub-menu is where SBBSecho configuration settings\n"
"are located which are neither NetMail nor EchoMail specific, but more\n"
"general to the operation of SBBSecho.\n"
"\n"
"The `Linked Nodes` sub-menu is where you configure your FidoNet-style\n"
"links: other FidoNet-style nodes/systems you regularly connect with\n"
"to exchange mail/files.\n"
"\n"
"The `Archive Types` sub-menu is where you configure your archive\n"
"programs (a.k.a. \"packers\") used for the packing and unpacking of\n"
"EchoMail bundle files (usually in 'zip' format).\n"
"\n"
"The `NetMail Settings` sub-menu is where you configure settings specific\n"
"to NetMail (private one-on-one networked mail).\n"
"\n"
"The `EchoMail Settings` sub-menu is where you configure settings specific\n"
"to EchoMail (public group discussions in topical message areas, echoes).\n"
"\n"
"The `Paths and Filenames` sub-menu is where you configure your system's\n"
"directory and file paths used by SBBSecho.\n"
"\n"
"The `EchoLists` sub-menu is for configuring additional (optional)\n"
"lists of FidoNet-style message areas (echoes) in `BACKBONE.NA` file\n"
"format. These lists, if configured, are used in addition to your main\n"
"`Area File` (e.g. areas.bbs) for advanced AreaFix/AreaMgr operations."
;
i=0;
sprintf(opt[i++],"%-25s %s","Mailer Type"
,cfg.flo_mailer ? "Binkley/FLO":"ArcMail/Attach");
sprintf(opt[i++],"%-25s %s","Log Level",logLevelStringList[cfg.log_level]);
sprintf(opt[i++],"Global Settings...");
sprintf(opt[i++],"Linked Nodes...");
sprintf(opt[i++],"Archive Types...");
sprintf(opt[i++],"NetMail Settings...");
sprintf(opt[i++],"EchoMail Settings...");
sprintf(opt[i++],"Paths and Filenames...");
sprintf(opt[i++],"Additional EchoLists...");
sprintf(opt[i++],"EchoLists...");
if(uifc.changes)
snprintf(opt[i++],MAX_OPLN-1,"Save Changes to %s", getfname(cfg.cfgfile));
opt[i][0]=0;
switch(uifc.list(WIN_ORG|WIN_MID|WIN_ACT|WIN_ESC,0,0,45,&dflt,0
switch(uifc.list(WIN_ORG|WIN_MID|WIN_ACT|WIN_ESC,0,0,0,&dflt,0
,"Configure SBBSecho",opt)) {
case 0:
cfg.flo_mailer = !cfg.flo_mailer;
global_settings();
break;
case 1:
uifc.helpbuf=
"~ Log Level ~\r\n"
"\r\n"
"Select the minimum severity of log entries to be logged to the log file.\r\n"
"The default/normal setting is `Informational`.";
j=cfg.log_level;
i=uifc.list(WIN_MID,0,0,0,&j,0,"Log Level",logLevelStringList);
if(i>=0 && i<=LOG_DEBUG)
cfg.log_level=i;
break;
case 2:
i=0;
while(1) {
uifc.helpbuf=
"~ Linked Nodes ~\r\n\r\n"
"From this menu you can configure the settings for your linked\r\n"
"FidoNet-style nodes (uplinks and downlinks).\r\n"
"\r\n"
"A single node configuration can represent one node or a collection\r\n"
"~ Linked Nodes ~\n\n"
"From this menu you can configure the settings for your linked\n"
"FidoNet-style nodes (uplinks and downlinks).\n"
"\n"
"A single node configuration can represent one node or a collection\n"
"of nodes, by using the `ALL` wildcard word."
;
......@@ -327,7 +450,7 @@ int main(int argc, char **argv)
| WIN_INSACT | WIN_DELACT | WIN_XTR;
if (savnodecfg.addr.zone)
mode |= WIN_PUT;
i=uifc.list(mode,0,0,0,&i,0,"Linked Nodes",opt);
i=uifc.list(mode,0,0,0,&node_opt,0,"Linked Nodes",opt);
if(i==-1)
break;
int msk = i&MSK_ON;
......@@ -335,8 +458,10 @@ int main(int argc, char **argv)
if (msk == MSK_INS) {
str[0]=0;
uifc.helpbuf=
"~ Address ~\r\n\r\n"
"This is the FidoNet style address of the node you wish to add (4D).\r\n";
"~ Address ~\n\n"
"This is the FidoNet style address of the node you wish to add (3D or 4D).\n"
"The `ALL` wildcard may be usd for portions of the address.\n"
;
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"Node Address (ALL wildcard allowed)",str
,25,K_EDIT)<1)
......@@ -386,73 +511,78 @@ int main(int argc, char **argv)
}
while(1) {
uifc.helpbuf=
"~ Linked Node Settings ~\r\n\r\n"
"These are the settings available for each configured node:\r\n"
"\r\n"
"`Address` is the FidoNet-style address in the Zone:Net/Node (3D) or\r\n"
"Zone:Net/Node.Point (4D) format. The wildcard word '`ALL`' may be used\r\n"
"in place of one of the fields to create a node configuration which\r\n"
"will apply to *all* nodes matching that address pattern.\r\n"
"e.g. '`1:ALL`' matches all nodes within FidoNet Zone 1.\r\n"
"\r\n"
"`Comment` is a note to yourself about this node. Setting this to the\r\n"
"user or sysop name corresponding with the configured node can be\r\n"
"a helpful reminder to yourself later.\r\n"
"\r\n"
"`Archive Type` is the name of an archive type corresponding with one of\r\n"
"your configured archive types or '`None`'. This archive type will\r\n"
"be used when creating EchoMail bundles or if `None`, raw/uncompressed\r\n"
"EchoMail packets will be sent to this node.\r\n"
"This setting may be managed by the node using NetMail/AreaFix requests.\r\n"
"\r\n"
"`Packet Type` is the type of outbound packet generated for this node.\r\n"
"Incoming packet types are automatically detected from among the list\r\n"
"of supported packet types (`2`, `2.2`, `2e`, and `2+`).\r\n"
"The default outbound packet type is `Type-2+`.\r\n"
"\r\n"
"`Packet Password` is an optional password that may be added to outbound\r\n"
"packets for this node. Incoming packets from this node must also have\r\n"
"the same password value if this password is configured (not blank).\r\n"
"Packet passwords are case insensitive.\r\n"
"This setting may be managed by the node using NetMail/AreaFix requests.\r\n"
"\r\n"
"`TIC File Password` is an optional password that may be configured here\r\n"
"(and in your `sbbsecho.ini` file) for use by `ticket.js` when creating\r\n"
"or authenticating `.TIC` files.\r\n"
"This setting may be managed by the node using NetMail/AreaFix requests.\r\n"
"\r\n"
"`AreaFix Password` is an optional password used to enable AreaFix\r\n"
"NetMail requests (remote Area Management) from this node.\r\n"
"AreaFix Passwords are case insensitive.\r\n"
"This setting may be managed by the node using NetMail/AreaFix requests.\r\n"
"\r\n"
"`AreaFix Keys` is a list of keys which enable AreaFix access to one or\r\n"
"more Additional EchoLists.\r\n"
"\r\n"
"`Status` is the default mode for sending mail to this node: `Normal`, `Hold`\r\n"
"(wait for pickup) or `Crash` (immediate).\r\n"
"\r\n"
"`Direct` determines whether to connect to this node directly (whenever\r\n"
"possible) when sending mail to this node.\r\n"
"\r\n"
"`Passive` is used to temporarily disable the packing and sending of\r\n"
"EchoMail for a node. The opposite of Passive is `Active`.\r\n"
"This setting may be managed by the node using NetMail/AreaFix requests.\r\n"
"\r\n"
"`Send Notify List` is used to flag nodes that you want notified via\r\n"
"NetMail of their current AreaFix settings whenever SBBSecho is run\r\n"
"with the '`G`' option.\r\n"
"\r\n"
"`Route To` is only used in Binkley-Style Outbound (BSO/FLO) operating\r\n"
"mode and is used to set the FidoNet address to route mail for this node.\r\n"
"\r\n"
"`Inbox Directory` is only used in BSO operating mode and is an optional\r\n"
"alternate directory to search for incoming files from this node (e.g.\r\n"
"used in combination with BinkD's ibox setting).\r\n"
"\r\n"
"`Outbox Directory` is only used in BSO operating mode and is an optional\r\n"
"alternate directory to place outbound files for this node (e.g. used\r\n"
"in combination with BinkD's obox setting).\r\n"
"~ Linked Node Settings ~\n"
"\n"
"`Address` is the FidoNet-style address in the Zone:Net/Node (3D) or\n"
" Zone:Net/Node.Point (4D) format. The wildcard word '`ALL`' may be used\n"
" in place of one of the fields to create a node configuration which\n"
" will apply to *all* nodes matching that address pattern.\n"
" e.g. '`1:ALL`' matches all nodes within FidoNet Zone 1.\n"
"\n"
"`Comment` is a note to yourself about this node. Setting this to the\n"
" user or sysop name corresponding with the configured node can be\n"
" a helpful reminder to yourself later.\n"
"\n"
"`Archive Type` is the name of an archive type corresponding with one of\n"
" your configured archive types or '`None`'. This archive type will\n"
" be used when creating EchoMail bundles or if `None`, raw/uncompressed\n"
" EchoMail packets will be sent to this node.\n"
" This setting may be managed by the node using AreaFix requests.\n"
"\n"
"`Packet Type` is the type of outbound packet generated for this node.\n"
" Incoming packet types are automatically detected from among the list\n"
" of supported packet types (`2`, `2.2`, `2e`, and `2+`).\n"
" The default outbound packet type is `2+`.\n"
"\n"
"`Packet Password` is an optional password that may be added to outbound\n"
" packets for this node. Incoming packet passwords are compared with\n"
" this password value. If this password is blank/empty and `Strict\n"
" Packet Passwords` are enabled, then incoming packets from this node\n"
" must also have no password. Packet passwords are case insensitive.\n"
" This setting may be managed by the node using AreaFix requests.\n"
"\n"
"`TIC File Password` is an optional password that may be configured here\n"
" (and in your `sbbsecho.ini` file) for use by `ticket.js` when creating\n"
" or authenticating `.TIC` files.\n"
" This setting may be managed by the node using AreaFix requests.\n"
"\n"
"`AreaFix Password` is an optional password used to enable AreaFix\n"
" NetMail requests (Remote Area Management) from this node.\n"
" AreaFix Passwords are case insensitive.\n"
" This setting may be managed by the node using AreaFix requests.\n"
"\n"
"`AreaFix Keys` is a list of keys which enable AreaFix access to one or\n"
" more additional EchoLists.\n"
"\n"
"`Status` is the default mode for sending mail to this node: `Normal`, `Hold`\n"
" (wait for pickup) or `Crash` (immediate).\n"
"\n"
"`Direct` determines whether to connect to this node directly (whenever\n"
" possible) when sending mail to this node.\n"
"\n"
"`Passive` is used to temporarily disable (pause) the packing and sending\n"
" of EchoMail for this node. The opposite of Passive is `Active`.\n"
" This setting may be managed by the node using AreaFix requests.\n"
"\n"
"`Send Notify List` is used to flag nodes that you want notified via\n"
" NetMail of their current AreaFix settings whenever SBBSecho is run\n"
" with the '`G`' option.\n"
"\n"
"`Uplink for Message Groups` is an optional list of Message Groups (short\n"
" names) for which this node is a hub/uplink for your system. This\n"
" setting is used in combination with the `Auto Add Sub-boards` feature\n"
" to auto-link hubs with the newly added areas in your Area File.\n"
"\n"
"`Route To` is only used in Binkley-Style Outbound (BSO/FLO) operating\n"
" mode and is used to set the FTN address to route mail for this node.\n"
"\n"
"`Inbox Directory` is only used in BSO operating mode and is an optional\n"
" alternate directory to search for incoming files from this node\n"
" (e.g. used in combination with BinkD's ibox setting).\n"
"\n"
"`Outbox Directory` is only used in BSO operating mode and is an optional\n"
" alternate directory to place outbound files for this node (e.g. used\n"
" in combination with BinkD's obox setting).\n"
;
j=0;
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Address"
......@@ -480,6 +610,8 @@ int main(int argc, char **argv)
,cfg.nodecfg[i].passive ? "Yes":"No");
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Send Notify List"
,cfg.nodecfg[i].send_notify ? "Yes" : "No");
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Uplink for Message Groups"
,strListCombine(cfg.nodecfg[i].grphub,str,sizeof(str),","));
if(cfg.flo_mailer) {
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","Route To"
,cfg.nodecfg[i].route.zone
......@@ -492,14 +624,14 @@ int main(int argc, char **argv)
opt[j][0]=0;
SAFEPRINTF(str, "Linked Node - %s"
,cfg.nodecfg[i].comment[0] ? cfg.nodecfg[i].comment : faddrtoa(&cfg.nodecfg[i].addr));
k=uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,60,&nodeop,0,str,opt);
k=uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,0,&nodeop,0,str,opt);
if(k==-1)
break;
switch(k) {
case 0:
uifc.helpbuf=
"~ Address ~\r\n\r\n"
"This is the FidoNet style address of this linked node.\r\n";
"~ Address ~\n\n"
"This is the FidoNet style address of this linked node.\n";
strcpy(str,faddrtoa(&cfg.nodecfg[i].addr));
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"Node Address (ALL wildcard allowed)",str
......@@ -508,9 +640,9 @@ int main(int argc, char **argv)
break;
case 1:
uifc.helpbuf=
"~ Comment ~\r\n\r\n"
"This is an optional comment for the node (e.g. the sysop's name).\r\n"
"This is used for informational purposes only.\r\n";
"~ Comment ~\n\n"
"This is an optional comment for the node (e.g. the sysop's name).\n"
"This is used for informational purposes only.\n";
uifc.input(WIN_MID|WIN_SAV,0,0
,"Comment"
,cfg.nodecfg[i].comment,sizeof(cfg.nodecfg[i].comment)-1
......@@ -518,9 +650,9 @@ int main(int argc, char **argv)
break;
case 2:
uifc.helpbuf=
"~ Archive Type ~\r\n\r\n"
"This is the archive type that will be used for compressing packets\r\n"
"into archive bundles for this node.\r\n";
"~ Archive Type ~\n\n"
"This is the archive type that will be used for compressing packets\n"
"into archive bundles for this node.\n";
int cur=cfg.arcdefs;
for(u=0;u<cfg.arcdefs;u++) {
if(cfg.nodecfg[i].archive == &cfg.arcdef[u])
......@@ -541,14 +673,14 @@ int main(int argc, char **argv)
break;
case 3:
uifc.helpbuf=
"~ Packet Type ~\r\n\r\n"
"This is the packet header type that will be used in mail packets\r\n"
"created for this node. SBBSecho defaults to creating `Type-2+` packets.\r\n"
"\r\n"
"`Type-2 ` packets are defined in FTS-0001.16 (Stone Age)\r\n"
"`Type-2e ` packets are defined in FSC-0039.04 (Sometimes called 2+)\r\n"
"`Type-2+ ` packets are defined in FSC-0048.02 (4D address support)\r\n"
"`Type-2.2` packets are defined in FSC-0045.01 (5D address support)\r\n"
"~ Packet Type ~\n\n"
"This is the packet header type that will be used in mail packets\n"
"created for this node. SBBSecho defaults to creating `Type-2+` packets.\n"
"\n"
"`Type-2 ` packets are defined in FTS-0001.16 (Stone Age)\n"
"`Type-2e ` packets are defined in FSC-0039.04 (Sometimes called 2+)\n"
"`Type-2+ ` packets are defined in FSC-0048.02 (4D address support)\n"
"`Type-2.2` packets are defined in FSC-0045.01 (5D address support)\n"
;
j=cfg.nodecfg[i].pkt_type;
k=uifc.list(WIN_RHT|WIN_SAV,0,0,0,&j,0,"Packet Type"
......@@ -560,9 +692,9 @@ int main(int argc, char **argv)
break;
case 4:
uifc.helpbuf=
"~ Packet Password ~\r\n\r\n"
"This is an optional password that SBBSecho will place into packets\r\n"
"destined for this node.\r\n";
"~ Packet Password ~\n\n"
"This is an optional password that SBBSecho will place into packets\n"
"destined for this node.\n";
uifc.input(WIN_MID|WIN_SAV,0,0
,"Packet Password (optional)"
,cfg.nodecfg[i].pktpwd,sizeof(cfg.nodecfg[i].pktpwd)-1
......@@ -570,9 +702,9 @@ int main(int argc, char **argv)
break;
case 5:
uifc.helpbuf=
"~ TIC File Password ~\r\n\r\n"
"This is an optional password that ticket.js will use for creating\r\n"
"and authenticating `.TIC` files to/from this node.\r\n";
"~ TIC File Password ~\n\n"
"This is an optional password that ticket.js will use for creating\n"
"and authenticating `.TIC` files to/from this node.\n";
uifc.input(WIN_MID|WIN_SAV,0,0
,"TIC File Password (optional)"
,cfg.nodecfg[i].ticpwd,sizeof(cfg.nodecfg[i].ticpwd)-1
......@@ -580,9 +712,9 @@ int main(int argc, char **argv)
break;
case 6:
uifc.helpbuf=
"~ AreaFix Password ~\r\n\r\n"
"This is the password that will be used by this node when doing remote\r\n"
"AreaManager / AreaFix functions.\r\n";
"~ AreaFix Password ~\n\n"
"This is the password that will be used by this node when doing remote\n"
"AreaManager / AreaFix functions.\n";
uifc.input(WIN_MID|WIN_SAV,0,0
,"AreaFix Password"
,cfg.nodecfg[i].password,sizeof(cfg.nodecfg[i].password)-1
......@@ -590,9 +722,9 @@ int main(int argc, char **argv)
break;
case 7:
uifc.helpbuf=
"~ AreaFix Keys ~\r\n\r\n"
"These are a named-keys to be given to this node allowing access to one or\r\n"
"more of the configured `Additional Echolists`\r\n";
"~ AreaFix Keys ~\n\n"
"These are a named-keys to be given to this node allowing access to one or\n"
"more of the configured `EchoLists`\n";
while(1) {
for(j=0; cfg.nodecfg[i].keys!=NULL && cfg.nodecfg[i].keys[j]!=NULL ;j++)
strcpy(opt[j],cfg.nodecfg[i].keys[j]);
......@@ -605,7 +737,7 @@ int main(int argc, char **argv)
if((k&MSK_ON)==MSK_INS) {
k&=MSK_OFF;
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"AreaFix Keys",str,SBBSECHO_MAX_KEY_LEN
,"AreaFix Key",str,SBBSECHO_MAX_KEY_LEN
,K_UPPER)<1)
continue;
strListInsert(&cfg.nodecfg[i].keys, str, k);
......@@ -629,8 +761,8 @@ int main(int argc, char **argv)
break;
case 8:
uifc.helpbuf=
"~ Mail Status ~\r\n\r\n"
"Set the mail status for this node: `Normal`, `Hold`, or `Crash`.\r\n";
"~ Mail Status ~\n\n"
"Set the mail status for this node: `Normal`, `Hold`, or `Crash`.\n";
j=cfg.nodecfg[i].status;
k=uifc.list(WIN_RHT|WIN_SAV,0,0,0,&j,0,"Mail Status"
,mailStatusStringList);
......@@ -667,13 +799,57 @@ int main(int argc, char **argv)
break;
case 12:
uifc.helpbuf=
"~ Route To ~\r\n\r\n"
"When using a BSO/FLO type mailer, this is the Fido address to route mail\r\n"
"for this node(s) to.\r\n"
"\r\n"
"This option is normally only used with wildcard type node entries\r\n"
"(e.g. `ALL`, or `1:ALL`, `2:ALL`, etc.) and is used to route non-direct\r\n"
"NetMail packets to your uplink node (hub).\r\n";
"~ Uplink for Message Groups ~\n\n"
"These are Message Group short names (as configured in SCFG) for which\n"
"this linked-node is your system's uplink (hub).\n"
"\n"
"Use of this setting allows your hub to be automatically linked with new\n"
"areas when new Sub-boards (within a listed group) are auto-added to the\n"
"Area File."
;
while(1) {
for(j=0; cfg.nodecfg[i].grphub!=NULL && cfg.nodecfg[i].grphub[j]!=NULL ;j++)
strcpy(opt[j],cfg.nodecfg[i].grphub[j]);
opt[j][0]=0;
k=uifc.list(WIN_SAV|WIN_INS|WIN_DEL|WIN_ACT|
WIN_XTR|WIN_INSACT|WIN_DELACT|WIN_RHT
,0,0,0,&k,0,"Uplink for Message Groups",opt);
if(k==-1)
break;
if((k&MSK_ON)==MSK_INS) {
k&=MSK_OFF;
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"Message Group (short name)",str,LEN_GSNAME
,/* kmode: */0) < 1)
continue;
strListInsert(&cfg.nodecfg[i].grphub, str, k);
uifc.changes=TRUE;
continue;
}
if((k&MSK_ON)==MSK_DEL) {
k&=MSK_OFF;
strListRemove(&cfg.nodecfg[i].grphub, k);
uifc.changes=TRUE;
continue;
}
SAFECOPY(str,cfg.nodecfg[i].grphub[k]);
uifc.input(WIN_MID|WIN_SAV,0,0,"Message Group (short name)"
,str,LEN_GSNAME,K_EDIT|K_UPPER);
strListReplace(cfg.nodecfg[i].grphub, k, str);
uifc.changes=TRUE;
continue;
}
break;
case 13:
uifc.helpbuf=
"~ Route To ~\n\n"
"When using a BSO/FLO type mailer, this is the Fido address to route mail\n"
"for this node(s) to.\n"
"\n"
"This option is normally only used with wildcard type node entries\n"
"(e.g. `ALL`, or `1:ALL`, `2:ALL`, etc.) and is used to route non-direct\n"
"NetMail packets to your uplink node (hub).\n";
strcpy(str,faddrtoa(&cfg.nodecfg[i].route));
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"Node Address to Route To",str
......@@ -685,12 +861,12 @@ int main(int argc, char **argv)
uifc.changes=TRUE;
}
break;
case 13:
case 14:
uifc.input(WIN_MID|WIN_SAV,0,0,"Inbound FileBox Directory"
,cfg.nodecfg[i].inbox, sizeof(cfg.nodecfg[i].inbox)-1
,K_EDIT);
break;
case 14:
case 15:
uifc.input(WIN_MID|WIN_SAV,0,0,"Outbound FileBox Directory"
,cfg.nodecfg[i].outbox, sizeof(cfg.nodecfg[i].outbox)-1
,K_EDIT);
......@@ -700,216 +876,250 @@ int main(int argc, char **argv)
}
break;
case 6: /* Paths and Filenames... */
case 5: /* Paths and Filenames... */
j=0;
while(1) {
i=0;
snprintf(opt[i++],MAX_OPLN-1,"%-30.30s %s","Non-secure Inbound Directory"
,cfg.inbound);
,cfg.inbound[0] ? cfg.inbound : DEFAULT_INBOUND);
snprintf(opt[i++],MAX_OPLN-1,"%-30.30s %s","Secure Inbound Directory"
,cfg.secure_inbound[0] ? cfg.secure_inbound : "<None>");
,cfg.secure_inbound[0] ? cfg.secure_inbound : DEFAULT_SECURE_INBOUND);
snprintf(opt[i++],MAX_OPLN-1,"%-30.30s %s","Outbound Directory"
,cfg.outbound);
,cfg.outbound[0] ? cfg.outbound : DEFAULT_OUTBOUND);
snprintf(opt[i++],MAX_OPLN-1,"%-30.30s %s","Area File"
,cfg.areafile);
,cfg.areafile[0] ? cfg.areafile : DEFAULT_AREA_FILE);
snprintf(opt[i++],MAX_OPLN-1,"%-30.30s %s","Bad Area File"
,cfg.badareafile);
,cfg.badareafile[0] ? cfg.badareafile : DEFAULT_BAD_AREA_FILE);
snprintf(opt[i++],MAX_OPLN-1,"%-30.30s %s","Log File"
,cfg.logfile[0] ? cfg.logfile
: "SCFG->data/sbbsecho.log");
,cfg.logfile[0] ? cfg.logfile : DEFAULT_LOG_FILE);
snprintf(opt[i++],MAX_OPLN-1,"%-30.30s %s","Echo Statistics File"
,cfg.echostats[0] ? cfg.echostats : DEFAULT_ECHOSTATS_FILE);
snprintf(opt[i++],MAX_OPLN-1,"%-30.30s %s","Temporary File Directory"
,cfg.temp_dir[0] ? cfg.temp_dir
: "../temp/sbbsecho");
,cfg.temp_dir[0] ? cfg.temp_dir : DEFAULT_TEMP_DIR);
snprintf(opt[i++],MAX_OPLN-1,"%-30.30s %s","Outgoing Semaphore File"
,cfg.outgoing_sem);
opt[i][0]=0;
uifc.helpbuf=
"~ Paths and Filenames ~\r\n\r\n"
"From this menu you can configure the paths that SBBSecho will use\r\n"
"when importing, exporting and logging.\r\n";
j=uifc.list(WIN_MID|WIN_ACT,0,0,60,&j,0
"~ Paths and Filenames ~\n\n"
"From this menu you can configure the paths and filenames that SBBSecho\n"
"will use during its operation (e.g. importing and exporting messages).\n";
j=uifc.list(WIN_BOT|WIN_L2R|WIN_ACT|WIN_SAV,0,0,0,&path_opt,0
,"Paths and Filenames",opt);
if(j==-1)
break;
switch(j) {
case 0:
uifc.helpbuf=
"~ Non-secure Inbound Directory ~\r\n\r\n"
"This is the path where your FTN mailer stores, and where SBBSecho will\r\n"
"look for, incoming files (potentially including message bundles and\r\n"
"packets) from unauthenticated (non-secure) mailer sessions."
"~ Non-secure Inbound Directory ~\n\n"
"This is the path where your FTN mailer stores, and where SBBSecho will\n"
"look for, incoming files (potentially including message bundles and\n"
"packets) from unauthenticated (non-secure) mailer sessions.\n"
"\n"
"Default value is `" DEFAULT_INBOUND "`."
;
uifc.input(WIN_MID|WIN_SAV,0,0,"Non-secure Inbound Directory"
uifc.input(WIN_L2R|WIN_SAV,0,0,"Non-secure Inbound Directory"
,cfg.inbound,sizeof(cfg.inbound)-1
,K_EDIT);
break;
case 1:
uifc.helpbuf=
"~ Secure Inbound Directory ~\r\n\r\n"
"This is the path where your FTN mailer stores, and where SBBSecho will\r\n"
"look for, incoming message bundles and packets for `Secure` (password\r\n"
"protected) sessions.";
uifc.input(WIN_MID|WIN_SAV,0,0,"Secure Inbound Directory"
"~ Secure Inbound Directory ~\n\n"
"This is the path where your FTN mailer stores, and where SBBSecho will\n"
"look for, incoming message bundles and packets for `Secure` (password\n"
"protected) sessions.\n"
"\n"
"Default value is `" DEFAULT_SECURE_INBOUND "`."
;
uifc.input(WIN_L2R|WIN_SAV,0,0,"Secure Inbound Directory"
,cfg.secure_inbound,sizeof(cfg.secure_inbound)-1
,K_EDIT);
break;
case 2:
uifc.helpbuf=
"~ Outbound Directory ~\r\n\r\n"
"This is the path where your FTN mailer will look for, and where SBBSecho\r\n"
"will place, outgoing message bundles and packets.\r\n"
"\r\n"
"In Binkley-Style Outbound mode, this serves as the base directory\r\n"
"~ Outbound Directory ~\n\n"
"This is the path where your FTN mailer will look for, and where SBBSecho\n"
"will place, outgoing message bundles and packets.\n"
"\n"
"In Binkley-Style Outbound mode, this serves as the base directory\n"
"name for special foreign zone and point destination nodes as well."
"\n"
"Default value is `" DEFAULT_OUTBOUND "`."
;
uifc.input(WIN_MID|WIN_SAV,0,0,"Outbound Directory"
uifc.input(WIN_L2R|WIN_SAV,0,0,"Outbound Directory"
,cfg.outbound,sizeof(cfg.outbound)-1
,K_EDIT);
break;
case 3:
uifc.helpbuf=
"~ Area File ~\r\n\r\n"
"This is the path of the file SBBSecho will use as your primary\r\n"
"list of FidoNet-style message areas (default is `data/areas.bbs`).\r\n"
"\r\n"
"Each line in the file defines an FTN message area (echo) of the format:\r\n"
"\r\n"
" <`code`> <`tag`> [[`link`] [`link`] [...]]\r\n"
"\r\n"
"Each field is separated by one or more white-space characters:\r\n"
"\r\n"
" `<code>` is the Synchronet `internal code` for the local sub-board\r\n"
" `<tag>` is the network's agreed-upon `echo tag` for the message area\r\n"
" `[link]` is an `FTN address` to send and receive messages for this area\r\n"
" (there may be many linked nodes for each area)\r\n"
" (often your FTN hub may be the only linked node)\r\n"
"\r\n"
"Example Area Line:\r\n"
"\r\n"
" `FIDO_BBS_CARN BBS_CARNIVAL 1:218/700`\r\n"
"\r\n"
"Notes:\r\n"
"\r\n"
" `*` Only the `<code>` and `<tag>` fields are required\r\n"
" `*` The `<code>` and `<tag>` fields are case in-sensitive\r\n"
" `*` The `[link]` fields must be 2D, 3D, or 4D FidoNet-style node addresses\r\n"
" `*` The '`<`' and '`>`', '`[`' and '`]`' characters are not part of the syntax\r\n"
" `*` Lines beginning with a semicolon (`;`) are ignored (i.e. comments)\r\n"
" `*` Leading white-space characters are ignored\r\n"
" `*` Blank lines are ignored\r\n"
" `*` This file may be import/exported to/from your `Message Areas` in `SCFG`\r\n"
" `*` This file may be remotely modified by authorized nodes using `AreaFix`\r\n"
"~ Area File ~\n\n"
"This is the path of the file SBBSecho will use as your primary\n"
"list of FidoNet-style message areas (default is `data/areas.bbs`).\n"
"\n"
"Each line in the file defines an FTN message area (echo) of the format:\n"
"\n"
" <`code`> <`tag`> [[`link`] [`link`] [...]]\n"
"\n"
"Each field is separated by one or more white-space characters:\n"
"\n"
" `<code>` is the Synchronet `internal code` for the local sub-board\n"
" `<tag>` is the network's agreed-upon `echo tag` for the message area\n"
" `[link]` is an `FTN address` to send and receive messages for this area\n"
" (there may be many linked nodes for each area)\n"
" (often your FTN uplink/hub may be the only linked node)\n"
"\n"
"Example Area Line:\n"
"\n"
" `FIDO_BBS_CARN BBS_CARNIVAL 1:218/700`\n"
"\n"
"Notes:\n"
"\n"
" `*` Only the `<code>` and `<tag>` fields are required\n"
" `*` The `<code>` and `<tag>` fields are case in-sensitive\n"
" `*` The `[link]` fields must be 2D, 3D, or 4D FidoNet-style node addresses\n"
" `*` The '`<`' and '`>`', '`[`' and '`]`' characters are not part of the syntax\n"
" `*` Lines beginning with a semicolon (`;`) are ignored (i.e. comments)\n"
" `*` Leading white-space characters are ignored\n"
" `*` Blank lines are ignored\n"
" `*` A `<tag>` value of `*` indicates a `bad echo` (unknown) area\n"
" `*` A `<code>` value of `P` indicates a pass-through message area\n"
" `*` This file may be import/exported to/from your `Message Areas` in `SCFG`\n"
" `*` This file may be remotely modified by authorized nodes using `AreaFix`\n"
"\n"
"Default value is `" DEFAULT_AREA_FILE "`."
;
uifc.input(WIN_MID|WIN_SAV,0,0,"Area File"
uifc.input(WIN_L2R|WIN_SAV,0,0,"Area File"
,cfg.areafile,sizeof(cfg.areafile)-1
,K_EDIT);
break;
case 4:
uifc.helpbuf=
"~ Bad Area File ~\r\n\r\n"
"This is the path of the file SBBSecho will use to record the names\r\n"
"(echo tags) and descriptions of FTN message areas (echoes) that your\r\n"
"system has received EchoMail for, but does not carry locally. The\r\n"
"default path/filename is `data/badareas.lst`.\r\n"
"\r\n"
"Notes:\r\n"
"\r\n"
" `*` The descriptions of the areas will only be included if the\r\n"
" corresponding echo tags can be located in one of your configured\r\n"
" `Additional EchoLists`.\r\n"
"\r\n"
" `*` The format of the file is the same as `BACKBONE.NA` and suitable for\r\n"
" importing into a Synchronet Message Group using `SCFG`.\r\n"
"\r\n"
" `*` SBBSecho will automatically sort and maintain this list, removing\r\n"
" areas if they are added to your configuration (`SCFG->Message Areas`\r\n"
" and `Area File`).\r\n"
"~ Bad Area File ~\n\n"
"This is the path of the file SBBSecho will use to record the names\n"
"(echo tags) and descriptions of FTN message areas (echoes) that your\n"
"system has received EchoMail for, but does not carry locally. The\n"
"default path/filename is `" DEFAULT_BAD_AREA_FILE "`.\n"
"\n"
"Notes:\n"
"\n"
" `*` The descriptions of the areas will only be included if the\n"
" corresponding echo tags can be located in one of your configured\n"
" `EchoLists`.\n"
"\n"
" `*` The format of the file is the same as `BACKBONE.NA` and suitable for\n"
" importing into a Synchronet Message Group using `SCFG`.\n"
"\n"
" `*` SBBSecho will automatically sort and maintain this list, removing\n"
" areas if they are added to your configuration (`SCFG->Message Areas`)\n"
" and your `Area File`.\n"
;
uifc.input(WIN_MID|WIN_SAV,0,0,"Bad Area File"
uifc.input(WIN_L2R|WIN_SAV,0,0,"Bad Area File"
,cfg.badareafile,sizeof(cfg.badareafile)-1
,K_EDIT);
break;
case 5:
uifc.helpbuf=
"~ Log File ~\r\n\r\n"
"This is the path of the file SBBSecho will use to log information each time\r\n"
"it is run (default is `data/sbbsecho.log`)."
"~ Log File ~\n\n"
"This is the path of the file SBBSecho will use to log information each\n"
"time it is run (default is `" DEFAULT_LOG_FILE "`)."
;
uifc.input(WIN_MID|WIN_SAV,0,0,"Log File"
uifc.input(WIN_L2R|WIN_SAV,0,0,"Log File"
,cfg.logfile,sizeof(cfg.logfile)-1
,K_EDIT);
break;
case 6:
uifc.helpbuf=
"~ Temporary File Directory ~\r\n\r\n"
"This is the directory where SBBSecho will store temporary files that\r\n"
"it creates and uses during its run-time.\r\n"
"(default is `../temp/sbbsecho`)."
"~ EchoStats File ~\n\n"
"This is the path of the file SBBSecho will use to track statistics for\n"
"EchoMail message areas (default is `" DEFAULT_ECHOSTATS_FILE "`)."
;
uifc.input(WIN_MID|WIN_SAV,0,0,"Temp Dir"
uifc.input(WIN_L2R|WIN_SAV,0,0,"EchoStats File"
,cfg.echostats,sizeof(cfg.echostats)-1
,K_EDIT);
break;
case 7:
uifc.helpbuf=
"~ Temporary File Directory ~\n\n"
"This is the directory where SBBSecho will store temporary files that\n"
"it creates and uses during its run-time (default is `" DEFAULT_TEMP_DIR "`)."
;
uifc.input(WIN_L2R|WIN_SAV,0,0,"Temp Dir"
,cfg.temp_dir,sizeof(cfg.temp_dir)-1
,K_EDIT);
break;
case 8:
uifc.helpbuf=
"~ Outgoing Semaphore File ~\n\n"
"This is an optional file to create/touch whenever there are new outbound\n"
"files created or updated by SBBSecho."
;
uifc.input(WIN_L2R|WIN_SAV,0,0,"Outgoing Sem File"
,cfg.outgoing_sem,sizeof(cfg.outgoing_sem)-1
,K_EDIT);
break;
}
}
break;
case 4: /* NetMail Settings */
case 3: /* NetMail Settings */
j=0;
while(1) {
uifc.helpbuf=
"~ NetMail Settings ~\r\n"
"\r\n"
"`Sysop Aliases` is a comma-separated list of names by which the sysop\r\n"
" (user #1) may receive NetMail messages, in addition to the alias\r\n"
" and real name associated with their BBS user account.\r\n"
" This setting defaults to just '`SYSOP`'.\r\n"
"\r\n"
"`Default Recipient` is the name of the user account you wish to receive\r\n"
" inbound NetMail messages that have been addressed to an unrecognized\r\n"
" user name or alias.\r\n"
"\r\n"
"`Fuzzy Zone Operation` when set to `Yes`, if SBBSecho receives an inbound\r\n"
" netmail with no international zone information, it will compare the\r\n"
" net/node of the destination to the net/node information in your AKAs\r\n"
" and assume the zone of a matching AKA.\r\n"
" This setting defaults to `No`.\r\n"
"\r\n"
"`Kill/Ignore Empty NetMail Messages` will instruct SBBSecho to simply\r\n"
" discard (not import or export) NetMail messages without any body.\r\n"
" This setting defaults to `Yes`.\r\n"
"\r\n"
"`Delete Processed NetMail Messages` will instruct SBBSecho to delete\r\n"
" NetMail messages/files after they have been sent or imported.\r\n"
" When set to `No`, SBBSecho will mark them as Sent or Received instead.\r\n"
" This setting defaults to `Yes`.\r\n"
"\r\n"
"`Ignore NetMail Destination Address` will instruct SBBSecho to treat\r\n"
" all NetMail as though it is destined for one of your systems's FTN\r\n"
" addresses (AKAs) and potentially import it.\r\n"
" This setting defaults to `No`.\r\n"
"\r\n"
"`Ignore Netmail 'Sent' Attribute` will instruct SBBSecho to export\r\n"
" NetMail messages even when their 'Sent' attribute flag is set.\r\n"
" This setting `should not` be set to `Yes` when `Delete NetMail` is\r\n"
" disabled.\r\n"
" This setting defaults to `No`.\r\n"
"\r\n"
"`Ignore Netmail 'Received' Attribute` will instruct SBBSecho to import\r\n"
" NetMail messages even when their 'Received' attribute flag is set.\r\n"
" This setting defaults to `No`.\r\n"
"\r\n"
"`Ignore NetMail 'Local' Attribute` will instruct SBBSecho to import\r\n"
" NetMail messages even when their 'Local' attribute flag is set.\r\n"
" This setting defaults to `No`.\r\n"
"\r\n"
"`Maximum Age of Imported NetMail` allows you to optionally set an age\r\n"
" limit (in days) of NetMail messages that may be imported.\r\n"
" This setting defaults to `None` (no maximum age).\r\n"
"~ NetMail Settings ~\n"
"\n"
"`Sysop Aliases` is a comma-separated list of names by which the sysop\n"
" (user #1) may receive NetMail messages, in addition to the alias\n"
" and real name associated with their BBS user account.\n"
" This setting defaults to just '`SYSOP`'.\n"
"\n"
"`Default Recipient` is the name of the user account you wish to receive\n"
" inbound NetMail messages that have been addressed to an unrecognized\n"
" user name or alias.\n"
"\n"
"`Fuzzy Zone Operation` when set to `Yes`, if SBBSecho receives an inbound\n"
" netmail with no international zone information, it will compare the\n"
" net/node of the destination to the net/node information in your AKAs\n"
" and assume the zone of a matching AKA.\n"
" This setting defaults to `No`.\n"
"\n"
"`Kill/Ignore Empty NetMail Messages` will instruct SBBSecho to simply\n"
" discard (not import or export) NetMail messages without any body.\n"
" This setting defaults to `Yes`.\n"
"\n"
"`Delete Processed NetMail Messages` will instruct SBBSecho to delete\n"
" NetMail messages/files after they have been sent or imported.\n"
" When set to `No`, SBBSecho will mark them as Sent or Received instead.\n"
" This setting defaults to `Yes`.\n"
"\n"
"`Ignore NetMail Destination Address` will instruct SBBSecho to treat\n"
" all NetMail as though it is destined for one of your systems's FTN\n"
" addresses (AKAs) and potentially import it.\n"
" This setting defaults to `No`.\n"
"\n"
"`Ignore Netmail 'Sent' Attribute` will instruct SBBSecho to export\n"
" NetMail messages even when their 'Sent' attribute flag is set.\n"
" This setting `should not` be set to `Yes` when `Delete NetMail` is\n"
" disabled.\n"
" This setting defaults to `No`.\n"
"\n"
"`Ignore Netmail 'Received' Attribute` will instruct SBBSecho to import\n"
" NetMail messages even when their 'Received' attribute flag is set.\n"
" This setting defaults to `No`.\n"
"\n"
"`Ignore NetMail 'Local' Attribute` will instruct SBBSecho to import\n"
" NetMail messages even when their 'Local' attribute flag is set.\n"
" This setting defaults to `No`.\n"
"\n"
"`Maximum Age of Imported NetMail` allows you to optionally set an age\n"
" limit of NetMail messages that may be imported.\n"
" This setting defaults to `None` (no maximum age).\n"
;
i=0;
strListCombine(cfg.sysop_alias_list, sysop_aliases, sizeof(sysop_aliases)-1, ",");
......@@ -931,22 +1141,22 @@ int main(int argc, char **argv)
snprintf(opt[i++],MAX_OPLN-1,"%-40.40s%-3.3s","Ignore NetMail 'Local' Attribute"
,cfg.ignore_netmail_local_attr ? "Yes" : "No");
if(cfg.max_netmail_age)
sprintf(str,"%1.0f days", cfg.max_netmail_age / (24.0*60.0*60.0));
duration_to_vstr(cfg.max_netmail_age, str, sizeof(str));
else
strcpy(str, "None");
snprintf(opt[i++],MAX_OPLN-1,"%-40.40s%s","Maximum Age of Imported NetMail" , str);
opt[i][0]=0;
j=uifc.list(WIN_ACT,0,0,60,&j,0,"NetMail Settings",opt);
j=uifc.list(WIN_ACT|WIN_SAV,0,0,0,&netmail_opt,0,"NetMail Settings",opt);
if(j==-1)
break;
switch(j) {
case 0:
uifc.helpbuf=
"~ Sysop Aliases ~\r\n\r\n"
"This is a comma-separated list of additional `To` names that the sysop\r\n"
"(user #1) can receive netmail by. When specifying multiple aliases,\r\n"
"they must be separated by a single comma and no extra white-space\r\n"
"(e.g. \"SYSOP,COORDINATOR\"). The default value is just `SYSOP`.\r\n";
"~ Sysop Aliases ~\n\n"
"This is a comma-separated list of additional `To` names that the sysop\n"
"(user #1) can receive netmail by. When specifying multiple aliases,\n"
"they must be separated by a single comma and no extra white-space\n"
"(e.g. \"SYSOP,COORDINATOR\"). The default value is just `SYSOP`.\n";
if(uifc.input(WIN_MID|WIN_BOT|WIN_SAV,0,0,"Sysop Aliases (comma separated)"
,sysop_aliases
,sizeof(sysop_aliases)-1,K_EDIT|K_UPPER) >= 0) {
......@@ -1017,82 +1227,98 @@ int main(int argc, char **argv)
break;
case 9:
uifc.helpbuf=
"~ Maximum Age of Imported NetMail ~\r\n\r\n"
"Maximum age (in days) of NetMail that may be imported. The age is based\r\n"
"on the date supplied in the message header and may be incorrect in some\r\n"
"conditions (e.g. erroneous software or incorrect system date).\r\n"
"~ Maximum Age of Imported NetMail ~\n\n"
"Maximum age of NetMail that may be imported. The age is based\n"
"on the date supplied in the message header and may be incorrect in some\n"
"conditions (e.g. erroneous software or incorrect system date).\n"
"Set this value to `0` to disable this feature (no maximum age imposed)."
;
if(cfg.max_netmail_age)
sprintf(str,"%1.0f", cfg.max_netmail_age / (24.0*60.0*60.0));
duration_to_vstr(cfg.max_netmail_age, str, sizeof(str));
else
strcpy(str, "None");
if(uifc.input(WIN_MID|WIN_BOT|WIN_SAV,0,0,"Maximum NetMail Age (in Days)"
,str, 5, K_EDIT) >= 0)
cfg.max_netmail_age = (long) (strtod(str, NULL) * (24.0*60.0*60.0));
if(uifc.input(WIN_MID|WIN_BOT|WIN_SAV,0,0,"Maximum NetMail Age"
,str, 10, K_EDIT) >= 0)
cfg.max_netmail_age = (ulong)parse_duration(str);
break;
}
}
break;
case 5: /* EchoMail Settings */
case 4: /* EchoMail Settings */
j=0;
while(1) {
uifc.helpbuf=
"~ EchoMail Settings ~\r\n"
"\r\n"
"`Area Manager` is the BBS user name or alias to notify (via email) of\r\n"
" AreaFix activities and errors. This setting defaults to `SYSOP`.\r\n"
"\r\n"
"`Maximum Packet Size` is the largest packet file size that SBBSecho will\r\n"
" normally create (in bytes).\r\n"
" This settings defaults to `250K` (250 Kilobytes, or 256,000 bytes).\r\n"
"\r\n"
"`Maximum Bundle Size` is the largest bundle file size that SBBSecho will\r\n"
" normally create (in bytes).\r\n"
" This settings defaults to `250K` (250 Kilobytes, or 256,000 bytes).\r\n"
"\r\n"
"`Secure Operation` tells SBBSecho to check the Area File (e.g. areas.bbs)\r\n"
" to insure that the packet origin (FTN address) of EchoMail messages\r\n"
" is already linked to the EchoMail area where the message was posted.\r\n"
" This setting defaults to `No`.\r\n"
"\r\n"
"`Notify Users of Received EchoMail` tells SBBSecho to send telegrams\r\n"
" (short messages) to BBS users when EchoMail addressed to their name\r\n"
" or alias has been imported into a message base that the user has\r\n"
" access to read.\r\n"
"\r\n"
"`Convert Existing Tear Lines` tells SBBSecho to convert any tear lines\r\n"
" (`---`) existing in the message text to `===`.\r\n"
" This setting defaults to `No`.\r\n"
"\r\n"
"`Allow Nodes to Add Areas from Area File` when set to `Yes` allows linked\r\n"
" nodes to add areas listed in your Area File (e.g. `areas.bbs`).\r\n"
" This setting defaults to `Yes`.\r\n"
"\r\n"
"`Strip Line Feeds From Outgoing Messages` when set to `Yes` instructs\r\n"
" SBBSecho to remove any line-feed (ASCII 10) characters from the body\r\n"
" text of messages being exported to FidoNet EchoMail.\r\n"
" This setting defaults to `No`.\r\n"
"\r\n"
"`Circular Path Detection` when `Enabled` will cause SBBSecho, during\r\n"
" EchoMail import, to check the PATH kludge lines for any of the\r\n"
" system's AKAs and if found (indicating a message loop), not import\r\n"
" the message.\r\n"
"\r\n"
"`Outbound Bundle Attachments` may be either `Deleted` (killed) or `Truncated`\r\n"
" (changed to 0-bytes in length) after being sent by your mailer.\r\n"
"\r\n"
"`Zone Blind SEEN-BY and PATH Lines` when `Enabled` will cause SBBSecho\r\n"
" to assume that node numbers are not duplicated across zones and\r\n"
" that a net/node combination in either of these Kludge lines should\r\n"
" be used to identify a specific node regardless of which zone that\r\n"
" node is located (thus breaking the rules of FidoNet 3D addressing).\r\n"
"\r\n"
"`Maximum Age of Imported EchoMail` allows you to optionally set an age\r\n"
" limit (in days) of EchoMail messages that may be imported.\r\n"
" This setting defaults to `60` (60 days).\r\n"
"~ EchoMail Settings ~\n"
"\n"
"`Area Manager` is the BBS user name or alias to notify (via email) of\n"
" AreaFix activities and errors. This setting defaults to `SYSOP`.\n"
"\n"
"`Maximum Packet Size` is the largest packet file size that SBBSecho will\n"
" normally create (in bytes).\n"
" This settings defaults to `250K` (250 Kilobytes, or 256,000 bytes).\n"
"\n"
"`Maximum Bundle Size` is the largest bundle file size that SBBSecho will\n"
" normally create (in bytes).\n"
" This settings defaults to `250K` (250 Kilobytes, or 256,000 bytes).\n"
"\n"
"`Secure Operation` tells SBBSecho to check the Area File (e.g. areas.bbs)\n"
" to insure that the packet origin (FTN address) of EchoMail messages\n"
" is already linked to the EchoMail area where the message was posted.\n"
" This setting defaults to `No`.\n"
"\n"
"`Notify Users of Received EchoMail` tells SBBSecho to send telegrams\n"
" (short messages) to BBS users when EchoMail addressed to their name\n"
" or alias has been imported into a message base that the user has\n"
" access to read.\n"
"\n"
"`Convert Existing Tear Lines` tells SBBSecho to convert any tear lines\n"
" (`---`) existing in the message text to `===`.\n"
" This setting defaults to `No`.\n"
"\n"
"`Strip Line Feeds From Outgoing Messages` when set to `Yes` instructs\n"
" SBBSecho to remove any line-feed (ASCII 10) characters from the body\n"
" text of messages being exported to FidoNet EchoMail.\n"
" This setting defaults to `No`.\n"
"\n"
"`Automatically Add New Subs to Area File`, when set to `Yes`, enables\n"
" SBBSecho to detect newly added Sub-boards in any Message Groups that\n"
" are listed with a `Linked Node` as their hub/uplink and add those\n"
" Sub-boards as new areas in your Area File.\n"
"\n"
"`Allow Nodes to Add Areas from Area File` when set to `Yes` allows linked\n"
" nodes to add areas listed in your Area File (e.g. `areas.bbs`).\n"
" When set to `No`, only areas found in one or more `EchoLists` may be\n"
" added via AreaFix, provided the linked node has access.\n"
" This setting defaults to `Yes`.\n"
"\n"
"`Maximum Backups to Maintain of Area File` defines the number of backup\n"
" versions SBBSecho will maintain of your Area File (e.g. `areas.bbs`).\n"
"\n"
"`Circular Path Detection` when `Enabled` will cause SBBSecho, during\n"
" EchoMail import, to check the PATH kludge lines for any of the\n"
" system's AKAs and if found (indicating a message loop), not import\n"
" the message.\n"
"\n"
"`Relay Filtered Messages` controls whether or not incoming messages that\n"
" have been filtered (e.g. due to maximum message age restrictions)\n"
" are to be forwarded to downlinks.\n"
"\n"
"`Outbound Bundle Attachments` may be either `Deleted` (killed) or `Truncated`\n"
" (changed to 0-bytes in length) after being sent by your mailer.\n"
" This only controls the bundle prefix that is written to the FLO\n"
" files (`#` for truncate, `^` for delete).\n"
"\n"
"`Zone Blind SEEN-BY and PATH Lines` when `Enabled` will cause SBBSecho\n"
" to assume that node numbers are not duplicated across zones and\n"
" that a net/node combination in either of these Kludge lines should\n"
" be used to identify a specific node regardless of which zone that\n"
" node is located (thus breaking the rules of FidoNet 3D addressing).\n"
"\n"
"`Maximum Age of Imported EchoMail` allows you to optionally set an age\n"
" limit of EchoMail messages that may be imported.\n"
" This setting defaults to `60 days`.\n"
;
i=0;
......@@ -1107,12 +1333,18 @@ int main(int argc, char **argv)
,cfg.echomail_notify ? "Yes":"No");
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%-3.3s","Convert Existing Tear Lines"
,cfg.convert_tear ? "Yes":"No");
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%-3.3s","Allow Nodes to Add Areas "
"from Area File",cfg.add_from_echolists_only ?"No":"Yes");
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%-3.3s","Strip Line Feeds "
"from Outgoing Messages",cfg.strip_lf ? "Yes":"No");
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%-3.3s","Automatically Add New Subs "
"to Area File",cfg.auto_add_subs ? "Yes":"No");
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%-3.3s","Allow Nodes to Add Areas "
"from Area File",cfg.add_from_echolists_only ? "No":"Yes");
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%u","Maximum Backups to Maintain of Area File"
,cfg.areafile_backups);
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%s","Circular Path Detection"
,cfg.check_path ? "Enabled" : "Disabled");
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%s","Relay Filtered Messages"
,cfg.relay_filtered_msgs ? "Yes" : "No");
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%s","Outbound Bundle Attachments"
,cfg.trunc_bundles ? "Truncate" : "Delete");
if(cfg.zone_blind)
......@@ -1121,19 +1353,19 @@ int main(int argc, char **argv)
strcpy(str,"Disabled");
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%s","Zone Blind SEEN-BY and PATH Lines", str);
if(cfg.max_echomail_age)
sprintf(str,"%1.0f days", ((float)cfg.max_echomail_age) / (24.0*60.0*60.0));
duration_to_vstr(cfg.max_echomail_age, str, sizeof(str));
else
strcpy(str, "None");
snprintf(opt[i++],MAX_OPLN-1,"%-45.45s%s","Maximum Age of Imported EchoMail", str);
opt[i][0]=0;
j=uifc.list(WIN_ACT|WIN_RHT|WIN_BOT,0,0,64,&j,0,"EchoMail Settings",opt);
j=uifc.list(WIN_ACT|WIN_MID|WIN_SAV,0,0,0,&echomail_opt,0,"EchoMail Settings",opt);
if(j==-1)
break;
switch(j) {
case 0:
uifc.helpbuf=
"~ Area Manager ~\r\n\r\n"
"User to notify of AreaFix activity and errors.\r\n";
"~ Area Manager ~\n\n"
"User to notify of AreaFix activity and errors.\n";
uifc.input(WIN_MID|WIN_BOT|WIN_SAV,0,0,"Area Manager (user name or alias)"
,cfg.areamgr
,LEN_ALIAS,K_EDIT);
......@@ -1141,9 +1373,9 @@ int main(int argc, char **argv)
case 1:
uifc.helpbuf=
"~ Maximum Packet Size ~\r\n\r\n"
"This is the maximum file size that SBBSecho will create when placing\r\n"
"outgoing messages into packets. The default max size is 250 Kilobytes.\r\n";
"~ Maximum Packet Size ~\n\n"
"This is the maximum file size that SBBSecho will create when placing\n"
"outgoing messages into packets. The default max size is 250 Kilobytes.\n";
sprintf(str,"%lu",cfg.maxpktsize);
uifc.input(WIN_MID|WIN_BOT|WIN_SAV,0,0,"Maximum Packet Size (in Bytes)",str
,9,K_EDIT|K_NUMBER);
......@@ -1152,9 +1384,9 @@ int main(int argc, char **argv)
case 2:
uifc.helpbuf=
"~ Maximum Bundle Size ~\r\n\r\n"
"This is the maximum file size that SBBSecho will create when placing\r\n"
"outgoing packets into bundles. The default max size is 250 Kilobytes.\r\n";
"~ Maximum Bundle Size ~\n\n"
"This is the maximum file size that SBBSecho will create when placing\n"
"outgoing packets into bundles. The default max size is 250 Kilobytes.\n";
sprintf(str,"%lu",cfg.maxbdlsize);
uifc.input(WIN_MID|WIN_BOT|WIN_SAV,0,0,"Maximum Bundle Size (in Bytes)",str
,9,K_EDIT|K_NUMBER);
......@@ -1185,14 +1417,6 @@ int main(int argc, char **argv)
}
break;
case 6:
k = cfg.add_from_echolists_only;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Allow Add from Area File",uifcYesNoOpts)) {
case 0: cfg.add_from_echolists_only = false; break;
case 1: cfg.add_from_echolists_only = true; break;
}
break;
case 7:
k = !cfg.strip_lf;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Strip Line Feeds",uifcYesNoOpts)) {
......@@ -1200,7 +1424,29 @@ int main(int argc, char **argv)
case 1: cfg.strip_lf = false; break;
}
break;
case 7:
k = !cfg.auto_add_subs;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Automatically Add New Sub-boards to Area File",uifcYesNoOpts)) {
case 0: cfg.auto_add_subs = true; break;
case 1: cfg.auto_add_subs = false; break;
}
break;
case 8:
k = cfg.add_from_echolists_only;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Allow AreaFix-Add from Area File",uifcYesNoOpts)) {
case 0: cfg.add_from_echolists_only = false; break;
case 1: cfg.add_from_echolists_only = true; break;
}
break;
case 9:
sprintf(str, "%u", cfg.areafile_backups);
if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Total Area File Backups to Maintain"
,str, 5, K_EDIT|K_NUMBER) >= 0)
cfg.areafile_backups = atoi(str);
break;
case 10:
k = !cfg.check_path;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Circular Path Detection",uifcYesNoOpts)) {
......@@ -1208,7 +1454,15 @@ int main(int argc, char **argv)
case 1: cfg.check_path = false; break;
}
break;
case 9:
case 11:
k = !cfg.check_path;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
,"Relay Filtered EchoMail Messages",uifcYesNoOpts)) {
case 0: cfg.relay_filtered_msgs = true; break;
case 1: cfg.relay_filtered_msgs = false; break;
}
break;
case 12:
{
k = cfg.trunc_bundles;
char* opt[] = {"Delete after Sent", "Truncate after Sent", NULL };
......@@ -1219,7 +1473,7 @@ int main(int argc, char **argv)
}
break;
}
case 10:
case 13:
k = !cfg.zone_blind;
switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0,"Zone Blind",uifcYesNoOpts)) {
case 0:
......@@ -1237,36 +1491,36 @@ int main(int argc, char **argv)
break;
}
break;
case 11:
case 14:
uifc.helpbuf=
"~ Maximum Age of Imported EchoMail ~\r\n\r\n"
"Maximum age (in days) of EchoMail that may be imported. The age is based\r\n"
"on the date supplied in the message header and may be incorrect in some\r\n"
"conditions (e.g. erroneous software or incorrect system date).\r\n"
"~ Maximum Age of Imported EchoMail ~\n\n"
"Maximum age of EchoMail that may be imported. The age is based\n"
"on the date supplied in the message header and may be incorrect in some\n"
"conditions (e.g. erroneous software or incorrect system date).\n"
"Set this value to `0` to disable this feature (no maximum age imposed)."
;
if(cfg.max_echomail_age)
sprintf(str,"%1.0f", cfg.max_echomail_age / (24.0*60.0*60.0));
duration_to_vstr(cfg.max_echomail_age, str, sizeof(str));
else
strcpy(str, "None");
if(uifc.input(WIN_MID|WIN_BOT|WIN_SAV,0,0,"Maximum EchoMail Age (in Days)"
,str, 5, K_EDIT) >= 0)
cfg.max_echomail_age = (long) (strtod(str, NULL) * (24.0*60.0*60.0));
if(uifc.input(WIN_MID|WIN_BOT|WIN_SAV,0,0,"Maximum EchoMail Age"
,str, 10, K_EDIT) >= 0)
cfg.max_echomail_age = (ulong)parse_duration(str);
break;
}
}
break;
case 3: /* Archive Types */
case 2: /* Archive Types */
i=0;
while(1) {
uifc.helpbuf=
"~ Archive Types ~\r\n\r\n"
"These are the archive file types that have been configured along with\r\n"
"their corresponding archive programs and command-lines for the packing\r\n"
"and unpacking of EchoMail bundle files.\r\n"
"\r\n"
"~ Archive Types ~\n\n"
"These are the archive file types that have been configured along with\n"
"their corresponding archive programs and command-lines for the packing\n"
"and unpacking of EchoMail bundle files.\n"
"\n"
"The corresponding archive programs are sometimes referred to as `packers`."
;
for(u=0;u<cfg.arcdefs;u++)
......@@ -1276,7 +1530,7 @@ int main(int argc, char **argv)
| WIN_INSACT | WIN_DELACT | WIN_XTR;
if(savarcdef.name[0])
mode |= WIN_PUT;
i=uifc.list(mode,0,0,0,&i,0,"Archive Types",opt);
i=uifc.list(mode,0,0,0,&archive_opt,0,"Archive Types",opt);
if(i==-1)
break;
int msk = i & MSK_ON;
......@@ -1284,8 +1538,8 @@ int main(int argc, char **argv)
if (msk == MSK_INS) {
str[0]=0;
uifc.helpbuf=
"~ Archive Type ~\r\n\r\n"
"This is the identifying name of the archiving program (packer).\r\n";
"~ Archive Type ~\n\n"
"This is the identifying name of the archiving program (packer).\n";
if(uifc.input(WIN_MID,0,0
,"Archive Type",str,25,K_EDIT|K_UPPER)<1)
continue;
......@@ -1349,15 +1603,15 @@ int main(int argc, char **argv)
,cfg.arcdef[i].unpack);
opt[j][0]=0;
SAFEPRINTF(str,"Archive Type - %s", cfg.arcdef[i].name);
k=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,0,0,60,&packop,0,str,opt);
k=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,0,0,0,&packop,0,str,opt);
if(k==-1)
break;
switch(k) {
case 0:
uifc.helpbuf=
"~ Archive Type ~\r\n\r\n"
"This is the identifying name of the archive file type. Usually this name\r\n"
"corresponds with the common file extension or suffix denoting this type\r\n"
"~ Archive Type ~\n\n"
"This is the identifying name of the archive file type. Usually this name\n"
"corresponds with the common file extension or suffix denoting this type\n"
"of archive file (e.g. `zip`, `arc`, etc.)."
;
uifc.input(WIN_MID|WIN_SAV,0,0
......@@ -1367,10 +1621,10 @@ int main(int argc, char **argv)
break;
case 1:
uifc.helpbuf=
"~ Archive Signature ~\r\n\r\n"
"This is the identifying signature of the archive file format (in\r\n"
"hexadecimal notation). This signature is used in combination with the\r\n"
"Archive `Signature Offset` for the automatic detection of proper archive\r\n"
"~ Archive Signature ~\n\n"
"This is the identifying signature of the archive file format (in\n"
"hexadecimal notation). This signature is used in combination with the\n"
"Archive `Signature Offset` for the automatic detection of proper archive\n"
"program to extract (unarchive) inbound EchoMail bundle files."
;
uifc.input(WIN_MID|WIN_SAV,0,0
......@@ -1380,10 +1634,10 @@ int main(int argc, char **argv)
break;
case 2:
uifc.helpbuf=
"~ Archive Signature Offset ~\r\n\r\n"
"This is the byte-offset of the identifying signature of the archive file\r\n"
"format. This offset is used in combination with the Archive `Signature`\r\n"
"for the automatic detection of proper archive program to extract\r\n"
"~ Archive Signature Offset ~\n\n"
"This is the byte-offset of the identifying signature of the archive file\n"
"format. This offset is used in combination with the Archive `Signature`\n"
"for the automatic detection of proper archive program to extract\n"
"(unarchive) inbound EchoMail bundle files."
;
sprintf(str,"%u",cfg.arcdef[i].byteloc);
......@@ -1394,22 +1648,22 @@ int main(int argc, char **argv)
break;
case 3:
uifc.helpbuf=
"~ Pack Command Line ~\r\n\r\n"
"This is the command-line to execute to create an archive file of the\r\n"
"selected type. The following command-line specifiers may be used for\r\n"
"dynamic variable replacement:\r\n"
"\r\n"
" `%f` The path/filename of the archive file to be created\r\n"
" `%s` The path/filename of the file(s) to be added to the archive\r\n"
" `%!` The Synchronet `exec` directory\r\n"
" `%@` The Synchronet `exec` directory only for non-Unix systems\r\n"
" `%.` Blank for Unix systems, '`.exe`' otherwise\r\n"
" `%?` The current platform description (e.g. 'linux', 'win32')\r\n"
" `%j` The Synchronet `data` directory\r\n"
" `%k` The Synchronet `ctrl` directory\r\n"
" `%o` The configured system operator name\r\n"
" `%q` The configured system QWK-ID\r\n"
" `%g` The configured temporary file directory\r\n"
"~ Pack Command Line ~\n\n"
"This is the command-line to execute to create an archive file of the\n"
"selected type. The following command-line specifiers may be used for\n"
"dynamic variable replacement:\n"
"\n"
" `%f` The path/filename of the archive file to be created\n"
" `%s` The path/filename of the file(s) to be added to the archive\n"
" `%!` The Synchronet `exec` directory\n"
" `%@` The Synchronet `exec` directory only for non-Unix systems\n"
" `%.` Blank for Unix systems, '`.exe`' otherwise\n"
" `%?` The current platform description (e.g. 'linux', 'win32')\n"
" `%j` The Synchronet `data` directory\n"
" `%k` The Synchronet `ctrl` directory\n"
" `%o` The configured system operator name\n"
" `%q` The configured system QWK-ID\n"
" `%g` The configured temporary file directory\n"
;
uifc.input(WIN_MID|WIN_SAV,0,0
,"Pack Command Line"
......@@ -1418,22 +1672,22 @@ int main(int argc, char **argv)
break;
case 4:
uifc.helpbuf=
"~ Unpack Command Line ~\r\n\r\n"
"This is the command-line to execute to extract an archive file of the\r\n"
"selected type. The following command-line specifiers may be used for\r\n"
"dynamic variable replacement:\r\n"
"\r\n"
" `%f` The path/filename of the archive file to be extracted\r\n"
" `%s` The path/filename of the file(s) to extracted from the archive\r\n"
" `%!` The Synchronet `exec` directory\r\n"
" `%@` The Synchronet `exec` directory only for non-Unix systems\r\n"
" `%.` Blank for Unix systems, '`.exe`' otherwise\r\n"
" `%?` The current platform description (e.g. 'linux', 'win32')\r\n"
" `%j` The Synchronet `data` directory\r\n"
" `%k` The Synchronet `ctrl` directory\r\n"
" `%o` The configured system operator name\r\n"
" `%q` The configured system QWK-ID\r\n"
" `%g` The configured temporary file directory\r\n"
"~ Unpack Command Line ~\n\n"
"This is the command-line to execute to extract an archive file of the\n"
"selected type. The following command-line specifiers may be used for\n"
"dynamic variable replacement:\n"
"\n"
" `%f` The path/filename of the archive file to be extracted\n"
" `%s` The path/filename of the file(s) to extracted from the archive\n"
" `%!` The Synchronet `exec` directory\n"
" `%@` The Synchronet `exec` directory only for non-Unix systems\n"
" `%.` Blank for Unix systems, '`.exe`' otherwise\n"
" `%?` The current platform description (e.g. 'linux', 'win32')\n"
" `%j` The Synchronet `data` directory\n"
" `%k` The Synchronet `ctrl` directory\n"
" `%o` The configured system operator name\n"
" `%q` The configured system QWK-ID\n"
" `%g` The configured temporary file directory\n"
;
uifc.input(WIN_MID|WIN_SAV,0,0
,"Unpack Command Line"
......@@ -1445,12 +1699,12 @@ int main(int argc, char **argv)
}
break;
case 7:
case 6:
uifc.helpbuf=
"~ Additional EchoLists ~\r\n\r\n"
"This feature allows you to specify lists of echoes, in `BACKBONE.NA`\r\n"
"format, which are utilized in `addition` to your Area File (e.g. \r\n"
"`areas.bbs`) for advanced AreaFix (Area Management) operations.\r\n";
"~ EchoLists ~\n\n"
"This feature allows you to specify lists of echoes, in `BACKBONE.NA`\n"
"format, which are utilized in `addition` to your Area File (e.g. \n"
"`areas.bbs`) for advanced AreaFix (Area Management) operations.\n";
i=0;
while(1) {
for(u=0;u<cfg.listcfgs;u++)
......@@ -1460,7 +1714,7 @@ int main(int argc, char **argv)
| WIN_INSACT | WIN_DELACT | WIN_XTR;
if(savlistcfg.listpath[0])
mode |= WIN_PUT;
i=uifc.list(mode,0,0,0,&i,0,"Additional EchoLists",opt);
i=uifc.list(mode,0,0,0,&echolist_opt,0,"EchoLists",opt);
if(i==-1)
break;
int msk = i&MSK_ON;
......@@ -1468,9 +1722,9 @@ int main(int argc, char **argv)
if (msk == MSK_INS) {
str[0]=0;
uifc.helpbuf=
"~ EchoList ~\r\n\r\n"
"This is the path and filename of the echolist file you wish\r\n"
"to add.\r\n";
"~ EchoList ~\n\n"
"This is the path and filename of the echolist file you wish\n"
"to add.\n";
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"EchoList Path/Name",str,50,K_EDIT)<1)
continue;
......@@ -1519,7 +1773,7 @@ int main(int argc, char **argv)
while(1) {
j=0;
uifc.helpbuf=
"Configuring an Additional EchoList"
"Configuring an EchoList"
;
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","EchoList Path/Name"
,cfg.listcfg[i].listpath);
......@@ -1534,8 +1788,8 @@ int main(int argc, char **argv)
snprintf(opt[j++],MAX_OPLN-1,"%-30.30s %s","AreaFix Keys"
,strListCombine(cfg.listcfg[i].keys, str, sizeof(str), ","));
opt[j][0]=0;
SAFEPRINTF(str, "Additional EchoList - %s", getfname(cfg.listcfg[i].listpath));
k=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,0,0,60,&listop,0,str,opt);
SAFEPRINTF(str, "EchoList - %s", getfname(cfg.listcfg[i].listpath));
k=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,0,0,0,&listop,0,str,opt);
if(k==-1)
break;
switch(k) {
......@@ -1570,9 +1824,9 @@ int main(int argc, char **argv)
break;
case 4:
uifc.helpbuf=
"~ AreaFix Keys ~\r\n\r\n"
"These keys determine which linked nodes have access to the current\r\n"
"echolist file via AreaFix requests (e.g. query, add, remove).\r\n";
"~ AreaFix Keys ~\n\n"
"These keys determine which linked nodes have access to the current\n"
"echolist file via AreaFix requests (e.g. query, add, remove).\n";
while(1) {
for(u=0; cfg.listcfg[i].keys!=NULL && cfg.listcfg[i].keys[u] != NULL;u++)
strcpy(opt[u],cfg.listcfg[i].keys[u]);
......@@ -1586,7 +1840,7 @@ int main(int argc, char **argv)
x&=MSK_OFF;
str[0]=0;
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"AreaFix Keys",str,SBBSECHO_MAX_KEY_LEN
,"AreaFix Key",str,SBBSECHO_MAX_KEY_LEN
,K_EDIT|K_UPPER)<1)
continue;
strListInsert(&cfg.listcfg[i].keys,str,x);
......@@ -1610,7 +1864,7 @@ int main(int argc, char **argv)
}
break;
case 8:
case 7:
if(!sbbsecho_write_ini(&cfg))
uifc.msg("Error saving configuration file");
else {
......@@ -1621,9 +1875,9 @@ int main(int argc, char **argv)
case -1:
if(uifc.changes) {
uifc.helpbuf=
"~ Save Configuration File ~\r\n\r\n"
"Select `Yes` to save the config file, `No` to quit without saving,\r\n"
"or hit ~ ESC ~ to go back to the menu.\r\n\r\n";
"~ Save Configuration File ~\n\n"
"Select `Yes` to save the config file, `No` to quit without saving,\n"
"or hit ~ ESC ~ to go back to the menu.\n\n";
i=0;
strcpy(opt[0],"Yes");
strcpy(opt[1],"No");
......
......@@ -226,6 +226,8 @@ void get_default_echocfg(sbbsecho_cfg_t* cfg)
cfg->relay_filtered_msgs = false;
cfg->umask = 077;
cfg->areafile_backups = 100;
cfg->cfgfile_backups = 100;
cfg->auto_add_subs = true;
}
char* pktTypeStringList[] = {"2+", "2e", "2.2", "2", NULL}; // Must match enum pkt_type
......@@ -248,15 +250,15 @@ bool sbbsecho_read_ini(sbbsecho_cfg_t* cfg)
/* Global/root section: */
/************************/
iniFreeStringList(cfg->sysop_alias_list);
SAFECOPY(cfg->inbound , iniGetString(ini, ROOT_SECTION, "Inbound", "../fido/nonsecure", value));
SAFECOPY(cfg->secure_inbound, iniGetString(ini, ROOT_SECTION, "SecureInbound", "../fido/inbound", value));
SAFECOPY(cfg->outbound , iniGetString(ini, ROOT_SECTION, "Outbound", "../fido/outbound", value));
SAFECOPY(cfg->areafile , iniGetString(ini, ROOT_SECTION, "AreaFile", "../data/areas.bbs", value));
SAFECOPY(cfg->badareafile , iniGetString(ini, ROOT_SECTION, "BadAreaFile", "../data/badareas.lst", value));
SAFECOPY(cfg->echostats , iniGetString(ini, ROOT_SECTION, "EchoStats", "../data/echostats.ini", value));
SAFECOPY(cfg->logfile , iniGetString(ini, ROOT_SECTION, "LogFile", "../data/sbbsecho.log", value));
SAFECOPY(cfg->logtime , iniGetString(ini, ROOT_SECTION, "LogTimeFormat", "%Y-%m-%d %H:%M:%S", value));
SAFECOPY(cfg->temp_dir , iniGetString(ini, ROOT_SECTION, "TempDirectory", "../temp/sbbsecho", value));
SAFECOPY(cfg->inbound , iniGetString(ini, ROOT_SECTION, "Inbound" ,DEFAULT_INBOUND , value));
SAFECOPY(cfg->secure_inbound, iniGetString(ini, ROOT_SECTION, "SecureInbound" ,DEFAULT_SECURE_INBOUND , value));
SAFECOPY(cfg->outbound , iniGetString(ini, ROOT_SECTION, "Outbound" ,DEFAULT_OUTBOUND , value));
SAFECOPY(cfg->areafile , iniGetString(ini, ROOT_SECTION, "AreaFile" ,DEFAULT_AREA_FILE , value));
SAFECOPY(cfg->badareafile , iniGetString(ini, ROOT_SECTION, "BadAreaFile" ,DEFAULT_BAD_AREA_FILE , value));
SAFECOPY(cfg->echostats , iniGetString(ini, ROOT_SECTION, "EchoStats" ,DEFAULT_ECHOSTATS_FILE , value));
SAFECOPY(cfg->logfile , iniGetString(ini, ROOT_SECTION, "LogFile" ,DEFAULT_LOG_FILE , value));
SAFECOPY(cfg->logtime , iniGetString(ini, ROOT_SECTION, "LogTimeFormat" ,DEFAULT_LOG_TIME_FMT , value));
SAFECOPY(cfg->temp_dir , iniGetString(ini, ROOT_SECTION, "TempDirectory" ,DEFAULT_TEMP_DIR , value));
SAFECOPY(cfg->outgoing_sem , iniGetString(ini, ROOT_SECTION, "OutgoingSemaphore", "", value));
cfg->log_level = iniGetLogLevel(ini, ROOT_SECTION, "LogLevel", cfg->log_level);
cfg->strip_lf = iniGetBool(ini, ROOT_SECTION, "StripLineFeeds", cfg->strip_lf);
......@@ -269,6 +271,7 @@ bool sbbsecho_read_ini(sbbsecho_cfg_t* cfg)
cfg->relay_filtered_msgs = iniGetBool(ini, ROOT_SECTION, "RelayFilteredMsgs", cfg->relay_filtered_msgs);
cfg->umask = iniGetInteger(ini, ROOT_SECTION, "umask", cfg->umask);
cfg->areafile_backups = iniGetInteger(ini, ROOT_SECTION, "AreaFileBackups", cfg->areafile_backups);
cfg->cfgfile_backups = iniGetInteger(ini, ROOT_SECTION, "CfgFileBackups", cfg->cfgfile_backups);
/* EchoMail options: */
cfg->maxbdlsize = (ulong)iniGetBytes(ini, ROOT_SECTION, "BundleSize", 1, cfg->maxbdlsize);
......@@ -462,6 +465,9 @@ bool sbbsecho_write_ini(sbbsecho_cfg_t* cfg)
FILE* fp;
str_list_t ini;
if(cfg->cfgfile_backups)
backup(cfg->cfgfile, cfg->cfgfile_backups, /* ren: */false);
if((fp=iniOpenFile(cfg->cfgfile, /* create: */true))==NULL)
return false;
ini = iniReadFile(fp);
......@@ -477,6 +483,7 @@ bool sbbsecho_write_ini(sbbsecho_cfg_t* cfg)
iniSetString(&ini, ROOT_SECTION, "Outbound" ,cfg->outbound ,NULL);
iniSetString(&ini, ROOT_SECTION, "AreaFile" ,cfg->areafile ,NULL);
iniSetInteger(&ini, ROOT_SECTION, "AreaFileBackups" ,cfg->areafile_backups ,NULL);
iniSetInteger(&ini, ROOT_SECTION, "CfgFileBackups" ,cfg->cfgfile_backups ,NULL);
iniSetString(&ini, ROOT_SECTION, "BadAreaFile" ,cfg->badareafile ,NULL);
iniSetString(&ini, ROOT_SECTION, "EchoStats" ,cfg->echostats ,NULL);
if(cfg->logfile[0])
......
......@@ -1766,6 +1766,10 @@ bool alter_config(fidoaddr_t addr, const char* key, const char* value)
{
FILE* fp;
static ulong alterations;
if(alterations++ == 0)
backup(cfg.cfgfile, cfg.cfgfile_backups, /* ren: */false);
if((fp=iniOpenFile(cfg.cfgfile, false)) == NULL) {
lprintf(LOG_ERR, "ERROR %d (%s) opening %s for altering configuration of node %s"
,errno, strerror(errno), cfg.cfgfile, smb_faddrtoa(&addr, NULL));
......
......@@ -42,10 +42,20 @@
#include "fidodefs.h"
#define SBBSECHO_VERSION_MAJOR 3
#define SBBSECHO_VERSION_MINOR 1
#define SBBSECHO_VERSION_MINOR 2
#define SBBSECHO_PRODUCT_CODE 0x12FF /* from http://ftsc.org/docs/ftscprod.013 */
#define DEFAULT_INBOUND "../fido/nonsecure"
#define DEFAULT_SECURE_INBOUND "../fido/inbound"
#define DEFAULT_OUTBOUND "../fido/outbound"
#define DEFAULT_AREA_FILE "../data/areas.bbs"
#define DEFAULT_BAD_AREA_FILE "../data/badareas.lst"
#define DEFAULT_ECHOSTATS_FILE "../data/echostats.ini"
#define DEFAULT_LOG_FILE "../data/sbbsecho.log"
#define DEFAULT_LOG_TIME_FMT "%Y-%m-%d %H:%M:%S"
#define DEFAULT_TEMP_DIR "../temp/sbbsecho"
enum mail_status {
MAIL_STATUS_NORMAL
,MAIL_STATUS_HOLD
......@@ -140,8 +150,9 @@ typedef struct {
char logfile[MAX_PATH+1]; /* LOG path/filename */
char logtime[64]; /* format of log timestamp */
char cfgfile[MAX_PATH+1]; /* Configuration path/filename */
uint cfgfile_backups; /* Number of backups to keep of cfg file */
char temp_dir[MAX_PATH+1]; /* Temporary file directory */
char outgoing_sem[MAX_PATH+1]; /* Semaphore file to creat when there's outgoing data */
char outgoing_sem[MAX_PATH+1]; /* Semaphore file to create/touch when there's outgoing data */
str_list_t sysop_alias_list; /* List of sysop aliases */
ulong maxpktsize /* Maximum size for packets */
,maxbdlsize; /* Maximum size for bundles */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment