예제 #1
0
void guru_cfg()
{
	static int guru_dflt,guru_bar,opt_dflt;
	char str[128],code[128],done=0;
	int j,k;
	uint i;
	static guru_t savguru;

while(1) {
	for(i=0;i<cfg.total_gurus && i<MAX_OPTS;i++)
		sprintf(opt[i],"%-25s",cfg.guru[i]->name);
	opt[i][0]=0;
	j=WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT;
	if(cfg.total_gurus)
		j|=WIN_DEL|WIN_GET;
	if(cfg.total_gurus<MAX_OPTS)
		j|=WIN_INS|WIN_INSACT|WIN_XTR;
	if(savguru.name[0])
		j|=WIN_PUT;
	uifc.helpbuf=
		"`Gurus:`\n"
		"\n"
		"This is a list of the configured Gurus.\n"
		"\n"
		"To add a Guru, select the desired location with the arrow keys and\n"
		"hit ~ INS ~.\n"
		"\n"
		"To delete a Guru, select it with the arrow keys and hit ~ DEL ~.\n"
		"\n"
		"To configure a Guru, select it with the arrow keys and hit ~ ENTER ~.\n"
	;
	i=uifc.list(j,0,0,45,&guru_dflt,&guru_bar,"Artificial Gurus",opt);
	if((signed)i==-1)
		return;
	if((i&MSK_ON)==MSK_INS) {
		i&=MSK_OFF;
		uifc.helpbuf=
			"`Guru Name:`\n"
			"\n"
			"This is the name of the selected Guru.\n"
		;
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Guru Name",str,25
			,0)<1)
            continue;
		SAFECOPY(code,str);
		prep_code(code,/* prefix: */NULL);
		uifc.helpbuf=
			"`Guru Internal Code:`\n"
			"\n"
			"Every Guru must have its own unique code for Synchronet to refer to\n"
			"it internally. This code is usually an abreviation of the Guru name.\n"
		;
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Internal Code"
			,code,LEN_CODE,K_EDIT|K_UPPER)<1)
			continue;
		if(!code_ok(code)) {
			uifc.helpbuf=invalid_code;
			uifc.msg("Invalid Code");
			uifc.helpbuf=0;
            continue; 
		}
		if((cfg.guru=(guru_t **)realloc(cfg.guru,sizeof(guru_t *)*(cfg.total_gurus+1)))
            ==NULL) {
			errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_gurus+1);
			cfg.total_gurus=0;
			bail(1);
            continue; 
		}
		if(cfg.total_gurus)
			for(j=cfg.total_gurus;j>i;j--)
				cfg.guru[j]=cfg.guru[j-1];
		if((cfg.guru[i]=(guru_t *)malloc(sizeof(guru_t)))==NULL) {
			errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(guru_t));
			continue; 
		}
		memset((guru_t *)cfg.guru[i],0,sizeof(guru_t));
		strcpy(cfg.guru[i]->name,str);
		strcpy(cfg.guru[i]->code,code);
		cfg.total_gurus++;
		uifc.changes=1;
		continue; 
	}
	if((i&MSK_ON)==MSK_DEL) {
		i&=MSK_OFF;
		free(cfg.guru[i]);
		cfg.total_gurus--;
		for(j=i;j<cfg.total_gurus;j++)
			cfg.guru[j]=cfg.guru[j+1];
		uifc.changes=1;
		continue; 
	}
	if((i&MSK_ON)==MSK_GET) {
		i&=MSK_OFF;
		savguru=*cfg.guru[i];
		continue; 
	}
	if((i&MSK_ON)==MSK_PUT) {
		i&=MSK_OFF;
		*cfg.guru[i]=savguru;
		uifc.changes=1;
        continue; 
	}
    j=0;
	done=0;
	while(!done) {
		k=0;
		sprintf(opt[k++],"%-27.27s%s","Guru Name",cfg.guru[i]->name);
		sprintf(opt[k++],"%-27.27s%s","Guru Internal Code",cfg.guru[i]->code);
		sprintf(opt[k++],"%-27.27s%.40s","Access Requirements",cfg.guru[i]->arstr);
		opt[k][0]=0;
		uifc.helpbuf=
			"`Guru Configuration:`\n"
			"\n"
			"This menu is for configuring the selected Guru.\n"
		;
		switch(uifc.list(WIN_ACT|WIN_MID|WIN_SAV,0,0,60,&opt_dflt,0,cfg.guru[i]->name
			,opt)) {
			case -1:
				done=1;
				break;
			case 0:
				uifc.helpbuf=
					"`Guru Name:`\n"
					"\n"
					"This is the name of the selected Guru.\n"
				;
				strcpy(str,cfg.guru[i]->name);
				if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Guru Name"
					,cfg.guru[i]->name,sizeof(cfg.guru[i]->name)-1,K_EDIT))
					strcpy(cfg.guru[i]->name,str);
				break;
			case 1:
uifc.helpbuf=
	"`Guru Internal Code:`\n"
	"\n"
	"Every Guru must have its own unique code for Synchronet to refer to\n"
	"it internally. This code is usually an abreviation of the Guru name.\n"
;
				strcpy(str,cfg.guru[i]->code);
				if(!uifc.input(WIN_MID|WIN_SAV,0,0,"Guru Internal Code"
					,str,LEN_CODE,K_EDIT|K_UPPER))
					break;
				if(code_ok(str))
					strcpy(cfg.guru[i]->code,str);
				else {
					uifc.helpbuf=invalid_code;
					uifc.msg("Invalid Code");
                    uifc.helpbuf=0; 
				}
				break;
			case 2:
				getar(cfg.guru[i]->name,cfg.guru[i]->arstr);
				break; 
			} 
		} 
	}
}
예제 #2
0
파일: scfgsub.c 프로젝트: ftnapps/pkg-sbbs
void sub_cfg(uint grpnum)
{
	static int dflt,tog_dflt,opt_dflt,net_dflt,adv_dflt,bar;
	char str[81],str2[81],done=0,code[9],*p;
	int j,m,n,ptridx,q,s;
	uint i,subnum[MAX_OPTS+1];
	static sub_t savsub;

while(1) {
	for(i=0,j=0;i<cfg.total_subs && j<MAX_OPTS;i++)
        if(cfg.sub[i]->grp==grpnum) {
			subnum[j]=i;
			if(cfg.sub[subnum[0]]->qwkconf)
				sprintf(opt[j],"%-5u %s"
					,cfg.sub[i]->qwkconf,cfg.sub[i]->lname);
			else
				sprintf(opt[j],"%s"
					,cfg.sub[i]->lname);
			j++; }
	subnum[j]=cfg.total_subs;
	opt[j][0]=0;
	sprintf(str,"%s Sub-boards",cfg.grp[grpnum]->sname);
	i=WIN_SAV|WIN_ACT;
	if(j)
		i|=WIN_DEL|WIN_GET|WIN_DELACT;
	if(j<MAX_OPTS)
		i|=WIN_INS|WIN_XTR|WIN_INSACT;
	if(savsub.sname[0])
		i|=WIN_PUT;
	SETHELP(WHERE);
/*
Message Sub-boards:

This is a list of message sub-boards that have been configured for the
selected message group.

To add a sub-board, select the desired position with the arrow keys and
hit  INS .

To delete a sub-board, select it with the arrow keys and hit  DEL .

To configure a sub-board, select it with the arrow keys and hit  ENTER .
*/
	i=uifc.list(i,24,1,LEN_SLNAME+5,&dflt,&bar,str,opt);
	if((signed)i==-1)
		return;
	if((i&MSK_ON)==MSK_INS) {
		i&=MSK_OFF;
		strcpy(str,"General");
		SETHELP(WHERE);
/*
Sub-board Long Name:

This is a description of the message sub-board which is displayed in all
sub-board listings.
*/
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Sub-board Long Name",str,LEN_SLNAME
			,K_EDIT)<1)
			continue;
		sprintf(str2,"%.*s",LEN_SSNAME,str);
		SETHELP(WHERE);
/*
Sub-board Short Name:

This is a short description of the message sub-board which is displayed
at the main and reading messages prompts.
*/
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Sub-board Short Name",str2,LEN_SSNAME
			,K_EDIT)<1)
			continue;
#if 0
		sprintf(str3,"%.10s",str2);
		SETHELP(WHERE);
/*
Sub-board QWK Name:

This is the name of the sub-board used for QWK off-line readers.
*/
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Sub-board QWK Name",str3,10
            ,K_EDIT)<1)
            continue;
#endif
		sprintf(code,"%.8s",str2);
		p=strchr(code,' ');
		if(p) *p=0;
		strupr(code);
		SETHELP(WHERE);
/*
Sub-board Internal Code Suffix:

Every sub-board must have its own unique code for Synchronet to refer to
it internally. This code should be descriptive of the sub-board's topic,
usually an abreviation of the sub-board's name.
*/
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Sub-board Internal Code Suffix",code,LEN_CODE
			,K_EDIT|K_UPPER)<1)
			continue;
		if(!code_ok(code)) {
			uifc.helpbuf=invalid_code;
			uifc.msg("Invalid Code");
			uifc.helpbuf=0;
			continue; 
		}

		if((cfg.sub=(sub_t **)realloc(cfg.sub,sizeof(sub_t *)*(cfg.total_subs+1)))==NULL) {
            errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_subs+1);
			cfg.total_subs=0;
			bail(1);
            continue; }

		for(ptridx=0;ptridx<USHRT_MAX;ptridx++) { /* Search for unused pointer indx */
            for(n=0;n<cfg.total_subs;n++)
				if(cfg.sub[n]->ptridx==ptridx)
                    break;
            if(n==cfg.total_subs)
                break; }

		if(j) {
			for(n=cfg.total_subs;n>subnum[i];n--)
                cfg.sub[n]=cfg.sub[n-1];
			for(q=0;q<cfg.total_qhubs;q++)
				for(s=0;s<cfg.qhub[q]->subs;s++)
					if(cfg.qhub[q]->sub[s]>=subnum[i])
						cfg.qhub[q]->sub[s]++; }

		if((cfg.sub[subnum[i]]=(sub_t *)malloc(sizeof(sub_t)))==NULL) {
			errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(sub_t));
			continue; }
		memset((sub_t *)cfg.sub[subnum[i]],0,sizeof(sub_t));
		cfg.sub[subnum[i]]->grp=grpnum;
		if(cfg.total_faddrs)
			cfg.sub[subnum[i]]->faddr=cfg.faddr[0];
		else
			memset(&cfg.sub[subnum[i]]->faddr,0,sizeof(faddr_t));
		cfg.sub[subnum[i]]->maxmsgs=500;
		strcpy(cfg.sub[subnum[i]]->code_suffix,code);
		strcpy(cfg.sub[subnum[i]]->lname,str);
		strcpy(cfg.sub[subnum[i]]->sname,str2);
		strcpy(cfg.sub[subnum[i]]->qwkname,code);
		if(strchr(str,'.') && strchr(str,' ')==NULL)
			strcpy(cfg.sub[subnum[i]]->newsgroup,str);
		cfg.sub[subnum[i]]->misc=(SUB_NSDEF|SUB_SSDEF|SUB_QUOTE|SUB_TOUSER
			|SUB_HDRMOD|SUB_FAST);
		cfg.sub[subnum[i]]->ptridx=ptridx;
		cfg.total_subs++;
		uifc.changes=1;
		continue; }
	if((i&MSK_ON)==MSK_DEL) {
		i&=MSK_OFF;
		SETHELP(WHERE);
/*
Delete Data in Sub-board:

If you want to delete all the messages for this sub-board, select Yes.
*/
		j=1;
		strcpy(opt[0],"Yes");
		strcpy(opt[1],"No");
		opt[2][0]=0;
		j=uifc.list(WIN_MID|WIN_SAV,0,0,0,&j,0
			,"Delete Data in Sub-board",opt);
		if(j==-1)
			continue;
		if(j==0) {
				sprintf(str,"%s%s.*"
					,cfg.grp[cfg.sub[i]->grp]->code_prefix
					,cfg.sub[i]->code_suffix);
				strlwr(str);
				if(!cfg.sub[subnum[i]]->data_dir[0])
					sprintf(tmp,"%ssubs/",cfg.data_dir);
				else
					strcpy(tmp,cfg.sub[subnum[i]]->data_dir);
				delfiles(tmp,str);
				clearptrs(subnum[i]); 
		}
		free(cfg.sub[subnum[i]]);
		cfg.total_subs--;
		for(j=subnum[i];j<cfg.total_subs;j++)
			cfg.sub[j]=cfg.sub[j+1];
		for(q=0;q<cfg.total_qhubs;q++)
			for(s=0;s<cfg.qhub[q]->subs;s++) {
				if(cfg.qhub[q]->sub[s]==subnum[i])
					cfg.qhub[q]->sub[s]=INVALID_SUB;
				else if(cfg.qhub[q]->sub[s]>subnum[i])
					cfg.qhub[q]->sub[s]--; }
		uifc.changes=1;
		continue; }
	if((i&MSK_ON)==MSK_GET) {
		i&=MSK_OFF;
		savsub=*cfg.sub[subnum[i]];
		continue; }
	if((i&MSK_ON)==MSK_PUT) {
		i&=MSK_OFF;
		ptridx=cfg.sub[subnum[i]]->ptridx;
		*cfg.sub[subnum[i]]=savsub;
		cfg.sub[subnum[i]]->ptridx=ptridx;
		cfg.sub[subnum[i]]->grp=grpnum;
		uifc.changes=1;
        continue; }
	i=subnum[i];
	j=0;
	done=0;
	while(!done) {
		n=0;
		sprintf(opt[n++],"%-27.27s%s","Long Name",cfg.sub[i]->lname);
		sprintf(opt[n++],"%-27.27s%s","Short Name",cfg.sub[i]->sname);
		sprintf(opt[n++],"%-27.27s%s","QWK Name",cfg.sub[i]->qwkname);
		sprintf(opt[n++],"%-27.27s%s%s","Internal Code"
			,cfg.grp[cfg.sub[i]->grp]->code_prefix, cfg.sub[i]->code_suffix);
		sprintf(opt[n++],"%-27.27s%s","Newsgroup Name",cfg.sub[i]->newsgroup);
		sprintf(opt[n++],"%-27.27s%.40s","Access Requirements"
			,cfg.sub[i]->arstr);
		sprintf(opt[n++],"%-27.27s%.40s","Reading Requirements"
            ,cfg.sub[i]->read_arstr);
		sprintf(opt[n++],"%-27.27s%.40s","Posting Requirements"
			,cfg.sub[i]->post_arstr);
		sprintf(opt[n++],"%-27.27s%.40s","Operator Requirements"
			,cfg.sub[i]->op_arstr);
		sprintf(opt[n++],"%-27.27s%.40s","Moderated Posting User"
			,cfg.sub[i]->mod_arstr);
		sprintf(opt[n++],"%-27.27s%lu","Maximum Messages"
            ,cfg.sub[i]->maxmsgs);
		if(cfg.sub[i]->maxage)
            sprintf(str,"Enabled (%u days old)",cfg.sub[i]->maxage);
        else
            strcpy(str,"Disabled");
		sprintf(opt[n++],"%-27.27s%s","Purge by Age",str);
		if(cfg.sub[i]->maxcrcs)
			sprintf(str,"Enabled (%lu message CRCs)",cfg.sub[i]->maxcrcs);
		else
			strcpy(str,"Disabled");
		sprintf(opt[n++],"%-27.27s%s","Duplicate Checking",str);

		strcpy(opt[n++],"Toggle Options...");
		strcpy(opt[n++],"Network Options...");
		strcpy(opt[n++],"Advanced Options...");
		opt[n][0]=0;
		sprintf(str,"%s Sub-board",cfg.sub[i]->sname);
		SETHELP(WHERE);
/*
Sub-board Configuration:

This menu allows you to configure the individual selected sub-board.
Options with a trailing ... provide a sub-menu of more options.
*/
		switch(uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT
			,0,0,60,&opt_dflt,0,str,opt)) {
			case -1:
				done=1;
				break;
			case 0:
				SETHELP(WHERE);
/*
Sub-board Long Name:

This is a description of the message sub-board which is displayed in all
sub-board listings.
*/
				strcpy(str,cfg.sub[i]->lname);	/* save */
				if(!uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for Listings"
					,cfg.sub[i]->lname,LEN_SLNAME,K_EDIT))
					strcpy(cfg.sub[i]->lname,str);	/* restore */
				break;
			case 1:
				SETHELP(WHERE);
/*
Sub-board Short Name:

This is a short description of the message sub-board which is displayed
at the main and reading messages prompts.
*/
				uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for Prompts"
					,cfg.sub[i]->sname,LEN_SSNAME,K_EDIT);
				break;
			case 2:
				SETHELP(WHERE);
/*
Sub-board QWK Name:

This is the name of the sub-board used for QWK off-line readers.
*/
				uifc.input(WIN_MID|WIN_SAV,0,17,"Name to use for QWK Packets"
					,cfg.sub[i]->qwkname,10,K_EDIT);
                break;
			case 3:
                SETHELP(WHERE);
/*
Sub-board Internal Code Suffix:

Every sub-board must have its own unique code for Synchronet to refer
to it internally. This code should be descriptive of the sub-board's
topic, usually an abreviation of the sub-board's name.
*/
                strcpy(str,cfg.sub[i]->code_suffix);
                uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code Suffix (unique)"
                    ,str,LEN_CODE,K_EDIT|K_UPPER);
                if(code_ok(str))
                    strcpy(cfg.sub[i]->code_suffix,str);
                else {
                    uifc.helpbuf=invalid_code;
                    uifc.msg("Invalid Code");
                    uifc.helpbuf=0; 
				}
                break;
			case 4:
				SETHELP(WHERE);
/*
Newsgroup Name:

This is the name of the sub-board used for newsgroup readers. If no name
is configured here, a name will be automatically generated from the
sub-board's name and group name.
*/
				uifc.input(WIN_MID|WIN_SAV,0,17,""
					,cfg.sub[i]->newsgroup,sizeof(cfg.sub[i]->newsgroup)-1,K_EDIT);
                break;
			case 5:
				sprintf(str,"%s Access",cfg.sub[i]->sname);
				getar(str,cfg.sub[i]->arstr);
				break;
			case 6:
				sprintf(str,"%s Reading",cfg.sub[i]->sname);
				getar(str,cfg.sub[i]->read_arstr);
                break;
			case 7:
				sprintf(str,"%s Posting",cfg.sub[i]->sname);
				getar(str,cfg.sub[i]->post_arstr);
                break;
			case 8:
				sprintf(str,"%s Operator",cfg.sub[i]->sname);
				getar(str,cfg.sub[i]->op_arstr);
                break;
			case 9:
				sprintf(str,"%s Moderated Posting User",cfg.sub[i]->sname);
				getar(str,cfg.sub[i]->mod_arstr);
                break;
			case 10:
				sprintf(str,"%lu",cfg.sub[i]->maxmsgs);
                SETHELP(WHERE);
/*
Maximum Number of Messages:

This value is the maximum number of messages that will be kept in the
sub-board. Once this maximum number of messages is reached, the oldest
messages will be automatically purged. Usually, 100 messages is a
sufficient maximum.
*/
                uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Number of Messages"
                    ,str,9,K_EDIT|K_NUMBER);
                cfg.sub[i]->maxmsgs=atoi(str);
                cfg.sub[i]->misc|=SUB_HDRMOD;
				break;
			case 11:
				sprintf(str,"%u",cfg.sub[i]->maxage);
                SETHELP(WHERE);
/*
Maximum Age of Messages:

This value is the maximum number of days that messages will be kept in
the sub-board.
*/
                uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Age of Messages (in days)"
                    ,str,5,K_EDIT|K_NUMBER);
                cfg.sub[i]->maxage=atoi(str);
                cfg.sub[i]->misc|=SUB_HDRMOD;
				break;
			case 12:
				sprintf(str,"%lu",cfg.sub[i]->maxcrcs);
				SETHELP(WHERE);
/*
Maximum Number of CRCs:

This value is the maximum number of CRCs that will be kept in the
sub-board for duplicate message checking. Once this maximum number of
CRCs is reached, the oldest CRCs will be automatically purged.
*/
				uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Number of CRCs"
					,str,9,K_EDIT|K_NUMBER);
				cfg.sub[i]->maxcrcs=atol(str);
				cfg.sub[i]->misc|=SUB_HDRMOD;
                break;
			case 13:
				while(1) {
					n=0;
					sprintf(opt[n++],"%-27.27s%s","Allow Private Posts"
						,cfg.sub[i]->misc&SUB_PRIV ? cfg.sub[i]->misc&SUB_PONLY
						? "Only":"Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Allow Anonymous Posts"
						,cfg.sub[i]->misc&SUB_ANON ? cfg.sub[i]->misc&SUB_AONLY
						? "Only":"Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Post Using Real Names"
						,cfg.sub[i]->misc&SUB_NAME ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Users Can Edit Posts"
						,cfg.sub[i]->misc&SUB_EDIT ? cfg.sub[i]->misc&SUB_EDITLAST 
						? "Last" : "Yes" : "No");
					sprintf(opt[n++],"%-27.27s%s","Users Can Delete Posts"
						,cfg.sub[i]->misc&SUB_DEL ? cfg.sub[i]->misc&SUB_DELLAST
						? "Last" : "Yes" : "No");
					sprintf(opt[n++],"%-27.27s%s","Default On for New Scan"
						,cfg.sub[i]->misc&SUB_NSDEF ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Forced On for New Scan"
						,cfg.sub[i]->misc&SUB_FORCED ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Default On for Your Scan"
						,cfg.sub[i]->misc&SUB_SSDEF ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Public 'To' User"
						,cfg.sub[i]->misc&SUB_TOUSER ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Allow Message Quoting"
						,cfg.sub[i]->misc&SUB_QUOTE ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Suppress User Signatures"
						,cfg.sub[i]->misc&SUB_NOUSERSIG ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Permanent Operator Msgs"
						,cfg.sub[i]->misc&SUB_SYSPERM ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Kill Read Messages"
						,cfg.sub[i]->misc&SUB_KILL ? "Yes"
						: (cfg.sub[i]->misc&SUB_KILLP ? "Pvt" : "No"));
					sprintf(opt[n++],"%-27.27s%s","Compress Messages (LZH)"
						,cfg.sub[i]->misc&SUB_LZH ? "Yes" : "No");

					opt[n][0]=0;
					SETHELP(WHERE);
/*
Sub-board Toggle Options:

This menu allows you to toggle certain options for the selected
sub-board between two or more settings, such as Yes and No.
*/
					n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,2,36,&tog_dflt,0
						,"Toggle Options",opt);
					if(n==-1)
						break;
					switch(n) {
						case 0:
							if(cfg.sub[i]->misc&SUB_PONLY)
								n=2;
							else 
								n=(cfg.sub[i]->misc&SUB_PRIV) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							strcpy(opt[2],"Only");
							opt[3][0]=0;
							SETHELP(WHERE);
/*
Allow Private Posts on Sub-board:

If you want users to be able to post private messages to other users
on this sub-board, set this value to Yes. Usually, E-mail is the
preferred method of private communication. If you want users to be able
to post private messages only on this sub-board, select Only.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Allow Private Posts",opt);
							if(n==-1)
								break;
							if(!n && (cfg.sub[i]->misc&(SUB_PRIV|SUB_PONLY))
								!=SUB_PRIV) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_PONLY;
								cfg.sub[i]->misc|=SUB_PRIV;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_PRIV) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_PRIV;
								break; }
							if(n==2 && (cfg.sub[i]->misc&(SUB_PRIV|SUB_PONLY))
								!=(SUB_PRIV|SUB_PONLY)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=(SUB_PRIV|SUB_PONLY); }
							break;
						case 1:
							if(cfg.sub[i]->misc&SUB_AONLY)
								n=2;
							else 
								n=(cfg.sub[i]->misc&SUB_ANON) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							strcpy(opt[2],"Only");
							opt[3][0]=0;
							SETHELP(WHERE);
/*
Allow Anonymous Posts on Sub-board:

If you want users with the A exemption to be able to post anonymously on
this sub-board, select Yes. If you want all posts on this sub-board to be
forced anonymous, select Only. If you do not want anonymous posts allowed
on this sub-board at all, select No.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Allow Anonymous Posts",opt);
							if(n==-1)
								break;
							if(!n && (cfg.sub[i]->misc&(SUB_ANON|SUB_AONLY))
								!=SUB_ANON) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_AONLY;
								cfg.sub[i]->misc|=SUB_ANON;
								break; }
							if(n==1 && cfg.sub[i]->misc&(SUB_ANON|SUB_AONLY)) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~(SUB_ANON|SUB_AONLY);
								break; }
							if(n==2 && (cfg.sub[i]->misc&(SUB_ANON|SUB_AONLY))
								!=(SUB_ANON|SUB_AONLY)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=(SUB_ANON|SUB_AONLY); }
                            break;
						case 2:
							n=(cfg.sub[i]->misc&SUB_NAME) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
User Real Names in Posts on Sub-board:

If you allow aliases on your system, you can have messages on this
sub-board automatically use the real name of the posting user by setting
this option to Yes.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Use Real Names in Posts",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_NAME)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_NAME;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_NAME) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_NAME; }
							break;
						case 3:
							if(cfg.sub[i]->misc&SUB_EDITLAST)
								n=2;
							else
								n=(cfg.sub[i]->misc&SUB_EDIT) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							strcpy(opt[2],"Last Post Only");
							opt[3][0]=0;
							SETHELP(WHERE);
/*
Users Can Edit Posts on Sub-board:

If you wish to allow users to edit their messages after they have been
posted, this option to Yes. If you wish to allow users to edit only the
last message on a message base, set this option to Last Post Only.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Users Can Edit Messages",opt);
							if(n==-1)
                                break;
							if(n==0 /* yes */
								&& (cfg.sub[i]->misc&(SUB_EDIT|SUB_EDITLAST))
								!=SUB_EDIT
								) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_EDIT;
								cfg.sub[i]->misc&=~SUB_EDITLAST;
								break; 
							}
							if(n==1 /* no */
								&& cfg.sub[i]->misc&(SUB_EDIT|SUB_EDITLAST)
								) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~(SUB_EDIT|SUB_EDITLAST);
								break;
							}
							if(n==2 /* last only */
								&& (cfg.sub[i]->misc&(SUB_EDIT|SUB_EDITLAST))
								!=(SUB_EDIT|SUB_EDITLAST)
								) {
								uifc.changes=1;
								cfg.sub[i]->misc|=(SUB_EDIT|SUB_EDITLAST);
								break;
							}
                            break;
						case 4:
							if(cfg.sub[i]->misc&SUB_DELLAST)
								n=2;
							else 
								n=(cfg.sub[i]->misc&SUB_DEL) ? 0:1;

							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							strcpy(opt[2],"Last Post Only");
							opt[3][0]=0;
							SETHELP(WHERE);
/*
Users Can Delete Posts on Sub-board:

If you want users to be able to delete any of their own posts on this
sub-board, set this option to Yes. If you want to allow users the
ability to delete their message only if it is the last message on the
sub-board, select Last Post Only. If you want to disallow users from
deleting any of their posts, set this option to No.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Users Can Delete Posts",opt);
							if(n==-1)
								break;
							if(!n && (cfg.sub[i]->misc&(SUB_DEL|SUB_DELLAST))
								!=SUB_DEL) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_DELLAST;
								cfg.sub[i]->misc|=SUB_DEL;
								break; 
							}
							if(n==1 && cfg.sub[i]->misc&SUB_DEL) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_DEL;
								break; 
							}
							if(n==2 && (cfg.sub[i]->misc&(SUB_DEL|SUB_DELLAST))
								!=(SUB_DEL|SUB_DELLAST)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=(SUB_DEL|SUB_DELLAST); 
							}
                            break;
						case 5:
							n=(cfg.sub[i]->misc&SUB_NSDEF) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Default On for New Scan:

If you want this sub-board to be included in all user new message scans
by default, set this option to Yes.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Default On for New Scan",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_NSDEF)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_NSDEF;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_NSDEF) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_NSDEF; }
                            break;
						case 6:
							n=(cfg.sub[i]->misc&SUB_FORCED) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Forced On for New Scan:

If you want this sub-board to be included in all user new message scans
even if the user has removed it from their new scan configuration, set
this option to Yes.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Forced New Scan",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_FORCED)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_FORCED;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_FORCED) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_FORCED; }
                            break;
						case 7:
							n=(cfg.sub[i]->misc&SUB_SSDEF) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Default On for Your Scan:

If you want this sub-board to be included in all user personal message
scans by default, set this option to Yes.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Default On for Your Scan",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_SSDEF)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_SSDEF;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_SSDEF) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_SSDEF; }
                            break;
						case 8:
							n=(cfg.sub[i]->misc&SUB_TOUSER) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Prompt for 'To' User on Public Posts:

If you want all posts on this sub-board to be prompted for a 'To' user,
set this option to Yes. This is a useful option for sub-boards that
are on a network that does not allow private posts.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Prompt for 'To' User on Public Posts",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_TOUSER)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_TOUSER;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_TOUSER) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_TOUSER; }
							break;
						case 9:
							n=(cfg.sub[i]->misc&SUB_QUOTE) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Allow Message Quoting:

If you want users to be allowed to quote messages on this sub-board, set
this option to Yes.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Allow Message Quoting",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_QUOTE)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_QUOTE;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_QUOTE) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_QUOTE; }
                            break;
						case 10:
							n=(cfg.sub[i]->misc&SUB_NOUSERSIG) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Suppress User Signatures:

If you do not wish to have user signatures automatically appended to
messages posted in this sub-board, set this option to Yes.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Suppress User Signatures",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_NOUSERSIG)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_NOUSERSIG;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_NOUSERSIG) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_NOUSERSIG; }
                            break;
						case 11:
							n=(cfg.sub[i]->misc&SUB_SYSPERM) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Operator Messages Automatically Permanent:

If you want messages posted by System and Sub-board Operators to be
automatically permanent (non-purgable) for this sub-board, set this
option to Yes.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Permanent Operator Messages",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_SYSPERM)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_SYSPERM;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_SYSPERM) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_SYSPERM; }
                            break;
						case 12:
							if(cfg.sub[i]->misc&SUB_KILLP)
								n=2;
							else
								n=(cfg.sub[i]->misc&SUB_KILL) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							strcpy(opt[2],"Private");
							opt[3][0]=0;
							SETHELP(WHERE);
/*
Kill Read Messages Automatically:

If you want messages that have been read by the intended recipient to
be automatically deleted by SMBUTIL, set this option to Yes or
Private if you want only private messages to be automatically deleted.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Kill Read Messages",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_KILL)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_KILL;
								cfg.sub[i]->misc&=~SUB_KILLP;
								break; }
							if(n==1 && cfg.sub[i]->misc&(SUB_KILL|SUB_KILLP)) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~(SUB_KILL|SUB_KILLP); }
							if(n==2 && !(cfg.sub[i]->misc&SUB_KILLP)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_KILLP;
								cfg.sub[i]->misc&=~SUB_KILL;
                                break; }
                            break;
						case 13:
							n=(cfg.sub[i]->misc&SUB_LZH) ? 0:1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Compress Messages with LZH Encoding:

If you want all messages in this sub-board to be automatically
compressed via LZH (Lempel/Ziv/Huffman algorithm used in LHarc, LHA,
and other popular compression and archive programs), this option to Yes.

Compression will slow down the reading and writing of messages slightly,
but the storage space saved can be as much as 50 percent.

Before setting this option to Yes, make sure that all of the SMB
compatible mail programs you use support the LZH translation.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Compress Messages (LZH)",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_LZH)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_LZH;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_LZH) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_LZH; }
                            break;

							} }
				break;
			case 14:
				while(1) {
					n=0;
					sprintf(opt[n++],"%-27.27s%s","Append Tag/Origin Line"
						,cfg.sub[i]->misc&SUB_NOTAG ? "No":"Yes");
					sprintf(opt[n++],"%-27.27s%s","Export ASCII Only"
						,cfg.sub[i]->misc&SUB_ASCII ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","Gate Between Net Types"
						,cfg.sub[i]->misc&SUB_GATE ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","QWK Networked"
						,cfg.sub[i]->misc&SUB_QNET ? "Yes":"No");
					sprintf(opt[n++],"QWK Tagline");
					sprintf(opt[n++],"%-27.27s%s","Internet (UUCP/NNTP)"
						,cfg.sub[i]->misc&SUB_INET ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","PostLink or PCRelay"
                        ,cfg.sub[i]->misc&SUB_PNET ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","FidoNet EchoMail"
						,cfg.sub[i]->misc&SUB_FIDO ? "Yes":"No");
					sprintf(opt[n++],"%-27.27s%s","FidoNet Address"
                        ,smb_faddrtoa(&cfg.sub[i]->faddr,tmp));
					sprintf(opt[n++],"EchoMail Origin Line");
					opt[n][0]=0;
					SETHELP(WHERE);
/*
Sub-board Network Options:

This menu contains options for the selected sub-board that pertain
specifically to message networking.
*/
					n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,2,60,&net_dflt,0
						,"Network Options",opt);
					if(n==-1)
						break;
                    switch(n) {
						case 0:
							n=0;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Append Tag/Origin Line to Posts:

If you want to disable the automatic addition of a network tagline or
origin line to the bottom of outgoing networked posts from this
sub-board, set this option to No.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Append Tag/Origin Line to Posts",opt);
							if(n==-1)
                                break;
							if(!n && cfg.sub[i]->misc&SUB_NOTAG) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_NOTAG;
								break; }
							if(n==1 && !(cfg.sub[i]->misc&SUB_NOTAG)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_NOTAG; }
                            break;
						case 1:
							n=0;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Export ASCII Characters Only:

If the network that this sub-board is echoed on does not allow extended
ASCII (>127) or control codes (<20, not including CR), set this option
to Yes.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Export ASCII Characters Only",opt);
							if(n==-1)
                                break;
							if(n && cfg.sub[i]->misc&SUB_ASCII) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_ASCII;
								break; }
							if(!n && !(cfg.sub[i]->misc&SUB_ASCII)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_ASCII; }
                            break;
						case 2:
							n=1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Gate Between Net Types:

If this sub-board is networked using more than one network technology,
and you want messages to be gated between the networks, set this
option to Yes.

If this option is set to No, messages imported from one network type
will not be exported to another network type. This is the default and
should be used unless you have specific permission from both networks
to gate this sub-board. Incorrectly gated sub-boards can cause duplicate
messages loops and cross-posted messages.

This option does not affect the exporting of messages created on your
BBS.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Gate Between Net Types",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_GATE)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_GATE;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_GATE) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_GATE; }
                            break;
						case 3:
							n=1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Sub-board Networked via QWK Packets:

If this sub-board is networked with other BBSs via QWK packets, this
option should be set to Yes. With this option set to Yes, titles of
posts on this sub-board will be limited to the QWK packet limitation of
25 characters. It also allows the Network restriction to function
properly.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Networked via QWK Packets",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_QNET)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_QNET;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_QNET) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_QNET; }
                            break;
						case 4:
							SETHELP(WHERE);
/*
Sub-board QWK Network Tagline:

If you want to use a different QWK tagline than the configured default
tagline in the Networks configuration, you should enter that tagline
here. If this option is left blank, the default tagline is used.
*/
							uifc.input(WIN_MID|WIN_SAV,0,0,nulstr,cfg.sub[i]->tagline
								,sizeof(cfg.sub[i]->tagline)-1,K_MSG|K_EDIT);
							break;
						case 5:
							n=1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Sub-board Networked via Internet:

If this sub-board is networked to the Internet via UUCP or NNTP, this
option should be set to Yes.

It will allow the Network user restriction to function properly.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Networked via Internet",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_INET)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_INET;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_INET) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_INET; }
                            break;
						case 6:
                            n=1;
                            strcpy(opt[0],"Yes");
                            strcpy(opt[1],"No");
                            opt[2][0]=0;
                            SETHELP(WHERE);
/*
Sub-board Networked via PostLink or PCRelay:

If this sub-board is networked with other BBSs via PostLink or PCRelay,
this option should be set to Yes. With this option set to Yes,
titles of posts on this sub-board will be limited to the UTI
specification limitation of 25 characters. It also allows the Network
restriction to function properly.
*/
                            n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
                                ,"Networked via PostLink or PCRelay",opt);
                            if(n==-1)
                                break;
                            if(!n && !(cfg.sub[i]->misc&SUB_PNET)) {
                                uifc.changes=1;
                                cfg.sub[i]->misc|=SUB_PNET;
                                break; }
                            if(n==1 && cfg.sub[i]->misc&SUB_PNET) {
                                uifc.changes=1;
                                cfg.sub[i]->misc&=~SUB_PNET; }
                            break;
						case 7:
							n=1;
							strcpy(opt[0],"Yes");
							strcpy(opt[1],"No");
							opt[2][0]=0;
							SETHELP(WHERE);
/*
Sub-board Networked via FidoNet EchoMail:

If this sub-board is part of a FidoNet EchoMail conference, set this
option to Yes.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Networked via FidoNet EchoMail",opt);
							if(n==-1)
                                break;
							if(!n && !(cfg.sub[i]->misc&SUB_FIDO)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_FIDO;
								break; }
							if(n==1 && cfg.sub[i]->misc&SUB_FIDO) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~SUB_FIDO; }
                            break;
						case 8:
							smb_faddrtoa(&cfg.sub[i]->faddr,str);
							SETHELP(WHERE);
/*
Sub-board FidoNet Address:

If this sub-board is part of a FidoNet EchoMail conference, this is
the address used for this sub-board. Format: Zone:Net/Node[.Point]
*/
							uifc.input(WIN_MID|WIN_SAV,0,0,"FidoNet Address"
								,str,25,K_EDIT);
							cfg.sub[i]->faddr=atofaddr(str);
							break;
						case 9:
							SETHELP(WHERE);
/*
Sub-board FidoNet Origin Line:

If this sub-board is part of a FidoNet EchoMail conference and you
want to use an origin line other than the default origin line in the
Networks configuration, set this value to the desired origin line.

If this option is blank, the default origin line is used.
*/
							uifc.input(WIN_MID|WIN_SAV,0,0,nulstr,cfg.sub[i]->origline
								,sizeof(cfg.sub[i]->origline)-1,K_EDIT);
                            break;
					} 
				}
				break;
			case 15:
				while(1) {
					n=0;
					if(cfg.sub[i]->qwkconf)
						sprintf(str,"Static (%u)",cfg.sub[i]->qwkconf);
					else
						strcpy(str,"Dynamic");
					sprintf(opt[n++],"%-27.27s%s","QWK Conference Number"
						,str);
					sprintf(opt[n++],"%-27.27s%s","Storage Method"
						,cfg.sub[i]->misc&SUB_HYPER ? "Hyper Allocation"
						: cfg.sub[i]->misc&SUB_FAST ? "Fast Allocation"
						: "Self-packing");
					if(!cfg.sub[i]->data_dir[0])
						sprintf(str,"%ssubs/",cfg.data_dir);
					else
						strcpy(str,cfg.sub[i]->data_dir);
					sprintf(opt[n++],"%-27.27s%.40s","Storage Directory",str);
					sprintf(opt[n++],"%-27.27s%.40s","Semaphore File",cfg.sub[i]->post_sem);
					sprintf(opt[n++],"%-27.27s%u","Pointer File Index",cfg.sub[i]->ptridx);
					opt[n][0]=0;
					SETHELP(WHERE);
/*
Sub-board Advanced Options:

This menu contains options for the selected sub-board that are advanced
in nature.
*/
					n=uifc.list(WIN_ACT|WIN_SAV|WIN_RHT|WIN_BOT,3,2,60,&adv_dflt,0
						,"Advanced Options",opt);
					if(n==-1)
						break;
                    switch(n) {
                        case 0:
							SETHELP(WHERE);
/*
Sub-board QWK Conference Number:

If you wish to have the QWK conference number for this sub-board
automatically generated by Synchronet (based on the group number
and sub-board number for the user), set this option to Dynamic.

If you wish to have the same QWK conference number for this sub-board
regardless of which user access it, set this option to Static
by entering the conference number you want to use.
*/
							if(cfg.sub[i]->qwkconf)
								sprintf(str,"%u",cfg.sub[i]->qwkconf);
							else
								str[0]=0;
							if(uifc.input(WIN_MID|WIN_SAV,0,17
								,"QWK Conference Number (0=Dynamic)"
								,str,5,K_EDIT|K_NUMBER)>=0)
								cfg.sub[i]->qwkconf=atoi(str);
							break;
						case 1:
							n=0;
							strcpy(opt[0],"Hyper Allocation");
							strcpy(opt[1],"Fast Allocation");
							strcpy(opt[2],"Self-packing");
							opt[3][0]=0;
							SETHELP(WHERE);
/*
Self-Packing is the slowest storage method because it conserves disk
  space as it imports messages by using deleted message header and data
  blocks for new messages automatically. If you use this storage method,
  you will not need to run SMBUTIL P on this message base unless you
  accumilate a large number of deleted message blocks and wish to free
  that disk space. You can switch from self-packing to fast allocation
  storage method and back again as you wish.
Fast Allocation is faster than self-packing because it does not search
  for deleted message blocks for new messages. It automatically places
  all new message blocks at the end of the header and data files. If you
  use this storage method, you will need to run SMBUTIL P on this
  message base periodically or it will continually use up disk space.
Hyper Allocation is the fastest storage method because it does not
  maintain allocation files at all. Once a message base is setup to use
  this storage method, it should not be changed without first deleting
  the message base data files in your DATA\DIRS\SUBS directory for this
  sub-board. You must use SMBUTIL P as with the fast allocation method.
*/
							n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
								,"Storage Method",opt);
							if(n==-1)
								break;
							if(!n && !(cfg.sub[i]->misc&SUB_HYPER)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_HYPER;
								cfg.sub[i]->misc&=~SUB_FAST;
								cfg.sub[i]->misc|=SUB_HDRMOD;
								break; }
							if(!n)
								break;
							if(cfg.sub[i]->misc&SUB_HYPER) {	/* Switching from hyper */
								strcpy(opt[0],"Yes");
								strcpy(opt[1],"No, I want to use Hyper Allocation");
								opt[2][0]=0;
								m=0;
								if(uifc.list(WIN_SAV|WIN_MID,0,0,0,&m,0
									,"Delete all messages in this sub-board?",opt)!=0)
									break;
								if(cfg.sub[i]->data_dir[0])
									sprintf(str,"%s",cfg.sub[i]->data_dir);
								else
									sprintf(str,"%ssubs/",cfg.data_dir);
								sprintf(str2,"%s%s.*"
									,cfg.grp[cfg.sub[i]->grp]->code_prefix
									,cfg.sub[i]->code_suffix);
								strlwr(str2);
								delfiles(str,str2); 
							}

							if(cfg.sub[i]->misc&SUB_HYPER)
								cfg.sub[i]->misc|=SUB_HDRMOD;
							if(n==1 && !(cfg.sub[i]->misc&SUB_FAST)) {
								uifc.changes=1;
								cfg.sub[i]->misc|=SUB_FAST;
								cfg.sub[i]->misc&=~SUB_HYPER;
								break; 
							}
							if(n==2 && cfg.sub[i]->misc&(SUB_FAST|SUB_HYPER)) {
								uifc.changes=1;
								cfg.sub[i]->misc&=~(SUB_FAST|SUB_HYPER);
								break; 
							}
							break;
						case 2:
							SETHELP(WHERE);
/*
Sub-board Storage Directory:

Use this if you wish to place the data directory for this sub-board on
another drive or in another directory besides the default setting.
*/
							uifc.input(WIN_MID|WIN_SAV,0,17,"Directory"
								,cfg.sub[i]->data_dir,sizeof(cfg.sub[i]->data_dir)-1,K_EDIT);
							break; 
						case 3:
							SETHELP(WHERE);
/*
`Sub-board Semaphore File:`

This is a filename that will be created as a semaphore (signal) to an
external program or event whenever a message is posted in this sub-board.
*/
							uifc.input(WIN_MID|WIN_SAV,0,17,"Semaphore File"
								,cfg.sub[i]->post_sem,sizeof(cfg.sub[i]->post_sem)-1,K_EDIT);
							break; 
						case 4:
							SETHELP(WHERE);
/*
`Sub-board Pointer Index:`

You should normally have no reason to modify this value. If you get
crossed-up or duplicate ptridx values, then you may want to adjust
this value, but do so with great care and trepidation.
*/
							sprintf(str,"%u",cfg.sub[i]->ptridx);
							if(uifc.input(WIN_MID|WIN_SAV,0,17
								,"Pointer File Index (Danger!)"
								,str,5,K_EDIT|K_NUMBER)>=0)
								cfg.sub[i]->ptridx=atoi(str);
							break;

					} 
				}
				break;
			} 
		} 
	}
}
예제 #3
0
void chan_cfg()
{
	static int chan_dflt,chan_bar,opt_dflt;
	char str[128],code[128],done=0;
	int j,k;
	uint i;
	static chan_t savchan;

while(1) {
	for(i=0;i<cfg.total_chans && i<MAX_OPTS;i++)
		sprintf(opt[i],"%-25s",cfg.chan[i]->name);
	opt[i][0]=0;
	j=WIN_ACT|WIN_SAV|WIN_BOT|WIN_RHT;
	if(cfg.total_chans)
		j|=WIN_DEL|WIN_GET;
	if(cfg.total_chans<MAX_OPTS)
		j|=WIN_INS|WIN_INSACT|WIN_XTR;
	if(savchan.name[0])
		j|=WIN_PUT;
	uifc.helpbuf=
		"`Multinode Chat Channels:`\n"
		"\n"
		"This is a list of the configured multinode chat channels.\n"
		"\n"
		"To add a channel, select the desired location with the arrow keys and\n"
		"hit ~ INS ~.\n"
		"\n"
		"To delete a channel, select it with the arrow keys and hit ~ DEL ~.\n"
		"\n"
		"To configure a channel, select it with the arrow keys and hit ~ ENTER ~.\n"
	;
	i=uifc.list(j,0,0,45,&chan_dflt,&chan_bar,"Multinode Chat Channels",opt);
	if((signed)i==-1)
		return;
	if((i&MSK_ON)==MSK_INS) {
		i&=MSK_OFF;
		strcpy(str,"Open");
		uifc.helpbuf=
			"`Channel Name:`\n"
			"\n"
			"This is the name or description of the chat channel.\n"
		;
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Chat Channel Name",str,25
			,K_EDIT)<1)
            continue;
		SAFECOPY(code,str);
		prep_code(code,/* prefix: */NULL);
		uifc.helpbuf=
			"`Chat Channel Internal Code:`\n"
			"\n"
			"Every chat channel must have its own unique code for Synchronet to refer\n"
			"to it internally. This code is usually an abreviation of the chat\n"
			"channel name.\n"
		;
		if(uifc.input(WIN_MID|WIN_SAV,0,0,"Internal Code"
			,code,LEN_CODE,K_EDIT|K_UPPER)<1)
			continue;
		if(!code_ok(code)) {
			uifc.helpbuf=invalid_code;
			uifc.msg("Invalid Code");
			uifc.helpbuf=0;
            continue; 
		}
		if((cfg.chan=(chan_t **)realloc(cfg.chan,sizeof(chan_t *)*(cfg.total_chans+1)))
            ==NULL) {
            errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_chans+1);
			cfg.total_chans=0;
			bail(1);
            continue; 
		}
		if(cfg.total_chans)
			for(j=cfg.total_chans;j>i;j--)
				cfg.chan[j]=cfg.chan[j-1];
		if((cfg.chan[i]=(chan_t *)malloc(sizeof(chan_t)))==NULL) {
			errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(chan_t));
			continue; 
		}
		memset((chan_t *)cfg.chan[i],0,sizeof(chan_t));
		strcpy(cfg.chan[i]->name,str);
		strcpy(cfg.chan[i]->code,code);
		cfg.total_chans++;
		uifc.changes=1;
		continue; 
	}
	if((i&MSK_ON)==MSK_DEL) {
		i&=MSK_OFF;
		free(cfg.chan[i]);
		cfg.total_chans--;
		for(j=i;j<cfg.total_chans;j++)
			cfg.chan[j]=cfg.chan[j+1];
		uifc.changes=1;
		continue; 
	}
	if((i&MSK_ON)==MSK_GET) {
		i&=MSK_OFF;
		savchan=*cfg.chan[i];
		continue; 
	}
	if((i&MSK_ON)==MSK_PUT) {
		i&=MSK_OFF;
		*cfg.chan[i]=savchan;
		uifc.changes=1;
        continue; 
	}
    j=0;
	done=0;
	while(!done) {
		k=0;
		sprintf(opt[k++],"%-27.27s%s","Name",cfg.chan[i]->name);
		sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.chan[i]->code);
		sprintf(opt[k++],"%-27.27s%"PRIu32,"Cost in Credits",cfg.chan[i]->cost);
		sprintf(opt[k++],"%-27.27s%.40s","Access Requirements"
			,cfg.chan[i]->arstr);
		sprintf(opt[k++],"%-27.27s%s","Password Protection"
			,cfg.chan[i]->misc&CHAN_PW ? "Yes" : "No");
		sprintf(opt[k++],"%-27.27s%s","Guru Joins When Empty"
			,cfg.chan[i]->misc&CHAN_GURU ? "Yes" : "No");
		sprintf(opt[k++],"%-27.27s%s","Channel Guru"
			,cfg.chan[i]->guru<cfg.total_gurus ? cfg.guru[cfg.chan[i]->guru]->name : "");
        sprintf(opt[k++],"%-27.27s%s","Channel Action Set"
            ,cfg.actset[cfg.chan[i]->actset]->name);
		opt[k][0]=0;
		uifc.helpbuf=
			"`Chat Channel Configuration:`\n"
			"\n"
			"This menu is for configuring the selected chat channel.\n"
		;
		sprintf(str,"%s Chat Channel",cfg.chan[i]->name);
		switch(uifc.list(WIN_ACT|WIN_MID|WIN_SAV,0,0,60,&opt_dflt,0,str,opt)) {
			case -1:
				done=1;
				break;
			case 0:
				uifc.helpbuf=
					"`Chat Channel Name:`\n"
					"\n"
					"This is the name or description of the chat channel.\n"
				;
				strcpy(str,cfg.chan[i]->name);
				if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Chat Channel Name"
					,cfg.chan[i]->name,sizeof(cfg.chan[i]->name)-1,K_EDIT))
					strcpy(cfg.chan[i]->name,str);
				break;
			case 1:
				uifc.helpbuf=
					"`Chat Channel Internal Code:`\n"
					"\n"
					"Every chat channel must have its own unique code for Synchronet to refer\n"
					"to it internally. This code is usually an abreviation of the chat\n"
					"channel name.\n"
				;
				strcpy(str,cfg.chan[i]->code);
				if(!uifc.input(WIN_MID|WIN_SAV,0,10,"Internal Code"
					,str,LEN_CODE,K_UPPER|K_EDIT))
					break;
				if(code_ok(str))
					strcpy(cfg.chan[i]->code,str);
				else {
					uifc.helpbuf=invalid_code;
					uifc.msg("Invalid Code");
                    uifc.helpbuf=0; 
				}
                break;
			case 2:
				ultoa(cfg.chan[i]->cost,str,10);
                uifc.helpbuf=
	                "`Chat Channel Cost to Join:`\n"
	                "\n"
	                "If you want users to be charged credits to join this chat channel, set\n"
	                "this value to the number of credits to charge. If you want this channel\n"
	                "to be free, set this value to `0`.\n"
                ;
				uifc.input(WIN_MID|WIN_SAV,0,0,"Cost to Join (in Credits)"
                    ,str,10,K_EDIT|K_NUMBER);
				cfg.chan[i]->cost=atol(str);
                break;
			case 3:
				sprintf(str,"%s Chat Channel",cfg.chan[i]->name);
				getar(str,cfg.chan[i]->arstr);
				break;
			case 4:
				k=1;
				uifc.helpbuf=
					"`Allow Channel to be Password Protected:`\n"
					"\n"
					"If you want to allow the first user to join this channel to password\n"
					"protect it, set this option to `Yes`.\n"
				;
				k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
					,"Allow Channel to be Password Protected"
					,uifcYesNoOpts);
				if(!k && !(cfg.chan[i]->misc&CHAN_PW)) {
					cfg.chan[i]->misc|=CHAN_PW;
					uifc.changes=1; 
				}
				else if(k==1 && cfg.chan[i]->misc&CHAN_PW) {
					cfg.chan[i]->misc&=~CHAN_PW;
					uifc.changes=1; 
				}
				break;
			case 5:
				k=1;
				uifc.helpbuf=
					"`Guru Joins This Channel When Empty:`\n"
					"\n"
					"If you want the system guru to join this chat channel when there is\n"
					"only one user, set this option to `Yes`.\n"
				;
				k=uifc.list(WIN_MID|WIN_SAV,0,0,0,&k,0
					,"Guru Joins This Channel When Empty"
					,uifcYesNoOpts);
				if(!k && !(cfg.chan[i]->misc&CHAN_GURU)) {
					cfg.chan[i]->misc|=CHAN_GURU;
					uifc.changes=1; 
				}
				else if(k==1 && cfg.chan[i]->misc&CHAN_GURU) {
					cfg.chan[i]->misc&=~CHAN_GURU;
					uifc.changes=1; 
				}
				break;
			case 6:
uifc.helpbuf=
	"`Channel Guru:`\n"
	"\n"
	"This is a list of available chat Gurus.  Select the one that you wish\n"
	"to have available in this channel.\n"
;
				k=0;
				for(j=0;j<cfg.total_gurus && j<MAX_OPTS;j++)
					sprintf(opt[j],"%-25s",cfg.guru[j]->name);
				opt[j][0]=0;
				k=uifc.list(WIN_SAV|WIN_RHT,0,0,25,&j,0
					,"Available Chat Gurus",opt);
				if(k==-1)
					break;
				cfg.chan[i]->guru=k;
				break;
			case 7:
uifc.helpbuf=
	"`Channel Action Set:`\n"
	"\n"
	"This is a list of available chat action sets.  Select the one that you\n"
	"wish to have available in this channel.\n"
;
				k=0;
				for(j=0;j<cfg.total_actsets && j<MAX_OPTS;j++)
					sprintf(opt[j],"%-25s",cfg.actset[j]->name);
				opt[j][0]=0;
				k=uifc.list(WIN_SAV|WIN_RHT,0,0,25,&j,0
					,"Available Chat Action Sets",opt);
				if(k==-1)
					break;
				uifc.changes=1;
				cfg.chan[i]->actset=k;
				break; 
			} 
		} 
	}
}
예제 #4
0
void msg_opts()
{
	char str[128],*p;
	static int msg_dflt;
	int i,j,n;

	while(1) {
		i=0;
		sprintf(opt[i++],"%-33.33s%s"
			,"BBS ID for QWK Packets",cfg.sys_id);
		sprintf(opt[i++],"%-33.33s%s"
			,"Local Time Zone",smb_zonestr(cfg.sys_timezone,NULL));
		sprintf(opt[i++],"%-33.33s%u seconds"
			,"Maximum Retry Time",cfg.smb_retry_time);
		if(cfg.max_qwkmsgs)
			sprintf(str,"%"PRIu32,cfg.max_qwkmsgs);
		else
			sprintf(str,"Unlimited");
		sprintf(opt[i++],"%-33.33s%s"
			,"Maximum QWK Messages",str);
		if(cfg.max_qwkmsgage)
			sprintf(str,"%u days",cfg.max_qwkmsgage);
		else
			sprintf(str,"Unlimited");
		sprintf(opt[i++],"%-33.33s%s"
			,"Maximum QWK Message Age",str);
		sprintf(opt[i++],"%-33.33s%s","Pre-pack QWK Requirements",cfg.preqwk_arstr);
		if(cfg.mail_maxage)
			sprintf(str,"Enabled (%u days old)",cfg.mail_maxage);
        else
            strcpy(str,"Disabled");
		sprintf(opt[i++],"%-33.33s%s","Purge E-mail by Age",str);
		if(cfg.sys_misc&SM_DELEMAIL)
			strcpy(str,"Immediately");
		else
			strcpy(str,"Daily");
		sprintf(opt[i++],"%-33.33s%s","Purge Deleted E-mail",str);
		if(cfg.mail_maxcrcs)
			sprintf(str,"Enabled (%"PRIu32" mail CRCs)",cfg.mail_maxcrcs);
		else
			strcpy(str,"Disabled");
		sprintf(opt[i++],"%-33.33s%s","Duplicate E-mail Checking",str);
		sprintf(opt[i++],"%-33.33s%s","Allow Anonymous E-mail"
			,cfg.sys_misc&SM_ANON_EM ? "Yes" : "No");
		sprintf(opt[i++],"%-33.33s%s","Allow Quoting in E-mail"
			,cfg.sys_misc&SM_QUOTE_EM ? "Yes" : "No");
		sprintf(opt[i++],"%-33.33s%s","Allow Uploads in E-mail"
			,cfg.sys_misc&SM_FILE_EM ? "Yes" : "No");
		sprintf(opt[i++],"%-33.33s%s","Allow Forwarding to NetMail"
			,cfg.sys_misc&SM_FWDTONET ? "Yes" : "No");
		sprintf(opt[i++],"%-33.33s%s","Kill Read E-mail"
			,cfg.sys_misc&SM_DELREADM ? "Yes" : "No");
		sprintf(opt[i++],"%-33.33s%s","Receive E-mail by Real Name"
			,cfg.msg_misc&MM_REALNAME ? "Yes" : "No");
		sprintf(opt[i++],"%-33.33s%s","Include Signatures in E-mail"
			,cfg.msg_misc&MM_EMAILSIG ? "Yes" : "No");
		sprintf(opt[i++],"%-33.33s%s","Users Can View Deleted Messages"
			,cfg.sys_misc&SM_USRVDELM ? "Yes" : cfg.sys_misc&SM_SYSVDELM
				? "Sysops Only":"No");
		strcpy(opt[i++],"Extra Attribute Codes...");
		opt[i][0]=0;
		uifc.helpbuf=
			"`Message Options:`\n"
			"\n"
			"This is a menu of system-wide message related options. Messages include\n"
			"E-mail and public posts (on sub-boards).\n"
		;

		switch(uifc.list(WIN_ORG|WIN_ACT|WIN_MID|WIN_CHE,0,0,72,&msg_dflt,0
			,"Message Options",opt)) {
			case -1:
				i=save_changes(WIN_MID);
				if(i==-1)
				   continue;
				if(!i) {
					cfg.new_install=new_install;
					write_msgs_cfg(&cfg,backup_level);
					write_main_cfg(&cfg,backup_level);
                    refresh_cfg(&cfg);
                }
				return;
			case 0:
				strcpy(str,cfg.sys_id);
				uifc.helpbuf=
					"`BBS ID for QWK Packets:`\n"
					"\n"
					"This is a short system ID for your BBS that is used for QWK packets.\n"
					"It should be an abbreviation of your BBS name or other related string.\n"
					"This ID will be used for your outgoing and incoming QWK packets. If\n"
					"you plan on networking via QWK packets with another Synchronet BBS,\n"
					"this ID should not begin with a number. The maximum length of the ID\n"
					"is eight characters and cannot contain spaces or other invalid DOS\n"
					"filename characters. In a QWK packet network, each system must have\n"
					"a unique QWK system ID.\n"
				;

				uifc.input(WIN_MID|WIN_SAV,0,0,"BBS ID for QWK Packets"
					,str,LEN_QWKID,K_EDIT|K_UPPER);
				if(code_ok(str))
					strcpy(cfg.sys_id,str);
				else
					uifc.msg("Invalid ID");
				break;
			case 1:
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				i=0;
				uifc.helpbuf=
					"`United States Time Zone:`\n"
					"\n"
					"If your local time zone is the United States, select `Yes`.\n"
				;

				i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
					,"United States Time Zone",opt);
				if(i==-1)
					break;
				if(i==0) {
					strcpy(opt[i++],"Atlantic");
					strcpy(opt[i++],"Eastern");
					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;
					i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
						,"Time Zone",opt);
					if(i==-1)
						break;
					uifc.changes=1;
					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;
						case 4:
							cfg.sys_timezone=PST;
                            break;
						case 5:
							cfg.sys_timezone=YST;
                            break;
						case 6:
							cfg.sys_timezone=HST;
                            break;
						case 7:
							cfg.sys_timezone=BST;
							break; 
					}
					strcpy(opt[0],"Yes");
					strcpy(opt[1],"No");
					opt[2][0]=0;
					i=1;
					i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
						,"Daylight Savings",opt);
					if(i==-1)
                        break;
					if(!i)
						cfg.sys_timezone|=DAYLIGHT;
					break; 
				}
				i=0;
				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++],"London");
				strcpy(opt[i++],"Berlin");
				strcpy(opt[i++],"Athens");
				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++],"Sydney");
				strcpy(opt[i++],"Noumea");
				strcpy(opt[i++],"Wellington");
				strcpy(opt[i++],"Other...");
				opt[i][0]=0;
				i=0;
				i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
					,"Time Zone",opt);
				if(i==-1)
					break;
				uifc.changes=1;
				switch(i) {
					case 0:
						cfg.sys_timezone=MID;
						break;
					case 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=LON;
                        break;
					case 10:
						cfg.sys_timezone=BER;
                        break;
					case 11:
						cfg.sys_timezone=ATH;
                        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=SYD;
                        break;
					case 23:
						cfg.sys_timezone=NOU;
                        break;
					case 24:
						cfg.sys_timezone=WEL;
                        break;
					default:
						if(cfg.sys_timezone>720 || cfg.sys_timezone<-720)
							cfg.sys_timezone=0;
						sprintf(str,"%02d:%02d"
							,cfg.sys_timezone/60,cfg.sys_timezone<0
							? (-cfg.sys_timezone)%60 : cfg.sys_timezone%60);
						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;
						p=strchr(str,':');
						if(p) {
							if(cfg.sys_timezone<0)
								cfg.sys_timezone-=atoi(p+1);
							else
								cfg.sys_timezone+=atoi(p+1); 
						}
                        break;
						}
                break;
			case 2:
				uifc.helpbuf=
					"`Maximum Message Base Retry Time:`\n"
					"\n"
					"This is the maximum number of seconds to allow while attempting to open\n"
					"or lock a message base (a value in the range of 10 to 45 seconds should\n"
					"be fine).\n"
				;
				ultoa(cfg.smb_retry_time,str,10);
				uifc.input(WIN_MID|WIN_SAV,0,0
					,"Maximum Message Base Retry Time (in seconds)"
					,str,2,K_NUMBER|K_EDIT);
				cfg.smb_retry_time=atoi(str);
				break;
			case 3:
				uifc.helpbuf=
					"`Maximum Messages Per QWK Packet:`\n"
					"\n"
					"This is the maximum number of messages (excluding E-mail), that a user\n"
					"can have in one QWK packet for download. This limit does not effect\n"
					"QWK network nodes (`Q` restriction). If set to `0`, no limit is imposed.\n"
				;

				ultoa(cfg.max_qwkmsgs,str,10);
				uifc.input(WIN_MID|WIN_SAV,0,0
					,"Maximum Messages Per QWK Packet (0=No Limit)"
					,str,6,K_NUMBER|K_EDIT);
				cfg.max_qwkmsgs=atol(str);
                break;
			case 4:
				uifc.helpbuf=
					"`Maximum Age of Messages Imported From QWK Packets:`\n"
					"\n"
					"This is the maximum age of messages (in days), allowed for messages in\n"
					"QWK packets. Messages with an age older than this value will not be\n"
					"imported. If set to `0`, no age limit is imposed.\n"
				;

				itoa(cfg.max_qwkmsgage,str,10);
				uifc.input(WIN_MID|WIN_SAV,0,0
					,"Maximum Age (in days) of QWK-imported Messages (0=No Limit)"
					,str,4,K_NUMBER|K_EDIT);
				cfg.max_qwkmsgage=atoi(str);
                break;
			case 5:
				uifc.helpbuf=
					"`Pre-pack QWK Requirements:`\n"
					"\n"
					"ALL user accounts on the BBS meeting this requirmenet will have a QWK\n"
					"packet automatically created for them every day after midnight\n"
					"(during the internal daily event).\n"
					"\n"
					"This is mainly intended for QWK network nodes that wish to save connect\n"
					"time by having their packets pre-packed. If a large number of users meet\n"
					"this requirement, it can take up a large amount of disk space on your\n"
					"system (in the `DATA\\FILE` directory).\n"
				;
				getar("Pre-pack QWK (Use with caution!)",cfg.preqwk_arstr);
				break;
			case 6:
				sprintf(str,"%u",cfg.mail_maxage);
                uifc.helpbuf=
	                "`Maximum Age of Mail:`\n"
	                "\n"
	                "This value is the maximum number of days that mail will be kept.\n"
                ;
                uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Age of Mail "
                    "(in days)",str,5,K_EDIT|K_NUMBER);
                cfg.mail_maxage=atoi(str);
                break;
			case 7:
				strcpy(opt[0],"Daily");
				strcpy(opt[1],"Immediately");
				opt[2][0]=0;
				i=cfg.sys_misc&SM_DELEMAIL ? 0:1;
				uifc.helpbuf=
					"`Purge Deleted E-mail:`\n"
					"\n"
					"If you wish to have deleted e-mail physically (and permanently) removed\n"
					"from your e-mail database immediately after a users exits the reading\n"
					"e-mail prompt, set this option to `Immediately`.\n"
					"\n"
					"For the best system performance and to avoid delays when deleting e-mail\n"
					"from a large e-mail database, set this option to `Daily` (the default).\n"
					"Your system maintenance will automatically purge deleted e-mail once a\n"
					"day.\n"
				;

				i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
					,"Purge Deleted E-mail",opt);
				if(!i && cfg.sys_misc&SM_DELEMAIL) {
					cfg.sys_misc&=~SM_DELEMAIL;
					uifc.changes=1; 
				}
				else if(i==1 && !(cfg.sys_misc&SM_DELEMAIL)) {
					cfg.sys_misc|=SM_DELEMAIL;
					uifc.changes=1; 
				}
                break;
			case 8:
				sprintf(str,"%"PRIu32,cfg.mail_maxcrcs);
                uifc.helpbuf=
	                "`Maximum Number of Mail CRCs:`\n"
	                "\n"
	                "This value is the maximum number of CRCs that will be kept for duplicate\n"
	                "mail checking. Once this maximum number of CRCs is reached, the oldest\n"
	                "CRCs will be automatically purged.\n"
                ;
                uifc.input(WIN_MID|WIN_SAV,0,17,"Maximum Number of Mail "
                    "CRCs",str,5,K_EDIT|K_NUMBER);
                cfg.mail_maxcrcs=atol(str);
                break;
			case 9:
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				i=cfg.sys_misc&SM_ANON_EM ? 0:1;
				uifc.helpbuf=
					"`Allow Anonymous E-mail:`\n"
					"\n"
					"If you want users with the `A` exemption to be able to send E-mail\n"
					"anonymously, set this option to `Yes`.\n"
				;

				i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
					,"Allow Anonymous E-mail",opt);
				if(!i && !(cfg.sys_misc&SM_ANON_EM)) {
					cfg.sys_misc|=SM_ANON_EM;
					uifc.changes=1; 
				}
				else if(i==1 && cfg.sys_misc&SM_ANON_EM) {
					cfg.sys_misc&=~SM_ANON_EM;
					uifc.changes=1; 
				}
				break;
			case 10:
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				i=cfg.sys_misc&SM_QUOTE_EM ? 0:1;
				uifc.helpbuf=
					"`Allow Quoting in E-mail:`\n"
					"\n"
					"If you want your users to be allowed to use message quoting when\n"
					"responding in E-mail, set this option to `Yes`.\n"
				;

				i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
					,"Allow Quoting in E-mail",opt);
				if(!i && !(cfg.sys_misc&SM_QUOTE_EM)) {
					cfg.sys_misc|=SM_QUOTE_EM;
					uifc.changes=1; 
				}
				else if(i==1 && cfg.sys_misc&SM_QUOTE_EM) {
					cfg.sys_misc&=~SM_QUOTE_EM;
					uifc.changes=1; 
				}
				break;
			case 11:
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				i=cfg.sys_misc&SM_FILE_EM ? 0:1;
				uifc.helpbuf=
					"`Allow File Attachment Uploads in E-mail:`\n"
					"\n"
					"If you want your users to be allowed to attach an uploaded file to\n"
					"an E-mail message, set this option to `Yes`.\n"
				;

				i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
					,"Allow File Attachment Uploads in E-mail",opt);
				if(!i && !(cfg.sys_misc&SM_FILE_EM)) {
					cfg.sys_misc|=SM_FILE_EM;
					uifc.changes=1; 
				}
				else if(i==1 && cfg.sys_misc&SM_FILE_EM) {
					cfg.sys_misc&=~SM_FILE_EM;
					uifc.changes=1; 
				}
				break;
			case 12:
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				i=cfg.sys_misc&SM_FWDTONET ? 0:1;
				uifc.helpbuf=
					"`Allow Users to Have Their E-mail Forwarded to NetMail:`\n"
					"\n"
					"If you want your users to be able to have any e-mail sent to them\n"
					"optionally (at the sender's discretion) forwarded to a NetMail address,\n"
					"set this option to `Yes`.\n"
				;

				i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
					,"Allow Forwarding of E-mail to NetMail",opt);
				if(!i && !(cfg.sys_misc&SM_FWDTONET)) {
					cfg.sys_misc|=SM_FWDTONET;
					uifc.changes=1; 
				}
				else if(i==1 && cfg.sys_misc&SM_FWDTONET) {
					cfg.sys_misc&=~SM_FWDTONET;
					uifc.changes=1; 
				}
                break;
			case 13:
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				i=cfg.sys_misc&SM_DELREADM ? 0:1;
				uifc.helpbuf=
					"`Kill Read E-mail Automatically:`\n"
					"\n"
					"If this option is set to `Yes`, e-mail that has been read will be\n"
					"automatically deleted when message base maintenance is run.\n"
				;

				i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
					,"Kill Read E-mail Automatically",opt);
				if(!i && !(cfg.sys_misc&SM_DELREADM)) {
					cfg.sys_misc|=SM_DELREADM;
					uifc.changes=1; 
				}
				else if(i==1 && cfg.sys_misc&SM_DELREADM) {
					cfg.sys_misc&=~SM_DELREADM;
					uifc.changes=1; 
				}
                break;
			case 14:
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				i=cfg.msg_misc&MM_REALNAME ? 0:1;
				uifc.helpbuf=
					"`Receive E-mail by Real Name:`\n"
					"\n"
					"If this option is set to ~Yes~, e-mail messages may be received when\n"
					"addressed to a user's real name (rather than their alias).\n"
				;

				i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
					,"Receive E-mail by Real Name",opt);
				if(!i && !(cfg.msg_misc&MM_REALNAME)) {
					cfg.msg_misc|=MM_REALNAME;
					uifc.changes=1; 
				}
				else if(i==1 && cfg.msg_misc&MM_REALNAME) {
					cfg.msg_misc&=~MM_REALNAME;
					uifc.changes=1; 
				}
                break;
			case 15:
				n=(cfg.sub[i]->misc&MM_EMAILSIG) ? 0:1;
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				opt[2][0]=0;
				uifc.helpbuf=
					"`Include User Signatures in E-mail:`\n"
					"\n"
					"If you wish to have user signatures automatically appended to e-mail\n"
					"messages, set this option to ~Yes~.\n"
				;
				n=uifc.list(WIN_SAV|WIN_MID,0,0,0,&n,0
					,"Include User Signatures in E-mail",opt);
				if(n==-1)
                    break;
				if(!n && !(cfg.msg_misc&MM_EMAILSIG)) {
					uifc.changes=1;
					cfg.msg_misc|=MM_EMAILSIG;
					break; 
				}
				if(n==1 && cfg.msg_misc&MM_EMAILSIG) {
					uifc.changes=1;
					cfg.msg_misc&=~MM_EMAILSIG; 
				}
                break;
			case 16:
				strcpy(opt[0],"Yes");
				strcpy(opt[1],"No");
				strcpy(opt[2],"Sysops Only");
				opt[3][0]=0;
				i=1;
				uifc.helpbuf=
					"`Users Can View Deleted Messages:`\n"
					"\n"
					"If this option is set to `Yes`, then users will be able to view messages\n"
					"they've sent and deleted or messages sent to them and they've deleted\n"
					"with the option of un-deleting the message before the message is\n"
					"physically purged from the e-mail database.\n"
					"\n"
					"If this option is set to `No`, then when a message is deleted, it is no\n"
					"longer viewable (with SBBS) by anyone.\n"
					"\n"
					"If this option is set to `Sysops Only`, then only sysops and sub-ops (when\n"
					"appropriate) can view deleted messages.\n"
				;

				i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
					,"Users Can View Deleted Messages",opt);
				if(!i && (cfg.sys_misc&(SM_USRVDELM|SM_SYSVDELM))
					!=(SM_USRVDELM|SM_SYSVDELM)) {
					cfg.sys_misc|=(SM_USRVDELM|SM_SYSVDELM);
					uifc.changes=1; 
				}
				else if(i==1 && cfg.sys_misc&(SM_USRVDELM|SM_SYSVDELM)) {
					cfg.sys_misc&=~(SM_USRVDELM|SM_SYSVDELM);
					uifc.changes=1; 
				}
				else if(i==2 && (cfg.sys_misc&(SM_USRVDELM|SM_SYSVDELM))
					!=SM_SYSVDELM) {
					cfg.sys_misc|=SM_SYSVDELM;
					cfg.sys_misc&=~SM_USRVDELM;
					uifc.changes=1; 
				}
                break;
			case 17:
				uifc.helpbuf=
					"`Extra Attribute Codes...`\n"
					"\n"
					"Synchronet can suppport the native text attribute codes of other BBS\n"
					"programs in messages (menus, posts, e-mail, etc.) To enable the extra\n"
					"attribute codes for another BBS program, set the corresponding option\n"
					"to `Yes`.\n"
				;

				j=0;
				while(1) {
					i=0;
					sprintf(opt[i++],"%-15.15s %-3.3s","WWIV"
						,cfg.sys_misc&SM_WWIV ? "Yes":"No");
					sprintf(opt[i++],"%-15.15s %-3.3s","PCBoard"
						,cfg.sys_misc&SM_PCBOARD ? "Yes":"No");
					sprintf(opt[i++],"%-15.15s %-3.3s","Wildcat"
						,cfg.sys_misc&SM_WILDCAT ? "Yes":"No");
					sprintf(opt[i++],"%-15.15s %-3.3s","Celerity"
						,cfg.sys_misc&SM_CELERITY ? "Yes":"No");
					sprintf(opt[i++],"%-15.15s %-3.3s","Renegade"
						,cfg.sys_misc&SM_RENEGADE ? "Yes":"No");
					opt[i][0]=0;
					j=uifc.list(WIN_BOT|WIN_RHT|WIN_SAV,2,2,0,&j,0
						,"Extra Attribute Codes",opt);
					if(j==-1)
						break;

					uifc.changes=1;
					switch(j) {
						case 0:
							cfg.sys_misc^=SM_WWIV;
							break;
						case 1:
							cfg.sys_misc^=SM_PCBOARD;
							break;
						case 2:
							cfg.sys_misc^=SM_WILDCAT;
							break;
						case 3:
							cfg.sys_misc^=SM_CELERITY;
							break;
						case 4:
							cfg.sys_misc^=SM_RENEGADE;
							break; 
				} 
			} 
		} 
	}
}