diff --git a/src/sbbs3/scfg/scfgsrvr.c b/src/sbbs3/scfg/scfgsrvr.c index 7a34fc49726a95cc85bbf215ae78e07790985cdb..f89c903c21b4f63e79eafbccf0943eb9c5f49431 100644 --- a/src/sbbs3/scfg/scfgsrvr.c +++ b/src/sbbs3/scfg/scfgsrvr.c @@ -54,34 +54,58 @@ static const char* maximum(uint val) return str; } -static void global_cfg(global_startup_t* startup) +static void global_cfg(void) { static int cur; char str[256]; char tmp[256]; uint32_t ip4_addr; + global_startup_t startup = {0}; + + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */false); + if(fp == NULL) { + uifc.msgf("Error opening %s", cfg.filename); + return; + } + sbbs_read_ini( + fp + ,cfg.filename + ,&startup + ,NULL + ,NULL //&bbs_startup + ,NULL + ,NULL //&ftp_startup + ,NULL + ,NULL //&web_startup + ,NULL + ,NULL //&mail_startup + ,NULL + ,NULL //&services_startup + ); + iniCloseFile(fp); + global_startup_t saved_startup = startup; while(1) { int i = 0; - sprintf(opt[i++], "%-40s%s", "Log Level", iniLogLevelStringList()[startup->log_level]); - sprintf(opt[i++], "%-40s%s", "TLS Error Level", iniLogLevelStringList()[startup->tls_error_level]); - sprintf(opt[i++], "%-40s%s", "Network Interfaces (IPv4/6)", strListCombine(startup->interfaces, tmp, sizeof(tmp), ", ")); - 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", "Log Level", iniLogLevelStringList()[startup.log_level]); + sprintf(opt[i++], "%-40s%s", "TLS Error Level", iniLogLevelStringList()[startup.tls_error_level]); + sprintf(opt[i++], "%-40s%s", "Network Interfaces (IPv4/6)", strListCombine(startup.interfaces, tmp, sizeof(tmp), ", ")); + 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)); + ,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)); opt[i][0] = '\0'; uifc.helpbuf= @@ -91,66 +115,96 @@ static void global_cfg(global_startup_t* startup) switch(uifc.list(WIN_ACT|WIN_CHE|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, 0 ,"Global Server Setttings",opt)) { default: + if(memcmp(&saved_startup, &startup, sizeof(startup)) != 0) + uifc.changes = true; + i = save_changes(WIN_MID); + if(i < 0) + continue; + if(i == 0) { + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */true); + if(fp == NULL) + uifc.msgf("Error opening %s", cfg.filename); + else { + if(!sbbs_write_ini( + fp + ,&cfg + ,&startup + ,false + ,NULL + ,false + ,NULL + ,false + ,NULL + ,false + ,NULL + ,false + ,NULL + )) + uifc.msgf("Error writing %s", cfg.filename); + iniCloseFile(fp); + } + } + sbbs_free_ini(&startup + ,NULL //&bbs_startup + ,NULL //&ftp_startup + ,NULL //&web_startup + ,NULL //&mail_startup + ,NULL //&services_startup + ); return; case 0: - i = startup->log_level; + i = startup.log_level; i = uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &i, 0, "Log Level", iniLogLevelStringList()); - if(i >= 0 && startup->log_level != i) { - startup->log_level = i; - uifc.changes = true; + if(i >= 0 && startup.log_level != i) { + startup.log_level = i; } break; case 1: - i = startup->tls_error_level; + i = startup.tls_error_level; i = uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &i, 0, "TLS Error Log Level", iniLogLevelStringList()); - if(i >= 0 && startup->tls_error_level != i) { - startup->tls_error_level = i; - uifc.changes = true; + if(i >= 0 && startup.tls_error_level != i) { + startup.tls_error_level = i; } break; case 2: - strListCombine(startup->interfaces, str, sizeof(str), ", "); + strListCombine(startup.interfaces, str, sizeof(str), ", "); if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Network Interfaces", str, sizeof(str)-1, K_EDIT) >= 0) { - strListFree(&startup->interfaces); - strListSplitCopy(&startup->interfaces, str, ", "); + strListFree(&startup.interfaces); + strListSplitCopy(&startup.interfaces, str, ", "); uifc.changes = true; } break; case 3: - IPv4AddressToStr(ip4_addr = startup->outgoing4.s_addr, str, sizeof(str)); + IPv4AddressToStr(ip4_addr = startup.outgoing4.s_addr, str, sizeof(str)); if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Outbound Network Interface", str, sizeof(str)-1, K_EDIT) > 0) { - if((ip4_addr = parseIPv4Address(str)) != startup->outgoing4.s_addr) { - startup->outgoing4.s_addr = ip4_addr; - uifc.changes = true; + if((ip4_addr = parseIPv4Address(str)) != startup.outgoing4.s_addr) { + startup.outgoing4.s_addr = ip4_addr; } } break; case 4: - SAFECOPY(str, threshold(startup->bind_retry_count)); + SAFECOPY(str, threshold(startup.bind_retry_count)); if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Port Bind Retry Count", str, 6, K_EDIT) > 0) { - if(atoi(str) != startup->bind_retry_count) { - startup->bind_retry_count = atoi(str); - uifc.changes = true; + if(atoi(str) != startup.bind_retry_count) { + startup.bind_retry_count = atoi(str); } } break; case 5: - SAFECOPY(str, duration(startup->bind_retry_delay, false)); + SAFECOPY(str, duration(startup.bind_retry_delay, false)); if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Port Bind Retry Delay", str, 6, K_EDIT) > 0) { uint dur = parse_duration(str); - if(dur != startup->bind_retry_delay) { - startup->bind_retry_delay = dur; - uifc.changes = true; + if(dur != startup.bind_retry_delay) { + startup.bind_retry_delay = dur; } } break; case 6: - SAFEPRINTF(str, "%u", startup->login_attempt.delay); + 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) { uint dur = atoi(str); - if(dur != startup->login_attempt.delay) { - startup->login_attempt.delay = dur; - uifc.changes = true; + if(dur != startup.login_attempt.delay) { + startup.login_attempt.delay = dur; } } break; @@ -158,41 +212,66 @@ static void global_cfg(global_startup_t* startup) } } -static void termsrvr_cfg(BOOL* enabled, bbs_startup_t* startup) +static void termsrvr_cfg(void) { static int cur, bar; char tmp[256]; + BOOL enabled = FALSE; + bbs_startup_t startup = {0}; + + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */false); + if(fp == NULL) { + uifc.msgf("Error opening %s", cfg.filename); + return; + } + sbbs_read_ini( + fp + ,cfg.filename + ,NULL + ,&enabled + ,&startup + ,NULL + ,NULL //&ftp_startup + ,NULL + ,NULL //&web_startup + ,NULL + ,NULL //&mail_startup + ,NULL + ,NULL //&services_startup + ); + iniCloseFile(fp); + bbs_startup_t saved_startup = startup; while(1) { int i = 0; - sprintf(opt[i++], "%-30s%s", "Enabled", *enabled ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Log Level", iniLogLevelStringList()[startup->log_level]); - sprintf(opt[i++], "%-30s%u", "First Node", startup->first_node); - sprintf(opt[i++], "%-30s%u", "Last Node", startup->last_node); - sprintf(opt[i++], "%-30s%s", "DOS Program Support", startup->options & BBS_OPT_NO_DOS ? "No" : "Yes"); - sprintf(opt[i++], "%-30s%s", "SSH Support", startup->options & BBS_OPT_ALLOW_SSH ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "SSH Interfaces", startup->options & BBS_OPT_ALLOW_SSH ? strListCombine(startup->ssh_interfaces, tmp, sizeof(tmp), ", ") : "N/A"); - sprintf(opt[i++], "%-30s%u", "SSH Port", startup->ssh_port); - sprintf(opt[i++], "%-30s%s", "SSH Connect Timeout", startup->options & BBS_OPT_ALLOW_SSH ? vduration(startup->ssh_connect_timeout) : "N/A"); - sprintf(opt[i++], "%-30s%s", "Telnet Support", startup->options & BBS_OPT_NO_TELNET ? "No" : "Yes"); - sprintf(opt[i++], "%-30s%s", "Telnet Interfaces", startup->options & BBS_OPT_NO_TELNET ? "N/A" : strListCombine(startup->telnet_interfaces, tmp, sizeof(tmp), ", ")); - sprintf(opt[i++], "%-30s%u", "Telnet Port", startup->telnet_port); - sprintf(opt[i++], "%-30s%s", "Telnet Command Debug", startup->options & BBS_OPT_NO_TELNET ? "N/A" : startup->options & BBS_OPT_DEBUG_TELNET ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Telnet Send Go-Aheads", startup->options & BBS_OPT_NO_TELNET ? "N/A" : startup->options & BBS_OPT_NO_TELNET_GA ? "No" : "Yes"); - sprintf(opt[i++], "%-30s%s", "RLogin Support", startup->options & BBS_OPT_ALLOW_RLOGIN ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "RLogin Interfaces", startup->options & BBS_OPT_ALLOW_RLOGIN ? strListCombine(startup->rlogin_interfaces, tmp, sizeof(tmp), ", ") : "N/A"); - sprintf(opt[i++], "%-30s%u", "RLogin Port", startup->rlogin_port); - sprintf(opt[i++], "%-30s%u", "40 Column PETSCII Port", startup->pet40_port); - sprintf(opt[i++], "%-30s%u", "80 Column PETSCII Port", startup->pet80_port); - sprintf(opt[i++], "%-30s%s", "Max Concurrent Connections", maximum(startup->max_concurrent_connections)); - sprintf(opt[i++], "%-30s%s", "Max Login Inactivity", vduration(startup->max_login_inactivity)); - sprintf(opt[i++], "%-30s%s", "Max New User Inactivity", vduration(startup->max_newuser_inactivity)); - sprintf(opt[i++], "%-30s%s", "Max User Inactivity", vduration(startup->max_session_inactivity)); - sprintf(opt[i++], "%-30s%u ms", "Output Buffer Drain Timeout", startup->outbuf_drain_timeout); - sprintf(opt[i++], "%-30s%s", "Execute Timed Events", startup->options & BBS_OPT_NO_EVENTS ? "No" : "Yes"); - sprintf(opt[i++], "%-30s%s", "Execute QWK-relatd Events", startup->options & BBS_OPT_NO_EVENTS ? "N/A" : startup->options & BBS_OPT_NO_QWK_EVENTS ? "No" : "Yes"); - sprintf(opt[i++], "%-30s%s", "Lookup Client Hostname", startup->options & BBS_OPT_NO_HOST_LOOKUP ? "No" : "Yes"); - if(!*enabled) + sprintf(opt[i++], "%-30s%s", "Enabled", enabled ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Log Level", iniLogLevelStringList()[startup.log_level]); + sprintf(opt[i++], "%-30s%u", "First Node", startup.first_node); + sprintf(opt[i++], "%-30s%u", "Last Node", startup.last_node); + sprintf(opt[i++], "%-30s%s", "DOS Program Support", startup.options & BBS_OPT_NO_DOS ? "No" : "Yes"); + sprintf(opt[i++], "%-30s%s", "SSH Support", startup.options & BBS_OPT_ALLOW_SSH ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "SSH Interfaces", startup.options & BBS_OPT_ALLOW_SSH ? strListCombine(startup.ssh_interfaces, tmp, sizeof(tmp), ", ") : "N/A"); + sprintf(opt[i++], "%-30s%u", "SSH Port", startup.ssh_port); + sprintf(opt[i++], "%-30s%s", "SSH Connect Timeout", startup.options & BBS_OPT_ALLOW_SSH ? vduration(startup.ssh_connect_timeout) : "N/A"); + sprintf(opt[i++], "%-30s%s", "Telnet Support", startup.options & BBS_OPT_NO_TELNET ? "No" : "Yes"); + sprintf(opt[i++], "%-30s%s", "Telnet Interfaces", startup.options & BBS_OPT_NO_TELNET ? "N/A" : strListCombine(startup.telnet_interfaces, tmp, sizeof(tmp), ", ")); + sprintf(opt[i++], "%-30s%u", "Telnet Port", startup.telnet_port); + sprintf(opt[i++], "%-30s%s", "Telnet Command Debug", startup.options & BBS_OPT_NO_TELNET ? "N/A" : startup.options & BBS_OPT_DEBUG_TELNET ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Telnet Send Go-Aheads", startup.options & BBS_OPT_NO_TELNET ? "N/A" : startup.options & BBS_OPT_NO_TELNET_GA ? "No" : "Yes"); + sprintf(opt[i++], "%-30s%s", "RLogin Support", startup.options & BBS_OPT_ALLOW_RLOGIN ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "RLogin Interfaces", startup.options & BBS_OPT_ALLOW_RLOGIN ? strListCombine(startup.rlogin_interfaces, tmp, sizeof(tmp), ", ") : "N/A"); + sprintf(opt[i++], "%-30s%u", "RLogin Port", startup.rlogin_port); + sprintf(opt[i++], "%-30s%u", "40 Column PETSCII Port", startup.pet40_port); + sprintf(opt[i++], "%-30s%u", "80 Column PETSCII Port", startup.pet80_port); + sprintf(opt[i++], "%-30s%s", "Max Concurrent Connections", maximum(startup.max_concurrent_connections)); + sprintf(opt[i++], "%-30s%s", "Max Login Inactivity", vduration(startup.max_login_inactivity)); + sprintf(opt[i++], "%-30s%s", "Max New User Inactivity", vduration(startup.max_newuser_inactivity)); + sprintf(opt[i++], "%-30s%s", "Max User Inactivity", vduration(startup.max_session_inactivity)); + sprintf(opt[i++], "%-30s%u ms", "Output Buffer Drain Timeout", startup.outbuf_drain_timeout); + sprintf(opt[i++], "%-30s%s", "Execute Timed Events", startup.options & BBS_OPT_NO_EVENTS ? "No" : "Yes"); + sprintf(opt[i++], "%-30s%s", "Execute QWK-relatd Events", startup.options & BBS_OPT_NO_EVENTS ? "N/A" : startup.options & BBS_OPT_NO_QWK_EVENTS ? "No" : "Yes"); + sprintf(opt[i++], "%-30s%s", "Lookup Client Hostname", startup.options & BBS_OPT_NO_HOST_LOOKUP ? "No" : "Yes"); + if(!enabled) i = 1; opt[i][0] = '\0'; @@ -203,61 +282,123 @@ static void termsrvr_cfg(BOOL* enabled, bbs_startup_t* startup) switch(uifc.list(WIN_ACT|WIN_CHE|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar ,"Terminal Server",opt)) { case 0: - *enabled = !*enabled; + enabled = !enabled; + uifc.changes = true; break; case 1: - startup->options ^= BBS_OPT_NO_TELNET; + startup.options ^= BBS_OPT_NO_TELNET; break; case 2: - startup->options ^= BBS_OPT_ALLOW_SSH; + startup.options ^= BBS_OPT_ALLOW_SSH; break; case 3: - startup->options ^= BBS_OPT_ALLOW_RLOGIN; + startup.options ^= BBS_OPT_ALLOW_RLOGIN; break; default: + if(memcmp(&saved_startup, &startup, sizeof(startup)) != 0) + uifc.changes = true; + i = save_changes(WIN_MID); + if(i < 0) + continue; + if(i == 0) { + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */true); + if(fp == NULL) + uifc.msgf("Error opening %s", cfg.filename); + else { + if(!sbbs_write_ini( + fp + ,&cfg + ,NULL + ,enabled + ,&startup + ,false + ,NULL + ,false + ,NULL + ,false + ,NULL + ,false + ,NULL + )) + uifc.msgf("Error writing %s", cfg.filename); + iniCloseFile(fp); + } + } + sbbs_free_ini(NULL + ,&startup + ,NULL //&ftp_startup + ,NULL //&web_startup + ,NULL //&mail_startup + ,NULL //&services_startup + ); return; } } } -static void websrvr_cfg(BOOL* enabled, web_startup_t* startup) +static void websrvr_cfg(void) { static int cur, bar; char tmp[256]; + BOOL enabled = FALSE; + web_startup_t startup = {0}; + + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */false); + if(fp == NULL) { + uifc.msgf("Error opening %s", cfg.filename); + return; + } + sbbs_read_ini( + fp + ,cfg.filename + ,NULL + ,NULL + ,NULL + ,NULL + ,NULL //&ftp_startup + ,&enabled + ,&startup + ,NULL + ,NULL //&mail_startup + ,NULL + ,NULL //&services_startup + ); + iniCloseFile(fp); + web_startup_t saved_startup = startup; while(1) { int i = 0; - sprintf(opt[i++], "%-30s%s", "Enabled", *enabled ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Log Level", iniLogLevelStringList()[startup->log_level]); - sprintf(opt[i++], "%-30s%s", "HTTP Interfaces", strListCombine(startup->interfaces, tmp, sizeof(tmp), ", ")); - sprintf(opt[i++], "%-30s%u", "HTTP Port", startup->port); - sprintf(opt[i++], "%-30s%s", "HTTPS Support", startup->options & WEB_OPT_ALLOW_TLS ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "HTTPS Interfaces", startup->options & WEB_OPT_ALLOW_TLS ? strListCombine(startup->tls_interfaces, tmp, sizeof(tmp), ", ") : "N/A"); - sprintf(opt[i++], "%-30s%u", "HTTPS Port", startup->tls_port); - sprintf(opt[i++], "%-30s%s", "SSJS File Extension", startup->ssjs_ext); - sprintf(opt[i++], "%-30s%s", "Index Filenames", strListCombine(startup->index_file_name, tmp, sizeof(tmp), ", ")); - sprintf(opt[i++], "%-30s%s", "Content Root Directory", startup->root_dir); - sprintf(opt[i++], "%-30s%s", "Error Sub-directory", startup->error_dir); - sprintf(opt[i++], "%-30s%s", "Strict Transport Security", startup->options & WEB_OPT_HSTS_SAFE ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Virtual Host Support", startup->options & WEB_OPT_VIRTUAL_HOSTS ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Access Logging", startup->options & WEB_OPT_HTTP_LOGGING ? startup->logfile_base : strDisabled); - sprintf(opt[i++], "%-30s%s", "Max Clients", maximum(startup->max_clients)); - sprintf(opt[i++], "%-30s%s", "Max Inactivity", vduration(startup->max_inactivity)); - sprintf(opt[i++], "%-30s%s", "Filebase Index Script", startup->file_index_script); - sprintf(opt[i++], "%-30s%s", "Filebase VPath Prefix", startup->file_vpath_prefix); - sprintf(opt[i++], "%-30s%s", "Filebase VPath for VHosts", startup->file_vpath_for_vhosts ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Authentication Methods", startup->default_auth_list); - sprintf(opt[i++], "%-30s%u ms", "Output Buffer Drain Timeout", startup->outbuf_drain_timeout); - sprintf(opt[i++], "%-30s%s", "Lookup Client Hostname", startup->options & BBS_OPT_NO_HOST_LOOKUP ? "No" : "Yes"); - bool cgi_enabled = !(startup->options & WEB_OPT_NO_CGI); + sprintf(opt[i++], "%-30s%s", "Enabled", enabled ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Log Level", iniLogLevelStringList()[startup.log_level]); + sprintf(opt[i++], "%-30s%s", "HTTP Interfaces", strListCombine(startup.interfaces, tmp, sizeof(tmp), ", ")); + sprintf(opt[i++], "%-30s%u", "HTTP Port", startup.port); + sprintf(opt[i++], "%-30s%s", "HTTPS Support", startup.options & WEB_OPT_ALLOW_TLS ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "HTTPS Interfaces", startup.options & WEB_OPT_ALLOW_TLS ? strListCombine(startup.tls_interfaces, tmp, sizeof(tmp), ", ") : "N/A"); + sprintf(opt[i++], "%-30s%u", "HTTPS Port", startup.tls_port); + sprintf(opt[i++], "%-30s%s", "SSJS File Extension", startup.ssjs_ext); + sprintf(opt[i++], "%-30s%s", "Index Filenames", strListCombine(startup.index_file_name, tmp, sizeof(tmp), ", ")); + sprintf(opt[i++], "%-30s%s", "Content Root Directory", startup.root_dir); + sprintf(opt[i++], "%-30s%s", "Error Sub-directory", startup.error_dir); + sprintf(opt[i++], "%-30s%s", "Strict Transport Security", startup.options & WEB_OPT_HSTS_SAFE ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Virtual Host Support", startup.options & WEB_OPT_VIRTUAL_HOSTS ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Access Logging", startup.options & WEB_OPT_HTTP_LOGGING ? startup.logfile_base : strDisabled); + sprintf(opt[i++], "%-30s%s", "Max Clients", maximum(startup.max_clients)); + sprintf(opt[i++], "%-30s%s", "Max Inactivity", vduration(startup.max_inactivity)); + sprintf(opt[i++], "%-30s%s", "Filebase Index Script", startup.file_index_script); + sprintf(opt[i++], "%-30s%s", "Filebase VPath Prefix", startup.file_vpath_prefix); + sprintf(opt[i++], "%-30s%s", "Filebase VPath for VHosts", startup.file_vpath_for_vhosts ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Authentication Methods", startup.default_auth_list); + sprintf(opt[i++], "%-30s%u ms", "Output Buffer Drain Timeout", startup.outbuf_drain_timeout); + sprintf(opt[i++], "%-30s%s", "Lookup Client Hostname", startup.options & BBS_OPT_NO_HOST_LOOKUP ? "No" : "Yes"); + bool cgi_enabled = !(startup.options & WEB_OPT_NO_CGI); sprintf(opt[i++], "%-30s%s", "CGI Support", cgi_enabled ? "Yes" : "No"); if(cgi_enabled) { - sprintf(opt[i++], "%-30s%s", "CGI Directory", startup->cgi_dir); - sprintf(opt[i++], "%-30s%s", "CGI File Extensions", strListCombine(startup->cgi_ext, tmp, sizeof(tmp), ", ")); - sprintf(opt[i++], "%-30s%s", "CGI Default Content-Type", startup->default_cgi_content); - sprintf(opt[i++], "%-30s%s", "CGI Max Inactivity", vduration(startup->max_cgi_inactivity)); + sprintf(opt[i++], "%-30s%s", "CGI Directory", startup.cgi_dir); + sprintf(opt[i++], "%-30s%s", "CGI File Extensions", strListCombine(startup.cgi_ext, tmp, sizeof(tmp), ", ")); + sprintf(opt[i++], "%-30s%s", "CGI Default Content-Type", startup.default_cgi_content); + sprintf(opt[i++], "%-30s%s", "CGI Max Inactivity", vduration(startup.max_cgi_inactivity)); } - if(!*enabled) + if(!enabled) i = 1; opt[i][0] = '\0'; @@ -268,40 +409,102 @@ static void websrvr_cfg(BOOL* enabled, web_startup_t* startup) switch(uifc.list(WIN_ACT|WIN_CHE|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar ,"Web Server",opt)) { case 0: - *enabled = !*enabled; + enabled = !enabled; + uifc.changes = true; break; case 2: - startup->options ^= WEB_OPT_ALLOW_TLS; + startup.options ^= WEB_OPT_ALLOW_TLS; break; default: + if(memcmp(&saved_startup, &startup, sizeof(startup)) != 0) + uifc.changes = true; + i = save_changes(WIN_MID); + if(i < 0) + continue; + if(i == 0) { + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */true); + if(fp == NULL) + uifc.msgf("Error opening %s", cfg.filename); + else { + if(!sbbs_write_ini( + fp + ,&cfg + ,NULL + ,FALSE + ,NULL + ,false + ,NULL + ,enabled + ,&startup + ,false + ,NULL + ,false + ,NULL + )) + uifc.msgf("Error writing %s", cfg.filename); + iniCloseFile(fp); + } + } + sbbs_free_ini(NULL + ,NULL + ,NULL //&ftp_startup + ,&startup + ,NULL //&mail_startup + ,NULL //&services_startup + ); return; } } } -static void ftpsrvr_cfg(BOOL* enabled, ftp_startup_t* startup) +static void ftpsrvr_cfg(void) { static int cur, bar; char tmp[256]; + BOOL enabled = FALSE; + ftp_startup_t startup = {0}; + + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */false); + if(fp == NULL) { + uifc.msgf("Error opening %s", cfg.filename); + return; + } + sbbs_read_ini( + fp + ,cfg.filename + ,NULL + ,NULL + ,NULL + ,&enabled + ,&startup + ,NULL + ,NULL + ,NULL + ,NULL //&mail_startup + ,NULL + ,NULL //&services_startup + ); + iniCloseFile(fp); + ftp_startup_t saved_startup = startup; while(1) { int i = 0; - sprintf(opt[i++], "%-30s%s", "Enabled", *enabled ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Log Level", iniLogLevelStringList()[startup->log_level]); - sprintf(opt[i++], "%-30s%s", "Network Interfaces", strListCombine(startup->interfaces, tmp, sizeof(tmp), ", ")); - sprintf(opt[i++], "%-30s%u, Data: %u", "Control Port", startup->port, startup->port - 1); - sprintf(opt[i++], "%-30s%s", "Passive Interface (IPv4)", startup->options & FTP_OPT_LOOKUP_PASV_IP ? "<automatic>" : IPv4AddressToStr(startup->pasv_ip_addr.s_addr, tmp, sizeof(tmp))); - sprintf(opt[i++], "%-30s%u - %u", "Passive Port Range", startup->pasv_port_low, startup->pasv_port_high); - sprintf(opt[i++], "%-30s%s", "Auto-generate Index File", startup->options & FTP_OPT_INDEX_FILE ? startup->index_file_name : strDisabled); - sprintf(opt[i++], "%-30s%s", "QWK Message Packet Transfers", startup->options & FTP_OPT_ALLOW_QWK ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "QWK Message Packet Timeout", startup->options & FTP_OPT_ALLOW_QWK ? vduration(startup->qwk_timeout) : "N/A"); - sprintf(opt[i++], "%-30s%s", "Max Clients", maximum(startup->max_clients)); - sprintf(opt[i++], "%-30s%s", "Max Inactivity", vduration(startup->max_inactivity)); - sprintf(opt[i++], "%-30s%s", "Max Concurrent Connections", maximum(startup->max_concurrent_connections)); - sprintf(opt[i++], "%-30s%s", "Sysop Filesystem Access", startup->options & FTP_OPT_NO_LOCAL_FSYS ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Allow Bounce Transfers", startup->options & FTP_OPT_ALLOW_BOUNCE ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Lookup Client Hostname", startup->options & BBS_OPT_NO_HOST_LOOKUP ? "No" : "Yes"); - if(!*enabled) + sprintf(opt[i++], "%-30s%s", "Enabled", enabled ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Log Level", iniLogLevelStringList()[startup.log_level]); + sprintf(opt[i++], "%-30s%s", "Network Interfaces", strListCombine(startup.interfaces, tmp, sizeof(tmp), ", ")); + sprintf(opt[i++], "%-30s%u, Data: %u", "Control Port", startup.port, startup.port - 1); + sprintf(opt[i++], "%-30s%s", "Passive Interface (IPv4)", startup.options & FTP_OPT_LOOKUP_PASV_IP ? "<automatic>" : IPv4AddressToStr(startup.pasv_ip_addr.s_addr, tmp, sizeof(tmp))); + sprintf(opt[i++], "%-30s%u - %u", "Passive Port Range", startup.pasv_port_low, startup.pasv_port_high); + sprintf(opt[i++], "%-30s%s", "Auto-generate Index File", startup.options & FTP_OPT_INDEX_FILE ? startup.index_file_name : strDisabled); + sprintf(opt[i++], "%-30s%s", "QWK Message Packet Transfers", startup.options & FTP_OPT_ALLOW_QWK ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "QWK Message Packet Timeout", startup.options & FTP_OPT_ALLOW_QWK ? vduration(startup.qwk_timeout) : "N/A"); + sprintf(opt[i++], "%-30s%s", "Max Clients", maximum(startup.max_clients)); + sprintf(opt[i++], "%-30s%s", "Max Inactivity", vduration(startup.max_inactivity)); + sprintf(opt[i++], "%-30s%s", "Max Concurrent Connections", maximum(startup.max_concurrent_connections)); + sprintf(opt[i++], "%-30s%s", "Sysop Filesystem Access", startup.options & FTP_OPT_NO_LOCAL_FSYS ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Allow Bounce Transfers", startup.options & FTP_OPT_ALLOW_BOUNCE ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Lookup Client Hostname", startup.options & BBS_OPT_NO_HOST_LOOKUP ? "No" : "Yes"); + if(!enabled) i = 1; opt[i][0] = '\0'; @@ -312,82 +515,144 @@ static void ftpsrvr_cfg(BOOL* enabled, ftp_startup_t* startup) switch(uifc.list(WIN_ACT|WIN_CHE|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar ,"FTP Server",opt)) { case 0: - *enabled = !*enabled; + enabled = !enabled; + uifc.changes = true; break; default: + if(memcmp(&saved_startup, &startup, sizeof(startup)) != 0) + uifc.changes = true; + i = save_changes(WIN_MID); + if(i < 0) + continue; + if(i == 0) { + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */true); + if(fp == NULL) + uifc.msgf("Error opening %s", cfg.filename); + else { + if(!sbbs_write_ini( + fp + ,&cfg + ,NULL + ,FALSE + ,NULL + ,enabled + ,&startup + ,false + ,NULL + ,false + ,NULL + ,false + ,NULL + )) + uifc.msgf("Error writing %s", cfg.filename); + iniCloseFile(fp); + } + } + sbbs_free_ini(NULL + ,NULL + ,&startup + ,NULL + ,NULL //&mail_startup + ,NULL //&services_startup + ); return; } } } -static void mailsrvr_cfg(BOOL* enabled, mail_startup_t* startup) +static void mailsrvr_cfg(void) { static int cur, bar; char tmp[256]; const char* p; + BOOL enabled = FALSE; + mail_startup_t startup = {0}; + + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */false); + if(fp == NULL) { + uifc.msgf("Error opening %s", cfg.filename); + return; + } + sbbs_read_ini( + fp + ,cfg.filename + ,NULL + ,NULL + ,NULL + ,NULL + ,NULL + ,NULL + ,NULL + ,&enabled + ,&startup + ,NULL + ,NULL //&services_startup + ); + iniCloseFile(fp); + mail_startup_t saved_startup = startup; while(1) { int i = 0; - sprintf(opt[i++], "%-30s%s", "Enabled", *enabled ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Log Level", iniLogLevelStringList()[startup->log_level]); - sprintf(opt[i++], "%-30s%s", "SMTP Interfaces", strListCombine(startup->interfaces, tmp, sizeof(tmp), ", ")); - sprintf(opt[i++], "%-30s%u", "SMTP Port", startup->smtp_port); - sprintf(opt[i++], "%-30s%s", "Submission Support", startup->options & MAIL_OPT_USE_SUBMISSION_PORT ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%u", "Submission Port", startup->submission_port); - sprintf(opt[i++], "%-30s%s", "Submission/TLS Support", startup->options & MAIL_OPT_TLS_SUBMISSION ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%u", "Submission/TLS Port", startup->submissions_port); - sprintf(opt[i++], "%-30s%s", "POP3 Support", startup->options & MAIL_OPT_ALLOW_POP3 ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Enabled", enabled ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Log Level", iniLogLevelStringList()[startup.log_level]); + sprintf(opt[i++], "%-30s%s", "SMTP Interfaces", strListCombine(startup.interfaces, tmp, sizeof(tmp), ", ")); + sprintf(opt[i++], "%-30s%u", "SMTP Port", startup.smtp_port); + sprintf(opt[i++], "%-30s%s", "Submission Support", startup.options & MAIL_OPT_USE_SUBMISSION_PORT ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%u", "Submission Port", startup.submission_port); + sprintf(opt[i++], "%-30s%s", "Submission/TLS Support", startup.options & MAIL_OPT_TLS_SUBMISSION ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%u", "Submission/TLS Port", startup.submissions_port); + sprintf(opt[i++], "%-30s%s", "POP3 Support", startup.options & MAIL_OPT_ALLOW_POP3 ? "Yes" : "No"); sprintf(opt[i++], "%-30s%s", "POP3 Interfaces" - ,startup->options & (MAIL_OPT_ALLOW_POP3 | MAIL_OPT_TLS_POP3) - ? strListCombine(startup->pop3_interfaces, tmp, sizeof(tmp), ", ") : "N/A"); - sprintf(opt[i++], "%-30s%u", "POP3 Port", startup->pop3_port); - sprintf(opt[i++], "%-30s%s", "POP3/TLS Support", startup->options & MAIL_OPT_TLS_POP3 ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%u", "POP3/TLS Port", startup->pop3s_port); - sprintf(opt[i++], "%-30s%s", "Max Clients", maximum(startup->max_clients)); - sprintf(opt[i++], "%-30s%s", "Max Inactivity", vduration(startup->max_inactivity)); - sprintf(opt[i++], "%-30s%s", "Max Concurrent Connections", maximum(startup->max_concurrent_connections)); - sprintf(opt[i++], "%-30s%s", "Max Recipients Per Message", maximum(startup->max_recipients)); - sprintf(opt[i++], "%-30s%s", "Max Messages Waiting", maximum(startup->max_msgs_waiting)); - sprintf(opt[i++], "%-30s%s bytes", "Max Receive Message Size", byte_count_to_str(startup->max_msg_size, tmp, sizeof(tmp))); - sprintf(opt[i++], "%-30s%s", "Allow Users to Relay Mail", startup->options & MAIL_OPT_ALLOW_RELAY ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Receive By Sysop Aliases", startup->options & MAIL_OPT_ALLOW_SYSOP_ALIASES ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Notify Local Recipients", startup->options & MAIL_OPT_NO_NOTIFY ? "No" : "Yes"); - sprintf(opt[i++], "%-30s%s", "Lookup Client Hostname", startup->options & BBS_OPT_NO_HOST_LOOKUP ? "No" : "Yes"); - sprintf(opt[i++], "%-30s%s", "Check Headers against DNSBL", startup->options & MAIL_OPT_DNSBL_CHKRECVHDRS ? "Yes" : "No"); - if(startup->options & MAIL_OPT_DNSBL_REFUSE) + ,startup.options & (MAIL_OPT_ALLOW_POP3 | MAIL_OPT_TLS_POP3) + ? strListCombine(startup.pop3_interfaces, tmp, sizeof(tmp), ", ") : "N/A"); + sprintf(opt[i++], "%-30s%u", "POP3 Port", startup.pop3_port); + sprintf(opt[i++], "%-30s%s", "POP3/TLS Support", startup.options & MAIL_OPT_TLS_POP3 ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%u", "POP3/TLS Port", startup.pop3s_port); + sprintf(opt[i++], "%-30s%s", "Max Clients", maximum(startup.max_clients)); + sprintf(opt[i++], "%-30s%s", "Max Inactivity", vduration(startup.max_inactivity)); + sprintf(opt[i++], "%-30s%s", "Max Concurrent Connections", maximum(startup.max_concurrent_connections)); + sprintf(opt[i++], "%-30s%s", "Max Recipients Per Message", maximum(startup.max_recipients)); + sprintf(opt[i++], "%-30s%s", "Max Messages Waiting", maximum(startup.max_msgs_waiting)); + sprintf(opt[i++], "%-30s%s bytes", "Max Receive Message Size", byte_count_to_str(startup.max_msg_size, tmp, sizeof(tmp))); + sprintf(opt[i++], "%-30s%s", "Allow Users to Relay Mail", startup.options & MAIL_OPT_ALLOW_RELAY ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Receive By Sysop Aliases", startup.options & MAIL_OPT_ALLOW_SYSOP_ALIASES ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Notify Local Recipients", startup.options & MAIL_OPT_NO_NOTIFY ? "No" : "Yes"); + sprintf(opt[i++], "%-30s%s", "Lookup Client Hostname", startup.options & BBS_OPT_NO_HOST_LOOKUP ? "No" : "Yes"); + sprintf(opt[i++], "%-30s%s", "Check Headers against DNSBL", startup.options & MAIL_OPT_DNSBL_CHKRECVHDRS ? "Yes" : "No"); + if(startup.options & MAIL_OPT_DNSBL_REFUSE) p = "Refuse Session"; - else if(startup->options & MAIL_OPT_DNSBL_IGNORE) + else if(startup.options & MAIL_OPT_DNSBL_IGNORE) p = "Silently Ignore"; - else if(startup->options & MAIL_OPT_DNSBL_BADUSER) + else if(startup.options & MAIL_OPT_DNSBL_BADUSER) p = "Refuse Mail"; - else if(startup->options) + else if(startup.options) p = "Tag Mail"; - sprintf(opt[i++], "%-30s%s%s", "Blacklisted Servers", startup->options & MAIL_OPT_DNSBL_THROTTLE ? "Throttle and " : "", p); - 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%s", "Blacklisted Servers", startup.options & MAIL_OPT_DNSBL_THROTTLE ? "Throttle and " : "", p); + 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) + 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) + else if(startup.options & MAIL_OPT_RELAY_AUTH_LOGIN) p = "Login"; - else if(startup->options & MAIL_OPT_RELAY_AUTH_CRAM_MD5) + 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%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)); } - if(!*enabled) + if(!enabled) i = 1; opt[i][0] = '\0'; @@ -398,27 +663,89 @@ static void mailsrvr_cfg(BOOL* enabled, mail_startup_t* startup) switch(uifc.list(WIN_ACT|WIN_CHE|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar ,"Mail Server",opt)) { case 0: - *enabled = !*enabled; + enabled = !enabled; + uifc.changes = true; break; default: + if(memcmp(&saved_startup, &startup, sizeof(startup)) != 0) + uifc.changes = true; + i = save_changes(WIN_MID); + if(i < 0) + continue; + if(i == 0) { + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */true); + if(fp == NULL) + uifc.msgf("Error opening %s", cfg.filename); + else { + if(!sbbs_write_ini( + fp + ,&cfg + ,NULL + ,FALSE + ,NULL + ,false + ,NULL + ,false + ,NULL + ,enabled + ,&startup + ,false + ,NULL + )) + uifc.msgf("Error writing %s", cfg.filename); + iniCloseFile(fp); + } + } + sbbs_free_ini(NULL + ,NULL + ,NULL + ,NULL + ,&startup + ,NULL //&services_startup + ); return; } } } -static void services_cfg(BOOL* enabled, services_startup_t* startup) +static void services_cfg(void) { static int cur, bar; char tmp[256]; + BOOL enabled = FALSE; + services_startup_t startup = {0}; + + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */false); + if(fp == NULL) { + uifc.msgf("Error opening %s", cfg.filename); + return; + } + sbbs_read_ini( + fp + ,cfg.filename + ,NULL + ,NULL + ,NULL + ,NULL + ,NULL + ,NULL + ,NULL + ,NULL + ,NULL + ,&enabled + ,&startup + ); + iniCloseFile(fp); + services_startup_t saved_startup = startup; while(1) { int i = 0; - sprintf(opt[i++], "%-30s%s", "Enabled", *enabled ? "Yes" : "No"); - sprintf(opt[i++], "%-30s%s", "Log Level", iniLogLevelStringList()[startup->log_level]); - sprintf(opt[i++], "%-30s%s", "Network Interfaces", strListCombine(startup->interfaces, tmp, sizeof(tmp), ", ")); - sprintf(opt[i++], "%-30s%s", "Lookup Client Hostname", startup->options & BBS_OPT_NO_HOST_LOOKUP ? "No" : "Yes"); - sprintf(opt[i++], "%-30s%s", "Configuration File", startup->services_ini); - if(!*enabled) + sprintf(opt[i++], "%-30s%s", "Enabled", enabled ? "Yes" : "No"); + sprintf(opt[i++], "%-30s%s", "Log Level", iniLogLevelStringList()[startup.log_level]); + sprintf(opt[i++], "%-30s%s", "Network Interfaces", strListCombine(startup.interfaces, tmp, sizeof(tmp), ", ")); + sprintf(opt[i++], "%-30s%s", "Lookup Client Hostname", startup.options & BBS_OPT_NO_HOST_LOOKUP ? "No" : "Yes"); + sprintf(opt[i++], "%-30s%s", "Configuration File", startup.services_ini); + if(!enabled) i = 1; opt[i][0] = '\0'; @@ -429,9 +756,46 @@ static void services_cfg(BOOL* enabled, services_startup_t* startup) switch(uifc.list(WIN_ACT|WIN_CHE|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar ,"Services Server",opt)) { case 0: - *enabled = !*enabled; + enabled = !enabled; + uifc.changes = true; break; default: + if(memcmp(&saved_startup, &startup, sizeof(startup)) != 0) + uifc.changes = true; + i = save_changes(WIN_MID); + if(i < 0) + continue; + if(i == 0) { + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */true); + if(fp == NULL) + uifc.msgf("Error opening %s", cfg.filename); + else { + if(!sbbs_write_ini( + fp + ,&cfg + ,NULL + ,FALSE + ,NULL + ,false + ,NULL + ,false + ,NULL + ,false + ,NULL + ,enabled + ,&startup + )) + uifc.msgf("Error writing %s", cfg.filename); + iniCloseFile(fp); + } + } + sbbs_free_ini(NULL + ,NULL + ,NULL + ,NULL + ,NULL + ,&startup + ); return; } } @@ -440,39 +804,33 @@ static void services_cfg(BOOL* enabled, services_startup_t* startup) void server_cfg(void) { static int srvr_dflt; - BOOL run_bbs, run_ftp, run_web, run_mail, run_services; - global_startup_t global_startup = {0}; - bbs_startup_t bbs_startup = {0}; - ftp_startup_t ftp_startup = {0}; - web_startup_t web_startup = {0}; - mail_startup_t mail_startup = {0}; - services_startup_t services_startup = {0}; sbbs_get_ini_fname(cfg.filename, cfg.ctrl_dir); - FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */false); - if(fp == NULL) { - uifc.msgf("Error opening %s", cfg.filename); - return; - } - sbbs_read_ini( - fp - ,cfg.filename - ,&global_startup - ,&run_bbs - ,&bbs_startup - ,&run_ftp - ,&ftp_startup - ,&run_web - ,&web_startup - ,&run_mail - ,&mail_startup - ,&run_services - ,&services_startup - ); - iniCloseFile(fp); while(1) { + FILE* fp = iniOpenFile(cfg.filename, /* for_modify? */false); + if(fp == NULL) { + uifc.msgf("Error opening %s", cfg.filename); + return; + } + sbbs_read_ini( + fp + ,cfg.filename + ,NULL //&global_startup + ,&run_bbs + ,NULL //&bbs_startup + ,&run_ftp + ,NULL //&ftp_startup + ,&run_web + ,NULL //&web_startup + ,&run_mail + ,NULL //&mail_startup + ,&run_services + ,NULL //&services_startup + ); + iniCloseFile(fp); + int i = 0; strcpy(opt[i++], "Global Settings"); sprintf(opt[i++], "%-27s%s", "Terminal Server", run_bbs ? "Enabled" : strDisabled); @@ -492,61 +850,58 @@ void server_cfg(void) "the `ctrl/sbbs.ini` file and `https://wiki.synchro.net/config:sbbs.ini`\n" "for reference.\n" ; - switch(uifc.list(WIN_ORG|WIN_ACT|WIN_CHE,0,0,0,&srvr_dflt,0 - ,"Server Configuration",opt)) { + i = uifc.list(WIN_ORG|WIN_ACT|WIN_CHE,0,0,0,&srvr_dflt,0, "Server Configuration",opt); + if(i < 0) { +#if 0 + i = save_changes(WIN_MID); + if(i < 0) + continue; + if(i == 0) { + fp = iniOpenFile(cfg.filename, /* for_modify? */true); + if(fp == NULL) + uifc.msgf("Error opening %s", cfg.filename); + else { + if(!sbbs_write_ini( + fp + ,&cfg + ,&global_startup + ,run_bbs + ,&bbs_startup + ,run_ftp + ,&ftp_startup + ,run_web + ,&web_startup + ,run_mail + ,&mail_startup + ,run_services + ,&services_startup + )) + uifc.msgf("Error writing %s", cfg.filename); + iniCloseFile(fp); + } + } +#endif + break; + } + switch(i) { case 0: - global_cfg(&global_startup); + global_cfg(); break; case 1: - termsrvr_cfg(&run_bbs, &bbs_startup); + termsrvr_cfg(); break; case 2: - websrvr_cfg(&run_web, &web_startup); + websrvr_cfg(); break; case 3: - ftpsrvr_cfg(&run_ftp, &ftp_startup); + ftpsrvr_cfg(); break; case 4: - mailsrvr_cfg(&run_mail, &mail_startup); + mailsrvr_cfg(); break; case 5: - services_cfg(&run_services, &services_startup); + services_cfg(); break; - default: - i = save_changes(WIN_MID); - if(i < 0) - continue; - if(i == 0) { - fp = iniOpenFile(cfg.filename, /* for_modify? */true); - if(fp == NULL) - uifc.msgf("Error opening %s", cfg.filename); - else { - if(!sbbs_write_ini( - fp - ,&cfg - ,&global_startup - ,run_bbs - ,&bbs_startup - ,run_ftp - ,&ftp_startup - ,run_web - ,&web_startup - ,run_mail - ,&mail_startup - ,run_services - ,&services_startup - )) - uifc.msgf("Error writing %s", cfg.filename); - iniCloseFile(fp); - } - } - sbbs_free_ini(&global_startup - ,&bbs_startup - ,&ftp_startup - ,&web_startup - ,&mail_startup - ,&services_startup); - return; } } }