diff --git a/ctrl/main.ini b/ctrl/main.ini index 0edda5a710618a50ddd7e88d692fb3b238af626d..06c33f757ade3c1740d7dc9d55fa71a4fec4afa1 100644 --- a/ctrl/main.ini +++ b/ctrl/main.ini @@ -24,6 +24,8 @@ min_password_length=4 max_log_size=0 max_logs_kept=0 ctrlkey_passthru=0 +max_getkey_inactivity=5M +inactivity_warn=75 user_backup_level=5 mail_backup_level=5 valuser=0 @@ -58,6 +60,8 @@ editor=FSEDITOR expiration_days=0 command_shell=DEFAULT settings=0x6910 +chat_settings=0x10 +qwk_settings=0x10b download_protocol=Z msgscan_init=0 gender_options=MFX @@ -107,15 +111,21 @@ scanposts= scansubs= listmsgs=msglist textsec=text_sec +chatsec=chat_sec automsg=automsg -xtrnsec=xtrn_sec +feedback= userlist=userlist nodelist=nodelist whosonline=nodelist -active privatemsg=privatemsg logonlist=logonlist +xtrnsec=xtrn_sec prextrn=prextrn postxtrn=postxtrn +scandirs= +listfiles= +fileinfo= +batxfer= tempxfer=tempxfer [valset:0] level=10 diff --git a/ctrl/xtrn.ini b/ctrl/xtrn.ini index 04ee305325d7b0cf7c20be996cd053220fab1de9..d5b60866f9311a764b55c26c0f11d7edaad79943 100644 --- a/ctrl/xtrn.ini +++ b/ctrl/xtrn.ini @@ -44,6 +44,7 @@ clean_cmd= startup_dir= textra=0 max_time=0 +max_inactivity=0 [prog:MAIN:SBBSLIST] name=Synchronet BBS List ars= @@ -57,6 +58,7 @@ clean_cmd= startup_dir= textra=0 max_time=0 +max_inactivity=0 [prog:MAIN:AVATCHOO] name=Avatar Chooser ars=ANSI AND !GUEST @@ -70,6 +72,7 @@ clean_cmd= startup_dir= textra=0 max_time=0 +max_inactivity=0 [prog:GAMES:MSWEEPER] name=Synchronet Minesweeper ars= @@ -83,6 +86,7 @@ clean_cmd= startup_dir=../xtrn/minesweeper/ textra=0 max_time=0 +max_inactivity=0 [prog:OPERATOR:SCFGANSI] name=Synchronet Configuration (ANSI) ars=ANSI @@ -96,6 +100,7 @@ clean_cmd= startup_dir= textra=0 max_time=0 +max_inactivity=0 [prog:OPERATOR:SCFGDUMB] name=Synchronet Configuration (dumb) ars= @@ -109,6 +114,7 @@ clean_cmd= startup_dir= textra=0 max_time=0 +max_inactivity=0 [prog:OPERATOR:CHKSETUP] name=Check Setup ars= @@ -122,6 +128,7 @@ clean_cmd= startup_dir= textra=0 max_time=0 +max_inactivity=0 [prog:OPERATOR:FTNSETUP] name=Initial FidoNet Setup ars= @@ -135,6 +142,7 @@ clean_cmd= startup_dir= textra=0 max_time=0 +max_inactivity=0 [prog:OPERATOR:FIDOCFGA] name=FidoNet Configuration (ANSI) ars=ANSI @@ -148,6 +156,7 @@ clean_cmd= startup_dir= textra=0 max_time=0 +max_inactivity=0 [prog:OPERATOR:FIDOCFGD] name=FidoNet Configuration (dumb) ars= @@ -161,6 +170,7 @@ clean_cmd= startup_dir= textra=0 max_time=0 +max_inactivity=0 [prog:OPERATOR:XSETUP] name=Auto-install New External Programs ars= @@ -174,6 +184,7 @@ clean_cmd= startup_dir= textra=0 max_time=0 +max_inactivity=0 [event:FIDOIN] cmd=%!sbbsecho%. -ce days=128 diff --git a/exec/init-fidonet.js b/exec/init-fidonet.js index ffc140aa95937817f84b695092a2574306da87c4..28f2c380ba2a2def1abff86078aedae39998a20c 100644 --- a/exec/init-fidonet.js +++ b/exec/init-fidonet.js @@ -613,7 +613,7 @@ if(your.node === temp_node && network.email && network.email.indexOf('@') > 0 if(!find_sys_addr(fidoaddr.to_str(your)) && confirm("Add node address " + fidoaddr.to_str(your) + " to your configuration")) { var fido_addr_list = msgs_ini.iniGetValue("fidonet", "addr_list", []); - fido_addr_list.push(your); + fido_addr_list.push(fidoaddr.to_str(your)); msgs_ini.iniSetValue("fidonet", "addr_list", fido_addr_list); } diff --git a/node1/node.ini b/node1/node.ini index 85f13e34cc9032a23890e47a150d8ccf5ca5307c..11bf22013e06215e44dc68471b208fb0f8be2c86 100644 --- a/node1/node.ini +++ b/node1/node.ini @@ -1,27 +1,8 @@ -number=1 -name=Node 1 -phone=XXX-XXX-XXXX -comspec= -settings=33298 -ivt=1 -swap=2 -swapdir= -valuser=1 -minbps=300 -ars= -dollars_per_call=0 -editor= -viewer=%!list %f +phone=N/A daily= -scrnlen=0 -scrnblank=0 text_dir=../text/ -temp_dir=temp\ -mdm_hang= -sem_check=5 -stat_check=5 -scfg_cmd=%!scfg %k /t%w -sec_warn=180 -sec_hangup=300 -erruser=0 -errlevel=2 +temp_dir=temp +ars= +settings=0 +sem_check=0 +stat_check=0 diff --git a/src/sbbs3/ringbuf.c b/src/sbbs3/ringbuf.c index a982ba9138802522dc49365f1df9fff307b9ec37..a0745bf6a09861552eaef2a8fb81d0a4ce918c51 100644 --- a/src/sbbs3/ringbuf.c +++ b/src/sbbs3/ringbuf.c @@ -1,9 +1,5 @@ -/* ringbuf.c */ - /* Synchronet ring buffer routines */ -/* $Id: ringbuf.c,v 1.32 2019/08/26 23:37:52 rswindell Exp $ */ - /**************************************************************************** * @format.tab-size 4 (Plain Text/Source Code File Header) * * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * @@ -17,21 +13,9 @@ * See the GNU General Public License for more details: gpl.txt or * * http://www.fsf.org/copyleft/gpl.html * * * - * Anonymous FTP access to the most recent released source is available at * - * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * - * * - * Anonymous CVS access to the development source and modification history * - * is available at cvs.synchro.net:/cvsroot/sbbs, example: * - * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * - * (just hit return, no password is necessary) * - * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * - * * * For Synchronet coding style and modification guidelines, see * * http://www.synchro.net/source.html * * * - * You are encouraged to submit any modifications (preferably in Unix diff * - * format) via e-mail to mods@synchro.net * - * * * Note: If this box doesn't appear square, then you need to fix your tabs. * ****************************************************************************/ @@ -96,9 +80,9 @@ int RingBufInit( RingBuf* rb, DWORD size rb->pEnd=rb->pStart+size; rb->size=size; #ifdef RINGBUF_EVENT - rb->data_event=CreateEvent(NULL,TRUE,TRUE,NULL); - rb->highwater_event=CreateEvent(NULL,TRUE,TRUE,NULL); - rb->empty_event=CreateEvent(NULL,TRUE,TRUE,NULL); + rb->data_event=CreateEvent(NULL, /* ManualReset: */TRUE, /* InitialState: */FALSE, NULL); + rb->highwater_event=CreateEvent(NULL, /* ManualReset: */TRUE, /* InitialState: */FALSE, NULL); + rb->empty_event=CreateEvent(NULL, /* ManualReset: */TRUE, /* InitialState: */TRUE, NULL); #endif #ifdef RINGBUF_MUTEX pthread_mutex_init(&rb->mutex,NULL); diff --git a/src/sbbs3/sbbs_ini.c b/src/sbbs3/sbbs_ini.c index 4fa57207e379b7c5b1534fab1e30e3f547ec1108..b7421ef1a9d974e0af59e2439c2076dc98628c47 100644 --- a/src/sbbs3/sbbs_ini.c +++ b/src/sbbs3/sbbs_ini.c @@ -79,10 +79,10 @@ void sbbs_get_ini_fname(char* ini_file, const char* ctrl_dir) { /* pHostName is no longer used since iniFileName calls gethostname() itself */ -#if defined(_WINSOCKAPI_) - WSADATA WSAData; - (void)WSAStartup(MAKEWORD(1,1), &WSAData); /* req'd for gethostname */ -#endif +#if defined(_WINSOCKAPI_) + WSADATA WSAData; + (void)WSAStartup(MAKEWORD(1,1), &WSAData); /* req'd for gethostname */ +#endif #if defined(__unix__) && defined(PREFIX) sprintf(ini_file,PREFIX"/etc/sbbs.ini"); @@ -91,8 +91,8 @@ void sbbs_get_ini_fname(char* ini_file, const char* ctrl_dir) #endif iniFileName(ini_file,MAX_PATH,ctrl_dir,"sbbs.ini"); -#if defined(_WINSOCKAPI_) - WSACleanup(); +#if defined(_WINSOCKAPI_) + WSACleanup(); #endif } @@ -100,8 +100,7 @@ static BOOL iniSetStringWithGlobalDefault(str_list_t* lp, const char* section, c ,const char* value, const char* global_value, ini_style_t* style) { if(value != global_value && strcmp(value, global_value) == 0) { - iniRemoveKey(lp, section, key); - return iniKeyExists(*lp, section, key) == FALSE; + return iniKeyExists(*lp, section, key) == FALSE || iniRemoveValue(lp, section, key) == TRUE; } return iniSetString(lp, section, key, value, style) != NULL; } @@ -172,12 +171,12 @@ BOOL sbbs_set_js_settings( if(js->gc_interval==defaults->gc_interval) iniRemoveValue(lp,section,strJavaScriptGcInterval); - else + else failure|=iniSetInteger(lp,section,strJavaScriptGcInterval,js->gc_interval,style)==NULL; if(js->yield_interval==defaults->yield_interval) iniRemoveValue(lp,section,strJavaScriptYieldInterval); - else + else failure|=iniSetInteger(lp,section,strJavaScriptYieldInterval,js->yield_interval,style)==NULL; if(strcmp(js->load_path,defaults->load_path)==0) @@ -253,12 +252,13 @@ static void set_login_attempt_settings(str_list_t* lp, const char* section, stru iniSetInteger(lp,section,strLoginAttemptFilterThreshold,settings.filter_threshold,&style); } +static const struct in6_addr wildcard6; + static void get_ini_globals(str_list_t list, global_startup_t* global) { const char* section = "Global"; char value[INI_MAX_VALUE_LEN]; char* p; - struct in6_addr wildcard6 = {{{0}}}; p=iniGetString(list,section,strCtrlDirectory,nulstr,value); if(*p) { @@ -276,10 +276,9 @@ static void get_ini_globals(str_list_t list, global_startup_t* global) if(*p) SAFECOPY(global->host_name,value); - global->sem_chk_freq=iniGetShortInt(list,section,strSemFileCheckFrequency,DEFAULT_SEM_CHK_FREQ); - iniFreeStringList(global->interfaces); + global->sem_chk_freq=iniGetUInteger(list,section,strSemFileCheckFrequency,DEFAULT_SEM_CHK_FREQ); global->interfaces=iniGetStringList(list,section,strInterfaces, ",", "0.0.0.0,::"); - global->outgoing4.s_addr=iniGetIpAddress(list,section,strOutgoing4,0); + global->outgoing4.s_addr=iniGetIpAddress(list,section,strOutgoing4,INADDR_ANY); global->outgoing6=iniGetIp6Address(list,section,strOutgoing6,wildcard6); global->log_level=iniGetLogLevel(list,section,strLogLevel,DEFAULT_LOG_LEVEL); global->tls_error_level=iniGetLogLevel(list,section, strTLSErrorLevel, 0); @@ -299,6 +298,40 @@ static void get_ini_globals(str_list_t list, global_startup_t* global) sbbs_get_sound_settings(list, section, &global->sound, &global->sound); } +void sbbs_free_ini( + global_startup_t* global + ,bbs_startup_t* bbs + ,ftp_startup_t* ftp + ,web_startup_t* web + ,mail_startup_t* mail + ,services_startup_t* services + ) +{ + if(global != NULL) { + iniFreeStringList(global->interfaces); + } + if(bbs != NULL) { + iniFreeStringList(bbs->telnet_interfaces); + iniFreeStringList(bbs->rlogin_interfaces); + iniFreeStringList(bbs->ssh_interfaces); + } + if(web != NULL) { + iniFreeStringList(web->interfaces); + iniFreeStringList(web->tls_interfaces); + iniFreeStringList(web->index_file_name); + iniFreeStringList(web->cgi_ext); + } + if(ftp != NULL) { + iniFreeStringList(ftp->interfaces); + } + if(mail != NULL) { + iniFreeStringList(mail->interfaces); + iniFreeStringList(mail->pop3_interfaces); + } + if(services != NULL) { + iniFreeStringList(services->interfaces); + } +} void sbbs_read_ini( FILE* fp @@ -310,7 +343,7 @@ void sbbs_read_ini( ,ftp_startup_t* ftp ,BOOL* run_web ,web_startup_t* web - ,BOOL* run_mail + ,BOOL* run_mail ,mail_startup_t* mail ,BOOL* run_services ,services_startup_t* services @@ -335,6 +368,14 @@ void sbbs_read_ini( global=&global_buf; } + sbbs_free_ini(global + ,bbs + ,ftp + ,web + ,mail + ,services + ); + list=iniReadFile(fp); get_ini_globals(list, global); @@ -371,14 +412,12 @@ void sbbs_read_ini( =iniGetIp6Address(list,section,strOutgoing6,global->outgoing6); bbs->telnet_port - =iniGetShortInt(list,section,"TelnetPort",IPPORT_TELNET); - iniFreeStringList(bbs->telnet_interfaces); + =iniGetUInt16(list,section,"TelnetPort",IPPORT_TELNET); bbs->telnet_interfaces =iniGetStringList(list,section,"TelnetInterface",",",global_interfaces); bbs->rlogin_port =iniGetShortInt(list,section,"RLoginPort",513); - iniFreeStringList(bbs->rlogin_interfaces); bbs->rlogin_interfaces =iniGetStringList(list,section,"RLoginInterface",",",global_interfaces); @@ -391,7 +430,6 @@ void sbbs_read_ini( =iniGetShortInt(list,section,"SSHPort",22); bbs->ssh_connect_timeout =iniGetShortInt(list,section,"SSHConnectTimeout",10); - iniFreeStringList(bbs->ssh_interfaces); bbs->ssh_interfaces =iniGetStringList(list,section,"SSHInterface",",",global_interfaces); @@ -440,7 +478,7 @@ void sbbs_read_ini( default_dosemuconf_path=""; SAFECOPY(bbs->dosemuconf_path - ,iniGetString(list,section,"DOSemuConfPath",default_dosemuconf_path,value)); + ,iniGetString(list,section,"DOSemuConfPath",default_dosemuconf_path,value)); #endif bbs->usedosemu=iniGetBool(list,section,"UseDOSemu",TRUE); SAFECOPY(bbs->dosemu_path @@ -482,7 +520,6 @@ void sbbs_read_ini( =iniGetIp6Address(list,section,strOutgoing6,global->outgoing6); ftp->port =iniGetShortInt(list,section,strPort,IPPORT_FTP); - iniFreeStringList(ftp->interfaces); ftp->interfaces =iniGetStringList(list,section,strInterfaces,",",global_interfaces); ftp->max_clients @@ -539,7 +576,6 @@ void sbbs_read_ini( if(mail!=NULL) { - iniFreeStringList(mail->interfaces); mail->interfaces =iniGetStringList(list,section,strInterfaces,",",global_interfaces); mail->outgoing4.s_addr @@ -552,7 +588,6 @@ void sbbs_read_ini( =iniGetShortInt(list,section,"SubmissionPort",IPPORT_SUBMISSION); mail->submissions_port =iniGetShortInt(list,section,"TLSSubmissionPort",IPPORT_SUBMISSIONS); - iniFreeStringList(mail->pop3_interfaces); mail->pop3_interfaces =iniGetStringList(list,section,"POP3Interface",",",global_interfaces); mail->pop3_port @@ -566,15 +601,15 @@ void sbbs_read_ini( mail->max_inactivity =(uint16_t)iniGetDuration(list,section,strMaxInactivity,MAIL_DEFAULT_MAX_INACTIVITY); /* seconds */ mail->max_delivery_attempts - =iniGetShortInt(list,section,"MaxDeliveryAttempts",MAIL_DEFAULT_MAX_DELIVERY_ATTEMPTS); + =iniGetUInteger(list,section,"MaxDeliveryAttempts",MAIL_DEFAULT_MAX_DELIVERY_ATTEMPTS); mail->rescan_frequency - =iniGetShortInt(list,section,"RescanFrequency",MAIL_DEFAULT_RESCAN_FREQUENCY); /* 60 minutes */ + =iniGetUInteger(list,section,"RescanFrequency",MAIL_DEFAULT_RESCAN_FREQUENCY); /* 60 minutes */ mail->sem_chk_freq - =iniGetShortInt(list,section,strSemFileCheckFrequency,global->sem_chk_freq); + =iniGetUInteger(list,section,strSemFileCheckFrequency,global->sem_chk_freq); mail->lines_per_yield - =iniGetShortInt(list,section,"LinesPerYield",MAIL_DEFAULT_LINES_PER_YIELD); + =iniGetUInteger(list,section,"LinesPerYield",MAIL_DEFAULT_LINES_PER_YIELD); mail->max_recipients - =iniGetShortInt(list,section,"MaxRecipients",MAIL_DEFAULT_MAX_RECIPIENTS); + =iniGetUInteger(list,section,"MaxRecipients",MAIL_DEFAULT_MAX_RECIPIENTS); mail->max_msg_size =(DWORD)iniGetBytes(list,section,"MaxMsgSize",/* units: */1,MAIL_DEFAULT_MAX_MSG_SIZE); mail->max_msgs_waiting @@ -639,7 +674,6 @@ void sbbs_read_ini( if(services!=NULL) { - iniFreeStringList(services->interfaces); services->interfaces =iniGetStringList(list,section,strInterfaces,",",global_interfaces); services->outgoing4.s_addr @@ -648,7 +682,7 @@ void sbbs_read_ini( =iniGetIp6Address(list,section,strOutgoing6,global->outgoing6); services->sem_chk_freq - =iniGetShortInt(list,section,strSemFileCheckFrequency,global->sem_chk_freq); + =iniGetUInteger(list,section,strSemFileCheckFrequency,global->sem_chk_freq); /* JavaScript operating parameters */ sbbs_get_js_settings(list, section, &services->js, &global->js); @@ -683,22 +717,20 @@ void sbbs_read_ini( if(web!=NULL) { - iniFreeStringList(web->interfaces); web->interfaces =iniGetStringList(list,section,strInterfaces,",",global_interfaces); - iniFreeStringList(web->tls_interfaces); web->tls_interfaces =iniGetStringList(list,section,"TLSInterface",",",global_interfaces); web->port - =iniGetShortInt(list,section,strPort,IPPORT_HTTP); + =iniGetUInt16(list,section,strPort,IPPORT_HTTP); web->tls_port - =iniGetShortInt(list,section,"TLSPort",IPPORT_HTTPS); + =iniGetUInt16(list,section,"TLSPort",IPPORT_HTTPS); web->max_clients - =iniGetShortInt(list,section,strMaxClients,WEB_DEFAULT_MAX_CLIENTS); + =iniGetUInteger(list,section,strMaxClients,WEB_DEFAULT_MAX_CLIENTS); web->max_inactivity =(uint16_t)iniGetDuration(list,section,strMaxInactivity,WEB_DEFAULT_MAX_INACTIVITY); /* seconds */ web->sem_chk_freq - =iniGetShortInt(list,section,strSemFileCheckFrequency,global->sem_chk_freq); + =iniGetUInteger(list,section,strSemFileCheckFrequency,global->sem_chk_freq); /* JavaScript operating parameters */ sbbs_get_js_settings(list, section, &web->js, &global->js); @@ -728,10 +760,8 @@ void sbbs_read_ini( SAFECOPY(web->default_cgi_content ,iniGetString(list,section,"DefaultCGIContent",WEB_DEFAULT_CGI_CONTENT,value)); - iniFreeStringList(web->index_file_name); web->index_file_name =iniGetStringList(list,section,"IndexFileNames", "," ,"index.html,index.ssjs"); - iniFreeStringList(web->cgi_ext); web->cgi_ext =iniGetStringList(list,section,"CGIExtensions", "," ,".cgi"); SAFECOPY(web->ssjs_ext @@ -750,7 +780,7 @@ void sbbs_read_ini( =iniGetBitField(list,section,strOptions,web_options ,BBS_OPT_NO_HOST_LOOKUP | WEB_OPT_HTTP_LOGGING); web->outbuf_drain_timeout - =iniGetShortInt(list,section,"OutbufDrainTimeout",10); + =iniGetUInteger(list,section,"OutbufDrainTimeout",10); web->bind_retry_count=iniGetInteger(list,section,strBindRetryCount,global->bind_retry_count); web->bind_retry_delay=iniGetInteger(list,section,strBindRetryDelay,global->bind_retry_delay); @@ -771,7 +801,7 @@ BOOL sbbs_write_ini( ,ftp_startup_t* ftp ,BOOL run_web ,web_startup_t* web - ,BOOL run_mail + ,BOOL run_mail ,mail_startup_t* mail ,BOOL run_services ,services_startup_t* services @@ -798,7 +828,7 @@ BOOL sbbs_write_ini( get_ini_globals(list, &global_buf); global = &global_buf; } - + lp=&list; do { /* try */ @@ -810,9 +840,11 @@ BOOL sbbs_write_ini( iniSetString(lp,section,strCtrlDirectory,global->ctrl_dir,&style); iniSetString(lp,section,strTempDirectory,global->temp_dir,&style); iniSetString(lp,section,strHostName,global->host_name,&style); - iniSetShortInt(lp,section,strSemFileCheckFrequency,global->sem_chk_freq,&style); - iniSetIpAddress(lp,section,strOutgoing4,global->outgoing4.s_addr,&style); - iniSetIp6Address(lp,section,strOutgoing6,global->outgoing6,&style); + iniSetUInteger(lp,section,strSemFileCheckFrequency,global->sem_chk_freq,&style); + if(global->outgoing4.s_addr != INADDR_ANY) + iniSetIpAddress(lp,section,strOutgoing4,global->outgoing4.s_addr,&style); + if(memcmp(&global->outgoing6, &wildcard6, sizeof(wildcard6)) != 0) + iniSetIp6Address(lp,section,strOutgoing6,global->outgoing6,&style); iniSetStringList(lp, section, strInterfaces, ",", global->interfaces, &style); iniSetLogLevel(lp,section,strLogLevel,global->log_level,&style); iniSetLogLevel(lp,section,strTLSErrorLevel,global->tls_error_level,&style); @@ -841,37 +873,37 @@ BOOL sbbs_write_ini( else if(!iniSetStringList(lp,section,"TelnetInterface", ",", bbs->telnet_interfaces, &style)) break; - if(!iniSetShortInt(lp,section,"TelnetPort",bbs->telnet_port,&style)) + if(!iniSetUInt16(lp,section,"TelnetPort",bbs->telnet_port,&style)) break; if(strListCmp(bbs->rlogin_interfaces, global->interfaces)==0) iniRemoveValue(lp,section,"RLoginInterface"); else if(!iniSetStringList(lp,section,"RLoginInterface", ",", bbs->rlogin_interfaces,&style)) break; - if(!iniSetShortInt(lp,section,"RLoginPort",bbs->rlogin_port,&style)) + if(!iniSetUInt16(lp,section,"RLoginPort",bbs->rlogin_port,&style)) break; - if(!iniSetShortInt(lp,section,"Pet40Port",bbs->pet40_port,&style)) + if(!iniSetUInt16(lp,section,"Pet40Port",bbs->pet40_port,&style)) break; - if(!iniSetShortInt(lp,section,"Pet80Port",bbs->pet80_port,&style)) + if(!iniSetUInt16(lp,section,"Pet80Port",bbs->pet80_port,&style)) break; if(strListCmp(bbs->ssh_interfaces, global->interfaces)==0) iniRemoveValue(lp,section,"SSHInterface"); else if(!iniSetStringList(lp,section,"SSHInterface", ",", bbs->ssh_interfaces,&style)) break; - if(!iniSetShortInt(lp,section,"SSHPort",bbs->ssh_port,&style)) + if(!iniSetUInt16(lp,section,"SSHPort",bbs->ssh_port,&style)) break; - if(!iniSetShortInt(lp,section,"SSHConnectTimeout",bbs->ssh_connect_timeout,&style)) + if(!iniSetUInteger(lp,section,"SSHConnectTimeout",bbs->ssh_connect_timeout,&style)) break; - if(!iniSetShortInt(lp,section,"FirstNode",bbs->first_node,&style)) + if(!iniSetUInteger(lp,section,"FirstNode",bbs->first_node,&style)) break; - if(!iniSetShortInt(lp,section,"LastNode",bbs->last_node,&style)) + if(!iniSetUInteger(lp,section,"LastNode",bbs->last_node,&style)) break; - if(!iniSetShortInt(lp,section,"OutbufHighwaterMark",bbs->outbuf_highwater_mark,&style)) + if(!iniSetUInteger(lp,section,"OutbufHighwaterMark",bbs->outbuf_highwater_mark,&style)) break; - if(!iniSetShortInt(lp,section,"OutbufDrainTimeout",bbs->outbuf_drain_timeout,&style)) + if(!iniSetUInteger(lp,section,"OutbufDrainTimeout",bbs->outbuf_drain_timeout,&style)) break; if(!iniSetInteger(lp,section,strMaxConConn,bbs->max_concurrent_connections,&style)) break; @@ -884,7 +916,7 @@ BOOL sbbs_write_ini( if(bbs->sem_chk_freq==global->sem_chk_freq) iniRemoveValue(lp,section,strSemFileCheckFrequency); - else if(!iniSetShortInt(lp,section,strSemFileCheckFrequency,bbs->sem_chk_freq,&style)) + else if(!iniSetUInteger(lp,section,strSemFileCheckFrequency,bbs->sem_chk_freq,&style)) break; if(bbs->log_level==global->log_level) @@ -958,20 +990,20 @@ BOOL sbbs_write_ini( else if(!iniSetIpAddress(lp, section, strOutgoing4, ftp->outgoing4.s_addr, &style)) break; - if(memcmp(&ftp->outgoing6, &global->outgoing6, sizeof(ftp->outgoing6))) + if(memcmp(&ftp->outgoing6, &global->outgoing6, sizeof(ftp->outgoing6)) == 0) iniRemoveValue(lp,section,strOutgoing6); else if(!iniSetIp6Address(lp, section, strOutgoing6, ftp->outgoing6, &style)) break; - if(!iniSetShortInt(lp,section,strPort,ftp->port,&style)) + if(!iniSetUInt16(lp,section,strPort,ftp->port,&style)) break; - if(!iniSetShortInt(lp,section,strMaxClients,ftp->max_clients,&style)) + if(!iniSetUInteger(lp,section,strMaxClients,ftp->max_clients,&style)) break; if(!iniSetDuration(lp,section,strMaxInactivity,ftp->max_inactivity,&style)) break; if(!iniSetInteger(lp,section,strMaxConConn,ftp->max_concurrent_connections,&style)) break; - if(!iniSetShortInt(lp,section,"QwkTimeout",ftp->qwk_timeout,&style)) + if(!iniSetUInteger(lp,section,"QwkTimeout",ftp->qwk_timeout,&style)) break; if(!iniSetBytes(lp,section,"MinFileSize",1,ftp->min_fsize,&style)) break; @@ -983,14 +1015,14 @@ BOOL sbbs_write_ini( break; if(!iniSetIp6Address(lp,section,"PasvIp6Address",ftp->pasv_ip6_addr,&style)) break; - if(!iniSetShortInt(lp,section,"PasvPortLow",ftp->pasv_port_low,&style)) + if(!iniSetUInt16(lp,section,"PasvPortLow",ftp->pasv_port_low,&style)) break; - if(!iniSetShortInt(lp,section,"PasvPortHigh",ftp->pasv_port_high,&style)) + if(!iniSetUInt16(lp,section,"PasvPortHigh",ftp->pasv_port_high,&style)) break; if(ftp->sem_chk_freq==global->sem_chk_freq) iniRemoveValue(lp,section,strSemFileCheckFrequency); - else if(!iniSetShortInt(lp,section,strSemFileCheckFrequency,ftp->sem_chk_freq,&style)) + else if(!iniSetUInteger(lp,section,strSemFileCheckFrequency,ftp->sem_chk_freq,&style)) break; if(ftp->log_level==global->log_level) @@ -1014,7 +1046,7 @@ BOOL sbbs_write_ini( if(!sbbs_set_sound_settings(lp, section, &ftp->sound, &global->sound, &style)) break; - + if(!iniSetBitField(lp,section,strOptions,ftp_options,ftp->options,&style)) break; @@ -1046,14 +1078,14 @@ BOOL sbbs_write_ini( else if(!iniSetIpAddress(lp, section, strOutgoing4, mail->outgoing4.s_addr, &style)) break; - if(memcmp(&mail->outgoing6, &global->outgoing6, sizeof(ftp->outgoing6))) + if(memcmp(&mail->outgoing6, &global->outgoing6, sizeof(ftp->outgoing6)) == 0) iniRemoveValue(lp,section,strOutgoing6); else if(!iniSetIp6Address(lp, section, strOutgoing6, mail->outgoing6, &style)) break; if(mail->sem_chk_freq==global->sem_chk_freq) iniRemoveValue(lp,section,strSemFileCheckFrequency); - else if(!iniSetShortInt(lp,section,strSemFileCheckFrequency,mail->sem_chk_freq,&style)) + else if(!iniSetUInteger(lp,section,strSemFileCheckFrequency,mail->sem_chk_freq,&style)) break; if(mail->log_level==global->log_level) @@ -1064,29 +1096,29 @@ BOOL sbbs_write_ini( iniRemoveValue(lp,section,strTLSErrorLevel); else if(!iniSetLogLevel(lp,section,strTLSErrorLevel,mail->tls_error_level,&style)) break; - if(!iniSetShortInt(lp,section,"SMTPPort",mail->smtp_port,&style)) + if(!iniSetUInt16(lp,section,"SMTPPort",mail->smtp_port,&style)) break; - if(!iniSetShortInt(lp,section,"SubmissionPort",mail->submission_port,&style)) + if(!iniSetUInt16(lp,section,"SubmissionPort",mail->submission_port,&style)) break; - if(!iniSetShortInt(lp,section,"TLSSubmissionPort",mail->submissions_port,&style)) + if(!iniSetUInt16(lp,section,"TLSSubmissionPort",mail->submissions_port,&style)) break; - if(!iniSetShortInt(lp,section,"POP3Port",mail->pop3_port,&style)) + if(!iniSetUInt16(lp,section,"POP3Port",mail->pop3_port,&style)) break; - if(!iniSetShortInt(lp,section,"TLSPOP3Port",mail->pop3s_port,&style)) + if(!iniSetUInt16(lp,section,"TLSPOP3Port",mail->pop3s_port,&style)) break; - if(!iniSetShortInt(lp,section,"RelayPort",mail->relay_port,&style)) + if(!iniSetUInt16(lp,section,"RelayPort",mail->relay_port,&style)) break; - if(!iniSetShortInt(lp,section,strMaxClients,mail->max_clients,&style)) + if(!iniSetUInteger(lp,section,strMaxClients,mail->max_clients,&style)) break; if(!iniSetDuration(lp,section,strMaxInactivity,mail->max_inactivity,&style)) break; - if(!iniSetShortInt(lp,section,"MaxDeliveryAttempts",mail->max_delivery_attempts,&style)) + if(!iniSetUInteger(lp,section,"MaxDeliveryAttempts",mail->max_delivery_attempts,&style)) break; - if(!iniSetShortInt(lp,section,"RescanFrequency",mail->rescan_frequency,&style)) + if(!iniSetUInteger(lp,section,"RescanFrequency",mail->rescan_frequency,&style)) break; - if(!iniSetShortInt(lp,section,"LinesPerYield",mail->lines_per_yield,&style)) + if(!iniSetUInteger(lp,section,"LinesPerYield",mail->lines_per_yield,&style)) break; - if(!iniSetShortInt(lp,section,"MaxRecipients",mail->max_recipients,&style)) + if(!iniSetUInteger(lp,section,"MaxRecipients",mail->max_recipients,&style)) break; if(!iniSetBytes(lp,section,"MaxMsgSize",/* unit: */1,mail->max_msg_size,&style)) break; @@ -1171,14 +1203,14 @@ BOOL sbbs_write_ini( else if(!iniSetIpAddress(lp, section, strOutgoing4, services->outgoing4.s_addr, &style)) break; - if(memcmp(&services->outgoing6, &global->outgoing6, sizeof(ftp->outgoing6))) + if(memcmp(&services->outgoing6, &global->outgoing6, sizeof(ftp->outgoing6)) == 0) iniRemoveValue(lp,section,strOutgoing6); else if(!iniSetIp6Address(lp, section, strOutgoing6, services->outgoing6, &style)) break; if(services->sem_chk_freq==global->sem_chk_freq) iniRemoveValue(lp,section,strSemFileCheckFrequency); - else if(!iniSetShortInt(lp,section,strSemFileCheckFrequency,services->sem_chk_freq,&style)) + else if(!iniSetUInteger(lp,section,strSemFileCheckFrequency,services->sem_chk_freq,&style)) break; if(services->log_level==global->log_level) @@ -1237,12 +1269,11 @@ BOOL sbbs_write_ini( iniRemoveValue(lp,section,"TLSInterface"); else if(!iniSetStringList(lp,section,"TLSInterface",",",web->tls_interfaces,&style)) break; - - if(!iniSetShortInt(lp,section,strPort,web->port,&style)) + if(!iniSetUInt16(lp,section,strPort,web->port,&style)) break; - if(!iniSetShortInt(lp,section,"TLSPort",web->tls_port,&style)) + if(!iniSetUInt16(lp,section,"TLSPort",web->tls_port,&style)) break; - if(!iniSetShortInt(lp,section,strMaxClients,web->max_clients,&style)) + if(!iniSetUInteger(lp,section,strMaxClients,web->max_clients,&style)) break; if(!iniSetDuration(lp,section,strMaxInactivity,web->max_inactivity,&style)) break; @@ -1251,7 +1282,7 @@ BOOL sbbs_write_ini( if(web->sem_chk_freq==global->sem_chk_freq) iniRemoveValue(lp,section,strSemFileCheckFrequency); - else if(!iniSetShortInt(lp,section,strSemFileCheckFrequency,web->sem_chk_freq,&style)) + else if(!iniSetUInteger(lp,section,strSemFileCheckFrequency,web->sem_chk_freq,&style)) break; if(web->log_level==global->log_level) @@ -1320,7 +1351,7 @@ BOOL sbbs_write_ini( iniRemoveValue(lp,section,strBindRetryDelay); else if(!iniSetInteger(lp,section,strBindRetryDelay,web->bind_retry_delay,&style)) break; - if(!iniSetShortInt(lp,section,"OutbufDrainTimeout",web->outbuf_drain_timeout,&style)) + if(!iniSetUInteger(lp,section,"OutbufDrainTimeout",web->outbuf_drain_timeout,&style)) break; } diff --git a/src/sbbs3/sbbs_ini.h b/src/sbbs3/sbbs_ini.h index 2aaecba4b1e6b6af92790568f69638fd876f1e3e..9a7b3f8dac7ed05b4e26c41e37e53b0be4e6a647 100644 --- a/src/sbbs3/sbbs_ini.h +++ b/src/sbbs3/sbbs_ini.h @@ -49,12 +49,21 @@ void sbbs_read_ini( ,ftp_startup_t* ftp_startup ,BOOL* run_web ,web_startup_t* web_startup - ,BOOL* run_mail + ,BOOL* run_mail ,mail_startup_t* mail_startup ,BOOL* run_services ,services_startup_t* services_startup ); +void sbbs_free_ini( + global_startup_t* global + ,bbs_startup_t* bbs_startup + ,ftp_startup_t* ftp_startup + ,web_startup_t* web_startup + ,mail_startup_t* mail_startup + ,services_startup_t* services_startup + ); + void sbbs_get_js_settings( str_list_t list ,const char* section @@ -80,7 +89,7 @@ BOOL sbbs_write_ini( ,ftp_startup_t* ftp ,BOOL run_web ,web_startup_t* web - ,BOOL run_mail + ,BOOL run_mail ,mail_startup_t* mail ,BOOL run_services ,services_startup_t* services diff --git a/src/sbbs3/scfg/objects.mk b/src/sbbs3/scfg/objects.mk index 93fe2bb5f91b55264ca6c1a4c74d4c370330b6ba..be3d7aaac8aceb3ab1361ab287e90758b1c6109e 100644 --- a/src/sbbs3/scfg/objects.mk +++ b/src/sbbs3/scfg/objects.mk @@ -9,6 +9,7 @@ OBJS = $(MTOBJODIR)/scfg$(OFILE)\ $(MTOBJODIR)/scfgmsg$(OFILE)\ $(MTOBJODIR)/scfgnet$(OFILE)\ $(MTOBJODIR)/scfgnode$(OFILE)\ + $(MTOBJODIR)/scfgsrvr$(OFILE)\ $(MTOBJODIR)/scfgsub$(OFILE)\ $(MTOBJODIR)/scfgsys$(OFILE)\ $(MTOBJODIR)/scfgxfr1$(OFILE)\ @@ -18,6 +19,7 @@ OBJS = $(MTOBJODIR)/scfg$(OFILE)\ $(MTOBJODIR)/scfglib1$(OFILE)\ $(MTOBJODIR)/scfglib2$(OFILE)\ $(MTOBJODIR)/getctrl$(OFILE)\ + $(MTOBJODIR)/sbbs_ini$(OFILE)\ $(MTOBJODIR)/load_cfg$(OFILE)\ $(MTOBJODIR)/readtext$(OFILE)\ $(MTOBJODIR)/text_defaults$(OFILE)\ diff --git a/src/sbbs3/scfg/scfg.c b/src/sbbs3/scfg/scfg.c index 6ff22e049e6cdf71ee80c18b0e437c6c28e596fb..596a5247e5fcafb3d2fa1c903631cb3617395641 100644 --- a/src/sbbs3/scfg/scfg.c +++ b/src/sbbs3/scfg/scfg.c @@ -27,6 +27,7 @@ #include "git_branch.h" #include "cryptlib.h" #include "xpdatetime.h" +#include "sbbs_ini.h" /********************/ /* Global Variables */ @@ -362,12 +363,23 @@ void cfg_wizard(void) free_msgs_cfg(&cfg); } +void display_filename(BOOL force) +{ + static char last[MAX_PATH + 1]; + const char* fname = cfg.filename; + if(strlen(fname) + 30 > uifc.scrn_width) + fname = getfname(fname); + if(force || strcmp(last, fname) != 0) + uifc.printf(29, 1, uifc.bclr|(uifc.cclr<<4), "%*s", uifc.scrn_width - 30, fname); + SAFECOPY(last, fname); +} + int main(int argc, char **argv) { char **mopt,*p; char errormsg[MAX_PATH*2]; int i,j,main_dflt=0,chat_dflt=0; - char str[MAX_PATH+1]; + char cfg_fname[MAX_PATH + 1]; BOOL door_mode=FALSE; int ciolib_mode=CIOLIB_MODE_AUTO; char compiler[32]; @@ -647,20 +659,21 @@ int main(int argc, char **argv) if((mopt[i]=(char *)malloc(64))==NULL) allocfail(64); + uifc.timedisplay = display_filename; SAFEPRINTF2(title,"Synchronet for %s v%s",PLATFORM_DESC,VERSION); if(uifc.scrn(title)) { printf(" USCRN (len=%d) failed!\n",uifc.scrn_len+1); bail(1); } - SAFEPRINTF(str,"%smain.ini",cfg.ctrl_dir); - if(!fexist(str)) { - SAFEPRINTF(errormsg, "Main configuration file (%s) missing!",str); + SAFEPRINTF(cfg_fname, "%smain.ini", cfg.ctrl_dir); + if(!fexist(cfg_fname)) { + SAFEPRINTF(errormsg, "Main configuration file (%s) missing!", cfg_fname); uifc.msg(errormsg); } - FILE* fp = iniOpenFile(str, /* for_modify */TRUE); + FILE* fp = iniOpenFile(cfg_fname, /* for_modify */TRUE); if(fp == NULL) { - SAFEPRINTF2(errormsg, "Error %d opening configuration file: %s", errno, str); + SAFEPRINTF2(errormsg, "Error %d opening configuration file: %s", errno, cfg_fname); uifc.msg(errormsg); } else { cfg.new_install = iniReadBool(fp, ROOT_SECTION, "new_install", TRUE); @@ -672,10 +685,10 @@ int main(int argc, char **argv) if(run_wizard) bail(0); } - i=0; strcpy(mopt[i++],"Nodes"); strcpy(mopt[i++],"System"); + strcpy(mopt[i++],"Servers"); strcpy(mopt[i++],"Networks"); strcpy(mopt[i++],"File Areas"); strcpy(mopt[i++],"File Options"); @@ -689,6 +702,7 @@ int main(int argc, char **argv) i = cryptInit(); (void)i; while(1) { + *cfg.filename = '\0'; uifc.helpbuf= "`Main Configuration Menu:`\n" "\n" @@ -697,6 +711,7 @@ int main(int argc, char **argv) "\n" " `Nodes ` Add, delete, or configure nodes\n" " `System ` System-wide configuration options\n" + " `Servers ` TCP/IP Servers and Services\n" " `Networks ` Networking configuration\n" " `File Areas ` File area configuration\n" " `File Options ` File area options\n" @@ -721,12 +736,12 @@ int main(int argc, char **argv) free_main_cfg(&cfg); break; case 1: - if(!load_main_cfg(&cfg, error, sizeof(error))) { + if(!load_xtrn_cfg(&cfg, error, sizeof(error))) { SAFEPRINTF(errormsg,"ERROR: %s",error); uifc.msg(errormsg); break; } - if(!load_xtrn_cfg(&cfg, error, sizeof(error))) { + if(!load_main_cfg(&cfg, error, sizeof(error))) { SAFEPRINTF(errormsg,"ERROR: %s",error); uifc.msg(errormsg); break; @@ -736,9 +751,12 @@ int main(int argc, char **argv) free_main_cfg(&cfg); break; case 2: - net_cfg(); + server_cfg(); break; case 3: + net_cfg(); + break; + case 4: if(!load_main_cfg(&cfg, error, sizeof(error))) { SAFEPRINTF(errormsg,"ERROR: %s",error); uifc.msg(errormsg); @@ -748,12 +766,12 @@ int main(int argc, char **argv) SAFEPRINTF(errormsg,"ERROR: %s",error); uifc.msg(errormsg); break; - } + } xfer_cfg(); free_file_cfg(&cfg); free_main_cfg(&cfg); break; - case 4: + case 5: if(!load_main_cfg(&cfg, error, sizeof(error))) { SAFEPRINTF(errormsg,"ERROR: %s",error); uifc.msg(errormsg); @@ -768,12 +786,12 @@ int main(int argc, char **argv) free_file_cfg(&cfg); free_main_cfg(&cfg); break; - case 5: + case 6: if(!load_chat_cfg(&cfg, error, sizeof(error))) { SAFEPRINTF(errormsg,"ERROR: %s",error); uifc.msg(errormsg); break; - } + } while(1) { i=0; strcpy(opt[i++],"Artificial Gurus"); @@ -809,12 +827,12 @@ int main(int argc, char **argv) break; case 3: page_cfg(); - break; - } + break; + } } free_chat_cfg(&cfg); break; - case 6: + case 7: if(!load_main_cfg(&cfg, error, sizeof(error))) { SAFEPRINTF(errormsg, "ERROR: %s",error); uifc.msg(errormsg); @@ -829,7 +847,7 @@ int main(int argc, char **argv) free_msgs_cfg(&cfg); free_main_cfg(&cfg); break; - case 7: + case 8: if(!load_main_cfg(&cfg, error, sizeof(error))) { SAFEPRINTF(errormsg, "ERROR: %s",error); uifc.msg(errormsg); @@ -844,7 +862,7 @@ int main(int argc, char **argv) free_msgs_cfg(&cfg); free_main_cfg(&cfg); break; - case 8: + case 9: if(!load_main_cfg(&cfg, error, sizeof(error))) { SAFEPRINTF(errormsg, "ERROR: %s",error); uifc.msg(errormsg); @@ -853,7 +871,7 @@ int main(int argc, char **argv) shell_cfg(); free_main_cfg(&cfg); break; - case 9: + case 10: if(!load_main_cfg(&cfg, error, sizeof(error))) { SAFEPRINTF(errormsg, "ERROR: %s",error); uifc.msg(errormsg); @@ -868,7 +886,7 @@ int main(int argc, char **argv) free_xtrn_cfg(&cfg); free_main_cfg(&cfg); break; - case 10: + case 11: if(!load_main_cfg(&cfg, error, sizeof(error))) { SAFEPRINTF(errormsg, "ERROR: %s",error); uifc.msg(errormsg); @@ -894,8 +912,8 @@ int main(int argc, char **argv) i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Exit SCFG",uifcYesNoOpts); if(!i) bail(0); - break; - } + break; + } } } @@ -1097,28 +1115,28 @@ void txt_cfg() uifc.helpbuf=invalid_code; uifc.msg(strInvalidCode); uifc.helpbuf=0; - continue; + continue; } if((cfg.txtsec=(txtsec_t **)realloc(cfg.txtsec ,sizeof(txtsec_t *)*(cfg.total_txtsecs+1)))==NULL) { errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_txtsecs+1); cfg.total_txtsecs=0; bail(1); - continue; + continue; } if(cfg.total_txtsecs) for(u=cfg.total_txtsecs;u>i;u--) cfg.txtsec[u]=cfg.txtsec[u-1]; if((cfg.txtsec[i]=(txtsec_t *)malloc(sizeof(txtsec_t)))==NULL) { errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(txtsec_t)); - continue; + continue; } memset((txtsec_t *)cfg.txtsec[i],0,sizeof(txtsec_t)); SAFECOPY(cfg.txtsec[i]->name,str); SAFECOPY(cfg.txtsec[i]->code,code); cfg.total_txtsecs++; uifc.changes=1; - continue; + continue; } if (msk == MSK_DEL || msk == MSK_CUT) { if(msk == MSK_CUT) @@ -1128,16 +1146,16 @@ void txt_cfg() for(j=i;j<cfg.total_txtsecs;j++) cfg.txtsec[j]=cfg.txtsec[j+1]; uifc.changes=1; - continue; + continue; } if (msk == MSK_COPY) { savtxtsec=*cfg.txtsec[i]; - continue; + continue; } if (msk == MSK_PASTE) { *cfg.txtsec[i]=savtxtsec; uifc.changes=1; - continue; + continue; } if (msk != 0) continue; @@ -1197,15 +1215,15 @@ void txt_cfg() else { uifc.helpbuf=invalid_code; uifc.msg(strInvalidCode); - uifc.helpbuf=0; + uifc.helpbuf=0; } - break; + break; case 2: sprintf(str,"%s Text Section",cfg.txtsec[i]->name); getar(str,cfg.txtsec[i]->arstr); break; - } - } + } + } } } @@ -1285,28 +1303,28 @@ void shell_cfg() uifc.helpbuf=invalid_code; uifc.msg(strInvalidCode); uifc.helpbuf=0; - continue; + continue; } if((cfg.shell=(shell_t **)realloc(cfg.shell ,sizeof(shell_t *)*(cfg.total_shells+1)))==NULL) { errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_shells+1); cfg.total_shells=0; bail(1); - continue; + continue; } if(cfg.total_shells) for(u=cfg.total_shells;u>i;u--) cfg.shell[u]=cfg.shell[u-1]; if((cfg.shell[i]=(shell_t *)malloc(sizeof(shell_t)))==NULL) { errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(shell_t)); - continue; + continue; } memset((shell_t *)cfg.shell[i],0,sizeof(shell_t)); SAFECOPY(cfg.shell[i]->name,str); SAFECOPY(cfg.shell[i]->code,code); cfg.total_shells++; uifc.changes=1; - continue; + continue; } if (msk == MSK_DEL || msk == MSK_CUT) { if(msk == MSK_CUT) @@ -1316,16 +1334,16 @@ void shell_cfg() for(j=i;j<cfg.total_shells;j++) cfg.shell[j]=cfg.shell[j+1]; uifc.changes=1; - continue; + continue; } if (msk == MSK_COPY) { savshell=*cfg.shell[i]; - continue; + continue; } if (msk == MSK_PASTE) { *cfg.shell[i]=savshell; uifc.changes=1; - continue; + continue; } if (msk != 0) continue; @@ -1406,15 +1424,15 @@ void shell_cfg() else { uifc.helpbuf=invalid_code; uifc.msg(strInvalidCode); - uifc.helpbuf=0; + uifc.helpbuf=0; } break; case 2: SAFEPRINTF(str,"%s Command Shell",cfg.shell[i]->name); getar(str,cfg.shell[i]->arstr); - break; - } - } + break; + } + } } } @@ -1484,33 +1502,33 @@ void getar(char *desc, char *inar) for(i=0;i<n;i++) { /* Shorten operators */ if(!strncmp(ar+i,"AND",3)) { strcat(str,"&"); - i+=2; + i+=2; } else if(!strncmp(ar+i,"NOT",3)) { strcat(str,"!"); - i+=2; + i+=2; } else if(!strncmp(ar+i,"EQUAL",5)) { strcat(str,"="); - i+=4; + i+=4; } else if(!strncmp(ar+i,"EQUALS",6)) { strcat(str,"="); - i+=5; + i+=5; } else if(!strncmp(ar+i,"EQUAL TO",8)) { strcat(str,"="); - i+=7; + i+=7; } else if(!strncmp(ar+i,"OR",2)) { strcat(str,"|"); - i+=1; + i+=1; } else - strncat(str,ar+i,1); + strncat(str,ar+i,1); } SAFECOPY(ar,str); - len=strlen(ar); + len=strlen(ar); } if(len>=30) { @@ -1519,21 +1537,21 @@ void getar(char *desc, char *inar) for(i=0;i<n;i++) { /* Remove spaces from ! and = */ if(!strncmp(ar+i," ! ",3)) { strcat(str,"!"); - i+=2; + i+=2; } else if(!strncmp(ar+i,"= ",2)) { strcat(str,"="); - i++; + i++; } else if(!strncmp(ar+i," = ",3)) { strcat(str,"="); - i+=2; + i+=2; } else - strncat(str,ar+i,1); + strncat(str,ar+i,1); } SAFECOPY(ar,str); - len=strlen(ar); + len=strlen(ar); } if(len>=30) { @@ -1542,17 +1560,17 @@ void getar(char *desc, char *inar) for(i=0;i<n;i++) { /* Remove spaces from & and | */ if(!strncmp(ar+i," & ",3)) { strcat(str," "); - i+=2; + i+=2; } else if(!strncmp(ar+i," | ",3)) { strcat(str,"|"); - i+=2; + i+=2; } else - strncat(str,ar+i,1); + strncat(str,ar+i,1); } SAFECOPY(ar,str); - len=strlen(ar); + len=strlen(ar); } if(len>=30) { /* change week days to numbers */ @@ -1566,10 +1584,10 @@ void getar(char *desc, char *inar) break; } if(j==7) - strncat(str,ar+i,1); + strncat(str,ar+i,1); } SAFECOPY(ar,str); - len=strlen(ar); + len=strlen(ar); } if(len>=30) { /* Shorten parameters */ @@ -1578,112 +1596,112 @@ void getar(char *desc, char *inar) for(i=0;i<n;i++) { if(!strncmp(ar+i,"AGE",3)) { strcat(str,"$A"); - i+=2; + i+=2; } else if(!strncmp(ar+i,"BPS",3)) { strcat(str,"$B"); - i+=2; + i+=2; } else if(!strncmp(ar+i,"PCR",3)) { strcat(str,"$P"); - i+=2; + i+=2; } else if(!strncmp(ar+i,"RIP",3)) { strcat(str,"$*"); - i+=2; + i+=2; } else if(!strncmp(ar+i,"SEX",3)) { strcat(str,"$S"); - i+=2; + i+=2; } else if(!strncmp(ar+i,"UDR",3)) { strcat(str,"$K"); - i+=2; + i+=2; } else if(!strncmp(ar+i,"DAY",3)) { strcat(str,"$W"); - i+=2; + i+=2; } else if(!strncmp(ar+i,"ANSI",4)) { strcat(str,"$["); - i+=3; + i+=3; } else if(!strncmp(ar+i,"UDFR",4)) { strcat(str,"$D"); - i+=3; + i+=3; } else if(!strncmp(ar+i,"FLAG",4)) { strcat(str,"$F"); - i+=3; + i+=3; } else if(!strncmp(ar+i,"NODE",4)) { strcat(str,"$N"); - i+=3; + i+=3; } else if(!strncmp(ar+i,"NULL",4)) { strcat(str,"$0"); - i+=3; + i+=3; } else if(!strncmp(ar+i,"TIME",4)) { strcat(str,"$T"); - i+=3; + i+=3; } else if(!strncmp(ar+i,"USER",4)) { strcat(str,"$U"); - i+=3; + i+=3; } else if(!strncmp(ar+i,"REST",4)) { strcat(str,"$Z"); - i+=3; + i+=3; } else if(!strncmp(ar+i,"LOCAL",5)) { strcat(str,"$G"); - i+=4; + i+=4; } else if(!strncmp(ar+i,"LEVEL",5)) { strcat(str,"$L"); - i+=4; + i+=4; } else if(!strncmp(ar+i,"TLEFT",5)) { strcat(str,"$R"); - i+=4; + i+=4; } else if(!strncmp(ar+i,"TUSED",5)) { strcat(str,"$O"); - i+=4; + i+=4; } else if(!strncmp(ar+i,"EXPIRE",6)) { strcat(str,"$E"); - i+=5; + i+=5; } else if(!strncmp(ar+i,"CREDIT",6)) { strcat(str,"$C"); - i+=5; + i+=5; } else if(!strncmp(ar+i,"EXEMPT",6)) { strcat(str,"$X"); - i+=5; + i+=5; } else if(!strncmp(ar+i,"RANDOM",6)) { strcat(str,"$Q"); - i+=5; + i+=5; } else if(!strncmp(ar+i,"LASTON",6)) { strcat(str,"$Y"); - i+=5; + i+=5; } else if(!strncmp(ar+i,"LOGONS",6)) { strcat(str,"$V"); - i+=5; + i+=5; } else if(!strncmp(ar+i,":00",3)) { - i+=2; + i+=2; } else - strncat(str,ar+i,1); + strncat(str,ar+i,1); } SAFECOPY(ar,str); - len=strlen(ar); + len=strlen(ar); } if(len>=30) { /* Remove all spaces and &s */ str[0]=0; @@ -1759,13 +1777,13 @@ void getar(char *desc, char *inar) i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Are You Sure",uifcYesNoOpts); if(!i) { ar[0]=0; - uifc.changes=1; + uifc.changes=1; } break; case 2: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -1787,7 +1805,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"LEVEL "); switch(i) { @@ -1799,14 +1817,14 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; case 3: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } for(i=0;i<4;i++) @@ -1834,7 +1852,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"FLAG "); if(i) @@ -1844,7 +1862,7 @@ void getar(char *desc, char *inar) case 4: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -1866,7 +1884,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"AGE "); switch(i) { @@ -1878,14 +1896,14 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; case 5: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } str[0]=0; uifc.helpbuf= @@ -1906,7 +1924,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"SEX "); strcat(ar,str); @@ -1914,7 +1932,7 @@ void getar(char *desc, char *inar) case 6: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -1932,7 +1950,7 @@ void getar(char *desc, char *inar) j=atoi(str); if(j>=300 && j<30000) { j/=100; - sprintf(str,"%d",j); + sprintf(str,"%d",j); } if(ar[0]) { j=whichcond(); @@ -1941,7 +1959,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"BPS "); switch(i) { @@ -1953,14 +1971,14 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; case 7: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -1983,7 +2001,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"PCR "); switch(i) { @@ -1995,14 +2013,14 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; case 8: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -2025,7 +2043,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"CREDIT "); switch(i) { @@ -2037,14 +2055,14 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; case 9: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -2069,7 +2087,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"UDR "); switch(i) { @@ -2081,14 +2099,14 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; case 10: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -2114,7 +2132,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"UDFR "); switch(i) { @@ -2126,14 +2144,14 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; case 11: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=0; strcpy(opt[0],"Before"); @@ -2160,7 +2178,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"TIME "); if(!i) @@ -2170,7 +2188,7 @@ void getar(char *desc, char *inar) case 12: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -2197,7 +2215,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"DAY "); switch(i) { @@ -2209,14 +2227,14 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; case 13: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -2238,7 +2256,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"NODE "); switch(i) { @@ -2250,14 +2268,14 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; case 14: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -2279,7 +2297,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"USER "); switch(i) { @@ -2291,7 +2309,7 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; @@ -2299,7 +2317,7 @@ void getar(char *desc, char *inar) case 15: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -2322,7 +2340,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"TLEFT "); switch(i) { @@ -2334,7 +2352,7 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; @@ -2342,7 +2360,7 @@ void getar(char *desc, char *inar) case 16: if(strlen(ar)>=30) { uifc.msg("Maximum string length reached"); - break; + break; } i=whichlogic(); if(i==-1) @@ -2365,7 +2383,7 @@ void getar(char *desc, char *inar) if(!j) strcat(ar," AND "); else - strcat(ar," OR "); + strcat(ar," OR "); } strcat(ar,"EXPIRE "); switch(i) { @@ -2377,12 +2395,12 @@ void getar(char *desc, char *inar) break; case 3: strcat(ar,"NOT "); - break; + break; } strcat(ar,str); break; - - } + + } } sprintf(inar,"%.*s",LEN_ARSTR,ar); } @@ -2434,6 +2452,16 @@ void bail(int code) (void)getchar(); } else if(forcesave) { + FILE* fp; + BOOL run_bbs, run_ftp, run_web, run_mail, run_services; + global_startup_t global_startup = {0}; + bbs_startup_t bbs_startup = {0}; + web_startup_t web_startup = {0}; + ftp_startup_t ftp_startup = {0}; + mail_startup_t mail_startup = {0}; + services_startup_t services_startup = {0}; + + uifc.pop("Force-saving configuration files..."); load_main_cfg(&cfg, error, sizeof(error)); load_msgs_cfg(&cfg, error, sizeof(error)); load_file_cfg(&cfg, error, sizeof(error)); @@ -2444,7 +2472,47 @@ void bail(int code) save_msgs_cfg(&cfg,backup_level); save_file_cfg(&cfg,backup_level); save_chat_cfg(&cfg,backup_level); - save_xtrn_cfg(&cfg,backup_level); + save_xtrn_cfg(&cfg,backup_level); + + sbbs_get_ini_fname(cfg.filename, cfg.ctrl_dir); + + fp = iniOpenFile(cfg.filename, /* for_modify? */false); + if(fp == NULL) + uifc.msgf("Error opening %s", cfg.filename); + else { + 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 + ); + 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 + ); + iniCloseFile(fp); + } + uifc.pop(NULL); } uifc.pop("Exiting"); diff --git a/src/sbbs3/scfg/scfg.h b/src/sbbs3/scfg/scfg.h index b75b8bc2d94dc8a3efcdb4637bc4c1f6fe04a334..ef6ba97c152ecc09873ed70f5e0c8d1797439881 100644 --- a/src/sbbs3/scfg/scfg.h +++ b/src/sbbs3/scfg/scfg.h @@ -146,6 +146,7 @@ void init_mdms(void); void guru_cfg(void); void actsets_cfg(void); void chan_cfg(void); +void server_cfg(void); void mdm_cfg(int mdmnum); void wizard_msg(int page, int total, const char* text); int edit_sys_name(int page, int total); @@ -185,7 +186,7 @@ BOOL save_main_cfg(scfg_t*, int); BOOL save_node_cfg(scfg_t*, int); BOOL save_msgs_cfg(scfg_t*, int); BOOL save_file_cfg(scfg_t*, int); -BOOL save_chat_cfg(scfg_t*, int); +BOOL save_chat_cfg(scfg_t*, int); BOOL save_xtrn_cfg(scfg_t*, int); long import_msg_areas(enum import_list_type, FILE*, unsigned grpnum, int min_confnum, int max_confnum diff --git a/src/sbbs3/scfg/scfg.vcxproj b/src/sbbs3/scfg/scfg.vcxproj index 90c77a2919c3f9f03fc1958526a0a2d7ee05f92f..ef57ffbe89b6714213e9021ffe1b280a498cac98 100644 --- a/src/sbbs3/scfg/scfg.vcxproj +++ b/src/sbbs3/scfg/scfg.vcxproj @@ -166,6 +166,7 @@ </ClCompile> <ClCompile Include="..\getstats.c" /> <ClCompile Include="..\msgdate.c" /> + <ClCompile Include="..\sbbs_ini.c" /> <ClCompile Include="..\userdat.c" /> <ClCompile Include="scfg.c"> <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> @@ -203,6 +204,7 @@ <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> + <ClCompile Include="scfgsrvr.c" /> <ClCompile Include="scfgsub.c"> <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions> diff --git a/src/sbbs3/scfg/scfgnet.c b/src/sbbs3/scfg/scfgnet.c index 31bba2ec8b9f84cb961f33df4fad5ff4d99f37ed..b40f1f7697d6e55666e18571fea41ce12185644b 100644 --- a/src/sbbs3/scfg/scfgnet.c +++ b/src/sbbs3/scfg/scfgnet.c @@ -62,7 +62,7 @@ bool new_qhub_sub(qhub_t* qhub, unsigned subnum, sub_t* sub, unsigned confnum) for(unsigned u = qhub->subs; u > subnum; u--) { qhub->sub[u]=qhub->sub[u-1]; qhub->conf[u]=qhub->conf[u-1]; - qhub->mode[u]=qhub->mode[u-1]; + qhub->mode[u]=qhub->mode[u-1]; } qhub->sub[subnum] = sub; qhub->conf[subnum] = confnum; @@ -82,14 +82,14 @@ faddr_t atofaddr(char *str) addr.zone=addr.net=addr.node=addr.point=0; if((p=strchr(str,':'))!=NULL) { addr.zone=atoi(str); - addr.net=atoi(p+1); + addr.net=atoi(p+1); } else { if(cfg.total_faddrs) addr.zone=cfg.faddr[0].zone; else addr.zone=1; - addr.net=atoi(str); + addr.net=atoi(str); } if(!addr.zone) /* no such thing as zone 0 */ addr.zone=1; @@ -100,7 +100,7 @@ faddr_t atofaddr(char *str) addr.net=cfg.faddr[0].net; else addr.net=1; - addr.node=atoi(str); + addr.node=atoi(str); } if((p=strchr(str,'.'))!=NULL) addr.point=atoi(p+1); @@ -132,7 +132,7 @@ uint getsub(void) for(j=k=0;j<cfg.total_subs && k<MAX_OPTS;j++) if(cfg.sub[j]->grp==i) { sprintf(opt[k],"%-25s",cfg.sub[j]->lname); - subnum[k++]=j; + subnum[k++]=j; } opt[k][0]=0; sprintf(str,"Select %s Sub-board",cfg.grp[i]->sname); @@ -141,7 +141,7 @@ uint getsub(void) continue; sub_dflt++; sub_bar++; - return(subnum[j]); + return(subnum[j]); } } @@ -388,6 +388,7 @@ void net_cfg() int mode; while(1) { + *cfg.filename = '\0'; i=0; strcpy(opt[i++],"Internet E-mail"); strcpy(opt[i++],"QWK Packet Networks"); @@ -498,7 +499,7 @@ void net_cfg() cfg.qhub[i]->node = NODE_ANY; cfg.qhub[i]->days=0x7f; /* all days */ uifc.changes=1; - continue; + continue; } if (msk == MSK_DEL) { free(cfg.qhub[i]->mode); @@ -508,16 +509,16 @@ void net_cfg() cfg.total_qhubs--; while(i<cfg.total_qhubs) { cfg.qhub[i]=cfg.qhub[i+1]; - i++; + i++; } uifc.changes=1; - continue; + continue; } - qhub_edit(i); + qhub_edit(i); } - break; - } - } + break; + } + } } else if(i==2) { /* FidoNet Stuff */ @@ -601,7 +602,7 @@ void net_cfg() else sprintf(str,"AKA %u",i); sprintf(opt[i],"%-8.8s %16s" - ,str,smb_faddrtoa(&cfg.faddr[i],tmp)); + ,str,smb_faddrtoa(&cfg.faddr[i],tmp)); } opt[i][0]=0; mode=WIN_RHT|WIN_SAV|WIN_ACT|WIN_INSACT; @@ -633,7 +634,7 @@ void net_cfg() ,sizeof(faddr_t)*cfg.total_faddrs+1); cfg.total_faddrs=0; bail(1); - continue; + continue; } for(j=cfg.total_faddrs;j>i;j--) @@ -642,7 +643,7 @@ void net_cfg() cfg.faddr[i]=newfaddr; cfg.total_faddrs++; uifc.changes=1; - continue; + continue; } if (msk == MSK_COPY) { savfaddr = cfg.faddr[i]; @@ -654,15 +655,15 @@ void net_cfg() cfg.total_faddrs--; while(i<cfg.total_faddrs) { cfg.faddr[i]=cfg.faddr[i+1]; - i++; + i++; } uifc.changes=1; - continue; + continue; } smb_faddrtoa(&cfg.faddr[i],str); if(uifc.input(WIN_MID|WIN_SAV,0,0,"Address" ,str,25,K_EDIT|K_UPPER) >= 1) - cfg.faddr[i]=atofaddr(str); + cfg.faddr[i]=atofaddr(str); } break; case 1: @@ -726,11 +727,11 @@ void net_cfg() ,"Allow Users to Send NetMail",uifcYesNoOpts); if(!i && !(cfg.netmail_misc&NMAIL_ALLOW)) { uifc.changes=1; - cfg.netmail_misc|=NMAIL_ALLOW; + cfg.netmail_misc|=NMAIL_ALLOW; } else if(i==1 && cfg.netmail_misc&NMAIL_ALLOW) { uifc.changes=1; - cfg.netmail_misc&=~NMAIL_ALLOW; + cfg.netmail_misc&=~NMAIL_ALLOW; } break; case 6: @@ -745,11 +746,11 @@ void net_cfg() ,"Allow Users to Send NetMail File Attachments",uifcYesNoOpts); if(!i && !(cfg.netmail_misc&NMAIL_FILE)) { uifc.changes=1; - cfg.netmail_misc|=NMAIL_FILE; + cfg.netmail_misc|=NMAIL_FILE; } else if(i==1 && cfg.netmail_misc&NMAIL_FILE) { uifc.changes=1; - cfg.netmail_misc&=~NMAIL_FILE; + cfg.netmail_misc&=~NMAIL_FILE; } break; case 7: @@ -769,11 +770,11 @@ void net_cfg() ,"Use Aliases in NetMail",uifcYesNoOpts); if(!i && !(cfg.netmail_misc&NMAIL_ALIAS)) { uifc.changes=1; - cfg.netmail_misc|=NMAIL_ALIAS; + cfg.netmail_misc|=NMAIL_ALIAS; } else if(i==1 && cfg.netmail_misc&NMAIL_ALIAS) { uifc.changes=1; - cfg.netmail_misc&=~NMAIL_ALIAS; + cfg.netmail_misc&=~NMAIL_ALIAS; } break; case 8: @@ -788,11 +789,11 @@ void net_cfg() ,"NetMail Defaults to Crash Status",uifcYesNoOpts); if(!i && !(cfg.netmail_misc&NMAIL_CRASH)) { uifc.changes=1; - cfg.netmail_misc|=NMAIL_CRASH; + cfg.netmail_misc|=NMAIL_CRASH; } else if(i==1 && cfg.netmail_misc&NMAIL_CRASH) { uifc.changes=1; - cfg.netmail_misc&=~NMAIL_CRASH; + cfg.netmail_misc&=~NMAIL_CRASH; } break; case 9: @@ -807,11 +808,11 @@ void net_cfg() ,"NetMail Defaults to Direct Status",uifcYesNoOpts); if(!i && !(cfg.netmail_misc&NMAIL_DIRECT)) { uifc.changes=1; - cfg.netmail_misc|=NMAIL_DIRECT; + cfg.netmail_misc|=NMAIL_DIRECT; } else if(i==1 && cfg.netmail_misc&NMAIL_DIRECT) { uifc.changes=1; - cfg.netmail_misc&=~NMAIL_DIRECT; + cfg.netmail_misc&=~NMAIL_DIRECT; } break; case 10: @@ -826,11 +827,11 @@ void net_cfg() ,"NetMail Defaults to Hold Status",uifcYesNoOpts); if(!i && !(cfg.netmail_misc&NMAIL_HOLD)) { uifc.changes=1; - cfg.netmail_misc|=NMAIL_HOLD; + cfg.netmail_misc|=NMAIL_HOLD; } else if(i==1 && cfg.netmail_misc&NMAIL_HOLD) { uifc.changes=1; - cfg.netmail_misc&=~NMAIL_HOLD; + cfg.netmail_misc&=~NMAIL_HOLD; } break; case 11: @@ -845,11 +846,11 @@ void net_cfg() ,"Kill NetMail After it is Sent",uifcYesNoOpts); if(!i && !(cfg.netmail_misc&NMAIL_KILL)) { uifc.changes=1; - cfg.netmail_misc|=NMAIL_KILL; + cfg.netmail_misc|=NMAIL_KILL; } else if(i==1 && cfg.netmail_misc&NMAIL_KILL) { uifc.changes=1; - cfg.netmail_misc&=~NMAIL_KILL; + cfg.netmail_misc&=~NMAIL_KILL; } break; case 12: @@ -864,7 +865,7 @@ void net_cfg() ,"Cost in Credits to Send NetMail" ,str,10,K_EDIT|K_NUMBER); cfg.netmail_cost=atol(str); - break; + break; case 13: i = (cfg.netmail_misc & NMAIL_CHSRCADDR) ? 0 : 1; uifc.helpbuf= @@ -878,15 +879,15 @@ void net_cfg() ,"Allow Senders of NetMail to Choose the Source Address",uifcYesNoOpts); if(!i && !(cfg.netmail_misc&NMAIL_CHSRCADDR)) { uifc.changes=1; - cfg.netmail_misc|=NMAIL_CHSRCADDR; + cfg.netmail_misc|=NMAIL_CHSRCADDR; } else if(i==1 && cfg.netmail_misc&NMAIL_CHSRCADDR) { uifc.changes=1; - cfg.netmail_misc&=~NMAIL_CHSRCADDR; + cfg.netmail_misc&=~NMAIL_CHSRCADDR; } break; - } - } + } + } } else if(i==0) { /* Internet E-mail */ done=0; @@ -968,11 +969,11 @@ void net_cfg() ,"Allow Users to Send E-mail",uifcYesNoOpts); if(!i && !(cfg.inetmail_misc&NMAIL_ALLOW)) { uifc.changes=1; - cfg.inetmail_misc|=NMAIL_ALLOW; + cfg.inetmail_misc|=NMAIL_ALLOW; } else if(i==1 && cfg.inetmail_misc&NMAIL_ALLOW) { uifc.changes=1; - cfg.inetmail_misc&=~NMAIL_ALLOW; + cfg.inetmail_misc&=~NMAIL_ALLOW; } break; case 4: @@ -987,11 +988,11 @@ void net_cfg() ,"Allow Users to Send E-mail with File Attachments",uifcYesNoOpts); if(!i && !(cfg.inetmail_misc&NMAIL_FILE)) { uifc.changes=1; - cfg.inetmail_misc|=NMAIL_FILE; + cfg.inetmail_misc|=NMAIL_FILE; } else if(i==1 && cfg.inetmail_misc&NMAIL_FILE) { uifc.changes=1; - cfg.inetmail_misc&=~NMAIL_FILE; + cfg.inetmail_misc&=~NMAIL_FILE; } break; case 5: @@ -1011,11 +1012,11 @@ void net_cfg() ,"Use Aliases in Internet E-mail",uifcYesNoOpts); if(!i && !(cfg.inetmail_misc&NMAIL_ALIAS)) { uifc.changes=1; - cfg.inetmail_misc|=NMAIL_ALIAS; + cfg.inetmail_misc|=NMAIL_ALIAS; } else if(i==1 && cfg.inetmail_misc&NMAIL_ALIAS) { uifc.changes=1; - cfg.inetmail_misc&=~NMAIL_ALIAS; + cfg.inetmail_misc&=~NMAIL_ALIAS; } break; case 6: @@ -1030,7 +1031,7 @@ void net_cfg() ,"Kill Internet E-mail After it is Sent",uifcYesNoOpts); if(!i && !(cfg.inetmail_misc&NMAIL_KILL)) { uifc.changes=1; - cfg.inetmail_misc|=NMAIL_KILL; + cfg.inetmail_misc|=NMAIL_KILL; } else if(i==1 && cfg.inetmail_misc&NMAIL_KILL) { uifc.changes=1; @@ -1050,9 +1051,9 @@ void net_cfg() ,"Cost in Credits to Send Internet E-mail" ,str,10,K_EDIT|K_NUMBER); cfg.inetmail_cost=atol(str); - break; - } - } + break; + } + } } i=save_changes(WIN_MID|WIN_SAV); @@ -1139,11 +1140,11 @@ void qhub_edit(int num) sprintf(opt[i++],"%-27.27s%s","Call-out Days",daystr(cfg.qhub[num]->days)); if(cfg.qhub[num]->freq) { sprintf(str,"%u times a day",1440/cfg.qhub[num]->freq); - sprintf(opt[i++],"%-27.27s%s","Call-out Frequency",str); + sprintf(opt[i++],"%-27.27s%s","Call-out Frequency",str); } else { sprintf(str,"%2.2u:%2.2u",cfg.qhub[num]->time/60,cfg.qhub[num]->time%60); - sprintf(opt[i++],"%-27.27s%s","Call-out Time",str); + sprintf(opt[i++],"%-27.27s%s","Call-out Time",str); } sprintf(opt[i++],"%-27.27s%s","Include Kludge Lines", cfg.qhub[num]->misc&QHUB_NOKLUDGES ? "No":"Yes"); sprintf(opt[i++],"%-27.27s%s","Include VOTING.DAT File", cfg.qhub[num]->misc&QHUB_NOVOTING ? "No":"Yes"); @@ -1302,7 +1303,7 @@ void qhub_edit(int num) if(i==-1) break; cfg.qhub[num]->days^=(1<<i); - uifc.changes=1; + uifc.changes=1; } break; case __COUNTER__: @@ -1332,8 +1333,8 @@ void qhub_edit(int num) cfg.qhub[num]->freq=0; cfg.qhub[num]->time=atoi(str)*60; if((p=strchr(str,':'))!=NULL) - cfg.qhub[num]->time+=atoi(p+1); - } + cfg.qhub[num]->time+=atoi(p+1); + } } else if(i==1) { sprintf(str,"%u",cfg.qhub[num]->freq @@ -1355,8 +1356,8 @@ void qhub_edit(int num) if(i && i<=1440) cfg.qhub[num]->freq=1440/i; else - cfg.qhub[num]->freq=0; - } + cfg.qhub[num]->freq=0; + } } break; case __COUNTER__: @@ -1395,8 +1396,8 @@ void qhub_edit(int num) break; case __COUNTER__: qhub_sub_edit(num); - break; - } + break; + } } } @@ -1419,7 +1420,7 @@ void qhub_sub_edit(uint num) "a `CONTROL.DAT` file extracted from a `.QWK` packet downloaded from\n" "the QWK network hub." ; - char* qwk_ctrl_a_help = + char* qwk_ctrl_a_help = "`Ctrl-A Codes:`\n" "\n" "You are being prompted for the method of handling Ctrl-A attribute codes\n" @@ -1501,7 +1502,7 @@ void qhub_sub_edit(uint num) uifc.changes=1; k++; bar++; - continue; + continue; } if((j&MSK_ON)==MSK_DEL) { j&=MSK_OFF; @@ -1510,10 +1511,10 @@ void qhub_sub_edit(uint num) cfg.qhub[num]->sub[j]=cfg.qhub[num]->sub[j+1]; cfg.qhub[num]->mode[j]=cfg.qhub[num]->mode[j+1]; cfg.qhub[num]->conf[j]=cfg.qhub[num]->conf[j+1]; - j++; + j++; } uifc.changes=1; - continue; + continue; } l=0; while(1) { @@ -1561,8 +1562,8 @@ void qhub_sub_edit(uint num) m=getsub(); if(m!=-1) { cfg.qhub[num]->sub[j]=cfg.sub[m]; - uifc.changes=1; - } + uifc.changes=1; + } } else if(l==1) { uifc.helpbuf=qwk_conf_num_help; @@ -1570,7 +1571,7 @@ void qhub_sub_edit(uint num) if(uifc.input(WIN_MID|WIN_SAV,0,0 ,"Conference Number on Hub" ,str,5,K_NUMBER|K_EDIT) > 0) - cfg.qhub[num]->conf[j] = atoi(str); + cfg.qhub[num]->conf[j] = atoi(str); } else if(l==2) { strcpy(opt[0],"Strip out"); @@ -1587,9 +1588,9 @@ void qhub_sub_edit(uint num) else if(m==1) cfg.qhub[num]->mode[j]=QHUB_RETCTLA; else if(m==2) - cfg.qhub[num]->mode[j]=QHUB_EXPCTLA; - } - } + cfg.qhub[num]->mode[j]=QHUB_EXPCTLA; + } + } } } @@ -1627,7 +1628,7 @@ BOOL import_qwk_conferences(uint qhubnum) FILE *fp; if((fp = fopen(filename, "rt"))==NULL) { uifc.msg("File Open Failure"); - return FALSE; + return FALSE; } uifc.pop("Importing Areas..."); long added = 0; @@ -1660,7 +1661,7 @@ char *daystr(char days) for(i=0;i<7;i++) { if(days&(1<<i)) { SAFECAT(str,wday[i]); - SAFECAT(str," "); + SAFECAT(str," "); } } return(str); diff --git a/src/sbbs3/scfg/scfgnode.c b/src/sbbs3/scfg/scfgnode.c index 2ae15f7cb1946cc33b2f8d0a07160ede5c797556..763e79f5e7057ec4ea668f502299daba17dcd4f5 100644 --- a/src/sbbs3/scfg/scfgnode.c +++ b/src/sbbs3/scfg/scfgnode.c @@ -15,7 +15,7 @@ * http://www.synchro.net/source.html * * * * Note: If this box doesn't appear square, then you need to fix your tabs. * - ****************************************************************************/ + ****************************************************************************/ #include "scfg.h" @@ -32,10 +32,13 @@ static char* node_path_help = void node_menu() { char str[81],savnode=0; + char cfg_filename[MAX_PATH + 1]; int i,j; static int node_menu_dflt, node_bar; + SAFECOPY(cfg_filename, cfg.filename); while(1) { + SAFECOPY(cfg.filename, cfg_filename); for(i=0;i<cfg.sys_nodes;i++) sprintf(opt[i],"Node %d",i+1); opt[i][0]=0; @@ -70,9 +73,9 @@ void node_menu() if(i==-1) { if(savnode) { free_node_cfg(&cfg); - savnode=0; + savnode=0; } - return; + return; } int msk = i & MSK_ON; if(msk == MSK_DEL) { @@ -91,7 +94,7 @@ void node_menu() save_main_cfg(&cfg,backup_level); refresh_cfg(&cfg); } - continue; + continue; } if(msk == MSK_INS && cfg.sys_nodes < MAX_NODES) { SAFECOPY(cfg.node_dir,cfg.node_path[cfg.sys_nodes-1]); @@ -132,7 +135,7 @@ void node_menu() SAFECOPY(cfg.node_dir,cfg.node_path[i]); load_node_cfg(&cfg,error, sizeof(error)); savnode=1; - continue; + continue; } if(msk == MSK_PASTE) { i&=MSK_OFF; @@ -145,7 +148,7 @@ void node_menu() if(savnode) { free_node_cfg(&cfg); - savnode=0; + savnode=0; } SAFECOPY(cfg.node_dir,cfg.node_path[i]); prep_dir(cfg.ctrl_dir, cfg.node_dir, sizeof(cfg.node_dir)); @@ -157,7 +160,7 @@ void node_menu() } node_cfg(); - free_node_cfg(&cfg); + free_node_cfg(&cfg); } } @@ -244,11 +247,11 @@ void node_cfg() ,"Allow 8-bit Remote Input During Login",uifcYesNoOpts); if(i==1 && !(cfg.node_misc&NM_7BITONLY)) { cfg.node_misc|=NM_7BITONLY; - uifc.changes=1; + uifc.changes=1; } else if(i==0 && (cfg.node_misc&NM_7BITONLY)) { cfg.node_misc&=~NM_7BITONLY; - uifc.changes=1; + uifc.changes=1; } break; case 1: @@ -263,11 +266,11 @@ void node_cfg() ,"Spinning Cursor at Pause Prompt",uifcYesNoOpts); if(i==0 && cfg.node_misc&NM_NOPAUSESPIN) { cfg.node_misc&=~NM_NOPAUSESPIN; - uifc.changes=1; + uifc.changes=1; } else if(i==1 && !(cfg.node_misc&NM_NOPAUSESPIN)) { cfg.node_misc|=NM_NOPAUSESPIN; - uifc.changes=1; + uifc.changes=1; } break; case 2: @@ -284,11 +287,11 @@ void node_cfg() ,"Keep Node File Open",uifcYesNoOpts); if(i==0 && cfg.node_misc&NM_CLOSENODEDAB) { cfg.node_misc&=~NM_CLOSENODEDAB; - uifc.changes=1; + uifc.changes=1; } else if(i==1 && !(cfg.node_misc&NM_CLOSENODEDAB)) { cfg.node_misc|=NM_CLOSENODEDAB; - uifc.changes=1; + uifc.changes=1; } break; } @@ -376,10 +379,10 @@ void node_cfg() ; uifc.input(WIN_MID|WIN_SAV,0,10,"Text Directory" ,cfg.text_dir,sizeof(cfg.text_dir)-1,K_EDIT); - break; - } + break; + } } break; - } + } } } diff --git a/src/sbbs3/scfg/scfgsrvr.c b/src/sbbs3/scfg/scfgsrvr.c new file mode 100644 index 0000000000000000000000000000000000000000..1a8b42262a22500cd1bcff987ddb4c789c6b72f8 --- /dev/null +++ b/src/sbbs3/scfg/scfgsrvr.c @@ -0,0 +1,1465 @@ +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include "scfg.h" +#include "sbbs_ini.h" +#include "netwrap.h" + +const char* strDisabled = "<disabled>"; + +static const char* threshold(uint val) +{ + static char str[128]; + if(val == 0) + return strDisabled; + SAFEPRINTF(str, "%u", val); + return str; +} + +static const char* duration(uint val, bool verbose) +{ + static char str[128]; + if(val == 0) + return strDisabled; + return verbose ? duration_to_vstr(val, str, sizeof(str)) : duration_to_str(val, str, sizeof(str));; +} + +static const char* vduration(uint val) +{ + return duration(val, true); +} + +static const char* maximum(uint val) +{ + static char str[128]; + if(val == 0) + return "Unlimited"; + SAFEPRINTF(str, "%u", val); + return str; +} + +static void global_cfg(void) +{ + static int cur, bar; + char str[256]; + char tmp[256]; + 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", "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)); + opt[i][0] = '\0'; + + uifc.helpbuf= + "`Global Server Settings:`\n" + "\n" + ; + switch(uifc.list(WIN_ACT|WIN_RHT|WIN_SAV|WIN_ESC, 0, 0, 0, &cur, &bar + ,"Global Server Setttings",opt)) { + case 0: + uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &startup.log_level, 0, "Log Level", iniLogLevelStringList()); + break; + case 1: + uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &startup.tls_error_level, 0, "TLS Error Log Level", iniLogLevelStringList()); + break; + case 2: + strListCombine(startup.interfaces, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Inbound Network Interfaces (IPv4/6)", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.interfaces); + strListSplitCopy(&startup.interfaces, str, ", "); + uifc.changes = true; + } + break; + case 3: + IPv4AddressToStr(startup.outgoing4.s_addr, str, sizeof(str)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Outbound Network Interface (IPv4)", str, sizeof(str)-1, K_EDIT) > 0) + startup.outgoing4.s_addr = parseIPv4Address(str); + break; + case 4: + 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) + startup.bind_retry_count = atoi(str); + break; + case 5: + 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) + startup.bind_retry_delay = 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); + 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); + 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 = 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 = 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 = parse_duration(str); + 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 + ,&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; + } + } +} + +static void termsrvr_cfg(void) +{ + static int cur, bar; + char str[256]; + 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) + i = 1; + opt[i][0] = '\0'; + + uifc.helpbuf= + "`Terminal Server Configuration:`\n" + "\n" + ; + switch(uifc.list(WIN_ACT|WIN_ESC|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar + ,"Terminal Server",opt)) { + case 0: + enabled = !enabled; + uifc.changes = true; + break; + case 1: + uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &startup.log_level, 0, "Log Level", iniLogLevelStringList()); + break; + case 2: + SAFEPRINTF(str, "%u", startup.first_node); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "First Node Available For Terminal Logins", str, 3, K_NUMBER|K_EDIT) > 0) + startup.first_node = atoi(str); + break; + case 3: + SAFEPRINTF(str, "%u", startup.last_node); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Last Node Available For Terminal Logins", str, 3, K_NUMBER|K_EDIT) > 0) + startup.last_node = atoi(str); + break; + case 4: + startup.options ^= BBS_OPT_NO_DOS; + break; + case 5: + startup.options ^= BBS_OPT_ALLOW_SSH; + break; + case 6: + strListCombine(startup.ssh_interfaces, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "SSH Network Interfaces (IPv4/6)", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.ssh_interfaces); + strListSplitCopy(&startup.ssh_interfaces, str, ", "); + uifc.changes = true; + } + break; + case 7: + SAFEPRINTF(str, "%u", startup.ssh_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "SSH TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.ssh_port = atoi(str); + break; + case 8: + SAFECOPY(str, duration(startup.ssh_connect_timeout, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "SSH Connect Timeout", str, 6, K_EDIT) > 0) + startup.ssh_connect_timeout = parse_duration(str); + break; + case 9: + startup.options ^= BBS_OPT_NO_TELNET; + break; + case 10: + strListCombine(startup.telnet_interfaces, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Telnet Network Interfaces (IPv4/6)", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.telnet_interfaces); + strListSplitCopy(&startup.telnet_interfaces, str, ", "); + uifc.changes = true; + } + break; + case 11: + SAFEPRINTF(str, "%u", startup.telnet_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Telnet TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.telnet_port = atoi(str); + break; + case 12: + startup.options ^= BBS_OPT_DEBUG_TELNET; + break; + case 13: + startup.options ^= BBS_OPT_NO_TELNET_GA; + break; + case 14: + startup.options ^= BBS_OPT_ALLOW_RLOGIN; + break; + case 15: + strListCombine(startup.rlogin_interfaces, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "RLogin Network Interfaces (IPv4/6)", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.rlogin_interfaces); + strListSplitCopy(&startup.rlogin_interfaces, str, ", "); + uifc.changes = true; + } + break; + case 16: + SAFEPRINTF(str, "%u", startup.rlogin_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "RLogin TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.rlogin_port = atoi(str); + break; + case 17: + SAFEPRINTF(str, "%u", startup.pet40_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "40 Column CBM/PETSCII TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.pet40_port = atoi(str); + break; + case 18: + SAFEPRINTF(str, "%u", startup.pet80_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "80 Column CBM/PETSCII TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.pet80_port = atoi(str); + break; + case 19: + SAFECOPY(str, maximum(startup.max_concurrent_connections)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Concurrent (Unauthenticated) Connections", str, 10, K_EDIT) > 0) + startup.max_concurrent_connections = atoi(str); + break; + case 20: + SAFECOPY(str, duration(startup.max_login_inactivity, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Socket Inactivity at Login", str, 10, K_EDIT) > 0) + startup.max_login_inactivity = parse_duration(str); + break; + case 21: + SAFECOPY(str, duration(startup.max_newuser_inactivity, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Socket Inactivity at New User Registration", str, 10, K_EDIT) > 0) + startup.max_newuser_inactivity = parse_duration(str); + break; + case 22: + SAFECOPY(str, duration(startup.max_session_inactivity, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Socket Inactivity during User Session", str, 10, K_EDIT) > 0) + startup.max_session_inactivity = parse_duration(str); + break; + case 23: + SAFEPRINTF(str, "%u", startup.outbuf_drain_timeout); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Output Buffer Draing Timeout (milliseconds)", str, 5, K_NUMBER|K_EDIT) > 0) + startup.outbuf_drain_timeout = atoi(str); + break; + case 24: + startup.options ^= BBS_OPT_NO_EVENTS; + break; + case 25: + startup.options ^= BBS_OPT_NO_QWK_EVENTS; + break; + case 26: + startup.options ^= BBS_OPT_NO_HOST_LOOKUP; + 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(void) +{ + static int cur, bar; + char tmp[256]; + char str[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"); + SAFECOPY(str, startup.logfile_base); + if(*str == '\0') + SAFEPRINTF(str, "[%slogs/http-*]", cfg.logs_dir); + sprintf(opt[i++], "%-30s%s", "Access Logging", startup.options & WEB_OPT_HTTP_LOGGING ? str : 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)); + } + if(!enabled) + i = 1; + opt[i][0] = '\0'; + + uifc.helpbuf= + "`Web Server Configuration:`\n" + "\n" + ; + switch(uifc.list(WIN_ACT|WIN_ESC|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar + ,"Web Server",opt)) { + case 0: + enabled = !enabled; + uifc.changes = true; + break; + case 1: + uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &startup.log_level, 0, "Log Level", iniLogLevelStringList()); + break; + case 2: + strListCombine(startup.interfaces, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "HTTP Network Interfaces (IPv4/6)", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.interfaces); + strListSplitCopy(&startup.interfaces, str, ", "); + uifc.changes = true; + } + break; + case 3: + SAFEPRINTF(str, "%u", startup.port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "HTTP TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.port = atoi(str); + break; + case 4: + startup.options ^= WEB_OPT_ALLOW_TLS; + break; + case 5: + strListCombine(startup.tls_interfaces, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "HTTP/TLS (HTTPS) Network Interfaces (IPv4/6)", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.tls_interfaces); + strListSplitCopy(&startup.tls_interfaces, str, ", "); + uifc.changes = true; + } + break; + case 6: + SAFEPRINTF(str, "%u", startup.tls_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "HTTP/TLS (HTTPS) TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.tls_port = atoi(str); + break; + case 7: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Server-side JavaScript File Extension" + , startup.ssjs_ext, sizeof(startup.ssjs_ext) -1, K_EDIT); + break; + case 8: + strListCombine(startup.index_file_name, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Index Filenames", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.index_file_name); + strListSplitCopy(&startup.index_file_name, str, ", "); + uifc.changes = true; + } + break; + case 9: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Content Root Directory" + ,startup.root_dir, sizeof(startup.root_dir)-1, K_EDIT); + break; + case 10: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Error Sub-directory" + ,startup.error_dir, sizeof(startup.error_dir)-1, K_EDIT); + break; + case 11: + startup.options ^= WEB_OPT_HSTS_SAFE; + break; + case 12: + startup.options ^= WEB_OPT_VIRTUAL_HOSTS; + break; + case 13: + i = startup.options & WEB_OPT_HTTP_LOGGING ? 0 : 1; + i = uifc.list(WIN_SAV|WIN_MID, 0, 0, 0, &i, 0, "Log (to disk) HTTP Requests", uifcYesNoOpts); + if(i == 0) { + startup.options |= WEB_OPT_HTTP_LOGGING; + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Base path/filename (blank = default)" + ,startup.logfile_base, sizeof(startup.logfile_base)-1, K_EDIT); + } else if(i == 1) + startup.options &= ~WEB_OPT_HTTP_LOGGING; + break; + case 14: + SAFECOPY(str, maximum(startup.max_clients)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Client Count (0=unlimited)", str, 10, K_EDIT) > 0) + startup.max_clients = atoi(str); + break; + case 15: + SAFECOPY(str, duration(startup.max_inactivity, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Client Inactivity", str, 10, K_EDIT) > 0) + startup.max_inactivity = parse_duration(str); + break; + case 16: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Filebase Index Script" + ,startup.file_index_script, sizeof(startup.file_index_script)-1, K_EDIT); + break; + case 17: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Filebase Virtual Path Prefix" + ,startup.file_vpath_prefix, sizeof(startup.file_vpath_prefix)-1, K_EDIT); + break; + case 18: + startup.file_vpath_for_vhosts = !startup.file_vpath_for_vhosts; + break; + case 19: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Authentication Methods" + ,startup.default_auth_list, sizeof(startup.default_auth_list)-1, K_EDIT); + break; + case 20: + SAFEPRINTF(str, "%u", startup.outbuf_drain_timeout); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Output Buffer Drain Timeout (milliseconds)" + ,str, 5, K_NUMBER|K_EDIT) > 0) + startup.outbuf_drain_timeout = atoi(str); + break; + case 21: + startup.options ^= BBS_OPT_NO_HOST_LOOKUP; + break; + case 22: + startup.options ^= WEB_OPT_NO_CGI; + break; + case 23: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "CGI Directory" + ,startup.cgi_dir, sizeof(startup.cgi_dir)-1, K_EDIT); + break; + case 24: + strListCombine(startup.cgi_ext, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "CGI File Extensions", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.cgi_ext); + strListSplitCopy(&startup.cgi_ext, str, ", "); + uifc.changes = true; + } + break; + case 25: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Default CGI MIME Content-Type" + ,startup.default_cgi_content, sizeof(startup.default_cgi_content)-1, K_EDIT); + break; + case 26: + duration_to_str(startup.max_cgi_inactivity, str, sizeof(str)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum CGI Inactivity", str, 10, K_EDIT) > 0) + startup.max_cgi_inactivity = parse_duration(str); + 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(void) +{ + static int cur, bar; + char tmp[256]; + char str[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) + i = 1; + opt[i][0] = '\0'; + + uifc.helpbuf= + "`FTP Server Configuration:`\n" + "\n" + ; + switch(uifc.list(WIN_ACT|WIN_ESC|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar + ,"FTP Server",opt)) { + case 0: + enabled = !enabled; + uifc.changes = true; + break; + case 1: + uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &startup.log_level, 0, "Log Level", iniLogLevelStringList()); + break; + case 2: + strListCombine(startup.interfaces, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Network Interfaces (IPv4/6)", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.interfaces); + strListSplitCopy(&startup.interfaces, str, ", "); + uifc.changes = true; + } + break; + case 3: + SAFEPRINTF(str, "%u", startup.port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Control TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.port = atoi(str); + break; + case 4: + i = startup.options & FTP_OPT_LOOKUP_PASV_IP ? 0 : 1; + i = uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &i, 0, "Automatically Detect Public IP Address", uifcYesNoOpts); + if(i == 0) + startup.options |= FTP_OPT_LOOKUP_PASV_IP; + else if(i == 1) { + startup.options &= ~FTP_OPT_LOOKUP_PASV_IP; + IPv4AddressToStr(startup.pasv_ip_addr.s_addr, str, sizeof(str)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "IPv4 Address for Passive Connections", str, sizeof(str)-1, K_EDIT) > 0) + startup.pasv_ip_addr.s_addr = parseIPv4Address(str); + } + break; + case 5: + SAFEPRINTF(str, "%u", startup.pasv_port_low); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Lowest Passive TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.pasv_port_low = atoi(str); + else + break; + SAFEPRINTF(str, "%u", startup.pasv_port_high); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Highest Passive TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.pasv_port_high = atoi(str); + break; + case 6: + i = startup.options & FTP_OPT_INDEX_FILE ? 0 : 1; + i = uifc.list(WIN_SAV|WIN_MID, 0, 0, 0, &i, 0, "Autogenerate Index Files", uifcYesNoOpts); + if(i == 0) { + startup.options |= FTP_OPT_INDEX_FILE; + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Index Filename" + ,startup.index_file_name, sizeof(startup.index_file_name)-1, K_EDIT); + } else if(i == 1) + startup.options &= ~FTP_OPT_INDEX_FILE; + break; + case 7: + startup.options ^= FTP_OPT_ALLOW_QWK; + break; + case 8: + SAFECOPY(str, duration(startup.qwk_timeout, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "QWK Message Packet Creation Timeout", str, 10, K_EDIT) > 0) + startup.qwk_timeout = parse_duration(str); + break; + case 9: + SAFECOPY(str, maximum(startup.max_clients)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Client Count (0=unlimited)", str, 10, K_EDIT) > 0) + startup.max_clients = atoi(str); + break; + case 10: + SAFECOPY(str, duration(startup.max_inactivity, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Client Inactivity", str, 10, K_EDIT) > 0) + startup.max_inactivity = parse_duration(str); + break; + case 11: + SAFECOPY(str, maximum(startup.max_concurrent_connections)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Concurrent (Unauthenticated) Connections", str, 10, K_EDIT) > 0) + startup.max_concurrent_connections = atoi(str); + break; + case 12: + startup.options ^= FTP_OPT_NO_LOCAL_FSYS; + break; + case 13: + startup.options ^= FTP_OPT_ALLOW_BOUNCE; + break; + case 14: + startup.options ^= BBS_OPT_NO_HOST_LOOKUP; + 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(void) +{ + static int cur, bar; + char tmp[256]; + char str[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", "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) + p = "Refuse Session"; + else if(startup.options & MAIL_OPT_DNSBL_IGNORE) + p = "Silently Ignore"; + else if(startup.options & MAIL_OPT_DNSBL_BADUSER) + p = "Refuse Mail"; + else + 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", "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)); + } + if(!enabled) + i = 1; + opt[i][0] = '\0'; + + uifc.helpbuf= + "`Mail Server Configuration:`\n" + "\n" + ; + switch(uifc.list(WIN_ACT|WIN_ESC|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar + ,"Mail Server",opt)) { + case 0: + enabled = !enabled; + uifc.changes = true; + break; + case 1: + uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &startup.log_level, 0, "Log Level", iniLogLevelStringList()); + break; + case 2: + strListCombine(startup.interfaces, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "SMTP Network Interfaces (IPv4/6)", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.interfaces); + strListSplitCopy(&startup.interfaces, str, ", "); + uifc.changes = true; + } + break; + case 3: + SAFEPRINTF(str, "%u", startup.smtp_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "SMTP TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.smtp_port = atoi(str); + break; + case 4: + startup.options ^= MAIL_OPT_USE_SUBMISSION_PORT; + break; + case 5: + SAFEPRINTF(str, "%u", startup.submission_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "SMTP-Submission TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.submission_port = atoi(str); + break; + case 6: + startup.options ^= MAIL_OPT_TLS_SUBMISSION; + break; + case 7: + SAFEPRINTF(str, "%u", startup.submissions_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "SMTP-Submission/TLS TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.submissions_port = atoi(str); + break; + case 8: + startup.options ^= MAIL_OPT_ALLOW_POP3; + break; + case 9: + strListCombine(startup.pop3_interfaces, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "POP3 Network Interfaces (IPv4/6)", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.pop3_interfaces); + strListSplitCopy(&startup.pop3_interfaces, str, ", "); + uifc.changes = true; + } + break; + case 10: + SAFEPRINTF(str, "%u", startup.pop3_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "POP3 TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.pop3_port = atoi(str); + break; + case 11: + startup.options ^= MAIL_OPT_TLS_POP3; + break; + case 12: + SAFEPRINTF(str, "%u", startup.pop3s_port); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "POP3/TLS TCP Port", str, 5, K_NUMBER|K_EDIT) > 0) + startup.pop3s_port = atoi(str); + break; + case 13: + SAFECOPY(str, maximum(startup.max_clients)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Client Count (0=unlimited)", str, 10, K_EDIT) > 0) + startup.max_clients = atoi(str); + break; + case 14: + SAFECOPY(str, duration(startup.max_inactivity, false)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Client Inactivity", str, 10, K_EDIT) > 0) + startup.max_inactivity = parse_duration(str); + break; + case 15: + SAFECOPY(str, maximum(startup.max_concurrent_connections)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Concurrent (Unauthenticated) Connections", str, 10, K_EDIT) > 0) + startup.max_concurrent_connections = atoi(str); + break; + case 16: + SAFECOPY(str, maximum(startup.max_recipients)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Recipients per Message", str, 10, K_EDIT) > 0) + startup.max_recipients = atoi(str); + break; + case 17: + SAFECOPY(str, maximum(startup.max_msgs_waiting)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Messages Waiting per User", str, 10, K_EDIT) > 0) + startup.max_msgs_waiting = atoi(str); + break; + case 18: + byte_count_to_str(startup.max_msg_size, str, sizeof(str)); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Received Message Size (in bytes)", str, 10, K_EDIT) > 0) + startup.max_msg_size = parse_byte_count(str, 1); + break; + case 19: + startup.options ^= MAIL_OPT_ALLOW_RELAY; + break; + case 20: + startup.options ^= MAIL_OPT_ALLOW_SYSOP_ALIASES; + break; + case 21: + startup.options ^= MAIL_OPT_NO_NOTIFY; + break; + case 22: + startup.options ^= BBS_OPT_NO_HOST_LOOKUP; + break; + case 23: + startup.options ^= MAIL_OPT_DNSBL_CHKRECVHDRS; + break; + case 24: + i = 0; + strcpy(opt[i++], "Refuse Session"); + strcpy(opt[i++], "Silently Ignore"); + strcpy(opt[i++], "Refuse Mail"); + strcpy(opt[i++], "Tag Mail"); + opt[i][0] = '\0'; + if(startup.options & MAIL_OPT_DNSBL_REFUSE) + i = 0; + else if(startup.options & MAIL_OPT_DNSBL_IGNORE) + i = 1; + else if(startup.options & MAIL_OPT_DNSBL_BADUSER) + i = 2; + else + i = 3; + if(uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &i, 0, "DNS-Blacklisted Servers", opt) < 0) + break; + startup.options &= ~(MAIL_OPT_DNSBL_REFUSE | MAIL_OPT_DNSBL_IGNORE | MAIL_OPT_DNSBL_BADUSER); + switch(i) { + case 0: + startup.options |= MAIL_OPT_DNSBL_REFUSE; + break; + case 1: + startup.options |= MAIL_OPT_DNSBL_IGNORE; + break; + case 2: + startup.options |= MAIL_OPT_DNSBL_BADUSER; + } + i = startup.options & MAIL_OPT_DNSBL_THROTTLE ? 0 : 1; + if(uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &i, 0, "Throttle DNS-Blacklisted Servers", uifcYesNoOpts) < 0) + break; + if(i == 0) + startup.options |= MAIL_OPT_DNSBL_THROTTLE; + else + startup.options &= ~MAIL_OPT_DNSBL_THROTTLE; + break; + case 25: + startup.options ^= MAIL_OPT_DNSBL_SPAMHASH; + break; + case 26: + startup.options ^= MAIL_OPT_NO_AUTO_EXEMPT; + break; + case 27: + 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 = 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 = parse_duration(str); + 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(void) +{ + static int cur, bar; + char tmp[256]; + char str[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) + i = 1; + opt[i][0] = '\0'; + + uifc.helpbuf= + "`Services Server Configuration:`\n" + "\n" + ; + switch(uifc.list(WIN_ACT|WIN_ESC|WIN_RHT|WIN_SAV, 0, 0, 0, &cur, &bar + ,"Services Server",opt)) { + case 0: + enabled = !enabled; + uifc.changes = true; + break; + case 1: + uifc.list(WIN_MID|WIN_SAV, 0, 0, 0, &startup.log_level, 0, "Log Level", iniLogLevelStringList()); + break; + case 2: + strListCombine(startup.interfaces, str, sizeof(str), ", "); + if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Network Interfaces (IPv4/6)", str, sizeof(str)-1, K_EDIT) >= 0) { + strListFree(&startup.interfaces); + strListSplitCopy(&startup.interfaces, str, ", "); + uifc.changes = true; + } + break; + case 3: + startup.options ^= BBS_OPT_NO_HOST_LOOKUP; + break; + case 4: + uifc.input(WIN_MID|WIN_SAV, 0, 0, "Services Configuration File", startup.services_ini, sizeof(startup.services_ini)-1, K_EDIT); + 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; + } + } +} + +void server_cfg(void) +{ + static int srvr_dflt; + BOOL run_bbs, run_ftp, run_web, run_mail, run_services; + + sbbs_get_ini_fname(cfg.filename, cfg.ctrl_dir); + + 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); + 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); + opt[i][0] = '\0'; + + uifc.helpbuf= + "`Server Configuration:`\n" + "\n" + "Here you can configure initialization settings of the various TCP/IP\n" + "servers that are integrated into Synchronet BBS Software.\n" + "\n" + "For additinal advanced Synchronet server initialization settings, see\n" + "the `ctrl/sbbs.ini` file and `https://wiki.synchro.net/config:sbbs.ini`\n" + "for reference.\n" + ; + i = uifc.list(WIN_ORG|WIN_ACT,0,0,0,&srvr_dflt,0, "Server Configuration",opt); + switch(i) { + case 0: + global_cfg(); + break; + case 1: + termsrvr_cfg(); + break; + case 2: + websrvr_cfg(); + break; + case 3: + ftpsrvr_cfg(); + break; + case 4: + mailsrvr_cfg(); + break; + case 5: + services_cfg(); + break; + default: + return; + } + } +} diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h index 13fb795ec0a8f1730a5b53b62a890c11c716870b..68ace40f6759f3ecba69aa6ab86c73b738067e2a 100644 --- a/src/sbbs3/scfgdefs.h +++ b/src/sbbs3/scfgdefs.h @@ -286,7 +286,7 @@ enum xedit_soft_cr { // What to do with so-called "Soft CRs" XEDIT_SOFT_CR_EXPAND, XEDIT_SOFT_CR_STRIP, XEDIT_SOFT_CR_RETAIN -}; +}; typedef struct { /* External Editors */ char code[LEN_CODE+1], @@ -392,10 +392,11 @@ struct mqtt_cfg { } tls; }; -typedef struct +typedef struct { DWORD size; /* sizeof(scfg_t) */ BOOL prepped; /* TRUE if prep_cfg() has been used */ + char filename[MAX_PATH + 1]; // last-loaded cfg file path/name grp_t **grp; /* Each message group */ uint16_t total_grps; /* Total number of groups */ diff --git a/src/sbbs3/scfglib1.c b/src/sbbs3/scfglib1.c index 6827d8aa38d92b589ea5006130642c2e1a40c383..d521a5f9e0e97898f88d4cf07073ecd52fd4a79e 100644 --- a/src/sbbs3/scfglib1.c +++ b/src/sbbs3/scfglib1.c @@ -39,16 +39,15 @@ BOOL allocerr(char* error, size_t maxerrlen, const char* fname, const char *item /****************************************************************************/ BOOL read_node_cfg(scfg_t* cfg, char* error, size_t maxerrlen) { - char path[MAX_PATH+1]; char errstr[256]; FILE* fp; str_list_t ini; char value[INI_MAX_VALUE_LEN]; const char* fname = "node.ini"; - SAFEPRINTF2(path,"%s%s",cfg->node_dir,fname); - if((fp = fnopen(NULL, path, O_RDONLY)) == NULL) { - safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),path); + SAFEPRINTF2(cfg->filename,"%s%s",cfg->node_dir,fname); + if((fp = fnopen(NULL, cfg->filename, O_RDONLY)) == NULL) { + safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),cfg->filename); return FALSE; } ini = iniReadFile(fp); @@ -76,7 +75,6 @@ BOOL read_node_cfg(scfg_t* cfg, char* error, size_t maxerrlen) BOOL read_main_cfg(scfg_t* cfg, char* error, size_t maxerrlen) { BOOL result = FALSE; - char path[MAX_PATH+1]; char errstr[256]; FILE* fp; str_list_t ini = NULL; @@ -84,9 +82,9 @@ BOOL read_main_cfg(scfg_t* cfg, char* error, size_t maxerrlen) str_list_t section; const char* fname = "main.ini"; - SAFEPRINTF2(path,"%s%s",cfg->ctrl_dir,fname); - if((fp = fnopen(NULL, path, O_RDONLY)) == NULL) { - safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),path); + SAFEPRINTF2(cfg->filename,"%s%s",cfg->ctrl_dir,fname); + if((fp = fnopen(NULL, cfg->filename, O_RDONLY)) == NULL) { + safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),cfg->filename); } else { ini = iniReadFile(fp); fclose(fp); @@ -332,16 +330,15 @@ BOOL read_main_cfg(scfg_t* cfg, char* error, size_t maxerrlen) /****************************************************************************/ BOOL read_msgs_cfg(scfg_t* cfg, char* error, size_t maxerrlen) { - char path[MAX_PATH+1]; char errstr[256]; FILE* fp; str_list_t ini; char value[INI_MAX_VALUE_LEN]; const char* fname = "msgs.ini"; - SAFEPRINTF2(path,"%s%s",cfg->ctrl_dir,fname); - if((fp = fnopen(NULL, path, O_RDONLY)) == NULL) { - safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),path); + SAFEPRINTF2(cfg->filename,"%s%s",cfg->ctrl_dir,fname); + if((fp = fnopen(NULL, cfg->filename, O_RDONLY)) == NULL) { + safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),cfg->filename); return FALSE; } ini = iniReadFile(fp); @@ -678,7 +675,7 @@ void make_data_dirs(scfg_t* cfg) for(int i = 0; i < cfg->total_dirs; i++) { md(cfg->dir[i]->data_dir); - if(cfg->dir[i]->misc & DIR_FCHK) + if(cfg->dir[i]->misc & DIR_FCHK) md(cfg->dir[i]->path); } } diff --git a/src/sbbs3/scfglib2.c b/src/sbbs3/scfglib2.c index 4102329ea424f11d75d7f501c529a6849a64013a..04113f30f2fc576d098efad5a8d75dc98c4b69b6 100644 --- a/src/sbbs3/scfglib2.c +++ b/src/sbbs3/scfglib2.c @@ -46,16 +46,15 @@ static void read_dir_defaults_cfg(scfg_t* cfg, str_list_t ini, dir_t* dir) /****************************************************************************/ BOOL read_file_cfg(scfg_t* cfg, char* error, size_t maxerrlen) { - char path[MAX_PATH+1]; char errstr[256]; FILE* fp; str_list_t ini; char value[INI_MAX_VALUE_LEN]; const char* fname = "file.ini"; - SAFEPRINTF2(path,"%s%s",cfg->ctrl_dir,fname); - if((fp = fnopen(NULL, path, O_RDONLY)) == NULL) { - safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),path); + SAFEPRINTF2(cfg->filename,"%s%s",cfg->ctrl_dir,fname); + if((fp = fnopen(NULL, cfg->filename, O_RDONLY)) == NULL) { + safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),cfg->filename); return FALSE; } ini = iniReadFile(fp); @@ -364,16 +363,15 @@ BOOL read_file_cfg(scfg_t* cfg, char* error, size_t maxerrlen) /****************************************************************************/ BOOL read_xtrn_cfg(scfg_t* cfg, char* error, size_t maxerrlen) { - char path[MAX_PATH+1]; char errstr[256]; FILE* fp; str_list_t ini; char value[INI_MAX_VALUE_LEN]; const char* fname = "xtrn.ini"; - SAFEPRINTF2(path,"%s%s",cfg->ctrl_dir,fname); - if((fp = fnopen(NULL, path, O_RDONLY)) == NULL) { - safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),path); + SAFEPRINTF2(cfg->filename,"%s%s",cfg->ctrl_dir,fname); + if((fp = fnopen(NULL, cfg->filename, O_RDONLY)) == NULL) { + safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),cfg->filename); return FALSE; } ini = iniReadFile(fp); @@ -576,16 +574,15 @@ BOOL read_xtrn_cfg(scfg_t* cfg, char* error, size_t maxerrlen) /****************************************************************************/ BOOL read_chat_cfg(scfg_t* cfg, char* error, size_t maxerrlen) { - char path[MAX_PATH+1]; char errstr[256]; FILE* fp; str_list_t ini; char value[INI_MAX_VALUE_LEN]; const char* fname = "chat.ini"; - SAFEPRINTF2(path,"%s%s",cfg->ctrl_dir,fname); - if((fp = fnopen(NULL, path, O_RDONLY)) == NULL) { - safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),path); + SAFEPRINTF2(cfg->filename,"%s%s",cfg->ctrl_dir,fname); + if((fp = fnopen(NULL, cfg->filename, O_RDONLY)) == NULL) { + safe_snprintf(error, maxerrlen, "%d (%s) opening %s",errno,safe_strerror(errno, errstr, sizeof(errstr)),cfg->filename); return FALSE; } ini = iniReadFile(fp); @@ -746,7 +743,7 @@ uint32_t aftou32(const char *str) ch=toupper(str[c]); if(ch>='A' && ch<='Z') l|=FLAG(ch); - c++; + c++; } return(l); } @@ -762,7 +759,7 @@ char *u32toaf(uint32_t l,char *str) if(l & (1 << c)) str[c]='A'+c; else str[c]=' '; - c++; + c++; } str[c]=0; return(str); @@ -832,12 +829,12 @@ uint attrstr(char *str) break; case '6': /* Cyan Background */ atr=(uchar)((atr&0x8f)|BG_CYAN); - break; + break; case '7': /* White Background */ atr=(uchar)((atr&0x8f)|BG_LIGHTGRAY); break; } - l++; + l++; } return(atr); } diff --git a/src/sbbs3/umonitor/umonitor.c b/src/sbbs3/umonitor/umonitor.c index 19bffd961e0a54fcbdb2e0b88ee7f795a844016e..e8b0ef8d0069655d2a20604dc033c72a141be256 100644 --- a/src/sbbs3/umonitor/umonitor.c +++ b/src/sbbs3/umonitor/umonitor.c @@ -869,7 +869,10 @@ int main(int argc, char** argv) { if(fp!=NULL) fclose(fp); - chdir(bbs_startup.ctrl_dir); + if(chdir(bbs_startup.ctrl_dir) != 0) { + printf("Error %d changing directory to: %s\n", errno, bbs_startup.ctrl_dir); + exit(1); + } /* Read .cfg files here */ memset(&cfg,0,sizeof(cfg)); diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c index 2bcf1e677768258102020a9eebcd1ed473d15eda..6b7b33e1d5318c9a9c0c94f844bc1266e6d8c8a7 100644 --- a/src/sbbs3/websrvr.c +++ b/src/sbbs3/websrvr.c @@ -2392,7 +2392,7 @@ static void js_add_request_property(http_session_t * session, char *key, char *v js_str=JS_NewStringCopyN(session->js_cx, value, len); else js_str=JS_NewStringCopyZ(session->js_cx, value); - + if(js_str == NULL) return; @@ -7328,7 +7328,7 @@ void web_server(void* arg) lprintf(LOG_NOTICE, "%04d New active client highwater mark: %lu" ,client_socket, client_highwater); } - if(startup->max_clients && protected_uint32_value(active_clients)>=startup->max_clients) { + if(startup->max_clients && count>=startup->max_clients) { lprintf(LOG_WARNING,"%04d [%s] !MAXIMUM CLIENTS (%d) reached, access denied" ,client_socket, host_ip, startup->max_clients); if (!len_503) diff --git a/src/uifc/uifcx.c b/src/uifc/uifcx.c index 323ccca1c31e090e894e5f05fe20955b38b782ab..fb4c441552c785a277cc7316a7a0664e589fa2ad 100644 --- a/src/uifc/uifcx.c +++ b/src/uifc/uifcx.c @@ -206,6 +206,10 @@ int ulist(uifc_winmode_t mode, int left, int top, int width, int *cur, int *bar int optnumlen; int yesno=0; int lines; + int tmpcur=0; + + if(cur == NULL) + cur = &tmpcur; for(opts=0;opts<MAX_OPTS;opts++) if(option[opts]==NULL || option[opts][0]==0) @@ -230,7 +234,8 @@ int ulist(uifc_winmode_t mode, int left, int top, int width, int *cur, int *bar yesno=1; printf("%s? ",title); } else { - printf("\n[%s]\n",title); + if(title != NULL) + printf("\n[%s]\n",title); lines=2; for(i=0;i<opts;i++) { printf("%*d: %s\n",optnumlen,i+1,option[i]); diff --git a/src/xpdev/ini_file.c b/src/xpdev/ini_file.c index 74533b0bb9cd02e1d0137feefe453b34b489e8fc..ee838392c74fe249a97cb1792f47a5a3183cb051 100644 --- a/src/xpdev/ini_file.c +++ b/src/xpdev/ini_file.c @@ -425,6 +425,8 @@ BOOL iniRemoveValue(str_list_t* list, const char* section, const char* key) if(vp==NULL) return(FALSE); + while(*vp != '\0' && isspace(*(vp - 1))) + --vp; *vp=0; return(TRUE); } @@ -794,9 +796,11 @@ char* iniSetBytes(str_list_t* list, const char* section, const char* key, uint u char* iniSetDuration(str_list_t* list, const char* section, const char* key ,double value, ini_style_t* style) { - char str[INI_MAX_VALUE_LEN]; + char str[INI_MAX_VALUE_LEN] = "0"; - return iniSetString(list, section, key, duration_to_str(value, str, sizeof(str)), style); + if(value) + duration_to_str(value, str, sizeof(str)); + return iniSetString(list, section, key, str, style); } diff --git a/src/xpdev/str_list.c b/src/xpdev/str_list.c index 51e37b03dbd450c371742f3cf6b1ac39e5d36d1f..e91cc3162a561c3674eb404a758d345f4b609278 100644 --- a/src/xpdev/str_list.c +++ b/src/xpdev/str_list.c @@ -590,8 +590,7 @@ int strListCmp(str_list_t list1, str_list_t list2) strListSortAlphaCase(l1); strListSortAlphaCase(l2); - for(; *l1; l1++) { - l2++; + for(; *l1; l1++, l2++) { if(*l2==NULL) { ret=1; goto early_return; @@ -602,7 +601,6 @@ int strListCmp(str_list_t list1, str_list_t list2) goto early_return; } } - l2++; if(*l2==NULL) ret=0; else