diff --git a/src/sbbs3/scfg/scfgsrvr.c b/src/sbbs3/scfg/scfgsrvr.c index 0b8dca049a997ca71ba902172446e7b6af4eb498..b75ddc229ff3993d3c2778744a9aa31801ae0a60 100644 --- a/src/sbbs3/scfg/scfgsrvr.c +++ b/src/sbbs3/scfg/scfgsrvr.c @@ -21,6 +21,7 @@ #include "sbbs_ini.h" #include "netwrap.h" +const char* strReadingIniFile = "Reading sbbs.ini ..."; const char* strDisabled = "<disabled>"; static const char* threshold(uint val) @@ -54,6 +55,120 @@ static const char* maximum(uint val) return str; } +static void login_attempt_cfg(struct login_attempt_settings* login_attempt) +{ + static int cur, bar; + char str[256]; + BOOL changes = uifc.changes; + + while(1) { + int i = 0; + sprintf(opt[i++], "%-30s%u ms", "Delay", login_attempt->delay); + sprintf(opt[i++], "%-30s%u ms", "Throttle", login_attempt->throttle); + sprintf(opt[i++], "%-30s%s", "Hack Log Threshold", threshold(login_attempt->hack_threshold)); + sprintf(opt[i++], "%-30s%s", "Temporary Ban Threshold", threshold(login_attempt->tempban_threshold)); + sprintf(opt[i++], "%-30s%s", "Temporary Ban Duration" + ,duration_to_vstr(login_attempt->tempban_duration, tmp, sizeof(tmp))); + sprintf(opt[i++], "%-30s%s", "Auto-filter Threshold", threshold(login_attempt->filter_threshold)); + opt[i][0] = '\0'; + + uifc.helpbuf= + "`Failed Login Attempt Settings:`\n" + "\n" + "Settings that control the throttling, logging, and subsequent filtering\n" + "of clients (based on IP address) that have failed login attempts.\n" + ; + switch(uifc.list(WIN_ACT|WIN_BOT|WIN_SAV, 0, 0, 0, &cur, &bar + ,"Failed Login Attempts",opt)) { + case 0: + SAFEPRINTF(str, "%u", login_attempt->delay); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Millisecond Delay After Each Failed Login Attempt", str, 6, K_NUMBER|K_EDIT) > 0) + login_attempt->delay = atoi(str); + break; + case 1: + SAFEPRINTF(str, "%u", login_attempt->throttle); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Throttle multiplier (in milliseconds) for Failed Logins", str, 6, K_NUMBER|K_EDIT) > 0) + login_attempt->throttle = atoi(str); + break; + case 2: + SAFEPRINTF(str, "%u", login_attempt->hack_threshold); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Threshold for Logging Failed Logins to hack.log", str, 4, K_NUMBER|K_EDIT) > 0) + login_attempt->hack_threshold = atoi(str); + break; + case 3: + SAFEPRINTF(str, "%u", login_attempt->tempban_threshold); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Threshold for Temp-ban IPs of Failed Logins", str, 4, K_NUMBER|K_EDIT) > 0) + login_attempt->tempban_threshold = atoi(str); + break; + case 4: + SAFECOPY(str, duration(login_attempt->tempban_duration, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Duration of Temp-ban for Failed Logins", str, 6, K_EDIT) > 0) + login_attempt->tempban_duration = (uint)parse_duration(str); + break; + case 5: + SAFEPRINTF(str, "%u", login_attempt->filter_threshold); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Threshold for Filtering IPs of Failed Logins", str, 3, K_NUMBER|K_EDIT) > 0) + login_attempt->filter_threshold = atoi(str); + break; + default: + uifc.changes = changes; + return; + } + } +} + +static void js_startup_cfg(js_startup_t* js) +{ + static int cur, bar; + char str[256]; + BOOL changes = uifc.changes; + + while(1) { + int i = 0; + sprintf(opt[i++], "%-20s%s bytes", "Heap Size", byte_count_to_str(js->max_bytes, str, sizeof(str))); + sprintf(opt[i++], "%-20s%u ticks", "Time Limit", js->time_limit); + sprintf(opt[i++], "%-20s%u ticks", "GC Interval ", js->gc_interval); + sprintf(opt[i++], "%-20s%u ticks", "Yield Interval", js->yield_interval); + sprintf(opt[i++], "%-20s%s", "Load Path", js->load_path); + opt[i][0] = '\0'; + + uifc.helpbuf= + "`JavaScript Server Settings:`\n" + "\n" + "Settings that control the server-side JavaScript execution environment.\n" + ; + switch(uifc.list(WIN_ACT|WIN_BOT|WIN_SAV, 0, 0, 0, &cur, &bar + ,"JavaScript Settings",opt)) { + case 0: + byte_count_to_str(js->max_bytes, str, sizeof(str)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "JavaScript Heap Size (Maximum Allocated Bytes)", str, 6, K_UPPER|K_EDIT) > 0) + js->max_bytes = (uint)parse_byte_count(str, 1); + break; + case 1: + SAFEPRINTF(str, "%u", js->time_limit); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "JavaScript Execution Time Limit (in ticks)", str, 6, K_NUMBER|K_EDIT) > 0) + js->time_limit = atoi(str); + break; + case 2: + SAFEPRINTF(str, "%u", js->gc_interval); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "JavaScript Garbage Collection Interval (in ticks)", str, 6, K_NUMBER|K_EDIT) > 0) + js->gc_interval = atoi(str); + break; + case 3: + SAFEPRINTF(str, "%u", js->yield_interval); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "JavaScript Yield Interval (in ticks)", str, 6, K_NUMBER|K_EDIT) > 0) + js->yield_interval = atoi(str); + break; + case 4: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "JavaScript Load Library Path", js->load_path, sizeof(js->load_path) - 1, K_EDIT); + break; + default: + uifc.changes = changes; + return; + } + } +} + static void global_cfg(void) { static int cur, bar; @@ -66,6 +181,7 @@ static void global_cfg(void) uifc.msgf("Error opening %s", cfg.filename); return; } + uifc.pop(strReadingIniFile); sbbs_read_ini( fp ,cfg.filename @@ -82,6 +198,7 @@ static void global_cfg(void) ,NULL //&services_startup ); iniCloseFile(fp); + uifc.pop(NULL); global_startup_t saved_startup = startup; while(1) { @@ -92,27 +209,21 @@ static void global_cfg(void) sprintf(opt[i++], "%-40s%s", "Outbound Interface (IPv4)", IPv4AddressToStr(startup.outgoing4.s_addr, tmp, sizeof(tmp))); sprintf(opt[i++], "%-40s%s", "Bind Retry Count", threshold(startup.bind_retry_count)); sprintf(opt[i++], "%-40s%s", "Bind Retry Delay", vduration(startup.bind_retry_delay)); - sprintf(opt[i++], "%-40s%u ms", "Failed Login Delay", startup.login_attempt.delay); - sprintf(opt[i++], "%-40s%u ms", "Failed Login Throttle", startup.login_attempt.throttle); - sprintf(opt[i++], "%-40s%s", "Failed Login Hack Log Threshold", threshold(startup.login_attempt.hack_threshold)); - sprintf(opt[i++], "%-40s%s", "Failed Login Temporary Ban Threshold", threshold(startup.login_attempt.tempban_threshold)); - sprintf(opt[i++], "%-40s%s", "Failed Login Temporary Ban Duration" - ,duration_to_vstr(startup.login_attempt.tempban_duration, tmp, sizeof(tmp))); - sprintf(opt[i++], "%-40s%s", "Failed Login Auto-Filter Threshold", threshold(startup.login_attempt.filter_threshold)); - sprintf(opt[i++], "%-40s%s bytes", "JavaScript Heap Size", byte_count_to_str(startup.js.max_bytes, tmp, sizeof(tmp))); - sprintf(opt[i++], "%-40s%u ticks", "JavaScript Time Limit", startup.js.time_limit); - sprintf(opt[i++], "%-40s%u ticks", "JavaScript GC Interval ", startup.js.gc_interval); - sprintf(opt[i++], "%-40s%u ticks", "JavaScript Yield Interval", startup.js.yield_interval); - sprintf(opt[i++], "%-40s%s", "JavaScript Load Path", startup.js.load_path); sprintf(opt[i++], "%-40s%s", "Semaphore File Check Interval", vduration(startup.sem_chk_freq)); + strcpy(opt[i++], "JavaScript Settings..."); + strcpy(opt[i++], "Failed Login Attempts..."); opt[i][0] = '\0'; uifc.helpbuf= "`Global Server Settings:`\n" "\n" + "Settings that are shared among multiple Synchronet servers.\n" + "\n" + "These settings can be over-ridden on a per-server basis by editing the\n" + "corresponding keys in each `[server]` section of the `ctrl/sbbs.ini` file.\n" ; switch(uifc.list(WIN_ACT|WIN_RHT|WIN_SAV|WIN_ESC, 0, 0, 0, &cur, &bar - ,"Global Server Setttings",opt)) { + ,"Global Server Settings",opt)) { case 0: uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &startup.log_level, 0, "Log Level", iniLogLevelStringList()); break; @@ -143,62 +254,15 @@ static void global_cfg(void) startup.bind_retry_delay = (uint)parse_duration(str); break; case 6: - SAFEPRINTF(str, "%u", startup.login_attempt.delay); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Millisecond Delay After Failed Login Attempts", str, 6, K_NUMBER|K_EDIT) > 0) - startup.login_attempt.delay = atoi(str); + SAFECOPY(str, duration(startup.sem_chk_freq, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Semaphore File Check Interval", str, 6, K_EDIT) > 0) + startup.sem_chk_freq = (uint16_t)parse_duration(str); break; case 7: - SAFEPRINTF(str, "%u", startup.login_attempt.throttle); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Throttle multiplier (in milliseconds) for Failed Logins", str, 6, K_NUMBER|K_EDIT) > 0) - startup.login_attempt.throttle = atoi(str); + js_startup_cfg(&startup.js); break; case 8: - SAFEPRINTF(str, "%u", startup.login_attempt.hack_threshold); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Threshold for Logging Failed Logins to hack.log", str, 3, K_NUMBER|K_EDIT) > 0) - startup.login_attempt.hack_threshold = atoi(str); - break; - case 9: - SAFEPRINTF(str, "%u", startup.login_attempt.tempban_threshold); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Threshold for Temp-ban IPs of Failed Logins", str, 3, K_NUMBER|K_EDIT) > 0) - startup.login_attempt.tempban_threshold = atoi(str); - break; - case 10: - SAFECOPY(str, duration(startup.login_attempt.tempban_duration, false)); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Duration of Temp-ban for Failed Logins", str, 6, K_EDIT) > 0) - startup.login_attempt.tempban_duration = (uint)parse_duration(str); - break; - case 11: - SAFEPRINTF(str, "%u", startup.login_attempt.filter_threshold); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Threshold for Filtering IPs of Failed Logins", str, 3, K_NUMBER|K_EDIT) > 0) - startup.login_attempt.filter_threshold = atoi(str); - break; - case 12: - byte_count_to_str(startup.js.max_bytes, str, sizeof(str)); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "JavaScript Heap Size (Maximum Allocated Bytes)", str, 6, K_UPPER|K_EDIT) > 0) - startup.js.max_bytes = (uint)parse_byte_count(str, 1); - break; - case 13: - SAFEPRINTF(str, "%u", startup.js.time_limit); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "JavaScript Execution Time Limit (in ticks)", str, 6, K_NUMBER|K_EDIT) > 0) - startup.js.time_limit = atoi(str); - break; - case 14: - SAFEPRINTF(str, "%u", startup.js.gc_interval); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "JavaScript Garbage Collection Interval (in ticks)", str, 6, K_NUMBER|K_EDIT) > 0) - startup.js.gc_interval = atoi(str); - break; - case 15: - SAFEPRINTF(str, "%u", startup.js.yield_interval); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "JavaScript Yield Interval (in ticks)", str, 6, K_NUMBER|K_EDIT) > 0) - startup.js.yield_interval = atoi(str); - break; - case 16: - uifc.input(WIN_MID|WIN_SAV, 0, 0, "JavaScript Load Library Path", startup.js.load_path, sizeof(startup.js.load_path) - 1, K_EDIT); - break; - case 17: - SAFECOPY(str, duration(startup.sem_chk_freq, false)); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Semaphore File Check Interval", str, 6, K_EDIT) > 0) - startup.sem_chk_freq = (uint16_t)parse_duration(str); + login_attempt_cfg(&startup.login_attempt); break; default: if(memcmp(&saved_startup, &startup, sizeof(startup)) != 0) @@ -255,6 +319,7 @@ static void termsrvr_cfg(void) uifc.msgf("Error opening %s", cfg.filename); return; } + uifc.pop(strReadingIniFile); sbbs_read_ini( fp ,cfg.filename @@ -271,6 +336,7 @@ static void termsrvr_cfg(void) ,NULL //&services_startup ); iniCloseFile(fp); + uifc.pop(NULL); bbs_startup_t saved_startup = startup; while(1) { @@ -316,6 +382,9 @@ static void termsrvr_cfg(void) uifc.helpbuf= "`Terminal Server Configuration:`\n" "\n" + "The initialization settings of the Synchchronet server that provides the\n" + "traditional BBS experience over `Telnet`, `SSH`, `RLogin`, or `Raw TCP`\n" + "protocols.\n" ; switch(uifc.list(WIN_ACT|WIN_ESC|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar ,"Terminal Server",opt)) { @@ -497,6 +566,7 @@ static void websrvr_cfg(void) uifc.msgf("Error opening %s", cfg.filename); return; } + uifc.pop(strReadingIniFile); sbbs_read_ini( fp ,cfg.filename @@ -513,6 +583,7 @@ static void websrvr_cfg(void) ,NULL //&services_startup ); iniCloseFile(fp); + uifc.pop(NULL); web_startup_t saved_startup = startup; while(1) { @@ -746,6 +817,7 @@ static void ftpsrvr_cfg(void) uifc.msgf("Error opening %s", cfg.filename); return; } + uifc.pop(strReadingIniFile); sbbs_read_ini( fp ,cfg.filename @@ -762,6 +834,7 @@ static void ftpsrvr_cfg(void) ,NULL //&services_startup ); iniCloseFile(fp); + uifc.pop(NULL); ftp_startup_t saved_startup = startup; while(1) { @@ -918,6 +991,118 @@ static void ftpsrvr_cfg(void) } } +static void sendmail_cfg(mail_startup_t* startup) +{ + const char* p; + char str[256]; + static int cur, bar; + + while(1) { + int i = 0; + sprintf(opt[i++], "%-30s%s", "Enabled", startup->options & MAIL_OPT_NO_SENDMAIL ? "No" : "Yes"); + sprintf(opt[i++], "%-30s%s", "Rescan Interval", vduration(startup->rescan_frequency)); + sprintf(opt[i++], "%-30s%s", "Connect Timeout", vduration(startup->connect_timeout)); + sprintf(opt[i++], "%-30s%u", "Max Delivery Attempts", startup->max_delivery_attempts); + bool applicable = startup->options & MAIL_OPT_RELAY_TX; + sprintf(opt[i++], "%-30s%s", "Delivery Method", applicable ? "Relay" : "Direct"); + if(applicable) { + sprintf(opt[i++], "%-30s%s", "Relay Server Address", startup->relay_server); + sprintf(opt[i++], "%-30s%u", "Relay Server TCP Port", startup->relay_port); + if(startup->options & MAIL_OPT_RELAY_AUTH_PLAIN) + p = "Plain"; + else if(startup->options & MAIL_OPT_RELAY_AUTH_LOGIN) + p = "Login"; + else if(startup->options & MAIL_OPT_RELAY_AUTH_CRAM_MD5) + p = "CRAM-MD5"; + else + p = "None"; + sprintf(opt[i++], "%-30s%s", "Relay Server Authentication", p); + if(startup->options & (MAIL_OPT_RELAY_AUTH_PLAIN | MAIL_OPT_RELAY_AUTH_LOGIN | MAIL_OPT_RELAY_AUTH_CRAM_MD5)) { + sprintf(opt[i++], "%-30s%s", "Relay Server Username", startup->relay_user); + sprintf(opt[i++], "%-30s%s", "Relay Server Password", startup->relay_pass); + } + } + if(startup->options & MAIL_OPT_NO_SENDMAIL) + i = 1; + opt[i][0] = '\0'; + + uifc.helpbuf= + "`Mail Server SendMail Thread Configuration:`\n" + "\n" + ; + switch(uifc.list(WIN_ACT|WIN_ESC|WIN_BOT|WIN_SAV, 0, 0, 0, &cur, &bar + ,"SendMail",opt)) { + case 0: + startup->options ^= MAIL_OPT_NO_SENDMAIL; + break; + case 1: + SAFECOPY(str, duration(startup->rescan_frequency, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "MailBase Re-scan Interval", str, 5, K_EDIT) > 0) + startup->rescan_frequency = (uint16_t)parse_duration(str); + break; + case 2: + SAFECOPY(str, duration(startup->connect_timeout, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "SendMail Connect Timeout", str, 5, K_EDIT) > 0) + startup->connect_timeout = (uint32_t)parse_duration(str); + break; + case 3: + SAFEPRINTF(str, "%u", startup->max_delivery_attempts); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Number of SendMail Delivery Attempts", str, 5, K_NUMBER|K_EDIT) > 0) + startup->max_delivery_attempts = atoi(str); + break; + case 4: + startup->options ^= MAIL_OPT_RELAY_TX; + break; + case 5: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Relay Server Address", startup->relay_server, sizeof(startup->relay_server)-1, K_EDIT); + break; + case 6: + SAFEPRINTF(str, "%u", startup->relay_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Relay Server TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup->relay_port = atoi(str); + break; + case 7: + i = 0; + strcpy(opt[i++], "Plain"); + strcpy(opt[i++], "Login"); + strcpy(opt[i++], "CRAM-MD5"); + strcpy(opt[i++], "None"); + opt[i][0] = '\0'; + if(startup->options & MAIL_OPT_RELAY_AUTH_PLAIN) + i = 0; + else if(startup->options & MAIL_OPT_RELAY_AUTH_LOGIN) + i = 1; + else if(startup->options & MAIL_OPT_RELAY_AUTH_CRAM_MD5) + i = 2; + else + i = 3; + if(uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &i, 0, "Relay Server Authentication Method", opt) < 0) + break; + startup->options &= ~(MAIL_OPT_RELAY_AUTH_PLAIN | MAIL_OPT_RELAY_AUTH_LOGIN | MAIL_OPT_RELAY_AUTH_CRAM_MD5); + switch(i) { + case 0: + startup->options |= MAIL_OPT_RELAY_AUTH_PLAIN; + break; + case 1: + startup->options |= MAIL_OPT_RELAY_AUTH_LOGIN; + break; + case 2: + startup->options |= MAIL_OPT_RELAY_AUTH_CRAM_MD5; + break; + } + break; + case 8: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Relay Server Username", startup->relay_user, sizeof(startup->relay_user)-1, K_EDIT); + break; + case 9: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Relay Server Password", startup->relay_pass, sizeof(startup->relay_pass)-1, K_EDIT); + break; + default: + return; + } + } +} + static void mailsrvr_cfg(void) { static int cur, bar; @@ -932,6 +1117,7 @@ static void mailsrvr_cfg(void) uifc.msgf("Error opening %s", cfg.filename); return; } + uifc.pop(strReadingIniFile); sbbs_read_ini( fp ,cfg.filename @@ -948,6 +1134,7 @@ static void mailsrvr_cfg(void) ,NULL //&services_startup ); iniCloseFile(fp); + uifc.pop(NULL); mail_startup_t saved_startup = startup; while(1) { @@ -990,27 +1177,7 @@ static void mailsrvr_cfg(void) sprintf(opt[i++], "%-30s%s", "Hash Blacklisted Messages", startup.options & MAIL_OPT_DNSBL_SPAMHASH ? "Yes" : "No"); sprintf(opt[i++], "%-30s%s", "Auto-exempt Recipients", startup.options & MAIL_OPT_NO_AUTO_EXEMPT ? "No" : "Yes"); sprintf(opt[i++], "%-30s%s", "Kill SPAM When Read", startup.options & MAIL_OPT_KILL_READ_SPAM ? "Yes": "No"); - sprintf(opt[i++], "%-30s%s", "SendMail Support", startup.options & MAIL_OPT_NO_SENDMAIL ? "No" : "Yes"); - if(!(startup.options & MAIL_OPT_NO_SENDMAIL)) { - bool applicable = startup.options & MAIL_OPT_RELAY_TX; - sprintf(opt[i++], "%-30s%s", "SendMail Delivery", applicable ? "Relay" : "Direct"); - sprintf(opt[i++], "%-30s%s", "SendMail Relay Server", applicable ? startup.relay_server : "N/A"); - sprintf(opt[i++], "%-30s%u", "SendMail Relay Port", startup.relay_port); - sprintf(opt[i++], "%-30s%s", "SendMail Relay User", applicable ? startup.relay_user : "N/A"); - sprintf(opt[i++], "%-30s%s", "SendMail Relay Password", applicable ? startup.relay_pass : "N/A"); - if(startup.options & MAIL_OPT_RELAY_AUTH_PLAIN) - p = "Plain"; - else if(startup.options & MAIL_OPT_RELAY_AUTH_LOGIN) - p = "Login"; - else if(startup.options & MAIL_OPT_RELAY_AUTH_CRAM_MD5) - p = "CRAM-MD5"; - else - p = "None"; - sprintf(opt[i++], "%-30s%s", "SendMail Relay Auth", applicable ? p : "N/A"); - sprintf(opt[i++], "%-30s%u", "SendMail Max Attempts", startup.max_delivery_attempts); - sprintf(opt[i++], "%-30s%s", "SendMail Rescan Interval", vduration(startup.rescan_frequency)); - sprintf(opt[i++], "%-30s%s", "SendMail Connect Timeout", vduration(startup.connect_timeout)); - } + sprintf(opt[i++], "%-30s%s", "SendMail Support...", startup.options & MAIL_OPT_NO_SENDMAIL ? strDisabled : ""); if(!enabled) i = 1; opt[i][0] = '\0'; @@ -1172,69 +1339,7 @@ static void mailsrvr_cfg(void) startup.options ^= MAIL_OPT_KILL_READ_SPAM; break; case 28: - startup.options ^= MAIL_OPT_NO_SENDMAIL; - break; - case 29: - startup.options ^= MAIL_OPT_RELAY_TX; - break; - case 30: - uifc.input(WIN_MID|WIN_SAV, 0, 0, "Relay Server Address", startup.relay_server, sizeof(startup.relay_server)-1, K_EDIT); - break; - case 31: - SAFEPRINTF(str, "%u", startup.relay_port); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Relay Server TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) - startup.relay_port = atoi(str); - break; - case 32: - uifc.input(WIN_MID|WIN_SAV, 0, 0, "Relay Server Username", startup.relay_user, sizeof(startup.relay_user)-1, K_EDIT); - break; - case 33: - uifc.input(WIN_MID|WIN_SAV, 0, 0, "Relay Server Password", startup.relay_pass, sizeof(startup.relay_pass)-1, K_EDIT); - break; - case 34: - i = 0; - strcpy(opt[i++], "Plain"); - strcpy(opt[i++], "Login"); - strcpy(opt[i++], "CRAM-MD5"); - strcpy(opt[i++], "None"); - opt[i][0] = '\0'; - if(startup.options & MAIL_OPT_RELAY_AUTH_PLAIN) - i = 0; - else if(startup.options & MAIL_OPT_RELAY_AUTH_LOGIN) - i = 1; - else if(startup.options & MAIL_OPT_RELAY_AUTH_CRAM_MD5) - i = 2; - else - i = 3; - if(uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &i, 0, "Relay Server Authentication Method", opt) < 0) - break; - startup.options &= ~(MAIL_OPT_RELAY_AUTH_PLAIN | MAIL_OPT_RELAY_AUTH_LOGIN | MAIL_OPT_RELAY_AUTH_CRAM_MD5); - switch(i) { - case 0: - startup.options |= MAIL_OPT_RELAY_AUTH_PLAIN; - break; - case 1: - startup.options |= MAIL_OPT_RELAY_AUTH_LOGIN; - break; - case 2: - startup.options |= MAIL_OPT_RELAY_AUTH_CRAM_MD5; - break; - } - break; - case 35: - SAFEPRINTF(str, "%u", startup.max_delivery_attempts); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Number of SendMail Delivery Attempts", str, 5, K_NUMBER|K_EDIT) > 0) - startup.max_delivery_attempts = atoi(str); - break; - case 36: - SAFECOPY(str, duration(startup.rescan_frequency, false)); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "MailBase Re-scan Interval", str, 5, K_EDIT) > 0) - startup.rescan_frequency = (uint16_t)parse_duration(str); - break; - case 37: - SAFECOPY(str, duration(startup.connect_timeout, false)); - if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "SendMail Connect Timeout", str, 5, K_EDIT) > 0) - startup.connect_timeout = (uint32_t)parse_duration(str); + sendmail_cfg(&startup); break; default: if(memcmp(&saved_startup, &startup, sizeof(startup)) != 0) @@ -1291,6 +1396,7 @@ static void services_cfg(void) uifc.msgf("Error opening %s", cfg.filename); return; } + uifc.pop(strReadingIniFile); sbbs_read_ini( fp ,cfg.filename @@ -1307,6 +1413,7 @@ static void services_cfg(void) ,&startup ); iniCloseFile(fp); + uifc.pop(NULL); services_startup_t saved_startup = startup; while(1) { @@ -1402,6 +1509,7 @@ void server_cfg(void) uifc.msgf("Error opening %s", cfg.filename); return; } + uifc.pop(strReadingIniFile); sbbs_read_ini( fp ,cfg.filename @@ -1418,14 +1526,15 @@ void server_cfg(void) ,NULL //&services_startup ); iniCloseFile(fp); + uifc.pop(NULL); int i = 0; strcpy(opt[i++], "Global Settings"); - sprintf(opt[i++], "%-27s%s", "Terminal Server", run_bbs ? "Enabled" : strDisabled); - sprintf(opt[i++], "%-27s%s", "Web Server", run_web ? "Enabled" : strDisabled); - sprintf(opt[i++], "%-27s%s", "FTP Server", run_ftp ? "Enabled" : strDisabled); - sprintf(opt[i++], "%-27s%s", "Mail Server", run_mail ? "Enabled" : strDisabled); - sprintf(opt[i++], "%-27s%s", "Services Server", run_services ? "Enabled" : strDisabled); + sprintf(opt[i++], "%-20s%s", "Terminal Server", run_bbs ? "" : strDisabled); + sprintf(opt[i++], "%-20s%s", "Web Server", run_web ? "" : strDisabled); + sprintf(opt[i++], "%-20s%s", "FTP Server", run_ftp ? "" : strDisabled); + sprintf(opt[i++], "%-20s%s", "Mail Server", run_mail ? "" : strDisabled); + sprintf(opt[i++], "%-20s%s", "Services Server", run_services ? "" : strDisabled); opt[i][0] = '\0'; uifc.helpbuf= @@ -1434,12 +1543,12 @@ void server_cfg(void) "Here you can configure the initialization settings of the various\n" "Internet servers that are integrated into Synchronet BBS Software.\n" "\n" - "`Global Settings` Settings that are applied to multiple servers\n" - "`Terminal Server` Handles the traditional BBS user experience\n" - "`Web Server` Handles the modern HTTP/HTTPS browser experience\n" - "`FTP Server` Serves clients using the old File Transfer Protocol\n" - "`Mail Server` Supports SMTP and POP3 mail transfer protocols\n" - "`Services Server` Supports plug-in style servers: NNTP, IRC, IMAP, etc.\n" + "`Global Settings` Settings that are applied to multiple servers\n" + "`Terminal Server` Provides the traditional BBS user experience\n" + "`Web Server` Provides the modern HTTP/HTTPS browser experience\n" + "`FTP Server` Serves clients using ye olde File Transfer Protocol\n" + "`Mail Server` Supports SMTP and POP3 mail transfer protocols\n" + "`Services Server` Supports plug-in style servers: NNTP, IRC, IMAP, etc.\n" "\n" "For additional advanced Synchronet server initialization settings, see\n" "the `ctrl/sbbs.ini` file and `https://wiki.synchro.net/config:sbbs.ini`\n"