Skip to content
Snippets Groups Projects
Commit 9001d042 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Overhaul the System Configuration menu - moved all Security Options to submenu

The security-related options were really spread around and this menu was
getting very overloaded (the list of Toggle Options had grown huge), so now
most of the content is actually under the new "Security Options" sub-menu.

This does make a bunch of previous instructions/docs slightly out of sync
(e.g. SCFG->System->Security Level Values should now be
SCFG->System->Security Options->Security Level Values), but I think sysops
will still find stuff just fine.

This re-org will allow me to add more options that I've wanted to but needed
better organization and structuring to do so logically and clearly.

Using the memcmp() trick to detect changes in the configuration.

No new settings/option were added in this commit.
parent 0975d578
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
Pipeline #3754 passed
...@@ -60,25 +60,30 @@ static void configure_dst(void) ...@@ -60,25 +60,30 @@ static void configure_dst(void)
} }
} }
void sys_cfg(void) void security_cfg(void)
{ {
static int sys_dflt,adv_dflt,tog_dflt,new_dflt; char str[128];
static int dflt;
static int quick_dflt;
static int expired_dflt;
static int seclevel_dflt, seclevel_bar; static int seclevel_dflt, seclevel_bar;
static int tog_bar; int i, j, k;
static int adv_bar; BOOL done;
char str[81],done=0;
int i,j,k,dflt,bar;
char sys_pass[sizeof(cfg.sys_pass)];
SAFECOPY(sys_pass, cfg.sys_pass);
while(1) { while(1) {
i = 0; i = 0;
sprintf(opt[i++],"%-33.33s%s","BBS Name",cfg.sys_name); sprintf(opt[i++],"%-33.33s%s","System Password", "*******");
sprintf(opt[i++],"%-33.33s%s","Location",cfg.sys_location); if(cfg.sys_misc & SM_R_SYSOP) {
sprintf(opt[i++],"%-33.33s%s %s","Local Time Zone" SAFECOPY(str, "Yes");
,smb_zonestr(cfg.sys_timezone,NULL) if(cfg.sys_misc & SM_SYSPASSLOGIN)
,SMB_TZ_HAS_DST(cfg.sys_timezone) && cfg.sys_misc&SM_AUTO_DST ? "(Auto-DST)" : ""); SAFECAT(str, ", SYSPASS required at login");
sprintf(opt[i++],"%-33.33s%s","Operator",cfg.sys_op); } else
sprintf(opt[i++],"%-33.33s%s","Password","**********"); SAFECOPY(str, "No");
sprintf(opt[i++],"%-33.33s%s","Allow Sysop Access", str);
sprintf(opt[i++],"%-33.33s%s","Allow Login by Real Name"
,(!(cfg.uq&UQ_ALIASES) || cfg.sys_login & LOGIN_REALNAME) ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Allow Login by User Number"
,(cfg.sys_login & LOGIN_USERNUM) ? "Yes" : "No");
SAFEPRINTF(str,"%s Password" SAFEPRINTF(str,"%s Password"
,cfg.sys_misc&SM_PWEDIT && cfg.sys_pwdays ? "Users Must Change" ,cfg.sys_misc&SM_PWEDIT && cfg.sys_pwdays ? "Users Must Change"
...@@ -92,365 +97,148 @@ void sys_cfg(void) ...@@ -92,365 +97,148 @@ void sys_cfg(void)
if(cfg.sys_misc&SM_PWEDIT) if(cfg.sys_misc&SM_PWEDIT)
sprintf(tmp + strlen(tmp), ", %u chars minimum", cfg.min_pwlen); sprintf(tmp + strlen(tmp), ", %u chars minimum", cfg.min_pwlen);
sprintf(opt[i++],"%-33.33s%s",str,tmp); sprintf(opt[i++],"%-33.33s%s",str,tmp);
sprintf(opt[i++],"%-33.33s%s","Always Prompt for Password"
,cfg.sys_login & LOGIN_PWPROMPT ? "Yes":"No");
sprintf(opt[i++],"%-33.33s%s","Display/Log Passwords Locally"
,cfg.sys_misc&SM_ECHO_PW ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%u","Days to Preserve Deleted Users" sprintf(opt[i++],"%-33.33s%u","Days to Preserve Deleted Users"
,cfg.sys_deldays); ,cfg.sys_deldays);
sprintf(opt[i++],"%-33.33s%s","Maximum Days of Inactivity" sprintf(opt[i++],"%-33.33s%s","Maximum Days of User Inactivity"
,cfg.sys_autodel ? ultoa(cfg.sys_autodel,tmp,10) : "Unlimited"); ,cfg.sys_autodel ? ultoa(cfg.sys_autodel,tmp,10) : "Unlimited");
sprintf(opt[i++],"%-33.33s%s","New User Password",cfg.new_pass); if(cfg.sys_misc&SM_CLOSED)
SAFECOPY(str, "No");
else {
if(*cfg.new_pass)
SAFEPRINTF(str, "Yes, PW: %s", cfg.new_pass);
else
SAFECOPY(str, "Yes");
}
sprintf(opt[i++],"%-33.33s%s","Open to New Users", str);
sprintf(opt[i++],"%-33.33s%s","User Expires When Out-of-time"
,cfg.sys_misc&SM_TIME_EXP ? "Yes" : "No");
strcpy(opt[i++],"Toggle Options...");
strcpy(opt[i++],"New User Values...");
strcpy(opt[i++],"Advanced Options...");
strcpy(opt[i++],"Loadable Modules...");
strcpy(opt[i++],"Security Level Values..."); strcpy(opt[i++],"Security Level Values...");
strcpy(opt[i++],"Expired Account Values..."); strcpy(opt[i++],"Expired Account Values...");
strcpy(opt[i++],"Quick-Validation Values..."); strcpy(opt[i++],"Quick-Validation Values...");
opt[i][0]=0; opt[i][0]=0;
uifc.helpbuf= uifc.helpbuf=
"`System Configuration:`\n" "`System Security Options:`\n"
"\n" "\n"
"This menu contains options and sub-menus of options that affect the\n" "This menu contains options and sub-menus of options that affect the\n"
"entire BBS system and the Synchronet Terminal Server in particular.\n" "security related behavior of the entire BBS.\n"
; ;
switch(uifc.list(WIN_ORG|WIN_ACT|WIN_CHE,0,0,72,&sys_dflt,0 switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT, 0, 0, 72, &dflt, 0
,"System Configuration",opt)) { ,"Security Options",opt)) {
case -1: case -1:
i=save_changes(WIN_MID);
if(i==-1)
break;
if(!i) {
cfg.new_install=new_install;
if(strcmp(sys_pass, cfg.sys_pass) != 0) {
if(fexist("ssl.cert") || fexist("cryptlib.key") || fexist("letsyncrypt.key")) {
CRYPT_KEYSET ssl_keyset;
CRYPT_CONTEXT ssl_context = -1;
int status;
int ignoreme;
if (cryptStatusOK(status = cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, "ssl.cert", CRYPT_KEYOPT_NONE)))
if (cryptStatusOK(status = cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssl_cert", sys_pass)))
if (cryptStatusOK(status = cryptDeleteKey(ssl_keyset, CRYPT_KEYID_NAME, "ssl_cert"))) {
ignoreme = cryptAddPrivateKey(ssl_keyset, ssl_context, cfg.sys_pass);
cryptKeysetClose(ssl_keyset);
}
if (cryptStatusOK(status = cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, "cryptlib.key", CRYPT_KEYOPT_NONE)))
if (cryptStatusOK(status = cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssh_server", sys_pass)))
if (cryptStatusOK(status = cryptDeleteKey(ssl_keyset, CRYPT_KEYID_NAME, "ssh_server"))) {
ignoreme = cryptAddPrivateKey(ssl_keyset, ssl_context, cfg.sys_pass);
cryptKeysetClose(ssl_keyset);
}
if (cryptStatusOK(status = cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, "letsyncrypt.key", CRYPT_KEYOPT_NONE))) {
char value[INI_MAX_VALUE_LEN];
char* host = "acme-v02.api.letsencrypt.org";
FILE* fp = fopen("letsyncrypt.ini", "r");
if(fp != NULL) {
host = iniReadString(fp, "state", "host", host, value);
fclose(fp);
}
if (cryptStatusOK(status = cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, host, sys_pass)))
if (cryptStatusOK(status = cryptDeleteKey(ssl_keyset, CRYPT_KEYID_NAME, host))) {
ignoreme = cryptAddPrivateKey(ssl_keyset, ssl_context, cfg.sys_pass);
cryptKeysetClose(ssl_keyset);
}
}
(void)ignoreme;
}
}
save_main_cfg(&cfg,backup_level);
refresh_cfg(&cfg);
}
return; return;
case 0: case __COUNTER__:
uifc.helpbuf= uifc.helpbuf=
"`BBS Name:`\n" "`System Password:`\n"
"\n" "\n"
"This is the name of the BBS.\n" "This is an extra security password required for sysop logon and certain\n"
; "sysop functions. This password should be something not easily guessed\n"
uifc.input(WIN_MID,0,0,"BBS Name",cfg.sys_name,sizeof(cfg.sys_name)-1,K_EDIT); "and should be kept absolutely confidential. This password must be\n"
break; "entered at the Terminal Server `SY:` prompt.\n"
case 1:
uifc.helpbuf=
"`System Location:`\n"
"\n" "\n"
"This is the location of the BBS. The format is flexible, but it is\n" "This system password can also be used to enable sysop access to the\n"
"suggested you use the `City, State` format for clarity.\n" "FTP Server by authenticating with a password that combines a sysop's\n"
"password with the system password, separated by a colon\n"
"(i.e. '`user-pass:system-pass`').\n"
"\n"
"`Note:` When the `Allow Sysop Access` Toggle Option is set to `No`,\n"
" The system password is effectively disabled."
; ;
uifc.input(WIN_MID,0,0,"Location",cfg.sys_location,sizeof(cfg.sys_location)-1,K_EDIT); uifc.input(WIN_MID|WIN_SAV,0,0,"System Password",cfg.sys_pass,sizeof(cfg.sys_pass)-1,K_EDIT|K_UPPER);
break; break;
case 2: case __COUNTER__:
i = !(cfg.sys_timezone & US_ZONE); i=cfg.sys_misc&SM_R_SYSOP ? 0:1;
uifc.helpbuf= uifc.helpbuf=
"`United States Time Zone:`\n" "`Allow Sysop Access:`\n"
"\n" "\n"
"If your local time zone is the United States, select `Yes`.\n" "Setting this option to `No` will prevent users with sysop security level\n"
"from invoking functions that require system-password authentication.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"United States Time Zone",uifcYesNoOpts); ,"Allow Sysop Access",uifcYesNoOpts);
if(i==-1)
break;
if(i == 0) { if(i == 0) {
strcpy(opt[i++],"Atlantic"); cfg.sys_misc|=SM_R_SYSOP;
strcpy(opt[i++],"Eastern"); i=cfg.sys_misc&SM_SYSPASSLOGIN ? 0:1;
strcpy(opt[i++],"Central");
strcpy(opt[i++],"Mountain");
strcpy(opt[i++],"Pacific");
strcpy(opt[i++],"Yukon");
strcpy(opt[i++],"Hawaii/Alaska");
strcpy(opt[i++],"Bering");
opt[i][0]=0;
i=0;
uifc.helpbuf= uifc.helpbuf=
"`U.S. Time Zone:`\n" "`Require System Password for Sysop Login:`\n"
"\n" "\n"
"Choose the region which most closely reflects your local U.S. time zone.\n" "If you want to require the correct system password to be provided during\n"
"system operator logins (in addition to the sysop's personal user account\n"
"password), set this option to `Yes`.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"U.S. Time Zone",opt); ,"Require System Password for Sysop Login",uifcYesNoOpts);
if(i==-1) if(i==1)
break; cfg.sys_misc &= ~SM_SYSPASSLOGIN;
uifc.changes=1; else if(i==0)
switch(i) { cfg.sys_misc |= SM_SYSPASSLOGIN;
case 0: }
cfg.sys_timezone=AST; else if(i == 1) {
break; cfg.sys_misc &= ~SM_R_SYSOP;
case 1: }
cfg.sys_timezone=EST;
break;
case 2:
cfg.sys_timezone=CST;
break;
case 3:
cfg.sys_timezone=MST;
break;
case 4:
cfg.sys_timezone=PST;
break;
case 5:
cfg.sys_timezone=YST;
break;
case 6:
cfg.sys_timezone=HST;
break; break;
case 7: case __COUNTER__:
cfg.sys_timezone=BST; if(!(cfg.uq&UQ_ALIASES))
break; break;
i = (cfg.sys_login & LOGIN_REALNAME) ? 0:1;
uifc.helpbuf=
"`Allow Login by Real Name:`\n"
"\n"
"If you want users to be able login using their real name as well as\n"
"their alias, set this option to `Yes`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
,"Allow Login by Real Name",uifcYesNoOpts);
if((i==0 && !(cfg.sys_login & LOGIN_REALNAME))
|| (i==1 && (cfg.sys_login & LOGIN_REALNAME))) {
cfg.sys_login ^= LOGIN_REALNAME;
} }
configure_dst();
break; break;
} case __COUNTER__:
i=0; i = (cfg.sys_login & LOGIN_USERNUM) ? 0:1;
strcpy(opt[i++],"Midway");
strcpy(opt[i++],"Vancouver");
strcpy(opt[i++],"Edmonton");
strcpy(opt[i++],"Winnipeg");
strcpy(opt[i++],"Bogota");
strcpy(opt[i++],"Caracas");
strcpy(opt[i++],"Rio de Janeiro");
strcpy(opt[i++],"Fernando de Noronha");
strcpy(opt[i++],"Azores");
strcpy(opt[i++],"Western Europe (WET)");
strcpy(opt[i++],"Central Europe (CET)");
strcpy(opt[i++],"Eastern Europe (EET)");
strcpy(opt[i++],"Moscow");
strcpy(opt[i++],"Dubai");
strcpy(opt[i++],"Kabul");
strcpy(opt[i++],"Karachi");
strcpy(opt[i++],"Bombay");
strcpy(opt[i++],"Kathmandu");
strcpy(opt[i++],"Dhaka");
strcpy(opt[i++],"Bangkok");
strcpy(opt[i++],"Hong Kong");
strcpy(opt[i++],"Tokyo");
strcpy(opt[i++],"Australian Central");
strcpy(opt[i++],"Australian Eastern");
strcpy(opt[i++],"Noumea");
strcpy(opt[i++],"New Zealand");
strcpy(opt[i++],"Other...");
opt[i][0]=0;
i=0;
uifc.helpbuf= uifc.helpbuf=
"`Non-U.S. Time Zone:`\n" "`Allow Login by User Number:`\n"
"\n" "\n"
"Choose the region which most closely reflects your local time zone.\n" "If you want users to be able login using their user number at the\n"
"login prompt, set this option to `Yes`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
,"Allow Login by User Number",uifcYesNoOpts);
if((i==0 && !(cfg.sys_login & LOGIN_USERNUM))
|| (i==1 && (cfg.sys_login & LOGIN_USERNUM))) {
cfg.sys_login ^= LOGIN_USERNUM;
}
break;
case __COUNTER__:
i = (cfg.sys_misc&SM_PWEDIT) ? 0 : 1;
uifc.helpbuf=
"`Allow Users to Change Their Password:`\n"
"\n" "\n"
"Choose `Other...` if a region representing your local time zone is\n" "If you want the users of your system to have the option of changing\n"
"not listed (you will be able to set the UTC offset manually)." "their password to a string of their choice, set this option to `Yes`.\n"
"For the highest level of security, set this option to `No.`\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"None-U.S. Time Zone",opt); ,"Allow Users to Change Their Password",uifcYesNoOpts);
if(i==-1) if(!i && !(cfg.sys_misc&SM_PWEDIT)) {
cfg.sys_misc|=SM_PWEDIT;
}
else if(i==1 && cfg.sys_misc&SM_PWEDIT) {
cfg.sys_misc&=~SM_PWEDIT;
} else if(i == -1)
break; break;
uifc.changes=1;
switch(i) { if(cfg.sys_misc&SM_PWEDIT) {
case 0: SAFEPRINTF(tmp, "%u", cfg.min_pwlen);
cfg.sys_timezone=MID; SAFEPRINTF2(str, "Minimum Password Length (between %u and %u)", MIN_PASS_LEN, LEN_PASS);
break; if(uifc.input(WIN_MID|WIN_SAV,0,0, str
case 1: ,tmp, 2, K_NUMBER|K_EDIT) < 1)
cfg.sys_timezone=VAN;
break;
case 2:
cfg.sys_timezone=EDM;
break;
case 3:
cfg.sys_timezone=WIN;
break;
case 4:
cfg.sys_timezone=BOG;
break;
case 5:
cfg.sys_timezone=CAR;
break;
case 6:
cfg.sys_timezone=RIO;
break;
case 7:
cfg.sys_timezone=FER;
break;
case 8:
cfg.sys_timezone=AZO;
break;
case 9:
cfg.sys_timezone=WET;
break;
case 10:
cfg.sys_timezone=CET;
break;
case 11:
cfg.sys_timezone=EET;
break;
case 12:
cfg.sys_timezone=MOS;
break;
case 13:
cfg.sys_timezone=DUB;
break;
case 14:
cfg.sys_timezone=KAB;
break;
case 15:
cfg.sys_timezone=KAR;
break;
case 16:
cfg.sys_timezone=BOM;
break;
case 17:
cfg.sys_timezone=KAT;
break;
case 18:
cfg.sys_timezone=DHA;
break;
case 19:
cfg.sys_timezone=BAN;
break;
case 20:
cfg.sys_timezone=HON;
break;
case 21:
cfg.sys_timezone=TOK;
break;
case 22:
cfg.sys_timezone=ACST;
break;
case 23:
cfg.sys_timezone=AEST;
break;
case 24:
cfg.sys_timezone=NOU;
break;
case 25:
cfg.sys_timezone=NZST;
break;
default:
if(cfg.sys_timezone>720 || cfg.sys_timezone<-720)
cfg.sys_timezone=0;
if(cfg.sys_timezone==0)
str[0]=0;
else
sprintf(str,"%02d:%02d"
,cfg.sys_timezone/60,cfg.sys_timezone<0
? (-cfg.sys_timezone)%60 : cfg.sys_timezone%60);
uifc.helpbuf=
"`Time Zone Offset:`\n"
"\n"
"Enter your local time zone offset from Universal Time (UTC/GMT)\n"
"in `HH:MM` format.\n"
;
uifc.input(WIN_MID|WIN_SAV,0,0
,"Time (HH:MM) East (+) or West (-) of Universal "
"Time"
,str,6,K_EDIT|K_UPPER);
cfg.sys_timezone=atoi(str)*60;
char *p=strchr(str,':');
if(p) {
if(cfg.sys_timezone<0)
cfg.sys_timezone-=atoi(p+1);
else
cfg.sys_timezone+=atoi(p+1);
}
break;
}
if(SMB_TZ_HAS_DST(cfg.sys_timezone))
configure_dst();
break;
case 3:
uifc.helpbuf=
"`System Operator:`\n"
"\n"
"This is the name or alias of the system operator. This does not have to\n"
"be the same as user #1. This field is used for informational purposes\n"
"only.\n"
;
uifc.input(WIN_MID,0,0,"System Operator",cfg.sys_op,sizeof(cfg.sys_op)-1,K_EDIT);
break;
case 4:
uifc.helpbuf=
"`System Password:`\n"
"\n"
"This is an extra security password required for sysop logon and certain\n"
"sysop functions. This password should be something not easily guessed\n"
"and should be kept absolutely confidential. This password must be\n"
"entered at the Terminal Server `SY:` prompt.\n"
"\n"
"This system password can also be used to enable sysop access to the\n"
"FTP Server by authenticating with a password that combines a sysop's\n"
"password with the system password, separated by a colon\n"
"(i.e. '`user-pass:system-pass`').\n"
"\n"
"`Note:` When the `Allow Sysop Access` Toggle Option is set to `No`,\n"
" The system password is effectively disabled."
;
uifc.input(WIN_MID,0,0,"System Password",cfg.sys_pass,sizeof(cfg.sys_pass)-1,K_EDIT|K_UPPER);
break;
case 5:
i = (cfg.sys_misc&SM_PWEDIT) ? 0 : 1;
uifc.helpbuf=
"`Allow Users to Change Their Password:`\n"
"\n"
"If you want the users of your system to have the option of changing\n"
"their password to a string of their choice, set this option to `Yes`.\n"
"For the highest level of security, set this option to `No.`\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"Allow Users to Change Their Password",uifcYesNoOpts);
if(!i && !(cfg.sys_misc&SM_PWEDIT)) {
cfg.sys_misc|=SM_PWEDIT;
uifc.changes=1;
}
else if(i==1 && cfg.sys_misc&SM_PWEDIT) {
cfg.sys_misc&=~SM_PWEDIT;
uifc.changes=1;
} else if(i == -1)
break;
if(cfg.sys_misc&SM_PWEDIT) {
SAFEPRINTF(tmp, "%u", cfg.min_pwlen);
SAFEPRINTF2(str, "Minimum Password Length (between %u and %u)", MIN_PASS_LEN, LEN_PASS);
if(uifc.input(WIN_MID|WIN_SAV,0,0, str
,tmp, 2, K_NUMBER|K_EDIT) < 1)
break; break;
cfg.min_pwlen=atoi(tmp); cfg.min_pwlen=atoi(tmp);
if(cfg.min_pwlen < MIN_PASS_LEN) if(cfg.min_pwlen < MIN_PASS_LEN)
...@@ -483,11 +271,44 @@ void sys_cfg(void) ...@@ -483,11 +271,44 @@ void sys_cfg(void)
} }
else if(i==1 && cfg.sys_pwdays) { else if(i==1 && cfg.sys_pwdays) {
cfg.sys_pwdays=0; cfg.sys_pwdays=0;
uifc.changes=1;
} }
break; break;
case 6: case __COUNTER__:
i=cfg.sys_login & LOGIN_PWPROMPT ? 0:1;
uifc.helpbuf=
"`Always Prompt for Password:`\n"
"\n"
"If you want to have attempted logins using an unknown user name still\n"
"prompt for a password (i.e. for enhanced security), set this option to\n"
"`Yes`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
,"Always Prompt for Password",uifcYesNoOpts);
if((i==0 && !(cfg.sys_login & LOGIN_PWPROMPT))
|| (i==1 && (cfg.sys_login & LOGIN_PWPROMPT))) {
cfg.sys_login ^= LOGIN_PWPROMPT;
}
break;
case __COUNTER__:
i=cfg.sys_misc&SM_ECHO_PW ? 0:1;
uifc.helpbuf=
"`Display/Log Passwords Locally:`\n"
"\n"
"If you want to passwords to be displayed locally and/or logged to disk\n"
"(e.g. when there's a failed login attempt), set this option to `Yes`.\n"
"\n"
"For elevated security, set this option to `No`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"Display/Log Passwords Locally",uifcYesNoOpts);
if(!i && !(cfg.sys_misc&SM_ECHO_PW)) {
cfg.sys_misc|=SM_ECHO_PW;
}
else if(i==1 && cfg.sys_misc&SM_ECHO_PW) {
cfg.sys_misc&=~SM_ECHO_PW;
}
break;
case __COUNTER__:
sprintf(str,"%u",cfg.sys_deldays); sprintf(str,"%u",cfg.sys_deldays);
uifc.helpbuf= uifc.helpbuf=
"`Days Since Last Logon to Preserve Deleted Users:`\n" "`Days Since Last Logon to Preserve Deleted Users:`\n"
...@@ -497,14 +318,14 @@ void sys_cfg(void) ...@@ -497,14 +318,14 @@ void sys_cfg(void)
"of time since their last logon, set this value to the number of days to\n" "of time since their last logon, set this value to the number of days to\n"
"keep new users from taking over a deleted user's slot.\n" "keep new users from taking over a deleted user's slot.\n"
; ;
uifc.input(WIN_MID,0,0,"Days Since Last Logon to Preserve Deleted Users" uifc.input(WIN_MID|WIN_SAV,0,0,"Days Since Last Logon to Preserve Deleted Users"
,str,5,K_EDIT|K_NUMBER); ,str,5,K_EDIT|K_NUMBER);
cfg.sys_deldays=atoi(str); cfg.sys_deldays=atoi(str);
break; break;
case 7: case __COUNTER__:
sprintf(str,"%u",cfg.sys_autodel); sprintf(str,"%u",cfg.sys_autodel);
uifc.helpbuf= uifc.helpbuf=
"`Maximum Days of Inactivity Before Auto-Deletion:`\n" "`Maximum Days of User Inactivity Before Auto-Deletion:`\n"
"\n" "\n"
"If you want users that have not logged-on in a certain period of time to\n" "If you want users that have not logged-on in a certain period of time to\n"
"be automatically deleted, set this value to the maximum number of days\n" "be automatically deleted, set this value to the maximum number of days\n"
...@@ -513,11 +334,21 @@ void sys_cfg(void) ...@@ -513,11 +334,21 @@ void sys_cfg(void)
"\n" "\n"
"Users with the `P` exemption will not be deleted due to inactivity.\n" "Users with the `P` exemption will not be deleted due to inactivity.\n"
; ;
uifc.input(WIN_MID,0,0,"Maximum Days of Inactivity Before Auto-Deletion" uifc.input(WIN_MID|WIN_SAV,0,0,"Maximum Days of User Inactivity Before Auto-Deletion"
,str,5,K_EDIT|K_NUMBER); ,str,5,K_EDIT|K_NUMBER);
cfg.sys_autodel=atoi(str); cfg.sys_autodel=atoi(str);
break; break;
case 8: case __COUNTER__:
i=cfg.sys_misc&SM_CLOSED ? 1:0;
uifc.helpbuf=
"`Open to New Users:`\n"
"\n"
"If you want callers to be able to logon as `New`, set this option to Yes`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"Open to New Users",uifcYesNoOpts);
if(i == 0) {
cfg.sys_misc &= ~SM_CLOSED;
uifc.helpbuf= uifc.helpbuf=
"`New User Password:`\n" "`New User Password:`\n"
"\n" "\n"
...@@ -525,1848 +356,2005 @@ void sys_cfg(void) ...@@ -525,1848 +356,2005 @@ void sys_cfg(void)
"a secret password, enter that password here. If you prefer any caller\n" "a secret password, enter that password here. If you prefer any caller\n"
"be able to logon as `New`, leave this option blank.\n" "be able to logon as `New`, leave this option blank.\n"
; ;
uifc.input(WIN_MID,0,0,"New User Password",cfg.new_pass,sizeof(cfg.new_pass)-1 uifc.input(WIN_MID|WIN_SAV,0,0,"New User Password (optional)",cfg.new_pass,sizeof(cfg.new_pass)-1
,K_EDIT|K_UPPER); ,K_EDIT|K_UPPER);
}
else if(i == 1) {
cfg.sys_misc |= SM_CLOSED;
}
break; break;
case 9: /* Toggle Options */ case __COUNTER__:
done=0; i=cfg.sys_misc&SM_TIME_EXP ? 0:1;
while(!done) {
i=0;
sprintf(opt[i++],"%-33.33s%s","Allow User Aliases"
,cfg.uq&UQ_ALIASES ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Allow Login by Real Name"
,(!(cfg.uq&UQ_ALIASES) || cfg.sys_login & LOGIN_REALNAME) ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Allow Login by User Number"
,(cfg.sys_login & LOGIN_USERNUM) ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Allow Time Banking"
,cfg.sys_misc&SM_TIMEBANK ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Allow Credit Conversions"
,cfg.sys_misc&SM_NOCDTCVT ? "No" : "Yes");
sprintf(opt[i++],"%-33.33s%s","Allow Sysop Access"
,cfg.sys_misc&SM_R_SYSOP ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Display/Log Passwords Locally"
,cfg.sys_misc&SM_ECHO_PW ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Always Prompt for Password"
,cfg.sys_login & LOGIN_PWPROMPT ? "Yes":"No");
sprintf(opt[i++],"%-33.33s%s","Short Sysop Page"
,cfg.sys_misc&SM_SHRTPAGE ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Include Sysop in Statistics"
,cfg.sys_misc&SM_SYSSTAT ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Closed to New Users"
,cfg.sys_misc&SM_CLOSED ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Use Location in User Lists"
,cfg.sys_misc&SM_LISTLOC ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Military (24 hour) Time Format"
,cfg.sys_misc&SM_MILITARY ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","European Date Format (DD/MM/YY)"
,cfg.sys_misc&SM_EURODATE ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","User Expires When Out-of-time"
,cfg.sys_misc&SM_TIME_EXP ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Require Sys Pass During Login"
,cfg.sys_misc&SM_SYSPASSLOGIN ? "Yes" : "No");
sprintf(opt[i++],"%-33.33s%s","Display Sys Info During Logon"
,cfg.sys_misc&SM_NOSYSINFO ? "No" : "Yes");
sprintf(opt[i++],"%-33.33s%s","Display Node List During Logon"
,cfg.sys_misc&SM_NONODELIST ? "No" : "Yes");
opt[i][0]=0;
uifc.helpbuf= uifc.helpbuf=
"`System Toggle Options:`\n" "`User Expires When Out-of-time:`\n"
"\n" "\n"
"This is a menu of system related options that can be toggled between\n" "If you want users to be set to `Expired User Values` if they run out of\n"
"two or more states, such as `Yes` and `No`.\n" "time online, then set this option to `Yes`.\n"
; ;
switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT,0,0,41,&tog_dflt,&tog_bar i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"Toggle Options",opt)) { ,"User Expires When Out-of-time",uifcYesNoOpts);
case -1: if(!i && !(cfg.sys_misc&SM_TIME_EXP)) {
done=1; cfg.sys_misc|=SM_TIME_EXP;
}
else if(i==1 && cfg.sys_misc&SM_TIME_EXP) {
cfg.sys_misc&=~SM_TIME_EXP;
}
break; break;
case __COUNTER__: case __COUNTER__: /* Security Levels */
i=cfg.uq&UQ_ALIASES ? 0:1; k=0;
while(1) {
for(i=0;i<100;i++) {
byte_count_to_str(cfg.level_freecdtperday[i], tmp, sizeof(tmp));
sprintf(opt[i],"%-2d %5d %5d "
"%5d %5d %5d %5d %6s %7s %2u",i
,cfg.level_timeperday[i],cfg.level_timepercall[i]
,cfg.level_callsperday[i],cfg.level_emailperday[i]
,cfg.level_postsperday[i],cfg.level_linespermsg[i]
,tmp
,cfg.level_misc[i]&LEVEL_EXPTOVAL ? "Val Set" : "Level"
,cfg.level_misc[i]&(LEVEL_EXPTOVAL|LEVEL_EXPTOLVL) ?
cfg.level_expireto[i] : cfg.expired_level);
}
opt[i][0]=0;
i=0;
uifc.helpbuf= uifc.helpbuf=
"`Allow Users to Use Aliases:`\n" "`Security Level Values:`\n"
"\n" "\n"
"If you want the users of your system to be allowed to be known by a\n" "This menu allows you to change the security options for every possible\n"
"false name, handle, or alias, set this option to `Yes`. If you want all\n" "security level from 0 to 99. The available options for each level are:\n"
"users on your system to be known only by their real names, select `No`.\n" "\n"
" Time Per Day Maximum online time per day\n"
" Time Per Call Maximum online time per call (logon)\n"
" Calls Per Day Maximum number of calls (logons) per day\n"
" Email Per Day Maximum number of email sent per day\n"
" Posts Per Day Maximum number of posted messages per day\n"
" Lines Per Message Maximum number of lines per message\n"
" Free Credits Per Day Number of free credits awarded per day\n"
" Expire To Level or validation set to Expire to\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 i=uifc.list(WIN_RHT|WIN_ACT|WIN_SAV,0,3,0, &seclevel_dflt, &seclevel_bar
,"Allow Users to Use Aliases",uifcYesNoOpts); ,"Level T/D T/C C/D E/D P/D L/M F/D "
if(!i && !(cfg.uq&UQ_ALIASES)) { "Expire To",opt);
cfg.uq|=UQ_ALIASES; if(i==-1)
uifc.changes=1; break;
while(1) {
sprintf(str,"Security Level %d Values",i);
j=0;
sprintf(opt[j++],"%-22.22s%-5u","Time Per Day"
,cfg.level_timeperday[i]);
sprintf(opt[j++],"%-22.22s%-5u","Time Per Call"
,cfg.level_timepercall[i]);
sprintf(opt[j++],"%-22.22s%-5u","Calls Per Day"
,cfg.level_callsperday[i]);
sprintf(opt[j++],"%-22.22s%-5u","Email Per Day"
,cfg.level_emailperday[i]);
sprintf(opt[j++],"%-22.22s%-5u","Posts Per Day"
,cfg.level_postsperday[i]);
sprintf(opt[j++],"%-22.22s%-5u","Lines Per Message"
,cfg.level_linespermsg[i]);
byte_count_to_str(cfg.level_freecdtperday[i], tmp, sizeof(tmp));
sprintf(opt[j++],"%-22.22s%-6s","Free Credits Per Day"
,tmp);
sprintf(opt[j++],"%-22.22s%s %u","Expire To"
,cfg.level_misc[i]&LEVEL_EXPTOVAL ? "Validation Set"
: "Level"
,cfg.level_misc[i]&(LEVEL_EXPTOVAL|LEVEL_EXPTOLVL) ?
cfg.level_expireto[i] : cfg.expired_level);
opt[j][0]=0;
uifc_winmode_t wmode = WIN_RHT|WIN_SAV|WIN_ACT|WIN_EXTKEYS;
if(i > 0)
wmode |= WIN_LEFTKEY;
if(i + 1 < 100)
wmode |= WIN_RIGHTKEY;
j=uifc.list(wmode,2,1,0,&k,0
,str,opt);
if(j==-1)
break;
switch(j) {
case -CIO_KEY_LEFT-2:
if(i > 0)
i--;
break;
case -CIO_KEY_RIGHT-2:
if(i + 1 < 100)
i++;
break;
case 0:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Total Time Allowed Per Day (in minutes)"
,ultoa(cfg.level_timeperday[i],tmp,10),4
,K_NUMBER|K_EDIT);
cfg.level_timeperday[i]=atoi(tmp);
if(cfg.level_timeperday[i]>1440)
cfg.level_timeperday[i]=1440;
break;
case 1:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Time Allowed Per Call (in minutes)"
,ultoa(cfg.level_timepercall[i],tmp,10),4
,K_NUMBER|K_EDIT);
cfg.level_timepercall[i]=atoi(tmp);
if(cfg.level_timepercall[i]>1440)
cfg.level_timepercall[i]=1440;
break;
case 2:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Calls (Logons) Allowed Per Day"
,ultoa(cfg.level_callsperday[i],tmp,10),4
,K_NUMBER|K_EDIT);
cfg.level_callsperday[i]=atoi(tmp);
break;
case 3:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Email (Sent) Allowed Per Day"
,ultoa(cfg.level_emailperday[i],tmp,10),4
,K_NUMBER|K_EDIT);
cfg.level_emailperday[i]=atoi(tmp);
break;
case 4:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Posted Messages Allowed Per Day"
,ultoa(cfg.level_postsperday[i],tmp,10),4
,K_NUMBER|K_EDIT);
cfg.level_postsperday[i]=atoi(tmp);
break;
case 5:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Lines Allowed Per Message (Post/E-mail)"
,ultoa(cfg.level_linespermsg[i],tmp,10),5
,K_NUMBER|K_EDIT);
cfg.level_linespermsg[i]=atoi(tmp);
break;
case 6:
byte_count_to_str(cfg.level_freecdtperday[i], tmp, sizeof(tmp));
if(uifc.input(WIN_MID|WIN_SAV,0,0
,"Free Credits Awarded Per Day"
,tmp,19
,K_EDIT|K_UPPER) > 0)
cfg.level_freecdtperday[i] = parse_byte_count(tmp, 1);
break;
case 7:
j=0;
sprintf(opt[j++],"Default Expired Level "
"(Currently %u)",cfg.expired_level);
sprintf(opt[j++],"Specific Level");
sprintf(opt[j++],"Quick-Validation Set");
opt[j][0]=0;
j=0;
sprintf(str,"Level %u Expires To",i);
j=uifc.list(WIN_SAV,2,1,0,&j,0
,str,opt);
if(j==-1)
break;
if(j==0) {
cfg.level_misc[i]&=
~(LEVEL_EXPTOLVL|LEVEL_EXPTOVAL);
break;
} }
else if(i==1 && cfg.uq&UQ_ALIASES) { if(j==1) {
cfg.uq&=~UQ_ALIASES; cfg.level_misc[i]&=~LEVEL_EXPTOVAL;
uifc.changes=1; cfg.level_misc[i]|=LEVEL_EXPTOLVL;
uifc.input(WIN_MID|WIN_SAV,0,0
,"Expired Level"
,ultoa(cfg.level_expireto[i],tmp,10),2
,K_EDIT|K_NUMBER);
cfg.level_expireto[i]=atoi(tmp);
break;
} }
cfg.level_misc[i]&=~LEVEL_EXPTOLVL;
cfg.level_misc[i]|=LEVEL_EXPTOVAL;
uifc.input(WIN_MID|WIN_SAV,0,0
,"Quick-Validation Set to Expire To"
,ultoa(cfg.level_expireto[i],tmp,10),1
,K_EDIT|K_NUMBER);
cfg.level_expireto[i]=atoi(tmp);
break; break;
case __COUNTER__: }
if(!(cfg.uq&UQ_ALIASES)) }
}
break; break;
i = (cfg.sys_login & LOGIN_REALNAME) ? 0:1; case __COUNTER__: /* Expired Account Values */
done=0;
while(!done) {
i=0;
sprintf(opt[i++],"%-27.27s%u","Level",cfg.expired_level);
sprintf(opt[i++],"%-27.27s%s","Flag Set #1 to Remove"
,u32toaf(cfg.expired_flags1,str));
sprintf(opt[i++],"%-27.27s%s","Flag Set #2 to Remove"
,u32toaf(cfg.expired_flags2,str));
sprintf(opt[i++],"%-27.27s%s","Flag Set #3 to Remove"
,u32toaf(cfg.expired_flags3,str));
sprintf(opt[i++],"%-27.27s%s","Flag Set #4 to Remove"
,u32toaf(cfg.expired_flags4,str));
sprintf(opt[i++],"%-27.27s%s","Exemptions to Remove"
,u32toaf(cfg.expired_exempt,str));
sprintf(opt[i++],"%-27.27s%s","Restrictions to Add"
,u32toaf(cfg.expired_rest,str));
opt[i][0]=0;
uifc.helpbuf= uifc.helpbuf=
"`Allow Login by Real Name:`\n" "`Expired Account Values:`\n"
"\n" "\n"
"If you want users to be able login using their real name as well as\n" "If a user's account expires, the security levels for that account will\n"
"their alias, set this option to `Yes`.\n" "be modified according to the settings of this menu. The account's\n"
"security level will be set to the value listed on this menu. The `Flags`\n"
"and `Exemptions` listed on this menu will be removed from the account\n"
"if they are set. The `Restrictions` listed will be added to the account.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0 switch(uifc.list(WIN_ACT|WIN_MID|WIN_SAV,0,0,60,&expired_dflt,0
,"Allow Login by Real Name",uifcYesNoOpts); ,"Expired Account Values",opt)) {
if((i==0 && !(cfg.sys_login & LOGIN_REALNAME)) case -1:
|| (i==1 && (cfg.sys_login & LOGIN_REALNAME))) { done=1;
cfg.sys_login ^= LOGIN_REALNAME;
uifc.changes=1;
}
break; break;
case __COUNTER__: case 0:
i = (cfg.sys_login & LOGIN_USERNUM) ? 0:1; ultoa(cfg.expired_level,str,10);
uifc.helpbuf= uifc.helpbuf=
"`Allow Login by User Number:`\n" "`Expired Account Security Level:`\n"
"\n" "\n"
"If you want users to be able login using their user number at the\n" "This is the security level automatically given to expired user accounts.\n"
"login prompt, set this option to `Yes`.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0 uifc.input(WIN_SAV|WIN_MID,0,0,"Security Level"
,"Allow Login by User Number",uifcYesNoOpts); ,str,2,K_EDIT|K_NUMBER);
if((i==0 && !(cfg.sys_login & LOGIN_USERNUM)) cfg.expired_level=atoi(str);
|| (i==1 && (cfg.sys_login & LOGIN_USERNUM))) {
cfg.sys_login ^= LOGIN_USERNUM;
uifc.changes=1;
}
break; break;
case __COUNTER__: case 1:
i=cfg.sys_misc&SM_TIMEBANK ? 0:1; truncsp(u32toaf(cfg.expired_flags1,str));
uifc.helpbuf= uifc.helpbuf=
"`Allow Time Banking:`\n" "`Expired Security Flags to Remove:`\n"
"\n" "\n"
"If you want the users of your system to be allowed to deposit\n" "These are the security flags automatically removed when a user account\n"
"any extra time they may have left during a call into their minute bank,\n" "has expired.\n"
"set this option to `Yes`. If this option is set to `No`, then the only\n"
"way a user may get minutes in their minute bank is to purchase them\n"
"with credits.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 uifc.input(WIN_SAV|WIN_MID,0,0,"Flags Set #1"
,"Allow Users to Deposit Time in Minute Bank",uifcYesNoOpts); ,str,26,K_EDIT|K_UPPER|K_ALPHA);
if(!i && !(cfg.sys_misc&SM_TIMEBANK)) { cfg.expired_flags1=aftou32(str);
cfg.sys_misc|=SM_TIMEBANK;
uifc.changes=1;
}
else if(i==1 && cfg.sys_misc&SM_TIMEBANK) {
cfg.sys_misc&=~SM_TIMEBANK;
uifc.changes=1;
}
break;
case __COUNTER__:
i=cfg.sys_misc&SM_NOCDTCVT ? 1:0;
uifc.helpbuf=
"`Allow Credits to be Converted into Minutes:`\n"
"\n"
"If you want the users of your system to be allowed to convert\n"
"any credits they may have into minutes for their minute bank,\n"
"set this option to `Yes`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"Allow Users to Convert Credits into Minutes"
,uifcYesNoOpts);
if(!i && cfg.sys_misc&SM_NOCDTCVT) {
cfg.sys_misc&=~SM_NOCDTCVT;
uifc.changes=1;
}
else if(i==1 && !(cfg.sys_misc&SM_NOCDTCVT)) {
cfg.sys_misc|=SM_NOCDTCVT;
uifc.changes=1;
}
break; break;
case __COUNTER__: case 2:
i=cfg.sys_misc&SM_R_SYSOP ? 0:1; truncsp(u32toaf(cfg.expired_flags2,str));
uifc.helpbuf= uifc.helpbuf=
"`Allow Sysop Access:`\n" "`Expired Security Flags to Remove:`\n"
"\n" "\n"
"Setting this option to `No` will prevent users with sysop security level\n" "These are the security flags automatically removed when a user account\n"
"from invoking functions that require system-password authentication.\n" "has expired.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 uifc.input(WIN_SAV|WIN_MID,0,0,"Flags Set #2"
,"Allow Sysop Access",uifcYesNoOpts); ,str,26,K_EDIT|K_UPPER|K_ALPHA);
if(!i && !(cfg.sys_misc&SM_R_SYSOP)) { cfg.expired_flags2=aftou32(str);
cfg.sys_misc|=SM_R_SYSOP;
uifc.changes=1;
}
else if(i==1 && cfg.sys_misc&SM_R_SYSOP) {
cfg.sys_misc&=~SM_R_SYSOP;
uifc.changes=1;
}
break; break;
case __COUNTER__: case 3:
i=cfg.sys_misc&SM_ECHO_PW ? 0:1; truncsp(u32toaf(cfg.expired_flags3,str));
uifc.helpbuf= uifc.helpbuf=
"`Display/Log Passwords Locally:`\n" "`Expired Security Flags to Remove:`\n"
"\n"
"If you want to passwords to be displayed locally and/or logged to disk\n"
"(e.g. when there's a failed login attempt), set this option to `Yes`.\n"
"\n" "\n"
"For elevated security, set this option to `No`.\n" "These are the security flags automatically removed when a user account\n"
"has expired.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 uifc.input(WIN_SAV|WIN_MID,0,0,"Flags Set #3"
,"Display/Log Passwords Locally",uifcYesNoOpts); ,str,26,K_EDIT|K_UPPER|K_ALPHA);
if(!i && !(cfg.sys_misc&SM_ECHO_PW)) { cfg.expired_flags3=aftou32(str);
cfg.sys_misc|=SM_ECHO_PW;
uifc.changes=1;
}
else if(i==1 && cfg.sys_misc&SM_ECHO_PW) {
cfg.sys_misc&=~SM_ECHO_PW;
uifc.changes=1;
}
break; break;
case __COUNTER__: case 4:
i=cfg.sys_login & LOGIN_PWPROMPT ? 0:1; truncsp(u32toaf(cfg.expired_flags4,str));
uifc.helpbuf= uifc.helpbuf=
"`Always Prompt for Password:`\n" "`Expired Security Flags to Remove:`\n"
"\n" "\n"
"If you want to have attempted logins using an unknown user name still\n" "These are the security flags automatically removed when a user account\n"
"prompt for a password (i.e. for enhanced security), set this option to\n" "has expired.\n"
"`Yes`.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0 uifc.input(WIN_SAV|WIN_MID,0,0,"Flags Set #4"
,"Always Prompt for Password",uifcYesNoOpts); ,str,26,K_EDIT|K_UPPER|K_ALPHA);
if((i==0 && !(cfg.sys_login & LOGIN_PWPROMPT)) cfg.expired_flags4=aftou32(str);
|| (i==1 && (cfg.sys_login & LOGIN_PWPROMPT))) {
cfg.sys_login ^= LOGIN_PWPROMPT;
uifc.changes=1;
}
break; break;
case __COUNTER__: case 5:
i=cfg.sys_misc&SM_SHRTPAGE ? 0:1; truncsp(u32toaf(cfg.expired_exempt,str));
uifc.helpbuf= uifc.helpbuf=
"`Short Sysop Page:`\n" "`Expired Exemption Flags to Remove:`\n"
"\n" "\n"
"If you would like the sysop page to be a short series of beeps rather\n" "These are the exemptions that are automatically removed from a user\n"
"than continuous random tones, set this option to `Yes`.\n" "account if it expires.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Short Sysop Page" uifc.input(WIN_SAV|WIN_MID,0,0,"Exemption Flags",str,26
,uifcYesNoOpts); ,K_EDIT|K_UPPER|K_ALPHA);
if(i==1 && cfg.sys_misc&SM_SHRTPAGE) { cfg.expired_exempt=aftou32(str);
cfg.sys_misc&=~SM_SHRTPAGE;
uifc.changes=1;
}
else if(!i && !(cfg.sys_misc&SM_SHRTPAGE)) {
cfg.sys_misc|=SM_SHRTPAGE;
uifc.changes=1;
}
break; break;
case __COUNTER__: case 6:
i=cfg.sys_misc&SM_SYSSTAT ? 0:1; truncsp(u32toaf(cfg.expired_rest,str));
uifc.helpbuf= uifc.helpbuf=
"`Include Sysop Activity in System Statistics:`\n" "`Expired Restriction Flags to Add:`\n"
"\n" "\n"
"If you want sysops to be included in the statistical data of the BBS,\n" "These are the restrictions that are automatically added to a user\n"
"set this option to `Yes`. The suggested setting for this option is\n" "account if it expires.\n"
"`No` so that statistical data will only reflect user usage and not\n"
"include sysop maintenance activity.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 uifc.input(WIN_SAV|WIN_MID,0,0,"Restriction Flags",str,26
,"Include Sysop Activity in System Statistics" ,K_EDIT|K_UPPER|K_ALPHA);
,uifcYesNoOpts); cfg.expired_rest=aftou32(str);
if(!i && !(cfg.sys_misc&SM_SYSSTAT)) {
cfg.sys_misc|=SM_SYSSTAT;
uifc.changes=1;
}
else if(i==1 && cfg.sys_misc&SM_SYSSTAT) {
cfg.sys_misc&=~SM_SYSSTAT;
uifc.changes=1;
}
break; break;
case __COUNTER__:
i=cfg.sys_misc&SM_CLOSED ? 0:1;
uifc.helpbuf=
"`Closed to New Users:`\n"
"\n"
"If you want callers to be able to logon as `New`, set this option to `No`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"Closed to New Users",uifcYesNoOpts);
if(!i && !(cfg.sys_misc&SM_CLOSED)) {
cfg.sys_misc|=SM_CLOSED;
uifc.changes=1;
} }
else if(i==1 && cfg.sys_misc&SM_CLOSED) {
cfg.sys_misc&=~SM_CLOSED;
uifc.changes=1;
} }
break; break;
case __COUNTER__: case __COUNTER__: /* Quick-Validation Values */
i=cfg.sys_misc&SM_LISTLOC ? 0:1; k=0;
while(1) {
for(i=0;i<10;i++)
sprintf(opt[i],"%d SL: %-2d F1: %s"
,i,cfg.val_level[i],u32toaf(cfg.val_flags1[i],str));
opt[i][0]=0;
i=0;
uifc.helpbuf= uifc.helpbuf=
"`User Location in User Lists:`\n" "`Quick-Validation Values:`\n"
"\n" "\n"
"If you want user locations (city, state) displayed in the user lists,\n" "This is a list of the ten quick-validation sets. These sets are used to\n"
"set this option to `Yes`. If this option is set to `No`, the user notes\n" "quickly set a user's security values (Level, Flags, Exemptions,\n"
"(if they exist) are displayed in the user lists.\n" "Restrictions, Expiration Date, and Credits) with one key stroke. The\n"
; "user's expiration date may be extended and additional credits may also\n"
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 "be added using quick-validation sets.\n"
,"User Location (Instead of Note) in User Lists"
,uifcYesNoOpts);
if(!i && !(cfg.sys_misc&SM_LISTLOC)) {
cfg.sys_misc|=SM_LISTLOC;
uifc.changes=1;
}
else if(i==1 && cfg.sys_misc&SM_LISTLOC) {
cfg.sys_misc&=~SM_LISTLOC;
uifc.changes=1;
}
break;
case __COUNTER__:
i=cfg.sys_misc&SM_MILITARY ? 0:1;
uifc.helpbuf=
"`Military:`\n"
"\n" "\n"
"If you would like the time-of-day to be displayed and entered in 24 hour\n" "From within the `User Edit` function, a sysop can use the `V`alidate\n"
"format always, set this option to `Yes`.\n" "User command and select from this quick-validation list to change a\n"
"user's security values with very few key-strokes.\n"
; ;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 i=uifc.list(WIN_MID|WIN_ACT|WIN_SAV,0,0,0,&quick_dflt,0
,"Use Military Time Format",uifcYesNoOpts); ,"Quick-Validation Values",opt);
if(!i && !(cfg.sys_misc&SM_MILITARY)) { if(i==-1)
cfg.sys_misc|=SM_MILITARY;
uifc.changes=1;
}
else if(i==1 && cfg.sys_misc&SM_MILITARY) {
cfg.sys_misc&=~SM_MILITARY;
uifc.changes=1;
}
break; break;
case __COUNTER__: while(1) {
i=cfg.sys_misc&SM_EURODATE ? 0:1; j=0;
uifc.helpbuf= sprintf(opt[j++],"%-22.22s%u","Level",cfg.val_level[i]);
"`European Date Format:`\n" sprintf(opt[j++],"%-22.22s%s","Flag Set #1"
"\n" ,u32toaf(cfg.val_flags1[i],tmp));
"If you would like dates to be displayed and entered in `DD/MM/YY` format\n" sprintf(opt[j++],"%-22.22s%s","Flag Set #2"
"instead of `MM/DD/YY` format, set this option to `Yes`.\n" ,u32toaf(cfg.val_flags2[i],tmp));
; sprintf(opt[j++],"%-22.22s%s","Flag Set #3"
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 ,u32toaf(cfg.val_flags3[i],tmp));
,"European Date Format",uifcYesNoOpts); sprintf(opt[j++],"%-22.22s%s","Flag Set #4"
if(!i && !(cfg.sys_misc&SM_EURODATE)) { ,u32toaf(cfg.val_flags4[i],tmp));
cfg.sys_misc|=SM_EURODATE; sprintf(opt[j++],"%-22.22s%s","Exemptions"
uifc.changes=1; ,u32toaf(cfg.val_exempt[i],tmp));
} sprintf(opt[j++],"%-22.22s%s","Restrictions"
else if(i==1 && cfg.sys_misc&SM_EURODATE) { ,u32toaf(cfg.val_rest[i],tmp));
cfg.sys_misc&=~SM_EURODATE; sprintf(opt[j++],"%-22.22s%u days","Extend Expiration"
uifc.changes=1; ,cfg.val_expire[i]);
} sprintf(opt[j++],"%-22.22s%u","Additional Credits"
,cfg.val_cdt[i]);
opt[j][0]=0;
uifc_winmode_t wmode = WIN_RHT|WIN_SAV|WIN_ACT|WIN_EXTKEYS;
if(i > 0)
wmode |= WIN_LEFTKEY;
if(i + 1 < 10)
wmode |= WIN_RIGHTKEY;
SAFEPRINTF(str,"Quick-Validation Set %d",i);
j=uifc.list(wmode,2,1,0,&k,0,str,opt);
if(j==-1)
break; break;
case __COUNTER__: switch(j) {
i=cfg.sys_misc&SM_TIME_EXP ? 0:1; case -CIO_KEY_LEFT-2:
uifc.helpbuf= if(i > 0)
"`User Expires When Out-of-time:`\n" i--;
"\n"
"If you want users to be set to `Expired User Values` if they run out of\n"
"time online, then set this option to `Yes`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"User Expires When Out-of-time",uifcYesNoOpts);
if(!i && !(cfg.sys_misc&SM_TIME_EXP)) {
cfg.sys_misc|=SM_TIME_EXP;
uifc.changes=1;
}
else if(i==1 && cfg.sys_misc&SM_TIME_EXP) {
cfg.sys_misc&=~SM_TIME_EXP;
uifc.changes=1;
}
break; break;
case __COUNTER__: case -CIO_KEY_RIGHT-2:
i=cfg.sys_misc&SM_SYSPASSLOGIN ? 0:1; if(i + 1 < 10)
uifc.helpbuf= i++;
"`Require System Password for Sysop Login:`\n"
"\n"
"If you want to require the correct system password to be provided during\n"
"system operator logins (in addition to the sysop's personal user account\n"
"password), set this option to `Yes`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"Require System Password for Sysop Logon",uifcYesNoOpts);
if(i==1 && cfg.sys_misc&SM_SYSPASSLOGIN) {
cfg.sys_misc&=~SM_SYSPASSLOGIN;
uifc.changes=1;
}
else if(i==0 && !(cfg.sys_misc&SM_SYSPASSLOGIN)) {
cfg.sys_misc|=SM_SYSPASSLOGIN;
uifc.changes=1;
}
break; break;
case __COUNTER__: case 0:
i=cfg.sys_misc&SM_NOSYSINFO ? 1:0; uifc.input(WIN_MID|WIN_SAV,0,0
uifc.helpbuf= ,"Level"
"`Display System Information During Logon:`\n" ,ultoa(cfg.val_level[i],tmp,10),2
"\n" ,K_NUMBER|K_EDIT);
"If you want system information displayed during logon, set this option\n" cfg.val_level[i]=atoi(tmp);
"to `Yes`.\n" break;
; case 1:
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 uifc.input(WIN_MID|WIN_SAV,0,0
,"Display System Information During Logon",uifcYesNoOpts); ,"Flag Set #1"
if(!i && cfg.sys_misc&SM_NOSYSINFO) { ,truncsp(u32toaf(cfg.val_flags1[i],tmp)),26
cfg.sys_misc&=~SM_NOSYSINFO; ,K_UPPER|K_ALPHA|K_EDIT);
uifc.changes=1; cfg.val_flags1[i]=aftou32(tmp);
} break;
else if(i==1 && !(cfg.sys_misc&SM_NOSYSINFO)) { case 2:
cfg.sys_misc|=SM_NOSYSINFO; uifc.input(WIN_MID|WIN_SAV,0,0
uifc.changes=1; ,"Flag Set #2"
} ,truncsp(u32toaf(cfg.val_flags2[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_flags2[i]=aftou32(tmp);
break;
case 3:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Flag Set #3"
,truncsp(u32toaf(cfg.val_flags3[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_flags3[i]=aftou32(tmp);
break;
case 4:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Flag Set #4"
,truncsp(u32toaf(cfg.val_flags4[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_flags4[i]=aftou32(tmp);
break;
case 5:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Exemption Flags"
,truncsp(u32toaf(cfg.val_exempt[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_exempt[i]=aftou32(tmp);
break;
case 6:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Restriction Flags"
,truncsp(u32toaf(cfg.val_rest[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_rest[i]=aftou32(tmp);
break;
case 7:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Days to Extend Expiration"
,ultoa(cfg.val_expire[i],tmp,10),4
,K_NUMBER|K_EDIT);
cfg.val_expire[i]=atoi(tmp);
break;
case 8:
uifc.input(WIN_MID|WIN_SAV,0,0
,"Additional Credits"
,ultoa(cfg.val_cdt[i],tmp,10),10
,K_NUMBER|K_EDIT);
cfg.val_cdt[i]=atol(tmp);
break; break;
case __COUNTER__:
i=cfg.sys_misc&SM_NONODELIST ? 1:0;
uifc.helpbuf=
"`Display Active Node List During Logon:`\n"
"\n"
"If you want the active nodes displayed during logon, set this option\n"
"to `Yes`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"Display Active Node List During Logon",uifcYesNoOpts);
if(!i && cfg.sys_misc&SM_NONODELIST) {
cfg.sys_misc&=~SM_NONODELIST;
uifc.changes=1;
} }
else if(i==1 && !(cfg.sys_misc&SM_NONODELIST)) { }
cfg.sys_misc|=SM_NONODELIST;
uifc.changes=1;
} }
break; break;
} }
} }
break; }
case 10: /* New User Values */
done=0; void sys_cfg(void)
while(!done) { {
static int sys_dflt,adv_dflt,tog_dflt,new_dflt;
static int tog_bar;
static int adv_bar;
static int mod_dflt, mod_bar;
char str[81],done=0;
int i,j,k;
scfg_t saved_cfg = cfg;
char sys_pass[sizeof(cfg.sys_pass)];
SAFECOPY(sys_pass, cfg.sys_pass);
while(1) {
i=0; i=0;
sprintf(opt[i++],"%-27.27s%u","Level",cfg.new_level); sprintf(opt[i++],"%-33.33s%s","BBS Name",cfg.sys_name);
sprintf(opt[i++],"%-27.27s%s","Flag Set #1" sprintf(opt[i++],"%-33.33s%s","Location",cfg.sys_location);
,u32toaf(cfg.new_flags1,str)); sprintf(opt[i++],"%-33.33s%s %s","Local Time Zone"
sprintf(opt[i++],"%-27.27s%s","Flag Set #2" ,smb_zonestr(cfg.sys_timezone,NULL)
,u32toaf(cfg.new_flags2,str)); ,SMB_TZ_HAS_DST(cfg.sys_timezone) && cfg.sys_misc&SM_AUTO_DST ? "(Auto-DST)" : "");
sprintf(opt[i++],"%-27.27s%s","Flag Set #3" sprintf(opt[i++],"%-33.33s%s","Operator",cfg.sys_op);
,u32toaf(cfg.new_flags3,str));
sprintf(opt[i++],"%-27.27s%s","Flag Set #4"
,u32toaf(cfg.new_flags4,str));
sprintf(opt[i++],"%-27.27s%s","Exemptions"
,u32toaf(cfg.new_exempt,str));
sprintf(opt[i++],"%-27.27s%s","Restrictions"
,u32toaf(cfg.new_rest,str));
sprintf(opt[i++],"%-27.27s%s","Expiration Days"
,ultoa(cfg.new_expire,str,10));
u32toac(cfg.new_cdt,str,','); strcpy(opt[i++],"Toggle Options...");
sprintf(opt[i++],"%-27.27s%s","Credits",str); strcpy(opt[i++],"New User Values...");
u32toac(cfg.new_min,str,','); strcpy(opt[i++],"Security Options...");
sprintf(opt[i++],"%-27.27s%s","Minutes",str); strcpy(opt[i++],"Advanced Options...");
sprintf(opt[i++],"%-27.27s%s","Editor" strcpy(opt[i++],"Loadable Modules...");
,cfg.new_xedit);
sprintf(opt[i++],"%-27.27s%s","Command Shell"
,cfg.new_shell >= cfg.total_shells ? "<invalid>" : cfg.shell[cfg.new_shell]->code);
if(cfg.new_prot!=' ')
sprintf(str,"%c",cfg.new_prot);
else
strcpy(str,"None");
sprintf(opt[i++],"%-27.27s%s","Download Protocol",str);
sprintf(opt[i++],"%-27.27s%hu","Days of New Messages", cfg.new_msgscan_init);
sprintf(opt[i++],"%-27.27s%s", "Gender Options", cfg.new_genders);
strcpy(opt[i++],"Default Toggles...");
strcpy(opt[i++],"Question Toggles...");
opt[i][0]=0; opt[i][0]=0;
uifc.helpbuf= uifc.helpbuf=
"`New User Values:`\n" "`System Configuration:`\n"
"\n" "\n"
"This menu allows you to determine the default settings for new users.\n" "This menu contains options and sub-menus of options that affect the\n"
"entire BBS and the Synchronet Terminal Server in particular.\n"
; ;
switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT,0,0,60,&new_dflt,0 uifc.changes = memcmp(&saved_cfg, &cfg, sizeof(saved_cfg)) != 0;
,"New User Values",opt)) { switch(uifc.list(WIN_ORG|WIN_ACT|WIN_CHE,0,0,72,&sys_dflt,0
,"System Configuration",opt)) {
case -1: case -1:
done=1; i=save_changes(WIN_MID);
if(i==-1)
break; break;
if(!i) {
cfg.new_install=new_install;
if(strcmp(sys_pass, cfg.sys_pass) != 0) {
if(fexist("ssl.cert") || fexist("cryptlib.key") || fexist("letsyncrypt.key")) {
CRYPT_KEYSET ssl_keyset;
CRYPT_CONTEXT ssl_context = -1;
int status;
int ignoreme;
if (cryptStatusOK(status = cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, "ssl.cert", CRYPT_KEYOPT_NONE)))
if (cryptStatusOK(status = cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssl_cert", sys_pass)))
if (cryptStatusOK(status = cryptDeleteKey(ssl_keyset, CRYPT_KEYID_NAME, "ssl_cert"))) {
ignoreme = cryptAddPrivateKey(ssl_keyset, ssl_context, cfg.sys_pass);
cryptKeysetClose(ssl_keyset);
}
if (cryptStatusOK(status = cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, "cryptlib.key", CRYPT_KEYOPT_NONE)))
if (cryptStatusOK(status = cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssh_server", sys_pass)))
if (cryptStatusOK(status = cryptDeleteKey(ssl_keyset, CRYPT_KEYID_NAME, "ssh_server"))) {
ignoreme = cryptAddPrivateKey(ssl_keyset, ssl_context, cfg.sys_pass);
cryptKeysetClose(ssl_keyset);
}
if (cryptStatusOK(status = cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, "letsyncrypt.key", CRYPT_KEYOPT_NONE))) {
char value[INI_MAX_VALUE_LEN];
char* host = "acme-v02.api.letsencrypt.org";
FILE* fp = fopen("letsyncrypt.ini", "r");
if(fp != NULL) {
host = iniReadString(fp, "state", "host", host, value);
fclose(fp);
}
if (cryptStatusOK(status = cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, host, sys_pass)))
if (cryptStatusOK(status = cryptDeleteKey(ssl_keyset, CRYPT_KEYID_NAME, host))) {
ignoreme = cryptAddPrivateKey(ssl_keyset, ssl_context, cfg.sys_pass);
cryptKeysetClose(ssl_keyset);
}
}
(void)ignoreme;
}
}
save_main_cfg(&cfg,backup_level);
refresh_cfg(&cfg);
}
return;
case 0: case 0:
ultoa(cfg.new_level,str,10);
uifc.helpbuf= uifc.helpbuf=
"`New User Security Level:`\n" "`BBS Name:`\n"
"\n" "\n"
"This is the security level automatically given to new users.\n" "This is the name of the BBS.\n"
; ;
uifc.input(WIN_SAV|WIN_MID,0,0,"Security Level" uifc.input(WIN_MID,0,0,"BBS Name",cfg.sys_name,sizeof(cfg.sys_name)-1,K_EDIT);
,str,2,K_EDIT|K_NUMBER);
cfg.new_level=atoi(str);
break; break;
case 1: case 1:
truncsp(u32toaf(cfg.new_flags1,str));
uifc.helpbuf= uifc.helpbuf=
"`New User Security Flags:`\n" "`System Location:`\n"
"\n" "\n"
"These are the security flags automatically given to new users.\n" "This is the location of the BBS. The format is flexible, but it is\n"
"suggested you use the `City, State` format for clarity.\n"
; ;
uifc.input(WIN_SAV|WIN_MID,0,0,"Flag Set #1" uifc.input(WIN_MID,0,0,"Location",cfg.sys_location,sizeof(cfg.sys_location)-1,K_EDIT);
,str,26,K_EDIT|K_UPPER|K_ALPHA);
cfg.new_flags1=aftou32(str);
break; break;
case 2: case 2:
truncsp(u32toaf(cfg.new_flags2,str)); i = !(cfg.sys_timezone & US_ZONE);
uifc.helpbuf= uifc.helpbuf=
"`New User Security Flags:`\n" "`United States Time Zone:`\n"
"\n" "\n"
"These are the security flags automatically given to new users.\n" "If your local time zone is the United States, select `Yes`.\n"
; ;
uifc.input(WIN_SAV|WIN_MID,0,0,"Flag Set #2"
,str,26,K_EDIT|K_UPPER|K_ALPHA); i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
cfg.new_flags2=aftou32(str); ,"United States Time Zone",uifcYesNoOpts);
if(i==-1)
break; break;
case 3: if(i==0) {
truncsp(u32toaf(cfg.new_flags3,str)); strcpy(opt[i++],"Atlantic");
uifc.helpbuf= strcpy(opt[i++],"Eastern");
"`New User Security Flags:`\n" strcpy(opt[i++],"Central");
strcpy(opt[i++],"Mountain");
strcpy(opt[i++],"Pacific");
strcpy(opt[i++],"Yukon");
strcpy(opt[i++],"Hawaii/Alaska");
strcpy(opt[i++],"Bering");
opt[i][0]=0;
i=0;
uifc.helpbuf=
"`U.S. Time Zone:`\n"
"\n" "\n"
"These are the security flags automatically given to new users.\n" "Choose the region which most closely reflects your local U.S. time zone.\n"
; ;
uifc.input(WIN_SAV|WIN_MID,0,0,"Flag Set #3" i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,str,26,K_EDIT|K_UPPER|K_ALPHA); ,"U.S. Time Zone",opt);
cfg.new_flags3=aftou32(str); if(i==-1)
break;
switch(i) {
case 0:
cfg.sys_timezone=AST;
break;
case 1:
cfg.sys_timezone=EST;
break;
case 2:
cfg.sys_timezone=CST;
break;
case 3:
cfg.sys_timezone=MST;
break; break;
case 4: case 4:
truncsp(u32toaf(cfg.new_flags4,str)); cfg.sys_timezone=PST;
uifc.helpbuf=
"`New User Security Flags:`\n"
"\n"
"These are the security flags automatically given to new users.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Flag Set #4"
,str,26,K_EDIT|K_UPPER|K_ALPHA);
cfg.new_flags4=aftou32(str);
break; break;
case 5: case 5:
truncsp(u32toaf(cfg.new_exempt,str)); cfg.sys_timezone=YST;
uifc.helpbuf=
"`New User Exemption Flags:`\n"
"\n"
"These are the exemptions that are automatically given to new users.\n"
"\n"
"See `http://wiki.synchro.net/access:exemptions` for details.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Exemption Flags",str,26
,K_EDIT|K_UPPER|K_ALPHA);
cfg.new_exempt=aftou32(str);
break; break;
case 6: case 6:
truncsp(u32toaf(cfg.new_rest,str)); cfg.sys_timezone=HST;
uifc.helpbuf=
"`New User Restriction Flags:`\n"
"\n"
"These are the restrictions that are automatically given to new users.\n"
"\n"
"See `http://wiki.synchro.net/access:restrictions` for details.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Restriction Flags",str,26
,K_EDIT|K_UPPER|K_ALPHA);
cfg.new_rest=aftou32(str);
break; break;
case 7: case 7:
ultoa(cfg.new_expire,str,10); cfg.sys_timezone=BST;
uifc.helpbuf=
"`New User Expiration Days:`\n"
"\n"
"If you wish new users to have an automatic expiration date, set this\n"
"value to the number of days before the user will expire. To disable\n"
"New User expiration, set this value to `0`.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Expiration Days",str,4
,K_EDIT|K_NUMBER);
cfg.new_expire=atoi(str);
break;
case 8:
ultoa(cfg.new_cdt,str,10);
uifc.helpbuf=
"`New User Credits:`\n"
"\n"
"This is the amount of credits that are automatically given to new users.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Credits",str,10
,K_EDIT|K_NUMBER);
cfg.new_cdt=atol(str);
break;
case 9:
ultoa(cfg.new_min,str,10);
uifc.helpbuf=
"`New User Minutes:`\n"
"\n"
"This is the number of extra minutes automatically given to new users.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Minutes (Time Credit)"
,str,10,K_EDIT|K_NUMBER);
cfg.new_min=atol(str);
break; break;
case 10: }
if(!cfg.total_xedits) { configure_dst();
uifc.msg("No External Editors Configured");
break; break;
} }
strcpy(opt[0],"Internal"); i=0;
for(i=1;i<=cfg.total_xedits;i++) strcpy(opt[i++],"Midway");
strcpy(opt[i],cfg.xedit[i-1]->code); strcpy(opt[i++],"Vancouver");
strcpy(opt[i++],"Edmonton");
strcpy(opt[i++],"Winnipeg");
strcpy(opt[i++],"Bogota");
strcpy(opt[i++],"Caracas");
strcpy(opt[i++],"Rio de Janeiro");
strcpy(opt[i++],"Fernando de Noronha");
strcpy(opt[i++],"Azores");
strcpy(opt[i++],"Western Europe (WET)");
strcpy(opt[i++],"Central Europe (CET)");
strcpy(opt[i++],"Eastern Europe (EET)");
strcpy(opt[i++],"Moscow");
strcpy(opt[i++],"Dubai");
strcpy(opt[i++],"Kabul");
strcpy(opt[i++],"Karachi");
strcpy(opt[i++],"Bombay");
strcpy(opt[i++],"Kathmandu");
strcpy(opt[i++],"Dhaka");
strcpy(opt[i++],"Bangkok");
strcpy(opt[i++],"Hong Kong");
strcpy(opt[i++],"Tokyo");
strcpy(opt[i++],"Australian Central");
strcpy(opt[i++],"Australian Eastern");
strcpy(opt[i++],"Noumea");
strcpy(opt[i++],"New Zealand");
strcpy(opt[i++],"Other...");
opt[i][0]=0; opt[i][0]=0;
i=0; i=0;
uifc.helpbuf= uifc.helpbuf=
"`New User Editor:`\n" "`Non-U.S. Time Zone:`\n"
"\n" "\n"
"You can use this option to select the default editor for new users.\n" "Choose the region which most closely reflects your local time zone.\n"
"\n"
"Choose `Other...` if a region representing your local time zone is\n"
"not listed (you will be able to set the UTC offset manually)."
; ;
i=uifc.list(WIN_SAV|WIN_RHT,2,1,13,&i,0,"Editors",opt); i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"None-U.S. Time Zone",opt);
if(i==-1) if(i==-1)
break; break;
uifc.changes=1; switch(i) {
if(i && i<=cfg.total_xedits) case 0:
SAFECOPY(cfg.new_xedit, cfg.xedit[i-1]->code); cfg.sys_timezone=MID;
else
cfg.new_xedit[0]=0;
break; break;
case 11: case 1:
for(i=0;i<cfg.total_shells && i<MAX_OPTS;i++) cfg.sys_timezone=VAN;
sprintf(opt[i],"%-.*s", LEN_CODE, cfg.shell[i]->code);
opt[i][0]=0;
i=cfg.new_shell;
uifc.helpbuf=
"`New User Command Shell:`\n"
"\n"
"You can use this option to select the default command shell for new\n"
"users.\n"
;
i=uifc.list(WIN_SAV|WIN_RHT,2,1,13,&i,0
,"Command Shells",opt);
if(i==-1)
break; break;
cfg.new_shell=i; case 2:
uifc.changes=1; cfg.sys_timezone=EDM;
break;
case 3:
cfg.sys_timezone=WIN;
break;
case 4:
cfg.sys_timezone=BOG;
break;
case 5:
cfg.sys_timezone=CAR;
break;
case 6:
cfg.sys_timezone=RIO;
break;
case 7:
cfg.sys_timezone=FER;
break;
case 8:
cfg.sys_timezone=AZO;
break;
case 9:
cfg.sys_timezone=WET;
break;
case 10:
cfg.sys_timezone=CET;
break;
case 11:
cfg.sys_timezone=EET;
break; break;
case 12: case 12:
uifc.helpbuf= cfg.sys_timezone=MOS;
"`New User Default Download Protocol:`\n"
"\n"
"This option allows you to set the default download protocol of new users\n"
"(protocol command key or `BLANK` for no default).\n"
;
sprintf(str,"%c",cfg.new_prot);
uifc.input(WIN_SAV|WIN_MID,0,0
,"Default Download Protocol (SPACE=Disabled)"
,str,1,K_EDIT|K_UPPER);
cfg.new_prot=str[0];
if(cfg.new_prot<' ')
cfg.new_prot=' ';
break; break;
case 13: case 13:
uifc.helpbuf= cfg.sys_timezone=DUB;
"`New User Days of New Messages:`\n"
"\n"
"This option allows you to set the number of days worth of messages\n"
"which will be included in the new user's first `new message scan`.\n"
"\n"
"The value `0` means there will be `no` new messages for the new user.\n"
;
sprintf(str,"%hu",cfg.new_msgscan_init);
uifc.input(WIN_SAV|WIN_MID,0,0
,"Days of New Messages for New User's first new message scan"
,str,4,K_EDIT|K_NUMBER);
cfg.new_msgscan_init=atoi(str);
break; break;
case 14: case 14:
uifc.helpbuf= cfg.sys_timezone=KAB;
"`New User Gender Options:`\n"
"\n"
"This is a list of single-character gender options for new users to\n"
"choose from.\n"
"\n"
"Default: `MFX`\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Gender Options"
,cfg.new_genders, sizeof(cfg.new_genders) -1 , K_EDIT|K_UPPER);
break; break;
case 15: case 15:
uifc.helpbuf= cfg.sys_timezone=KAR;
"`New User Default Toggle Options:`\n"
"\n"
"This menu contains the default state of new user toggle options. All new\n"
"users on your system will have their defaults set according to the\n"
"settings on this menu. The user can then change them to his or her\n"
"liking.\n"
"\n"
"See the Synchronet User Manual (`http://synchro.net/docs/user.html`)\n"
"for more information on the individual options available.\n"
;
j=0;
k=0;
while(1) {
i=0;
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Expert Menu Mode"
,cfg.new_misc&EXPERT ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Screen Pause"
,cfg.new_misc&UPAUSE ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Spinning Cursor"
,cfg.new_misc&SPIN ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Clear Screen"
,cfg.new_misc&CLRSCRN ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Ask For New Scan"
,cfg.new_misc&ASK_NSCAN ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Ask For Your Msg Scan"
,cfg.new_misc&ASK_SSCAN ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Automatic New File Scan"
,cfg.new_misc&ANFSCAN ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Remember Current Sub-board"
,cfg.new_misc&CURSUB ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Batch Download File Flag"
,cfg.new_misc&BATCHFLAG ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Extended File Descriptions"
,cfg.new_misc&EXTDESC ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Hot Keys"
,cfg.new_misc&COLDKEYS ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Auto Hang-up After Xfer"
,cfg.new_misc&AUTOHANG ? "Yes":"No");
opt[i][0]=0;
j=uifc.list(WIN_BOT|WIN_RHT|WIN_SAV,2,1,0,&j,&k
,"Default Toggle Options",opt);
if(j==-1)
break;
uifc.changes=1;
switch(j) {
case 0:
cfg.new_misc^=EXPERT;
break;
case 1:
cfg.new_misc^=UPAUSE;
break; break;
case 2: case 16:
cfg.new_misc^=SPIN; cfg.sys_timezone=BOM;
break; break;
case 3: case 17:
cfg.new_misc^=CLRSCRN; cfg.sys_timezone=KAT;
break; break;
case 4: case 18:
cfg.new_misc^=ASK_NSCAN; cfg.sys_timezone=DHA;
break; break;
case 5: case 19:
cfg.new_misc^=ASK_SSCAN; cfg.sys_timezone=BAN;
break; break;
case 6: case 20:
cfg.new_misc^=ANFSCAN; cfg.sys_timezone=HON;
break; break;
case 7: case 21:
cfg.new_misc^=CURSUB; cfg.sys_timezone=TOK;
break; break;
case 8: case 22:
cfg.new_misc^=BATCHFLAG; cfg.sys_timezone=ACST;
break; break;
case 9: case 23:
cfg.new_misc^=EXTDESC; cfg.sys_timezone=AEST;
break; break;
case 10: case 24:
cfg.new_misc^=COLDKEYS; cfg.sys_timezone=NOU;
break; break;
case 11: case 25:
cfg.new_misc^=AUTOHANG; cfg.sys_timezone=NZST;
break; break;
default:
if(cfg.sys_timezone>720 || cfg.sys_timezone<-720)
cfg.sys_timezone=0;
if(cfg.sys_timezone==0)
str[0]=0;
else
sprintf(str,"%02d:%02d"
,cfg.sys_timezone/60,cfg.sys_timezone<0
? (-cfg.sys_timezone)%60 : cfg.sys_timezone%60);
uifc.helpbuf=
"`Time Zone Offset:`\n"
"\n"
"Enter your local time zone offset from Universal Time (UTC/GMT)\n"
"in `HH:MM` format.\n"
;
uifc.input(WIN_MID|WIN_SAV,0,0
,"Time (HH:MM) East (+) or West (-) of Universal "
"Time"
,str,6,K_EDIT|K_UPPER);
cfg.sys_timezone=atoi(str)*60;
char *p=strchr(str,':');
if(p) {
if(cfg.sys_timezone<0)
cfg.sys_timezone-=atoi(p+1);
else
cfg.sys_timezone+=atoi(p+1);
} }
break;
} }
if(SMB_TZ_HAS_DST(cfg.sys_timezone))
configure_dst();
break; break;
case 16: case 3:
uifc.helpbuf= uifc.helpbuf=
"`New User Question Toggles:`\n" "`System Operator:`\n"
"\n" "\n"
"This menu allows you to decide which questions will be asked of a new\n" "This is the name or alias of the system operator. This does not have to\n"
"user.\n" "be the same as user #1. This field is used for informational purposes\n"
"only.\n"
; ;
j=0; uifc.input(WIN_MID,0,0,"System Operator",cfg.sys_op,sizeof(cfg.sys_op)-1,K_EDIT);
k=0; break;
while(1) { case 4: /* Toggle Options */
done=0;
while(!done) {
i=0; i=0;
sprintf(opt[i++],"%-27.27s %-3.3s" sprintf(opt[i++],"%-33.33s%s","Allow User Aliases"
,"Real Name" ,cfg.uq&UQ_ALIASES ? "Yes" : "No");
,cfg.uq&UQ_REALNAME ? "Yes":"No"); sprintf(opt[i++],"%-33.33s%s","Allow Time Banking"
sprintf(opt[i++],"%-27.27s %-3.3s" ,cfg.sys_misc&SM_TIMEBANK ? "Yes" : "No");
,"Force Unique Real Name" sprintf(opt[i++],"%-33.33s%s","Allow Credit Conversions"
,cfg.uq&UQ_DUPREAL ? "Yes":"No"); ,cfg.sys_misc&SM_NOCDTCVT ? "No" : "Yes");
sprintf(opt[i++],"%-27.27s %-3.3s" sprintf(opt[i++],"%-33.33s%s","Short Sysop Page"
,"Force Upper/Lower Case" ,cfg.sys_misc&SM_SHRTPAGE ? "Yes" : "No");
,cfg.uq&UQ_NOUPRLWR ? "No":"Yes"); sprintf(opt[i++],"%-33.33s%s","Include Sysop in Statistics"
sprintf(opt[i++],"%-27.27s %-3.3s" ,cfg.sys_misc&SM_SYSSTAT ? "Yes" : "No");
,"Company Name" sprintf(opt[i++],"%-33.33s%s","Use Location in User Lists"
,cfg.uq&UQ_COMPANY ? "Yes":"No"); ,cfg.sys_misc&SM_LISTLOC ? "Yes" : "No");
sprintf(opt[i++],"%-27.27s %-3.3s" sprintf(opt[i++],"%-33.33s%s","Military (24 hour) Time Format"
,"Chat Handle / Call Sign" ,cfg.sys_misc&SM_MILITARY ? "Yes" : "No");
,cfg.uq&UQ_HANDLE ? "Yes":"No"); sprintf(opt[i++],"%-33.33s%s","European Date Format (DD/MM/YY)"
sprintf(opt[i++],"%-27.27s %-3.3s" ,cfg.sys_misc&SM_EURODATE ? "Yes" : "No");
,"Force Unique Handle / Call Sign" sprintf(opt[i++],"%-33.33s%s","Display Sys Info During Logon"
,cfg.uq&UQ_DUPHAND ? "Yes":"No"); ,cfg.sys_misc&SM_NOSYSINFO ? "No" : "Yes");
sprintf(opt[i++],"%-27.27s %-3.3s" sprintf(opt[i++],"%-33.33s%s","Display Node List During Logon"
,"E-mail/NetMail Address" ,cfg.sys_misc&SM_NONODELIST ? "No" : "Yes");
,cfg.uq&UQ_NONETMAIL ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Force Unique E-mail/NetMail Address"
,cfg.uq&UQ_DUPNETMAIL ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Sex (Gender)"
,cfg.uq&UQ_SEX ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Birthday"
,cfg.uq&UQ_BIRTH ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Address and Zip Code"
,cfg.uq&UQ_ADDRESS ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Location"
,cfg.uq&UQ_LOCATION ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Require Comma in Location"
,cfg.uq&UQ_NOCOMMAS ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Phone Number"
,cfg.uq&UQ_PHONE ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Allow EX-ASCII in Answers"
,cfg.uq&UQ_NOEXASC ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"External Editor"
,cfg.uq&UQ_XEDIT ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Command Shell"
,cfg.uq&UQ_CMDSHELL ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Default Settings"
,cfg.uq&UQ_NODEF ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Color Terminal"
,cfg.uq&UQ_COLORTERM ? "Yes":"No");
opt[i][0]=0; opt[i][0]=0;
j=uifc.list(WIN_BOT|WIN_RHT|WIN_SAV,2,1,0,&j,&k uifc.helpbuf=
,"New User Questions",opt); "`System Toggle Options:`\n"
if(j==-1) "\n"
"This is a menu of system related options that can be toggled between\n"
"two or more states, such as `Yes` and `No`.\n"
;
switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT,0,0,41,&tog_dflt,&tog_bar
,"Toggle Options",opt)) {
case -1:
done=1;
break; break;
uifc.changes=1;
switch(j) {
case 0: case 0:
cfg.uq^=UQ_REALNAME; i=cfg.uq&UQ_ALIASES ? 0:1;
uifc.helpbuf=
"`Allow Users to Use Aliases:`\n"
"\n"
"If you want the users of your system to be allowed to be known by a\n"
"false name, handle, or alias, set this option to `Yes`. If you want all\n"
"users on your system to be known only by their real names, select `No`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"Allow Users to Use Aliases",uifcYesNoOpts);
if(!i && !(cfg.uq&UQ_ALIASES)) {
cfg.uq|=UQ_ALIASES;
}
else if(i==1 && cfg.uq&UQ_ALIASES) {
cfg.uq&=~UQ_ALIASES;
}
break; break;
case 1: case 1:
cfg.uq^=UQ_DUPREAL; i=cfg.sys_misc&SM_TIMEBANK ? 0:1;
break; uifc.helpbuf=
case 2: "`Allow Time Banking:`\n"
cfg.uq^=UQ_NOUPRLWR; "\n"
break; "If you want the users of your system to be allowed to deposit\n"
case 3: "any extra time they may have left during a call into their minute bank,\n"
cfg.uq^=UQ_COMPANY; "set this option to `Yes`. If this option is set to `No`, then the only\n"
break; "way a user may get minutes in their minute bank is to purchase them\n"
case 4: "with credits.\n"
cfg.uq^=UQ_HANDLE; ;
break; i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
case 5: ,"Allow Users to Deposit Time in Minute Bank",uifcYesNoOpts);
cfg.uq^=UQ_DUPHAND; if(!i && !(cfg.sys_misc&SM_TIMEBANK)) {
break; cfg.sys_misc|=SM_TIMEBANK;
case 6:
cfg.uq^=UQ_NONETMAIL;
break;
case 7:
cfg.uq^=UQ_DUPNETMAIL;
break;
case 8:
cfg.uq^=UQ_SEX;
break;
case 9:
cfg.uq^=UQ_BIRTH;
break;
case 10:
cfg.uq^=UQ_ADDRESS;
break;
case 11:
cfg.uq^=UQ_LOCATION;
break;
case 12:
cfg.uq^=UQ_NOCOMMAS;
break;
case 13:
cfg.uq^=UQ_PHONE;
break;
case 14:
cfg.uq^=UQ_NOEXASC;
break;
case 15:
cfg.uq^=UQ_XEDIT;
break;
case 16:
cfg.uq^=UQ_CMDSHELL;
break;
case 17:
cfg.uq^=UQ_NODEF;
break;
case 18:
cfg.uq^=UQ_COLORTERM;
break;
} }
else if(i==1 && cfg.sys_misc&SM_TIMEBANK) {
cfg.sys_misc&=~SM_TIMEBANK;
} }
break; break;
case 2:
i=cfg.sys_misc&SM_NOCDTCVT ? 1:0;
uifc.helpbuf=
"`Allow Credits to be Converted into Minutes:`\n"
"\n"
"If you want the users of your system to be allowed to convert\n"
"any credits they may have into minutes for their minute bank,\n"
"set this option to `Yes`.\n"
;
i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"Allow Users to Convert Credits into Minutes"
,uifcYesNoOpts);
if(!i && cfg.sys_misc&SM_NOCDTCVT) {
cfg.sys_misc&=~SM_NOCDTCVT;
} }
else if(i==1 && !(cfg.sys_misc&SM_NOCDTCVT)) {
cfg.sys_misc|=SM_NOCDTCVT;
} }
break; break;
case 11: /* Advanced Options */ case 3:
done=0; i=cfg.sys_misc&SM_SHRTPAGE ? 0:1;
while(!done) {
i=0;
sprintf(opt[i++],"%-27.27s%s","New User Magic Word",cfg.new_magic);
sprintf(opt[i++],"%-27.27s%s","Data Directory"
,cfg.data_dir);
sprintf(opt[i++],"%-27.27s%s","Logs Directory"
,cfg.logs_dir);
sprintf(opt[i++],"%-27.27s%s","Exec Directory"
,cfg.exec_dir);
sprintf(opt[i++],"%-27.27s%s","Mods Directory"
,cfg.mods_dir);
sprintf(opt[i++],"%-27.27s%s","Input SIF Questionnaire"
,cfg.new_sif);
sprintf(opt[i++],"%-27.27s%s","Output SIF Questionnaire"
,cfg.new_sof);
u32toac(cfg.cdt_per_dollar,str,',');
sprintf(opt[i++],"%-27.27s%s","Credits Per Dollar",str);
sprintf(opt[i++],"%-27.27s%u","Minutes Per 100K Credits"
,cfg.cdt_min_value);
sprintf(opt[i++],"%-27.27s%s","Maximum Number of Minutes"
,cfg.max_minutes ? ultoa(cfg.max_minutes,tmp,10) : "Unlimited");
sprintf(opt[i++],"%-27.27s%u","Warning Days Till Expire"
,cfg.sys_exp_warn);
sprintf(opt[i++],"%-27.27s%u","Last Displayable Node"
,cfg.sys_lastnode);
sprintf(opt[i++],"%-27.27s%s","Phone Number Format"
,cfg.sys_phonefmt);
sprintf(opt[i++],"%-27.27s%s","Sysop Chat Override"
,cfg.sys_chat_arstr);
if(cfg.user_backup_level)
sprintf(str,"%hu",cfg.user_backup_level);
else
strcpy(str,"None");
sprintf(opt[i++],"%-27.27s%s","User Database Backups",str);
if(cfg.mail_backup_level)
sprintf(str,"%hu",cfg.mail_backup_level);
else
strcpy(str,"None");
sprintf(opt[i++],"%-27.27s%s","Mail Database Backups",str);
if(cfg.max_log_size && cfg.max_logs_kept) {
SAFEPRINTF2(str, "%s bytes, keep %hu"
,byte_count_to_str(cfg.max_log_size, tmp, sizeof(tmp))
,cfg.max_logs_kept);
} else {
SAFECOPY(str, "Unlimited");
}
sprintf(opt[i++],"%-27.27s%s","Maximum Log File Size", str);
sprintf(opt[i++],"%-27.27s%"PRIX32,"Control Key Pass-through"
,cfg.ctrlkey_passthru);
opt[i][0]=0;
uifc.helpbuf= uifc.helpbuf=
"`System Advanced Options:`\n" "`Short Sysop Page:`\n"
"\n" "\n"
"Care should be taken when modifying any of the options listed here.\n" "If you would like the sysop page to be a short series of beeps rather\n"
"than continuous random tones, set this option to `Yes`.\n"
; ;
switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT,0,0,60,&adv_dflt,&adv_bar i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Short Sysop Page"
,"Advanced Options",opt)) { ,uifcYesNoOpts);
case -1: if(i==1 && cfg.sys_misc&SM_SHRTPAGE) {
done=1; cfg.sys_misc&=~SM_SHRTPAGE;
}
else if(!i && !(cfg.sys_misc&SM_SHRTPAGE)) {
cfg.sys_misc|=SM_SHRTPAGE;
}
break; break;
case 4:
case 0: i=cfg.sys_misc&SM_SYSSTAT ? 0:1;
uifc.helpbuf= uifc.helpbuf=
"`New User Magic Word:`\n" "`Include Sysop Activity in System Statistics:`\n"
"\n"
"If this field has a value, it is assumed the sysop has placed some\n"
"reference to this `magic word` in `text/newuser.msg` and new users\n"
"will be prompted for the magic word after they enter their password.\n"
"If they do not enter it correctly, it is assumed they didn't read the\n"
"new user information displayed to them and they are disconnected.\n"
"\n" "\n"
"Think of it as a password to guarantee that new users read the text\n" "If you want sysops to be included in the statistical data of the BBS,\n"
"displayed to them.\n" "set this option to `Yes`. The suggested setting for this option is\n"
"`No` so that statistical data will only reflect user usage and not\n"
"include sysop maintenance activity.\n"
; ;
uifc.input(WIN_MID|WIN_SAV,0,0,"New User Magic Word",cfg.new_magic,sizeof(cfg.new_magic)-1 i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,K_EDIT|K_UPPER); ,"Include Sysop Activity in System Statistics"
,uifcYesNoOpts);
if(!i && !(cfg.sys_misc&SM_SYSSTAT)) {
cfg.sys_misc|=SM_SYSSTAT;
}
else if(i==1 && cfg.sys_misc&SM_SYSSTAT) {
cfg.sys_misc&=~SM_SYSSTAT;
}
break; break;
case 1: case 5:
i=cfg.sys_misc&SM_LISTLOC ? 0:1;
uifc.helpbuf= uifc.helpbuf=
"`Data File Directory:`\n" "`User Location in User Lists:`\n"
"\n"
"The Synchronet data directory contains almost all the data for your BBS.\n"
"This directory must be located where `ALL` nodes can access it and\n"
"`MUST NOT` be placed on a RAM disk or other volatile media.\n"
"\n"
"See `http://wiki.synchro.net/dir:data` for details.\n"
"\n" "\n"
"This option allows you to change the location of your data directory.\n" "If you want user locations (city, state) displayed in the user lists,\n"
"set this option to `Yes`. If this option is set to `No`, the user notes\n"
"(if they exist) are displayed in the user lists.\n"
; ;
strcpy(str,cfg.data_dir); i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
if(uifc.input(WIN_MID|WIN_SAV,0,9,"Data Directory" ,"User Location (Instead of Note) in User Lists"
,str,sizeof(cfg.data_dir)-1,K_EDIT)>0) { ,uifcYesNoOpts);
backslash(str); if(!i && !(cfg.sys_misc&SM_LISTLOC)) {
SAFECOPY(cfg.data_dir,str); cfg.sys_misc|=SM_LISTLOC;
}
else if(i==1 && cfg.sys_misc&SM_LISTLOC) {
cfg.sys_misc&=~SM_LISTLOC;
} }
break; break;
case 2: case 6:
i=cfg.sys_misc&SM_MILITARY ? 0:1;
uifc.helpbuf= uifc.helpbuf=
"`Log File Directory:`\n" "`Military:`\n"
"\n"
"Log files will be stored in this directory.\n"
"\n" "\n"
"By default, this is set to the same as your Data File directory.\n" "If you would like the time-of-day to be displayed and entered in 24 hour\n"
"format always, set this option to `Yes`.\n"
; ;
strcpy(str,cfg.logs_dir); i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
if(uifc.input(WIN_MID|WIN_SAV,0,9,"Logs Directory" ,"Use Military Time Format",uifcYesNoOpts);
,str,sizeof(cfg.logs_dir)-1,K_EDIT)>0) { if(!i && !(cfg.sys_misc&SM_MILITARY)) {
backslash(str); cfg.sys_misc|=SM_MILITARY;
SAFECOPY(cfg.logs_dir,str); }
else if(i==1 && cfg.sys_misc&SM_MILITARY) {
cfg.sys_misc&=~SM_MILITARY;
} }
break; break;
case 3: case 7:
i=cfg.sys_misc&SM_EURODATE ? 0:1;
uifc.helpbuf= uifc.helpbuf=
"`Executable/Module File Directory:`\n" "`European Date Format:`\n"
"\n"
"The Synchronet exec directory contains program and script files that the\n"
"BBS executes. This directory does `not` need to be in your OS search path.\n"
"\n"
"If you place programs in this directory for the BBS to execute, you\n"
"should place the `%!` specifier for the `exec` directory at the\n"
"beginning of the configured command-lines.\n"
"\n"
"See `http://wiki.synchro.net/dir:exec` for details.\n"
"\n" "\n"
"This option allows you to change the location of your exec directory.\n" "If you would like dates to be displayed and entered in `DD/MM/YY` format\n"
"instead of `MM/DD/YY` format, set this option to `Yes`.\n"
; ;
strcpy(str,cfg.exec_dir); i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
if(uifc.input(WIN_MID|WIN_SAV,0,9,"Exec Directory" ,"European Date Format",uifcYesNoOpts);
,str,sizeof(cfg.exec_dir)-1,K_EDIT)>0) { if(!i && !(cfg.sys_misc&SM_EURODATE)) {
backslash(str); cfg.sys_misc|=SM_EURODATE;
SAFECOPY(cfg.exec_dir,str); }
else if(i==1 && cfg.sys_misc&SM_EURODATE) {
cfg.sys_misc&=~SM_EURODATE;
} }
break; break;
case 4: case 8:
i=cfg.sys_misc&SM_NOSYSINFO ? 1:0;
uifc.helpbuf= uifc.helpbuf=
"`Modified Modules Directory:`\n" "`Display System Information During Logon:`\n"
"\n" "\n"
"This optional directory can be used to specify a location where modified\n" "If you want system information displayed during logon, set this option\n"
"module files are stored. These modified modules will take precedence\n" "to `Yes`.\n"
"over modules with the same filename (in the `exec` directory) and will\n"
"`not be overwritten` by future updates/upgrades.\n"
"\n"
"Sub-directory searches of this directory also take precedence\n"
"(e.g. `mods/load/*` overrides `exec/load/*`).\n"
"\n"
"If this directory is `blank`, then this feature is not used and all\n"
"modules are assumed to be located in the `exec` directory.\n"
"\n"
"See `http://wiki.synchro.net/dir:mods` for details.\n"
; ;
strcpy(str,cfg.mods_dir); i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
if(uifc.input(WIN_MID|WIN_SAV,0,9,"Mods Directory" ,"Display System Information During Logon",uifcYesNoOpts);
,str,sizeof(cfg.mods_dir)-1,K_EDIT)>0) { if(!i && cfg.sys_misc&SM_NOSYSINFO) {
backslash(str); cfg.sys_misc&=~SM_NOSYSINFO;
SAFECOPY(cfg.mods_dir,str); }
else if(i==1 && !(cfg.sys_misc&SM_NOSYSINFO)) {
cfg.sys_misc|=SM_NOSYSINFO;
} }
break; break;
case 5: case 9:
strcpy(str,cfg.new_sif); i=cfg.sys_misc&SM_NONODELIST ? 1:0;
uifc.helpbuf= uifc.helpbuf=
"`SIF Questionnaire for User Input:`\n" "`Display Active Node List During Logon:`\n"
"\n" "\n"
"This is the name of a SIF questionnaire file that resides your text\n" "If you want the active nodes displayed during logon, set this option\n"
"directory that all users will be prompted to answer.\n" "to `Yes`.\n"
; ;
uifc.input(WIN_MID|WIN_SAV,0,0 i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
,"SIF Questionnaire for User Input" ,"Display Active Node List During Logon",uifcYesNoOpts);
,str,LEN_CODE,K_UPPER|K_EDIT); if(!i && cfg.sys_misc&SM_NONODELIST) {
if(!str[0] || code_ok(str)) cfg.sys_misc&=~SM_NONODELIST;
strcpy(cfg.new_sif,str); }
else else if(i==1 && !(cfg.sys_misc&SM_NONODELIST)) {
uifc.msg("Invalid SIF Name"); cfg.sys_misc|=SM_NONODELIST;
}
break; break;
case 6: }
strcpy(str,cfg.new_sof); }
break;
case 5: /* New User Values */
done=0;
while(!done) {
i=0;
sprintf(opt[i++],"%-27.27s%u","Level",cfg.new_level);
sprintf(opt[i++],"%-27.27s%s","Flag Set #1"
,u32toaf(cfg.new_flags1,str));
sprintf(opt[i++],"%-27.27s%s","Flag Set #2"
,u32toaf(cfg.new_flags2,str));
sprintf(opt[i++],"%-27.27s%s","Flag Set #3"
,u32toaf(cfg.new_flags3,str));
sprintf(opt[i++],"%-27.27s%s","Flag Set #4"
,u32toaf(cfg.new_flags4,str));
sprintf(opt[i++],"%-27.27s%s","Exemptions"
,u32toaf(cfg.new_exempt,str));
sprintf(opt[i++],"%-27.27s%s","Restrictions"
,u32toaf(cfg.new_rest,str));
sprintf(opt[i++],"%-27.27s%s","Expiration Days"
,ultoa(cfg.new_expire,str,10));
u32toac(cfg.new_cdt,str,',');
sprintf(opt[i++],"%-27.27s%s","Credits",str);
u32toac(cfg.new_min,str,',');
sprintf(opt[i++],"%-27.27s%s","Minutes",str);
sprintf(opt[i++],"%-27.27s%s","Editor"
,cfg.new_xedit);
sprintf(opt[i++],"%-27.27s%s","Command Shell"
,cfg.new_shell >= cfg.total_shells ? "<invalid>" : cfg.shell[cfg.new_shell]->code);
if(cfg.new_prot!=' ')
sprintf(str,"%c",cfg.new_prot);
else
strcpy(str,"None");
sprintf(opt[i++],"%-27.27s%s","Download Protocol",str);
sprintf(opt[i++],"%-27.27s%hu","Days of New Messages", cfg.new_msgscan_init);
sprintf(opt[i++],"%-27.27s%s", "Gender Options", cfg.new_genders);
strcpy(opt[i++],"Default Toggles...");
strcpy(opt[i++],"Question Toggles...");
opt[i][0]=0;
uifc.helpbuf= uifc.helpbuf=
"`SIF Questionnaire for Reviewing User Input:`\n" "`New User Values:`\n"
"\n" "\n"
"This is the SIF file used to review the input of users from the user\n" "This menu allows you to determine the default settings for new users.\n"
"edit function.\n"
; ;
uifc.input(WIN_MID|WIN_SAV,0,0 switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT,0,0,60,&new_dflt,0
,"SIF Questionnaire for Reviewing User Input" ,"New User Values",opt)) {
,str,LEN_CODE,K_UPPER|K_EDIT); case -1:
if(!str[0] || code_ok(str)) done=1;
strcpy(cfg.new_sof,str);
else
uifc.msg("Invalid SIF Name");
break; break;
case 7: case 0:
ultoa(cfg.new_level,str,10);
uifc.helpbuf= uifc.helpbuf=
"`Credits Per Dollar:`\n" "`New User Security Level:`\n"
"\n" "\n"
"This is the monetary value of a credit (How many credits per dollar).\n" "This is the security level automatically given to new users.\n"
"This value should be a power of 2 (1, 2, 4, 8, 16, 32, 64, 128, etc.)\n"
"since credits are usually converted in 100 kibibyte (102400) blocks.\n"
"To make a dollar worth two mebibytes of credits, set this value to\n"
"2,097,152 (a mebibyte is 1024*1024 or 1048576).\n"
; ;
ultoa(cfg.cdt_per_dollar,str,10); uifc.input(WIN_SAV|WIN_MID,0,0,"Security Level"
uifc.input(WIN_MID|WIN_SAV,0,0 ,str,2,K_EDIT|K_NUMBER);
,"Credits Per Dollar",str,10,K_NUMBER|K_EDIT); cfg.new_level=atoi(str);
cfg.cdt_per_dollar=atol(str);
break; break;
case 8: case 1:
truncsp(u32toaf(cfg.new_flags1,str));
uifc.helpbuf= uifc.helpbuf=
"`Minutes Per 100K Credits:`\n" "`New User Security Flags:`\n"
"\n" "\n"
"This is the value of a minute of time online. This field is the number\n" "These are the security flags automatically given to new users.\n"
"of minutes to give the user in exchange for each 100K credit block.\n"
; ;
sprintf(str,"%u",cfg.cdt_min_value); uifc.input(WIN_SAV|WIN_MID,0,0,"Flag Set #1"
uifc.input(WIN_MID|WIN_SAV,0,0 ,str,26,K_EDIT|K_UPPER|K_ALPHA);
,"Minutes Per 100K Credits",str,5,K_NUMBER|K_EDIT); cfg.new_flags1=aftou32(str);
cfg.cdt_min_value=atoi(str);
break; break;
case 9: case 2:
truncsp(u32toaf(cfg.new_flags2,str));
uifc.helpbuf= uifc.helpbuf=
"`Maximum Number of Minutes User Can Have:`\n" "`New User Security Flags:`\n"
"\n" "\n"
"This value is the maximum total number of minutes a user can have. If a\n" "These are the security flags automatically given to new users.\n"
"user has this number of minutes or more, they will not be allowed to\n"
"convert credits into minutes. A sysop can add minutes to a user's\n"
"account regardless of this maximum. If this value is set to `0`, users\n"
"will have no limit on the total number of minutes they can have.\n"
; ;
sprintf(str,"%"PRIu32,cfg.max_minutes); uifc.input(WIN_SAV|WIN_MID,0,0,"Flag Set #2"
uifc.input(WIN_MID|WIN_SAV,0,0 ,str,26,K_EDIT|K_UPPER|K_ALPHA);
,"Maximum Number of Minutes a User Can Have " cfg.new_flags2=aftou32(str);
"(0=No Limit)"
,str,10,K_NUMBER|K_EDIT);
cfg.max_minutes=atol(str);
break; break;
case 10: case 3:
truncsp(u32toaf(cfg.new_flags3,str));
uifc.helpbuf= uifc.helpbuf=
"`Warning Days Till Expire:`\n" "`New User Security Flags:`\n"
"\n" "\n"
"If a user's account will expire in this many days or less, the user will\n" "These are the security flags automatically given to new users.\n"
"be notified at logon. Setting this value to `0` disables the warning\n"
"completely.\n"
; ;
sprintf(str,"%u",cfg.sys_exp_warn); uifc.input(WIN_SAV|WIN_MID,0,0,"Flag Set #3"
uifc.input(WIN_MID|WIN_SAV,0,0 ,str,26,K_EDIT|K_UPPER|K_ALPHA);
,"Warning Days Till Expire",str,5,K_NUMBER|K_EDIT); cfg.new_flags3=aftou32(str);
cfg.sys_exp_warn=atoi(str);
break; break;
case 11: case 4:
truncsp(u32toaf(cfg.new_flags4,str));
uifc.helpbuf= uifc.helpbuf=
"`Last Displayed Node:`\n" "`New User Security Flags:`\n"
"\n" "\n"
"This is the number of the last node to display to users in node lists.\n" "These are the security flags automatically given to new users.\n"
"This allows the sysop to define the higher numbered nodes as `invisible`\n"
"to users.\n"
; ;
sprintf(str,"%u",cfg.sys_lastnode); uifc.input(WIN_SAV|WIN_MID,0,0,"Flag Set #4"
uifc.input(WIN_MID|WIN_SAV,0,0 ,str,26,K_EDIT|K_UPPER|K_ALPHA);
,"Last Displayed Node",str,5,K_NUMBER|K_EDIT); cfg.new_flags4=aftou32(str);
cfg.sys_lastnode=atoi(str);
break; break;
case 12: case 5:
truncsp(u32toaf(cfg.new_exempt,str));
uifc.helpbuf= uifc.helpbuf=
"`Phone Number Format:`\n" "`New User Exemption Flags:`\n"
"\n" "\n"
"This is the format used for phone numbers in your local calling\n" "These are the exemptions that are automatically given to new users.\n"
"area. Use `N` for number positions, `A` for alphabetic, or `!` for any\n" "\n"
"character. All other characters will be static in the phone number\n" "See `http://wiki.synchro.net/access:exemptions` for details.\n"
"format. An example for North American phone numbers is `NNN-NNN-NNNN`.\n"
; ;
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_SAV|WIN_MID,0,0,"Exemption Flags",str,26
,"Phone Number Format",cfg.sys_phonefmt ,K_EDIT|K_UPPER|K_ALPHA);
,LEN_PHONE,K_UPPER|K_EDIT); cfg.new_exempt=aftou32(str);
break;
case 13:
getar("Sysop Chat Override",cfg.sys_chat_arstr);
break; break;
case 14: case 6:
truncsp(u32toaf(cfg.new_rest,str));
uifc.helpbuf= uifc.helpbuf=
"`User Database Backups:`\n" "`New User Restriction Flags:`\n"
"\n" "\n"
"Setting this option to anything but 0 will enable automatic daily\n" "These are the restrictions that are automatically given to new users.\n"
"backups of the user database. This number determines how many backups\n" "\n"
"to keep on disk.\n" "See `http://wiki.synchro.net/access:restrictions` for details.\n"
; ;
sprintf(str,"%u",cfg.user_backup_level); uifc.input(WIN_SAV|WIN_MID,0,0,"Restriction Flags",str,26
uifc.input(WIN_MID|WIN_SAV,0,0 ,K_EDIT|K_UPPER|K_ALPHA);
,"Number of Daily User Database Backups to Keep" cfg.new_rest=aftou32(str);
,str,4,K_NUMBER|K_EDIT);
cfg.user_backup_level=atoi(str);
break; break;
case 15: case 7:
ultoa(cfg.new_expire,str,10);
uifc.helpbuf= uifc.helpbuf=
"`Mail Database Backups:`\n" "`New User Expiration Days:`\n"
"\n" "\n"
"Setting this option to anything but 0 will enable automatic daily\n" "If you wish new users to have an automatic expiration date, set this\n"
"backups of the mail database. This number determines how many backups\n" "value to the number of days before the user will expire. To disable\n"
"to keep on disk.\n" "New User expiration, set this value to `0`.\n"
; ;
sprintf(str,"%u",cfg.mail_backup_level); uifc.input(WIN_SAV|WIN_MID,0,0,"Expiration Days",str,4
uifc.input(WIN_MID|WIN_SAV,0,0 ,K_EDIT|K_NUMBER);
,"Number of Daily Mail Database Backups to Keep" cfg.new_expire=atoi(str);
,str,4,K_NUMBER|K_EDIT);
cfg.mail_backup_level=atoi(str);
break; break;
case 16: case 8:
ultoa(cfg.new_cdt,str,10);
uifc.helpbuf= uifc.helpbuf=
"`Maximum Log File Size:`\n" "`New User Credits:`\n"
"\n" "\n"
"This option allows you to limit the size of the following log files\n" "This is the amount of credits that are automatically given to new users.\n"
"created and appended-to by Synchronet, in the `Logs Directory`:\n" ;
"\n" uifc.input(WIN_SAV|WIN_MID,0,0,"Credits",str,10
" `hungup.log`\n" ,K_EDIT|K_NUMBER);
" `error.log`\n" cfg.new_cdt=atol(str);
" `crash.log`\n" break;
" `hack.log`\n" case 9:
" `spam.log`\n" ultoa(cfg.new_min,str,10);
" `guru.log`\n" uifc.helpbuf=
"\n" "`New User Minutes:`\n"
"The largest supported log file size limit is 4294967295 (3.99G) bytes.\n"
"Log files that have reached or exceeded the configured size limit are\n"
"retained by renaming the `*.log` file to `*.#.log` beginning with `*.0.log`.\n"
"\n" "\n"
"You must also specify the number of older/max-size log files to retain.\n" "This is the number of extra minutes automatically given to new users.\n"
"The largest number of supported retained rotated log files is 9999.\n"
"Oldest rotated log files are automatically deleted to save disk space.\n"
; ;
byte_count_to_str(cfg.max_log_size, str, sizeof(str)); uifc.input(WIN_SAV|WIN_MID,0,0,"Minutes (Time Credit)"
if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Log File Size (in bytes, 0=unlimited)", str, 10, K_EDIT|K_UPPER) > 0) { ,str,10,K_EDIT|K_NUMBER);
cfg.max_log_size = (uint32_t)parse_byte_count(str, 1); cfg.new_min=atol(str);
if(cfg.max_log_size) { break;
SAFEPRINTF(str, "%u", cfg.max_logs_kept); case 10:
if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Number of old Log Files to Keep", str, 4, K_EDIT|K_NUMBER) > 0) if(!cfg.total_xedits) {
cfg.max_logs_kept = atoi(str); uifc.msg("No External Editors Configured");
} break;
} }
strcpy(opt[0],"Internal");
for(i=1;i<=cfg.total_xedits;i++)
strcpy(opt[i],cfg.xedit[i-1]->code);
opt[i][0]=0;
i=0;
uifc.helpbuf=
"`New User Editor:`\n"
"\n"
"You can use this option to select the default editor for new users.\n"
;
i=uifc.list(WIN_SAV|WIN_RHT,2,1,13,&i,0,"Editors",opt);
if(i==-1)
break; break;
case 17: if(i && i<=cfg.total_xedits)
SAFECOPY(cfg.new_xedit, cfg.xedit[i-1]->code);
else
cfg.new_xedit[0]=0;
break;
case 11:
for(i=0;i<cfg.total_shells && i<MAX_OPTS;i++)
sprintf(opt[i],"%-.*s", LEN_CODE, cfg.shell[i]->code);
opt[i][0]=0;
i=cfg.new_shell;
uifc.helpbuf= uifc.helpbuf=
"`Control Key Pass-through:`\n" "`New User Command Shell:`\n"
"\n" "\n"
"This value is a 32-bit hexadecimal number. Each set bit represents a\n" "You can use this option to select the default command shell for new\n"
"control key combination that will `not` be handled internally by\n" "users.\n"
"Synchronet or by a Global Hot Key Event.\n" ;
i=uifc.list(WIN_SAV|WIN_RHT,2,1,13,&i,0
,"Command Shells",opt);
if(i==-1)
break;
cfg.new_shell=i;
break;
case 12:
uifc.helpbuf=
"`New User Default Download Protocol:`\n"
"\n" "\n"
"To disable internal handling of the `Ctrl-C` key combination (for example)\n" "This option allows you to set the default download protocol of new users\n"
"set this value to `8`. The value is determined by taking 2 to the power of\n" "(protocol command key or `BLANK` for no default).\n"
"the ASCII value of the control character (Ctrl-A is 1, Ctrl-B is 2, \n" ;
"etc.). In the case of Ctrl-C, taking 2 to the power of 3 equals 8.\n" sprintf(str,"%c",cfg.new_prot);
uifc.input(WIN_SAV|WIN_MID,0,0
,"Default Download Protocol (SPACE=Disabled)"
,str,1,K_EDIT|K_UPPER);
cfg.new_prot=str[0];
if(cfg.new_prot<' ')
cfg.new_prot=' ';
break;
case 13:
uifc.helpbuf=
"`New User Days of New Messages:`\n"
"\n" "\n"
"To pass-through multiple control key combinations, multiple bits must be\n" "This option allows you to set the number of days worth of messages\n"
"set (or'd together) to create the necessary value, which may require the\n" "which will be included in the new user's first `new message scan`.\n"
"use of a hexadecimal calculator.\n"
"\n" "\n"
"If unsure, leave this value set to `0`, the default.\n" "The value `0` means there will be `no` new messages for the new user.\n"
; ;
sprintf(str,"%"PRIX32,cfg.ctrlkey_passthru); sprintf(str,"%hu",cfg.new_msgscan_init);
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_SAV|WIN_MID,0,0
,"Control Key Pass-through" ,"Days of New Messages for New User's first new message scan"
,str,8,K_UPPER|K_EDIT); ,str,4,K_EDIT|K_NUMBER);
cfg.ctrlkey_passthru=strtoul(str,NULL,16); cfg.new_msgscan_init=atoi(str);
break;
}
}
break; break;
case 12: /* Loadable Modules */ case 14:
done=0;
bar=0;
k=0;
while(!done) {
i=0;
sprintf(opt[i++],"%-16.16s%s","Login",cfg.login_mod);
sprintf(opt[i++],"%-16.16s%s","Logon",cfg.logon_mod);
sprintf(opt[i++],"%-16.16s%s","Sync",cfg.sync_mod);
sprintf(opt[i++],"%-16.16s%s","Logoff",cfg.logoff_mod);
sprintf(opt[i++],"%-16.16s%s","Logout",cfg.logout_mod);
sprintf(opt[i++],"%-16.16s%s","New User",cfg.newuser_mod);
sprintf(opt[i++],"%-16.16s%s","Expired User",cfg.expire_mod);
sprintf(opt[i++],"%-16.16s%s","Auto Message",cfg.automsg_mod);
sprintf(opt[i++],"%-16.16s%s","Text Section",cfg.textsec_mod);
sprintf(opt[i++],"%-16.16s%s","Xtrn Section",cfg.xtrnsec_mod);
sprintf(opt[i++],"%-16.16s%s","Pre Xtrn",cfg.prextrn_mod);
sprintf(opt[i++],"%-16.16s%s","Post Xtrn",cfg.postxtrn_mod);
sprintf(opt[i++],"%-16.16s%s","Read Mail",cfg.readmail_mod);
sprintf(opt[i++],"%-16.16s%s","Scan Msgs",cfg.scanposts_mod);
sprintf(opt[i++],"%-16.16s%s","Scan Subs",cfg.scansubs_mod);
sprintf(opt[i++],"%-16.16s%s","List Msgs",cfg.listmsgs_mod);
sprintf(opt[i++],"%-16.16s%s","List Logons",cfg.logonlist_mod);
sprintf(opt[i++],"%-16.16s%s","List Nodes",cfg.nodelist_mod);
sprintf(opt[i++],"%-16.16s%s","Who's Online",cfg.whosonline_mod);
sprintf(opt[i++],"%-16.16s%s","Private Msg",cfg.privatemsg_mod);
sprintf(opt[i++],"%-16.16s%s","Temp Transfer",cfg.tempxfer_mod);
opt[i][0]=0;
uifc.helpbuf= uifc.helpbuf=
"`Loadable Modules:`\n" "`New User Gender Options:`\n"
"\n"
"Baja modules (`.bin` files) or JavaScript modules (`.js` files) can be\n"
"automatically loaded and executed during certain Terminal Server\n"
"operations. The name (root filename) of the module can be specified for\n"
"each of the available operations listed below:\n"
"\n" "\n"
"`Login` Required module for interactive terminal logins (answer)\n" "This is a list of single-character gender options for new users to\n"
"`Logon` Executed during terminal logon procedure\n" "choose from.\n"
"`Sync` Executed when terminal nodes are periodically synchronized\n"
"`Logoff` Executed during terminal logoff procedure (interactive)\n"
"`Logout` Executed during terminal logout procedure (offline)\n"
"`New User` Executed at end of new terminal user creation process\n"
"`Expired User` Executed during daily event when user expires (offline)\n"
"`Auto Message` Executed when a user chooses to edit the auto-message\n"
"`Text Section` Executed to handle general text file (viewing) section\n"
"`Xtrn Section` Executed to handle external programs (doors) section\n"
"`Pre Xtrn` Executed before external programs (doors) run\n"
"`Post Xtrn` Executed after external programs (doors) run\n"
"`Temp Transfer` Temporary/archive file transfer menu\n"
"\n" "\n"
"Full module command-lines may be used for the operations listed below:\n" "Default: `MFX`\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Gender Options"
,cfg.new_genders, sizeof(cfg.new_genders) -1 , K_EDIT|K_UPPER);
break;
case 15:
uifc.helpbuf=
"`New User Default Toggle Options:`\n"
"\n" "\n"
"`Read Mail` Executed when a user reads email/netmail\n" "This menu contains the default state of new user toggle options. All new\n"
"`Scan Msgs` Executed when a user reads or scans a message sub-board\n" "users on your system will have their defaults set according to the\n"
"`Scan Subs` Executed when a user scans one or more sub-boards for msgs\n" "settings on this menu. The user can then change them to his or her\n"
"`List Msgs` Executed when a user lists msgs from the msg read prompt\n" "liking.\n"
"`List Logons` Executed when a user lists logons ('-y' for yesterday)\n"
"`List Nodes` Executed when a user lists all nodes\n"
"`Who's Online` Executed when a user lists the nodes in-use (e.g. `^U`)\n"
"`Private Msg` Executed when a user sends a private node msg (e.g. `^P`)\n"
"\n" "\n"
"`Note:` JavaScript modules take precedence over Baja modules if both exist\n" "See the Synchronet User Manual (`http://synchro.net/docs/user.html`)\n"
" in your `exec` or `mods` directories.\n" "for more information on the individual options available.\n"
; ;
switch(uifc.list(WIN_ACT|WIN_T2B|WIN_RHT,0,0,40,&k,&bar j=0;
,"Loadable Modules",opt)) { k=0;
while(1) {
case -1: i=0;
done=1; sprintf(opt[i++],"%-27.27s %-3.3s"
,"Expert Menu Mode"
,cfg.new_misc&EXPERT ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Screen Pause"
,cfg.new_misc&UPAUSE ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Spinning Cursor"
,cfg.new_misc&SPIN ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Clear Screen"
,cfg.new_misc&CLRSCRN ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Ask For New Scan"
,cfg.new_misc&ASK_NSCAN ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Ask For Your Msg Scan"
,cfg.new_misc&ASK_SSCAN ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Automatic New File Scan"
,cfg.new_misc&ANFSCAN ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Remember Current Sub-board"
,cfg.new_misc&CURSUB ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Batch Download File Flag"
,cfg.new_misc&BATCHFLAG ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Extended File Descriptions"
,cfg.new_misc&EXTDESC ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Hot Keys"
,cfg.new_misc&COLDKEYS ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Auto Hang-up After Xfer"
,cfg.new_misc&AUTOHANG ? "Yes":"No");
opt[i][0]=0;
j=uifc.list(WIN_BOT|WIN_RHT|WIN_SAV,2,1,0,&j,&k
,"Default Toggle Options",opt);
if(j==-1)
break; break;
switch(j) {
case 0: case 0:
uifc.input(WIN_MID|WIN_SAV,0,0,"Login Module" cfg.new_misc^=EXPERT;
,cfg.login_mod,sizeof(cfg.login_mod)-1,K_EDIT);
break; break;
case 1: case 1:
uifc.input(WIN_MID|WIN_SAV,0,0,"Logon Module" cfg.new_misc^=UPAUSE;
,cfg.logon_mod,sizeof(cfg.logon_mod)-1,K_EDIT);
break; break;
case 2: case 2:
uifc.input(WIN_MID|WIN_SAV,0,0,"Synchronize Module" cfg.new_misc^=SPIN;
,cfg.sync_mod,sizeof(cfg.sync_mod)-1,K_EDIT);
break; break;
case 3: case 3:
uifc.input(WIN_MID|WIN_SAV,0,0,"Logoff Module" cfg.new_misc^=CLRSCRN;
,cfg.logoff_mod,sizeof(cfg.logoff_mod)-1,K_EDIT);
break; break;
case 4: case 4:
uifc.input(WIN_MID|WIN_SAV,0,0,"Logout Module" cfg.new_misc^=ASK_NSCAN;
,cfg.logout_mod,sizeof(cfg.logout_mod)-1,K_EDIT);
break; break;
case 5: case 5:
uifc.input(WIN_MID|WIN_SAV,0,0,"New User Module" cfg.new_misc^=ASK_SSCAN;
,cfg.newuser_mod,sizeof(cfg.newuser_mod)-1,K_EDIT);
break; break;
case 6: case 6:
uifc.input(WIN_MID|WIN_SAV,0,0,"Expired User Module" cfg.new_misc^=ANFSCAN;
,cfg.expire_mod,sizeof(cfg.expire_mod)-1,K_EDIT);
break; break;
case 7: case 7:
uifc.input(WIN_MID|WIN_SAV,0,0,"Auto Message Module" cfg.new_misc^=CURSUB;
,cfg.automsg_mod,sizeof(cfg.automsg_mod)-1,K_EDIT);
break; break;
case 8: case 8:
uifc.input(WIN_MID|WIN_SAV,0,0,"Text File Section Module" cfg.new_misc^=BATCHFLAG;
,cfg.textsec_mod,sizeof(cfg.textsec_mod)-1,K_EDIT);
break; break;
case 9: case 9:
uifc.input(WIN_MID|WIN_SAV,0,0,"External Program Section Module" cfg.new_misc^=EXTDESC;
,cfg.xtrnsec_mod,sizeof(cfg.xtrnsec_mod)-1,K_EDIT);
break; break;
case 10: case 10:
uifc.input(WIN_MID|WIN_SAV,0,0,"Pre External Program Module" cfg.new_misc^=COLDKEYS;
,cfg.prextrn_mod,sizeof(cfg.prextrn_mod)-1,K_EDIT);
break; break;
case 11: case 11:
uifc.input(WIN_MID|WIN_SAV,0,0,"Post External Program Module" cfg.new_misc^=AUTOHANG;
,cfg.postxtrn_mod,sizeof(cfg.postxtrn_mod)-1,K_EDIT); break;
}
}
break;
case 16:
uifc.helpbuf=
"`New User Question Toggles:`\n"
"\n"
"This menu allows you to decide which questions will be asked of a new\n"
"user.\n"
;
j=0;
k=0;
while(1) {
i=0;
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Real Name"
,cfg.uq&UQ_REALNAME ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Force Unique Real Name"
,cfg.uq&UQ_DUPREAL ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Force Upper/Lower Case"
,cfg.uq&UQ_NOUPRLWR ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Company Name"
,cfg.uq&UQ_COMPANY ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Chat Handle / Call Sign"
,cfg.uq&UQ_HANDLE ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Force Unique Handle / Call Sign"
,cfg.uq&UQ_DUPHAND ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"E-mail/NetMail Address"
,cfg.uq&UQ_NONETMAIL ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Force Unique E-mail/NetMail Address"
,cfg.uq&UQ_DUPNETMAIL ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Sex (Gender)"
,cfg.uq&UQ_SEX ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Birthday"
,cfg.uq&UQ_BIRTH ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Address and Zip Code"
,cfg.uq&UQ_ADDRESS ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Location"
,cfg.uq&UQ_LOCATION ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Require Comma in Location"
,cfg.uq&UQ_NOCOMMAS ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Phone Number"
,cfg.uq&UQ_PHONE ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Allow EX-ASCII in Answers"
,cfg.uq&UQ_NOEXASC ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"External Editor"
,cfg.uq&UQ_XEDIT ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Command Shell"
,cfg.uq&UQ_CMDSHELL ? "Yes":"No");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Default Settings"
,cfg.uq&UQ_NODEF ? "No":"Yes");
sprintf(opt[i++],"%-27.27s %-3.3s"
,"Color Terminal"
,cfg.uq&UQ_COLORTERM ? "Yes":"No");
opt[i][0]=0;
j=uifc.list(WIN_BOT|WIN_RHT|WIN_SAV,2,1,0,&j,&k
,"New User Questions",opt);
if(j==-1)
break;
switch(j) {
case 0:
cfg.uq^=UQ_REALNAME;
break;
case 1:
cfg.uq^=UQ_DUPREAL;
break;
case 2:
cfg.uq^=UQ_NOUPRLWR;
break;
case 3:
cfg.uq^=UQ_COMPANY;
break;
case 4:
cfg.uq^=UQ_HANDLE;
break;
case 5:
cfg.uq^=UQ_DUPHAND;
break;
case 6:
cfg.uq^=UQ_NONETMAIL;
break;
case 7:
cfg.uq^=UQ_DUPNETMAIL;
break;
case 8:
cfg.uq^=UQ_SEX;
break;
case 9:
cfg.uq^=UQ_BIRTH;
break;
case 10:
cfg.uq^=UQ_ADDRESS;
break;
case 11:
cfg.uq^=UQ_LOCATION;
break; break;
case 12: case 12:
uifc.input(WIN_MID|WIN_SAV,0,0,"Read Mail Command" cfg.uq^=UQ_NOCOMMAS;
,cfg.readmail_mod,sizeof(cfg.readmail_mod)-1,K_EDIT);
break; break;
case 13: case 13:
uifc.input(WIN_MID|WIN_SAV,0,0,"Scan Msgs Command" cfg.uq^=UQ_PHONE;
,cfg.scanposts_mod,sizeof(cfg.scanposts_mod)-1,K_EDIT);
break; break;
case 14: case 14:
uifc.input(WIN_MID|WIN_SAV,0,0,"Scan Subs Command" cfg.uq^=UQ_NOEXASC;
,cfg.scansubs_mod,sizeof(cfg.scansubs_mod)-1,K_EDIT);
break; break;
case 15: case 15:
uifc.input(WIN_MID|WIN_SAV,0,0,"List Msgs Command" cfg.uq^=UQ_XEDIT;
,cfg.listmsgs_mod,sizeof(cfg.listmsgs_mod)-1,K_EDIT);
break; break;
case 16: case 16:
uifc.input(WIN_MID|WIN_SAV,0,0,"List Logons Command" cfg.uq^=UQ_CMDSHELL;
,cfg.logonlist_mod,sizeof(cfg.logonlist_mod)-1,K_EDIT);
break; break;
case 17: case 17:
uifc.input(WIN_MID|WIN_SAV,0,0,"List Nodes Command" cfg.uq^=UQ_NODEF;
,cfg.nodelist_mod,sizeof(cfg.nodelist_mod)-1,K_EDIT);
break; break;
case 18: case 18:
uifc.input(WIN_MID|WIN_SAV,0,0,"Who's Online Command" cfg.uq^=UQ_COLORTERM;
,cfg.whosonline_mod,sizeof(cfg.whosonline_mod)-1,K_EDIT);
break;
case 19:
uifc.input(WIN_MID|WIN_SAV,0,0,"Private Message Command"
,cfg.privatemsg_mod,sizeof(cfg.privatemsg_mod)-1,K_EDIT);
break; break;
case 20: }
uifc.input(WIN_MID|WIN_SAV,0,0,"Temporary File Transfer Module" }
,cfg.tempxfer_mod, sizeof(cfg.tempxfer_mod)-1, K_EDIT);
break; break;
} }
} }
break; break;
case 6:
case 13: /* Security Levels */ security_cfg();
k=0; break;
while(1) { case 7: /* Advanced Options */
for(i=0;i<100;i++) { done=0;
byte_count_to_str(cfg.level_freecdtperday[i], tmp, sizeof(tmp)); while(!done) {
sprintf(opt[i],"%-2d %5d %5d " i=0;
"%5d %5d %5d %5d %6s %7s %2u",i sprintf(opt[i++],"%-27.27s%s","New User Magic Word",cfg.new_magic);
,cfg.level_timeperday[i],cfg.level_timepercall[i] sprintf(opt[i++],"%-27.27s%s","Data Directory"
,cfg.level_callsperday[i],cfg.level_emailperday[i] ,cfg.data_dir);
,cfg.level_postsperday[i],cfg.level_linespermsg[i] sprintf(opt[i++],"%-27.27s%s","Logs Directory"
,tmp ,cfg.logs_dir);
,cfg.level_misc[i]&LEVEL_EXPTOVAL ? "Val Set" : "Level" sprintf(opt[i++],"%-27.27s%s","Exec Directory"
,cfg.level_misc[i]&(LEVEL_EXPTOVAL|LEVEL_EXPTOLVL) ? ,cfg.exec_dir);
cfg.level_expireto[i] : cfg.expired_level); sprintf(opt[i++],"%-27.27s%s","Mods Directory"
,cfg.mods_dir);
sprintf(opt[i++],"%-27.27s%s","Input SIF Questionnaire"
,cfg.new_sif);
sprintf(opt[i++],"%-27.27s%s","Output SIF Questionnaire"
,cfg.new_sof);
u32toac(cfg.cdt_per_dollar,str,',');
sprintf(opt[i++],"%-27.27s%s","Credits Per Dollar",str);
sprintf(opt[i++],"%-27.27s%u","Minutes Per 100K Credits"
,cfg.cdt_min_value);
sprintf(opt[i++],"%-27.27s%s","Maximum Number of Minutes"
,cfg.max_minutes ? ultoa(cfg.max_minutes,tmp,10) : "Unlimited");
sprintf(opt[i++],"%-27.27s%u","Warning Days Till Expire"
,cfg.sys_exp_warn);
sprintf(opt[i++],"%-27.27s%u","Last Displayable Node"
,cfg.sys_lastnode);
sprintf(opt[i++],"%-27.27s%s","Phone Number Format"
,cfg.sys_phonefmt);
sprintf(opt[i++],"%-27.27s%s","Sysop Chat Override"
,cfg.sys_chat_arstr);
if(cfg.user_backup_level)
sprintf(str,"%hu",cfg.user_backup_level);
else
strcpy(str,"None");
sprintf(opt[i++],"%-27.27s%s","User Database Backups",str);
if(cfg.mail_backup_level)
sprintf(str,"%hu",cfg.mail_backup_level);
else
strcpy(str,"None");
sprintf(opt[i++],"%-27.27s%s","Mail Database Backups",str);
if(cfg.max_log_size && cfg.max_logs_kept) {
SAFEPRINTF2(str, "%s bytes, keep %hu"
,byte_count_to_str(cfg.max_log_size, tmp, sizeof(tmp))
,cfg.max_logs_kept);
} else {
SAFECOPY(str, "Unlimited");
} }
sprintf(opt[i++],"%-27.27s%s","Maximum Log File Size", str);
sprintf(opt[i++],"%-27.27s%"PRIX32,"Control Key Pass-through"
,cfg.ctrlkey_passthru);
opt[i][0]=0; opt[i][0]=0;
i=0;
uifc.helpbuf= uifc.helpbuf=
"`Security Level Values:`\n" "`System Advanced Options:`\n"
"\n" "\n"
"This menu allows you to change the security options for every possible\n" "Care should be taken when modifying any of the options listed here.\n"
"security level from 0 to 99. The available options for each level are:\n" ;
switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT,0,0,60,&adv_dflt,&adv_bar
,"Advanced Options",opt)) {
case -1:
done=1;
break;
case 0:
uifc.helpbuf=
"`New User Magic Word:`\n"
"\n" "\n"
" Time Per Day Maximum online time per day\n" "If this field has a value, it is assumed the sysop has placed some\n"
" Time Per Call Maximum online time per call (logon)\n" "reference to this `magic word` in `text/newuser.msg` and new users\n"
" Calls Per Day Maximum number of calls (logons) per day\n" "will be prompted for the magic word after they enter their password.\n"
" Email Per Day Maximum number of email sent per day\n" "If they do not enter it correctly, it is assumed they didn't read the\n"
" Posts Per Day Maximum number of posted messages per day\n" "new user information displayed to them and they are disconnected.\n"
" Lines Per Message Maximum number of lines per message\n" "\n"
" Free Credits Per Day Number of free credits awarded per day\n" "Think of it as a password to guarantee that new users read the text\n"
" Expire To Level or validation set to Expire to\n" "displayed to them.\n"
; ;
i=uifc.list(WIN_RHT|WIN_ACT,0,3,0, &seclevel_dflt, &seclevel_bar uifc.input(WIN_MID|WIN_SAV,0,0,"New User Magic Word",cfg.new_magic,sizeof(cfg.new_magic)-1
,"Level T/D T/C C/D E/D P/D L/M F/D " ,K_EDIT|K_UPPER);
"Expire To",opt);
if(i==-1)
break; break;
while(1) { case 1:
sprintf(str,"Security Level %d Values",i); uifc.helpbuf=
j=0; "`Data File Directory:`\n"
sprintf(opt[j++],"%-22.22s%-5u","Time Per Day" "\n"
,cfg.level_timeperday[i]); "The Synchronet data directory contains almost all the data for your BBS.\n"
sprintf(opt[j++],"%-22.22s%-5u","Time Per Call" "This directory must be located where `ALL` nodes can access it and\n"
,cfg.level_timepercall[i]); "`MUST NOT` be placed on a RAM disk or other volatile media.\n"
sprintf(opt[j++],"%-22.22s%-5u","Calls Per Day" "\n"
,cfg.level_callsperday[i]); "See `http://wiki.synchro.net/dir:data` for details.\n"
sprintf(opt[j++],"%-22.22s%-5u","Email Per Day" "\n"
,cfg.level_emailperday[i]); "This option allows you to change the location of your data directory.\n"
sprintf(opt[j++],"%-22.22s%-5u","Posts Per Day" ;
,cfg.level_postsperday[i]); strcpy(str,cfg.data_dir);
sprintf(opt[j++],"%-22.22s%-5u","Lines Per Message" if(uifc.input(WIN_MID|WIN_SAV,0,9,"Data Directory"
,cfg.level_linespermsg[i]); ,str,sizeof(cfg.data_dir)-1,K_EDIT)>0) {
byte_count_to_str(cfg.level_freecdtperday[i], tmp, sizeof(tmp)); backslash(str);
sprintf(opt[j++],"%-22.22s%-6s","Free Credits Per Day" SAFECOPY(cfg.data_dir,str);
,tmp); }
sprintf(opt[j++],"%-22.22s%s %u","Expire To"
,cfg.level_misc[i]&LEVEL_EXPTOVAL ? "Validation Set"
: "Level"
,cfg.level_misc[i]&(LEVEL_EXPTOVAL|LEVEL_EXPTOLVL) ?
cfg.level_expireto[i] : cfg.expired_level);
opt[j][0]=0;
uifc_winmode_t wmode = WIN_RHT|WIN_SAV|WIN_ACT|WIN_EXTKEYS;
if(i > 0)
wmode |= WIN_LEFTKEY;
if(i + 1 < 100)
wmode |= WIN_RIGHTKEY;
j=uifc.list(wmode,2,1,0,&k,0
,str,opt);
if(j==-1)
break; break;
switch(j) { case 2:
case -CIO_KEY_LEFT-2: uifc.helpbuf=
if(i > 0) "`Log File Directory:`\n"
i--; "\n"
"Log files will be stored in this directory.\n"
"\n"
"By default, this is set to the same as your Data File directory.\n"
;
strcpy(str,cfg.logs_dir);
if(uifc.input(WIN_MID|WIN_SAV,0,9,"Logs Directory"
,str,sizeof(cfg.logs_dir)-1,K_EDIT)>0) {
backslash(str);
SAFECOPY(cfg.logs_dir,str);
}
break; break;
case -CIO_KEY_RIGHT-2: case 3:
if(i + 1 < 100) uifc.helpbuf=
i++; "`Executable/Module File Directory:`\n"
"\n"
"The Synchronet exec directory contains program and script files that the\n"
"BBS executes. This directory does `not` need to be in your OS search path.\n"
"\n"
"If you place programs in this directory for the BBS to execute, you\n"
"should place the `%!` specifier for the `exec` directory at the\n"
"beginning of the configured command-lines.\n"
"\n"
"See `http://wiki.synchro.net/dir:exec` for details.\n"
"\n"
"This option allows you to change the location of your exec directory.\n"
;
strcpy(str,cfg.exec_dir);
if(uifc.input(WIN_MID|WIN_SAV,0,9,"Exec Directory"
,str,sizeof(cfg.exec_dir)-1,K_EDIT)>0) {
backslash(str);
SAFECOPY(cfg.exec_dir,str);
}
break; break;
case 0: case 4:
uifc.helpbuf=
"`Modified Modules Directory:`\n"
"\n"
"This optional directory can be used to specify a location where modified\n"
"module files are stored. These modified modules will take precedence\n"
"over modules with the same filename (in the `exec` directory) and will\n"
"`not be overwritten` by future updates/upgrades.\n"
"\n"
"Sub-directory searches of this directory also take precedence\n"
"(e.g. `mods/load/*` overrides `exec/load/*`).\n"
"\n"
"If this directory is `blank`, then this feature is not used and all\n"
"modules are assumed to be located in the `exec` directory.\n"
"\n"
"See `http://wiki.synchro.net/dir:mods` for details.\n"
;
strcpy(str,cfg.mods_dir);
if(uifc.input(WIN_MID|WIN_SAV,0,9,"Mods Directory"
,str,sizeof(cfg.mods_dir)-1,K_EDIT)>0) {
backslash(str);
SAFECOPY(cfg.mods_dir,str);
}
break;
case 5:
strcpy(str,cfg.new_sif);
uifc.helpbuf=
"`SIF Questionnaire for User Input:`\n"
"\n"
"This is the name of a SIF questionnaire file that resides your text\n"
"directory that all users will be prompted to answer.\n"
;
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0
,"Total Time Allowed Per Day (in minutes)" ,"SIF Questionnaire for User Input"
,ultoa(cfg.level_timeperday[i],tmp,10),4 ,str,LEN_CODE,K_UPPER|K_EDIT);
,K_NUMBER|K_EDIT); if(!str[0] || code_ok(str))
cfg.level_timeperday[i]=atoi(tmp); strcpy(cfg.new_sif,str);
if(cfg.level_timeperday[i]>1440) else
cfg.level_timeperday[i]=1440; uifc.msg("Invalid SIF Name");
break; break;
case 1: case 6:
strcpy(str,cfg.new_sof);
uifc.helpbuf=
"`SIF Questionnaire for Reviewing User Input:`\n"
"\n"
"This is the SIF file used to review the input of users from the user\n"
"edit function.\n"
;
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0
,"Time Allowed Per Call (in minutes)" ,"SIF Questionnaire for Reviewing User Input"
,ultoa(cfg.level_timepercall[i],tmp,10),4 ,str,LEN_CODE,K_UPPER|K_EDIT);
,K_NUMBER|K_EDIT); if(!str[0] || code_ok(str))
cfg.level_timepercall[i]=atoi(tmp); strcpy(cfg.new_sof,str);
if(cfg.level_timepercall[i]>1440) else
cfg.level_timepercall[i]=1440; uifc.msg("Invalid SIF Name");
break; break;
case 2: case 7:
uifc.helpbuf=
"`Credits Per Dollar:`\n"
"\n"
"This is the monetary value of a credit (How many credits per dollar).\n"
"This value should be a power of 2 (1, 2, 4, 8, 16, 32, 64, 128, etc.)\n"
"since credits are usually converted in 100 kibibyte (102400) blocks.\n"
"To make a dollar worth two mebibytes of credits, set this value to\n"
"2,097,152 (a mebibyte is 1024*1024 or 1048576).\n"
;
ultoa(cfg.cdt_per_dollar,str,10);
uifc.input(WIN_MID|WIN_SAV,0,0
,"Credits Per Dollar",str,10,K_NUMBER|K_EDIT);
cfg.cdt_per_dollar=atol(str);
break;
case 8:
uifc.helpbuf=
"`Minutes Per 100K Credits:`\n"
"\n"
"This is the value of a minute of time online. This field is the number\n"
"of minutes to give the user in exchange for each 100K credit block.\n"
;
sprintf(str,"%u",cfg.cdt_min_value);
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0
,"Calls (Logons) Allowed Per Day" ,"Minutes Per 100K Credits",str,5,K_NUMBER|K_EDIT);
,ultoa(cfg.level_callsperday[i],tmp,10),4 cfg.cdt_min_value=atoi(str);
,K_NUMBER|K_EDIT);
cfg.level_callsperday[i]=atoi(tmp);
break; break;
case 3: case 9:
uifc.helpbuf=
"`Maximum Number of Minutes User Can Have:`\n"
"\n"
"This value is the maximum total number of minutes a user can have. If a\n"
"user has this number of minutes or more, they will not be allowed to\n"
"convert credits into minutes. A sysop can add minutes to a user's\n"
"account regardless of this maximum. If this value is set to `0`, users\n"
"will have no limit on the total number of minutes they can have.\n"
;
sprintf(str,"%"PRIu32,cfg.max_minutes);
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0
,"Email (Sent) Allowed Per Day" ,"Maximum Number of Minutes a User Can Have "
,ultoa(cfg.level_emailperday[i],tmp,10),4 "(0=No Limit)"
,K_NUMBER|K_EDIT); ,str,10,K_NUMBER|K_EDIT);
cfg.level_emailperday[i]=atoi(tmp); cfg.max_minutes=atol(str);
break; break;
case 4: case 10:
uifc.helpbuf=
"`Warning Days Till Expire:`\n"
"\n"
"If a user's account will expire in this many days or less, the user will\n"
"be notified at logon. Setting this value to `0` disables the warning\n"
"completely.\n"
;
sprintf(str,"%u",cfg.sys_exp_warn);
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0
,"Posted Messages Allowed Per Day" ,"Warning Days Till Expire",str,5,K_NUMBER|K_EDIT);
,ultoa(cfg.level_postsperday[i],tmp,10),4 cfg.sys_exp_warn=atoi(str);
,K_NUMBER|K_EDIT);
cfg.level_postsperday[i]=atoi(tmp);
break; break;
case 5: case 11:
uifc.helpbuf=
"`Last Displayed Node:`\n"
"\n"
"This is the number of the last node to display to users in node lists.\n"
"This allows the sysop to define the higher numbered nodes as `invisible`\n"
"to users.\n"
;
sprintf(str,"%u",cfg.sys_lastnode);
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0
,"Lines Allowed Per Message (Post/E-mail)" ,"Last Displayed Node",str,5,K_NUMBER|K_EDIT);
,ultoa(cfg.level_linespermsg[i],tmp,10),5 cfg.sys_lastnode=atoi(str);
,K_NUMBER|K_EDIT);
cfg.level_linespermsg[i]=atoi(tmp);
break; break;
case 6: case 12:
byte_count_to_str(cfg.level_freecdtperday[i], tmp, sizeof(tmp)); uifc.helpbuf=
if(uifc.input(WIN_MID|WIN_SAV,0,0 "`Phone Number Format:`\n"
,"Free Credits Awarded Per Day" "\n"
,tmp,19 "This is the format used for phone numbers in your local calling\n"
,K_EDIT|K_UPPER) > 0) "area. Use `N` for number positions, `A` for alphabetic, or `!` for any\n"
cfg.level_freecdtperday[i] = parse_byte_count(tmp, 1); "character. All other characters will be static in the phone number\n"
"format. An example for North American phone numbers is `NNN-NNN-NNNN`.\n"
;
uifc.input(WIN_MID|WIN_SAV,0,0
,"Phone Number Format",cfg.sys_phonefmt
,LEN_PHONE,K_UPPER|K_EDIT);
break; break;
case 7: case 13:
j=0; getar("Sysop Chat Override",cfg.sys_chat_arstr);
sprintf(opt[j++],"Default Expired Level "
"(Currently %u)",cfg.expired_level);
sprintf(opt[j++],"Specific Level");
sprintf(opt[j++],"Quick-Validation Set");
opt[j][0]=0;
j=0;
sprintf(str,"Level %u Expires To",i);
j=uifc.list(WIN_SAV,2,1,0,&j,0
,str,opt);
if(j==-1)
break; break;
if(j==0) { case 14:
cfg.level_misc[i]&= uifc.helpbuf=
~(LEVEL_EXPTOLVL|LEVEL_EXPTOVAL); "`User Database Backups:`\n"
uifc.changes=1; "\n"
"Setting this option to anything but 0 will enable automatic daily\n"
"backups of the user database. This number determines how many backups\n"
"to keep on disk.\n"
;
sprintf(str,"%u",cfg.user_backup_level);
uifc.input(WIN_MID|WIN_SAV,0,0
,"Number of Daily User Database Backups to Keep"
,str,4,K_NUMBER|K_EDIT);
cfg.user_backup_level=atoi(str);
break; break;
} case 15:
if(j==1) { uifc.helpbuf=
cfg.level_misc[i]&=~LEVEL_EXPTOVAL; "`Mail Database Backups:`\n"
cfg.level_misc[i]|=LEVEL_EXPTOLVL; "\n"
uifc.changes=1; "Setting this option to anything but 0 will enable automatic daily\n"
"backups of the mail database. This number determines how many backups\n"
"to keep on disk.\n"
;
sprintf(str,"%u",cfg.mail_backup_level);
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0
,"Expired Level" ,"Number of Daily Mail Database Backups to Keep"
,ultoa(cfg.level_expireto[i],tmp,10),2 ,str,4,K_NUMBER|K_EDIT);
,K_EDIT|K_NUMBER); cfg.mail_backup_level=atoi(str);
cfg.level_expireto[i]=atoi(tmp);
break; break;
case 16:
uifc.helpbuf=
"`Maximum Log File Size:`\n"
"\n"
"This option allows you to limit the size of the following log files\n"
"created and appended-to by Synchronet, in the `Logs Directory`:\n"
"\n"
" `hungup.log`\n"
" `error.log`\n"
" `crash.log`\n"
" `hack.log`\n"
" `spam.log`\n"
" `guru.log`\n"
"\n"
"The largest supported log file size limit is 4294967295 (3.99G) bytes.\n"
"Log files that have reached or exceeded the configured size limit are\n"
"retained by renaming the `*.log` file to `*.#.log` beginning with `*.0.log`.\n"
"\n"
"You must also specify the number of older/max-size log files to retain.\n"
"The largest number of supported retained rotated log files is 9999.\n"
"Oldest rotated log files are automatically deleted to save disk space.\n"
;
byte_count_to_str(cfg.max_log_size, str, sizeof(str));
if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Log File Size (in bytes, 0=unlimited)", str, 10, K_EDIT|K_UPPER) > 0) {
cfg.max_log_size = (uint32_t)parse_byte_count(str, 1);
if(cfg.max_log_size) {
SAFEPRINTF(str, "%u", cfg.max_logs_kept);
if(uifc.input(WIN_MID|WIN_SAV, 0, 0, "Maximum Number of old Log Files to Keep", str, 4, K_EDIT|K_NUMBER) > 0)
cfg.max_logs_kept = atoi(str);
} }
cfg.level_misc[i]&=~LEVEL_EXPTOLVL; }
cfg.level_misc[i]|=LEVEL_EXPTOVAL; break;
case 17:
uifc.helpbuf=
"`Control Key Pass-through:`\n"
"\n"
"This value is a 32-bit hexadecimal number. Each set bit represents a\n"
"control key combination that will `not` be handled internally by\n"
"Synchronet or by a Global Hot Key Event.\n"
"\n"
"To disable internal handling of the `Ctrl-C` key combination (for example)\n"
"set this value to `8`. The value is determined by taking 2 to the power of\n"
"the ASCII value of the control character (Ctrl-A is 1, Ctrl-B is 2, \n"
"etc.). In the case of Ctrl-C, taking 2 to the power of 3 equals 8.\n"
"\n"
"To pass-through multiple control key combinations, multiple bits must be\n"
"set (or'd together) to create the necessary value, which may require the\n"
"use of a hexadecimal calculator.\n"
"\n"
"If unsure, leave this value set to `0`, the default.\n"
;
sprintf(str,"%"PRIX32,cfg.ctrlkey_passthru);
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0
,"Quick-Validation Set to Expire To" ,"Control Key Pass-through"
,ultoa(cfg.level_expireto[i],tmp,10),1 ,str,8,K_UPPER|K_EDIT);
,K_EDIT|K_NUMBER); cfg.ctrlkey_passthru=strtoul(str,NULL,16);
cfg.level_expireto[i]=atoi(tmp);
break; break;
} }
} }
}
break; break;
case 14: /* Expired Acccount Values */ case 8: /* Loadable Modules */
dflt=0;
done=0; done=0;
while(!done) { while(!done) {
i=0; i=0;
sprintf(opt[i++],"%-27.27s%u","Level",cfg.expired_level); sprintf(opt[i++],"%-16.16s%s","Login",cfg.login_mod);
sprintf(opt[i++],"%-27.27s%s","Flag Set #1 to Remove" sprintf(opt[i++],"%-16.16s%s","Logon",cfg.logon_mod);
,u32toaf(cfg.expired_flags1,str)); sprintf(opt[i++],"%-16.16s%s","Sync",cfg.sync_mod);
sprintf(opt[i++],"%-27.27s%s","Flag Set #2 to Remove" sprintf(opt[i++],"%-16.16s%s","Logoff",cfg.logoff_mod);
,u32toaf(cfg.expired_flags2,str)); sprintf(opt[i++],"%-16.16s%s","Logout",cfg.logout_mod);
sprintf(opt[i++],"%-27.27s%s","Flag Set #3 to Remove" sprintf(opt[i++],"%-16.16s%s","New User",cfg.newuser_mod);
,u32toaf(cfg.expired_flags3,str)); sprintf(opt[i++],"%-16.16s%s","Expired User",cfg.expire_mod);
sprintf(opt[i++],"%-27.27s%s","Flag Set #4 to Remove" sprintf(opt[i++],"%-16.16s%s","Auto Message",cfg.automsg_mod);
,u32toaf(cfg.expired_flags4,str)); sprintf(opt[i++],"%-16.16s%s","Text Section",cfg.textsec_mod);
sprintf(opt[i++],"%-27.27s%s","Exemptions to Remove" sprintf(opt[i++],"%-16.16s%s","Xtrn Section",cfg.xtrnsec_mod);
,u32toaf(cfg.expired_exempt,str)); sprintf(opt[i++],"%-16.16s%s","Pre Xtrn",cfg.prextrn_mod);
sprintf(opt[i++],"%-27.27s%s","Restrictions to Add" sprintf(opt[i++],"%-16.16s%s","Post Xtrn",cfg.postxtrn_mod);
,u32toaf(cfg.expired_rest,str)); sprintf(opt[i++],"%-16.16s%s","Read Mail",cfg.readmail_mod);
sprintf(opt[i++],"%-16.16s%s","Scan Msgs",cfg.scanposts_mod);
sprintf(opt[i++],"%-16.16s%s","Scan Subs",cfg.scansubs_mod);
sprintf(opt[i++],"%-16.16s%s","List Msgs",cfg.listmsgs_mod);
sprintf(opt[i++],"%-16.16s%s","List Logons",cfg.logonlist_mod);
sprintf(opt[i++],"%-16.16s%s","List Nodes",cfg.nodelist_mod);
sprintf(opt[i++],"%-16.16s%s","Who's Online",cfg.whosonline_mod);
sprintf(opt[i++],"%-16.16s%s","Private Msg",cfg.privatemsg_mod);
sprintf(opt[i++],"%-16.16s%s","Temp Transfer",cfg.tempxfer_mod);
opt[i][0]=0; opt[i][0]=0;
uifc.helpbuf= uifc.helpbuf=
"`Expired Account Values:`\n" "`Loadable Modules:`\n"
"\n"
"Baja modules (`.bin` files) or JavaScript modules (`.js` files) can be\n"
"automatically loaded and executed during certain Terminal Server\n"
"operations. The name (root filename) of the module can be specified for\n"
"each of the available operations listed below:\n"
"\n"
"`Login` Required module for interactive terminal logins (answer)\n"
"`Logon` Executed during terminal logon procedure\n"
"`Sync` Executed when terminal nodes are periodically synchronized\n"
"`Logoff` Executed during terminal logoff procedure (interactive)\n"
"`Logout` Executed during terminal logout procedure (offline)\n"
"`New User` Executed at end of new terminal user creation process\n"
"`Expired User` Executed during daily event when user expires (offline)\n"
"`Auto Message` Executed when a user chooses to edit the auto-message\n"
"`Text Section` Executed to handle general text file (viewing) section\n"
"`Xtrn Section` Executed to handle external programs (doors) section\n"
"`Pre Xtrn` Executed before external programs (doors) run\n"
"`Post Xtrn` Executed after external programs (doors) run\n"
"`Temp Transfer` Temporary/archive file transfer menu\n"
"\n"
"Full module command-lines may be used for the operations listed below:\n"
"\n"
"`Read Mail` Executed when a user reads email/netmail\n"
"`Scan Msgs` Executed when a user reads or scans a message sub-board\n"
"`Scan Subs` Executed when a user scans one or more sub-boards for msgs\n"
"`List Msgs` Executed when a user lists msgs from the msg read prompt\n"
"`List Logons` Executed when a user lists logons ('-y' for yesterday)\n"
"`List Nodes` Executed when a user lists all nodes\n"
"`Who's Online` Executed when a user lists the nodes in-use (e.g. `^U`)\n"
"`Private Msg` Executed when a user sends a private node msg (e.g. `^P`)\n"
"\n" "\n"
"If a user's account expires, the security levels for that account will\n" "`Note:` JavaScript modules take precedence over Baja modules if both exist\n"
"be modified according to the settings of this menu. The account's\n" " in your `exec` or `mods` directories.\n"
"security level will be set to the value listed on this menu. The `Flags`\n"
"and `Exemptions` listed on this menu will be removed from the account\n"
"if they are set. The `Restrictions` listed will be added to the account.\n"
; ;
switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT,0,0,60,&dflt,0 switch(uifc.list(WIN_ACT|WIN_BOT|WIN_RHT,0,0,40,&mod_dflt,&mod_bar
,"Expired Account Values",opt)) { ,"Loadable Modules",opt)) {
case -1: case -1:
done=1; done=1;
break; break;
case 0: case 0:
ultoa(cfg.expired_level,str,10); uifc.input(WIN_MID|WIN_SAV,0,0,"Login Module"
uifc.helpbuf= ,cfg.login_mod,sizeof(cfg.login_mod)-1,K_EDIT);
"`Expired Account Security Level:`\n"
"\n"
"This is the security level automatically given to expired user accounts.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Security Level"
,str,2,K_EDIT|K_NUMBER);
cfg.expired_level=atoi(str);
break; break;
case 1: case 1:
truncsp(u32toaf(cfg.expired_flags1,str)); uifc.input(WIN_MID|WIN_SAV,0,0,"Logon Module"
uifc.helpbuf= ,cfg.logon_mod,sizeof(cfg.logon_mod)-1,K_EDIT);
"`Expired Security Flags to Remove:`\n"
"\n"
"These are the security flags automatically removed when a user account\n"
"has expired.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Flags Set #1"
,str,26,K_EDIT|K_UPPER|K_ALPHA);
cfg.expired_flags1=aftou32(str);
break; break;
case 2: case 2:
truncsp(u32toaf(cfg.expired_flags2,str)); uifc.input(WIN_MID|WIN_SAV,0,0,"Synchronize Module"
uifc.helpbuf= ,cfg.sync_mod,sizeof(cfg.sync_mod)-1,K_EDIT);
"`Expired Security Flags to Remove:`\n"
"\n"
"These are the security flags automatically removed when a user account\n"
"has expired.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Flags Set #2"
,str,26,K_EDIT|K_UPPER|K_ALPHA);
cfg.expired_flags2=aftou32(str);
break; break;
case 3: case 3:
truncsp(u32toaf(cfg.expired_flags3,str)); uifc.input(WIN_MID|WIN_SAV,0,0,"Logoff Module"
uifc.helpbuf= ,cfg.logoff_mod,sizeof(cfg.logoff_mod)-1,K_EDIT);
"`Expired Security Flags to Remove:`\n"
"\n"
"These are the security flags automatically removed when a user account\n"
"has expired.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Flags Set #3"
,str,26,K_EDIT|K_UPPER|K_ALPHA);
cfg.expired_flags3=aftou32(str);
break; break;
case 4: case 4:
truncsp(u32toaf(cfg.expired_flags4,str)); uifc.input(WIN_MID|WIN_SAV,0,0,"Logout Module"
uifc.helpbuf= ,cfg.logout_mod,sizeof(cfg.logout_mod)-1,K_EDIT);
"`Expired Security Flags to Remove:`\n"
"\n"
"These are the security flags automatically removed when a user account\n"
"has expired.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Flags Set #4"
,str,26,K_EDIT|K_UPPER|K_ALPHA);
cfg.expired_flags4=aftou32(str);
break; break;
case 5: case 5:
truncsp(u32toaf(cfg.expired_exempt,str)); uifc.input(WIN_MID|WIN_SAV,0,0,"New User Module"
uifc.helpbuf= ,cfg.newuser_mod,sizeof(cfg.newuser_mod)-1,K_EDIT);
"`Expired Exemption Flags to Remove:`\n"
"\n"
"These are the exemptions that are automatically removed from a user\n"
"account if it expires.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Exemption Flags",str,26
,K_EDIT|K_UPPER|K_ALPHA);
cfg.expired_exempt=aftou32(str);
break; break;
case 6: case 6:
truncsp(u32toaf(cfg.expired_rest,str)); uifc.input(WIN_MID|WIN_SAV,0,0,"Expired User Module"
uifc.helpbuf= ,cfg.expire_mod,sizeof(cfg.expire_mod)-1,K_EDIT);
"`Expired Restriction Flags to Add:`\n"
"\n"
"These are the restrictions that are automatically added to a user\n"
"account if it expires.\n"
;
uifc.input(WIN_SAV|WIN_MID,0,0,"Restriction Flags",str,26
,K_EDIT|K_UPPER|K_ALPHA);
cfg.expired_rest=aftou32(str);
break; break;
} case 7:
} uifc.input(WIN_MID|WIN_SAV,0,0,"Auto Message Module"
,cfg.automsg_mod,sizeof(cfg.automsg_mod)-1,K_EDIT);
break; break;
case 15: /* Quick-Validation Values */ case 8:
dflt=0; uifc.input(WIN_MID|WIN_SAV,0,0,"Text File Section Module"
k=0; ,cfg.textsec_mod,sizeof(cfg.textsec_mod)-1,K_EDIT);
while(1) {
for(i=0;i<10;i++)
sprintf(opt[i],"%d SL: %-2d F1: %s"
,i,cfg.val_level[i],u32toaf(cfg.val_flags1[i],str));
opt[i][0]=0;
i=0;
uifc.helpbuf=
"`Quick-Validation Values:`\n"
"\n"
"This is a list of the ten quick-validation sets. These sets are used to\n"
"quickly set a user's security values (Level, Flags, Exemptions,\n"
"Restrictions, Expiration Date, and Credits) with one key stroke. The\n"
"user's expiration date may be extended and additional credits may also\n"
"be added using quick-validation sets.\n"
"\n"
"From within the `User Edit` function, a sysop can use the `V`alidate\n"
"User command and select from this quick-validation list to change a\n"
"user's security values with very few key-strokes.\n"
;
i=uifc.list(WIN_RHT|WIN_BOT|WIN_ACT|WIN_SAV,0,0,0,&dflt,0
,"Quick-Validation Values",opt);
if(i==-1)
break; break;
while(1) { case 9:
j=0; uifc.input(WIN_MID|WIN_SAV,0,0,"External Program Section Module"
sprintf(opt[j++],"%-22.22s%u","Level",cfg.val_level[i]); ,cfg.xtrnsec_mod,sizeof(cfg.xtrnsec_mod)-1,K_EDIT);
sprintf(opt[j++],"%-22.22s%s","Flag Set #1"
,u32toaf(cfg.val_flags1[i],tmp));
sprintf(opt[j++],"%-22.22s%s","Flag Set #2"
,u32toaf(cfg.val_flags2[i],tmp));
sprintf(opt[j++],"%-22.22s%s","Flag Set #3"
,u32toaf(cfg.val_flags3[i],tmp));
sprintf(opt[j++],"%-22.22s%s","Flag Set #4"
,u32toaf(cfg.val_flags4[i],tmp));
sprintf(opt[j++],"%-22.22s%s","Exemptions"
,u32toaf(cfg.val_exempt[i],tmp));
sprintf(opt[j++],"%-22.22s%s","Restrictions"
,u32toaf(cfg.val_rest[i],tmp));
sprintf(opt[j++],"%-22.22s%u days","Extend Expiration"
,cfg.val_expire[i]);
sprintf(opt[j++],"%-22.22s%u","Additional Credits"
,cfg.val_cdt[i]);
opt[j][0]=0;
uifc_winmode_t wmode = WIN_RHT|WIN_SAV|WIN_ACT|WIN_EXTKEYS;
if(i > 0)
wmode |= WIN_LEFTKEY;
if(i + 1 < 10)
wmode |= WIN_RIGHTKEY;
SAFEPRINTF(str,"Quick-Validation Set %d",i);
j=uifc.list(wmode,2,1,0,&k,0,str,opt);
if(j==-1)
break; break;
switch(j) { case 10:
case -CIO_KEY_LEFT-2: uifc.input(WIN_MID|WIN_SAV,0,0,"Pre External Program Module"
if(i > 0) ,cfg.prextrn_mod,sizeof(cfg.prextrn_mod)-1,K_EDIT);
i--;
break; break;
case -CIO_KEY_RIGHT-2: case 11:
if(i + 1 < 10) uifc.input(WIN_MID|WIN_SAV,0,0,"Post External Program Module"
i++; ,cfg.postxtrn_mod,sizeof(cfg.postxtrn_mod)-1,K_EDIT);
break; break;
case 0: case 12:
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0,"Read Mail Command"
,"Level" ,cfg.readmail_mod,sizeof(cfg.readmail_mod)-1,K_EDIT);
,ultoa(cfg.val_level[i],tmp,10),2
,K_NUMBER|K_EDIT);
cfg.val_level[i]=atoi(tmp);
break; break;
case 1: case 13:
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0,"Scan Msgs Command"
,"Flag Set #1" ,cfg.scanposts_mod,sizeof(cfg.scanposts_mod)-1,K_EDIT);
,truncsp(u32toaf(cfg.val_flags1[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_flags1[i]=aftou32(tmp);
break; break;
case 2: case 14:
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0,"Scan Subs Command"
,"Flag Set #2" ,cfg.scansubs_mod,sizeof(cfg.scansubs_mod)-1,K_EDIT);
,truncsp(u32toaf(cfg.val_flags2[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_flags2[i]=aftou32(tmp);
break; break;
case 3: case 15:
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0,"List Msgs Command"
,"Flag Set #3" ,cfg.listmsgs_mod,sizeof(cfg.listmsgs_mod)-1,K_EDIT);
,truncsp(u32toaf(cfg.val_flags3[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_flags3[i]=aftou32(tmp);
break; break;
case 4: case 16:
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0,"List Logons Command"
,"Flag Set #4" ,cfg.logonlist_mod,sizeof(cfg.logonlist_mod)-1,K_EDIT);
,truncsp(u32toaf(cfg.val_flags4[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_flags4[i]=aftou32(tmp);
break; break;
case 5: case 17:
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0,"List Nodes Command"
,"Exemption Flags" ,cfg.nodelist_mod,sizeof(cfg.nodelist_mod)-1,K_EDIT);
,truncsp(u32toaf(cfg.val_exempt[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_exempt[i]=aftou32(tmp);
break; break;
case 6: case 18:
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0,"Who's Online Command"
,"Restriction Flags" ,cfg.whosonline_mod,sizeof(cfg.whosonline_mod)-1,K_EDIT);
,truncsp(u32toaf(cfg.val_rest[i],tmp)),26
,K_UPPER|K_ALPHA|K_EDIT);
cfg.val_rest[i]=aftou32(tmp);
break; break;
case 7: case 19:
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0,"Private Message Command"
,"Days to Extend Expiration" ,cfg.privatemsg_mod,sizeof(cfg.privatemsg_mod)-1,K_EDIT);
,ultoa(cfg.val_expire[i],tmp,10),4
,K_NUMBER|K_EDIT);
cfg.val_expire[i]=atoi(tmp);
break; break;
case 8: case 20:
uifc.input(WIN_MID|WIN_SAV,0,0 uifc.input(WIN_MID|WIN_SAV,0,0,"Temporary File Transfer Module"
,"Additional Credits" ,cfg.tempxfer_mod, sizeof(cfg.tempxfer_mod)-1, K_EDIT);
,ultoa(cfg.val_cdt[i],tmp,10),10
,K_NUMBER|K_EDIT);
cfg.val_cdt[i]=atol(tmp);
break; break;
} }
} }
}
break; break;
} }
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment