|
|
1.1 root 1: /* scfg.c */
2:
3: /* Synchronet configuration utility */
4:
5: /* $Id: scfg.c,v 1.64 2004/09/21 04:50:14 deuce Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #define __COLORS
39: #include "scfg.h"
40: #undef BLINK
41: #include "ciolib.h"
42:
43: /********************/
44: /* Global Variables */
45: /********************/
46:
47: scfg_t cfg; /* Synchronet Configuration */
48: uifcapi_t uifc; /* User Interface (UIFC) Library API */
49:
50: BOOL no_dirchk=FALSE,forcesave=FALSE;
51: BOOL new_install=FALSE;
52: static BOOL auto_save=FALSE;
53: extern BOOL all_msghdr;
54: extern BOOL no_msghdr;
55: char **opt;
56: char tmp[256];
57: char error[256];
58: int backup_level=5;
59:
60: char *invalid_code=
61: "&Invalid Internal Code:&\n\n"
62: "Internal codes can be up to eight characters in length and can only\n"
63: "contain valid DOS filename characters. The code you have entered\n"
64: "contains one or more invalid characters.";
65:
66: char *num_flags=
67: "&Number of Flags Needed:&\n\n"
68: "If you want users to be required to have all the flags, select &All&.\n"
69: "\n"
70: "If you want users to be required to have any one or more of the flags,\n"
71: "select &One& (Allowed).";
72:
73:
74: void allocfail(uint size)
75: {
76: printf("\7Error allocating %u bytes of memory.\r\n",size);
77: bail(1);
78: }
79:
80: int main(int argc, char **argv)
81: {
82: char **mopt,*p;
83: char errormsg[MAX_PATH*2];
84: int i,j,main_dflt=0,chat_dflt=0;
85: char str[MAX_PATH+1];
86: char exepath[MAX_PATH+1];
87: BOOL door_mode=FALSE;
88: int ciolib_mode=CIOLIB_MODE_AUTO;
89:
90: printf("\r\nSynchronet Configuration Utility (%s) v%s Copyright 2004 "
91: "Rob Swindell\r\n",PLATFORM_DESC,VERSION);
92:
93: cfg.size=sizeof(cfg);
94:
95: memset(&uifc,0,sizeof(uifc));
96: p=getenv("SBBSCTRL");
97: if(p!=NULL)
98: SAFECOPY(cfg.ctrl_dir,p);
99: else
100: getcwd(cfg.ctrl_dir,sizeof(cfg.ctrl_dir));
101:
102: uifc.esc_delay=25;
103:
104: for(i=1;i<argc;i++) {
105: if(argv[i][0]=='-'
106: #ifndef __unix__
107: || argv[i][0]=='/'
108: #endif
109: )
110: switch(toupper(argv[i][1])) {
111: case 'N': /* Set "New Installation" flag */
112: new_install=TRUE;
113: forcesave=TRUE;
114: continue;
115: case 'M': /* Monochrome mode */
116: uifc.mode|=UIFC_MONO;
117: break;
118: case 'C':
119: uifc.mode|=UIFC_COLOR;
120: break;
121: case 'D':
122: printf("NOTICE: The -d option is depreciated, use -id instead\r\n");
123: SLEEP(2000);
124: door_mode=TRUE;
125: break;
126: case 'B':
127: backup_level=atoi(argv[i]+2);
128: break;
129: case 'S':
130: no_dirchk=!no_dirchk;
131: break;
132: case 'H':
133: no_msghdr=!no_msghdr;
134: break;
135: case 'U':
136: all_msghdr=!all_msghdr;
137: break;
138: case 'F':
139: forcesave=TRUE;
140: break;
141: case 'L':
142: uifc.scrn_len=atoi(argv[i]+2);
143: break;
144: case 'E':
145: uifc.esc_delay=atoi(argv[i]+2);
146: break;
147: case 'I':
148: switch(toupper(argv[i][2])) {
149: case 'A':
150: ciolib_mode=CIOLIB_MODE_ANSI;
151: break;
152: case 'C':
153: ciolib_mode=CIOLIB_MODE_CURSES;
154: break;
155: case 0:
156: printf("NOTICE: The -i option is depreciated, use -if instead\r\n");
157: SLEEP(2000);
158: case 'F':
159: ciolib_mode=CIOLIB_MODE_CURSES_IBM;
160: break;
161: case 'X':
162: ciolib_mode=CIOLIB_MODE_X;
163: break;
164: case 'W':
165: ciolib_mode=CIOLIB_MODE_CONIO;
166: break;
167: case 'D':
168: door_mode=TRUE;
169: break;
170: default:
171: goto USAGE;
172: }
173: break;
174: case 'V':
175: textmode(atoi(argv[i]+2));
176: break;
177: case 'Y':
178: auto_save=TRUE;
179: break;
180: default:
181: USAGE:
182: printf("\nusage: scfg [ctrl_dir] [options]"
183: "\n\noptions:\n\n"
184: "-s = don't check directories\r\n"
185: "-f = force save of config files\r\n"
186: "-u = update all message base status headers\r\n"
187: "-h = don't update message base status headers\r\n"
188: "-c = force color mode\r\n"
189: "-m = force monochrome mode\r\n"
190: "-e# = set escape delay to #msec\r\n"
191: "-iX = set interface mode to X (default=auto) where X is one of:\r\n"
192: #ifdef __unix__
193: " X = X11 mode\r\n"
194: " C = Curses mode\r\n"
195: " F = Curses mode with forced IBM charset\r\n"
196: #else
197: " W = Win32 native mode\r\n"
198: #endif
199: " A = ANSI mode\r\n"
200: " D = standard input/output/door mode\r\n"
201: "-v# = set video mode to # (default=auto)\r\n"
202: "-l# = set screen lines to # (default=auto-detect)\r\n"
203: "-b# = set automatic back-up level (default=%d)\r\n"
204: "-y = automatically save changes (don't ask)\r\n"
205: ,backup_level
206: );
207: exit(0);
208: }
209: else
210: SAFECOPY(cfg.ctrl_dir,argv[i]);
211: }
212:
213: FULLPATH(exepath,argv[0],sizeof(exepath)); /* Must do this before chdir */
214:
215: if(chdir(cfg.ctrl_dir)!=0) {
216: printf("!ERROR %d changing current directory to: %s\n"
217: ,errno,cfg.ctrl_dir);
218: exit(-1);
219: }
220: FULLPATH(cfg.ctrl_dir,".",sizeof(cfg.ctrl_dir));
221: backslashcolon(cfg.ctrl_dir);
222:
223: uifc.size=sizeof(uifc);
224: if(!door_mode) {
225: i=initciolib(ciolib_mode);
226: if(i!=0) {
227: printf("ciolib library init returned error %d\n",i);
228: exit(1);
229: }
230: i=uifcini32(&uifc); /* curses/conio/X/ANSI */
231: }
232: else
233: i=uifcinix(&uifc); /* stdio */
234: if(i!=0) {
235: printf("uifc library init returned error %d\n",i);
236: exit(1);
237: }
238:
239: if((opt=(char **)MALLOC(sizeof(char *)*(MAX_OPTS+1)))==NULL)
240: allocfail(sizeof(char *)*(MAX_OPTS+1));
241: for(i=0;i<(MAX_OPTS+1);i++)
242: if((opt[i]=(char *)MALLOC(MAX_OPLN))==NULL)
243: allocfail(MAX_OPLN);
244:
245: if((mopt=(char **)MALLOC(sizeof(char *)*14))==NULL)
246: allocfail(sizeof(char *)*14);
247: for(i=0;i<14;i++)
248: if((mopt[i]=(char *)MALLOC(64))==NULL)
249: allocfail(64);
250:
251: if((p=getenv("SBBSEXEC"))!=NULL)
252: SAFECOPY(str,p);
253: else {
254: SAFECOPY(str,exepath);
255: p=strrchr(str,'/');
256: if(p==NULL)
257: p=strrchr(str,'\\');
258: if(p!=NULL)
259: *p=0;
260: else
261: sprintf(str,"%s../exec",cfg.ctrl_dir);
262: }
263: FULLPATH(uifc.helpdatfile,str,sizeof(uifc.helpdatfile));
264: backslash(uifc.helpdatfile);
265: SAFECOPY(uifc.helpixbfile,uifc.helpdatfile);
266: strcat(uifc.helpdatfile,"scfghelp.dat");
267: strcat(uifc.helpixbfile,"scfghelp.ixb");
268:
269: sprintf(str,"Synchronet for %s v%s",PLATFORM_DESC,VERSION);
270: if(uifc.scrn(str)) {
271: printf(" USCRN (len=%d) failed!\r\n",uifc.scrn_len+1);
272: bail(1);
273: }
274:
275: if(!fexist(uifc.helpdatfile)) {
276: sprintf(errormsg,"Help file (%s) missing!",uifc.helpdatfile);
277: uifc.msg(errormsg);
278: }
279: if(!fexist(uifc.helpixbfile)) {
280: sprintf(errormsg,"Help file (%s) missing!",uifc.helpixbfile);
281: uifc.msg(errormsg);
282: }
283: sprintf(str,"%smain.cnf",cfg.ctrl_dir);
284: if(!fexist(str)) {
285: sprintf(errormsg,"Main configuration file (%s) missing!",str);
286: uifc.msg(errormsg);
287: }
288:
289: i=0;
290: strcpy(mopt[i++],"Nodes");
291: strcpy(mopt[i++],"System");
292: strcpy(mopt[i++],"Networks");
293: strcpy(mopt[i++],"File Areas");
294: strcpy(mopt[i++],"File Options");
295: strcpy(mopt[i++],"Chat Features");
296: strcpy(mopt[i++],"Message Areas");
297: strcpy(mopt[i++],"Message Options");
298: strcpy(mopt[i++],"Command Shells");
299: strcpy(mopt[i++],"External Programs");
300: strcpy(mopt[i++],"Text File Sections");
301: mopt[i][0]=0;
302: while(1) {
303: SETHELP(WHERE);
304: /*
305: &Main Configuration Menu:&
306:
307: This is the main menu of the Synchronet configuration utility (SCFG).
308: From this menu, you have the following choices:
309:
310: Nodes : Add, delete, or configure nodes
311: System : System-wide configuration options
312: Networks : Message networking configuration
313: File Areas : File area configuration
314: File Options : File area options
315: Chat Features : Chat actions, sections, pagers, and gurus
316: Message Areas : Message area configuration
317: Message Options : Message and email options
318: External Programs : Events, editors, and online programs
319: Text File Sections : General text file area
320:
321: Use the arrow keys and ENTER to select an option, or ESC to exit.
322: */
323: switch(uifc.list(WIN_ORG|WIN_MID|WIN_ESC|WIN_ACT,0,0,30,&main_dflt,0
324: ,"Configure",mopt)) {
325: case 0:
326: uifc.pop("Reading MAIN.CNF...");
327: if(!read_main_cfg(&cfg,error)) {
328: uifc.pop(0);
329: sprintf(errormsg,"ERROR: %s",error);
330: uifc.msg(errormsg);
331: break;
332: }
333: uifc.pop(0);
334: node_menu();
335: free_main_cfg(&cfg);
336: break;
337: case 1:
338: uifc.pop("Reading MAIN.CNF...");
339: if(!read_main_cfg(&cfg,error)) {
340: uifc.pop(0);
341: sprintf(errormsg,"ERROR: %s",error);
342: uifc.msg(errormsg);
343: break;
344: }
345: uifc.pop("Reading XTRN.CNF...");
346: if(!read_xtrn_cfg(&cfg,error)) {
347: uifc.pop(0);
348: sprintf(errormsg,"ERROR: %s",error);
349: uifc.msg(errormsg);
350: break;
351: }
352: uifc.pop(0);
353: sys_cfg();
354: free_xtrn_cfg(&cfg);
355: free_main_cfg(&cfg);
356: break;
357: case 2:
358: uifc.pop("Reading MAIN.CNF...");
359: if(!read_main_cfg(&cfg,error)) {
360: uifc.pop(0);
361: sprintf(errormsg,"ERROR: %s",error);
362: uifc.msg(errormsg);
363: break;
364: }
365: uifc.pop("Reading MSGS.CNF...");
366: if(!read_msgs_cfg(&cfg,error)) {
367: uifc.pop(0);
368: sprintf(errormsg,"ERROR: %s",error);
369: uifc.msg(errormsg);
370: break;
371: }
372: uifc.pop(0);
373: net_cfg();
374: free_msgs_cfg(&cfg);
375: free_main_cfg(&cfg);
376: break;
377: case 3:
378: uifc.pop("Reading MAIN.CNF...");
379: if(!read_main_cfg(&cfg,error)) {
380: uifc.pop(0);
381: sprintf(errormsg,"ERROR: %s",error);
382: uifc.msg(errormsg);
383: break;
384: }
385: uifc.pop("Reading FILE.CNF...");
386: if(!read_file_cfg(&cfg,error)) {
387: uifc.pop(0);
388: sprintf(errormsg,"ERROR: %s",error);
389: uifc.msg(errormsg);
390: break;
391: }
392: uifc.pop(0);
393: xfer_cfg();
394: free_file_cfg(&cfg);
395: free_main_cfg(&cfg);
396: break;
397: case 4:
398: uifc.pop("Reading MAIN.CNF...");
399: if(!read_main_cfg(&cfg,error)) {
400: uifc.pop(0);
401: sprintf(errormsg,"ERROR: %s",error);
402: uifc.msg(errormsg);
403: break;
404: }
405: uifc.pop("Reading FILE.CNF...");
406: if(!read_file_cfg(&cfg,error)) {
407: uifc.pop(0);
408: sprintf(errormsg,"ERROR: %s",error);
409: uifc.msg(errormsg);
410: break;
411: }
412: uifc.pop(0);
413: xfer_opts();
414: free_file_cfg(&cfg);
415: free_main_cfg(&cfg);
416: break;
417: case 5:
418: uifc.pop("Reading CHAT.CNF...");
419: if(!read_chat_cfg(&cfg,error)) {
420: uifc.pop(0);
421: sprintf(errormsg,"ERROR: %s",error);
422: uifc.msg(errormsg);
423: break;
424: }
425: uifc.pop(0);
426: while(1) {
427: i=0;
428: strcpy(opt[i++],"Artificial Gurus");
429: strcpy(opt[i++],"Multinode Chat Actions");
430: strcpy(opt[i++],"Multinode Chat Channels");
431: strcpy(opt[i++],"External Sysop Chat Pagers");
432: opt[i][0]=0;
433: j=uifc.list(WIN_ORG|WIN_ACT|WIN_CHE,0,0,0,&chat_dflt,0
434: ,"Chat Features",opt);
435: if(j==-1) {
436: j=save_changes(WIN_MID);
437: if(j==-1)
438: continue;
439: if(!j) {
440: write_chat_cfg(&cfg,backup_level);
441: refresh_cfg(&cfg);
442: }
443: break;
444: }
445: switch(j) {
446: case 0:
447: guru_cfg();
448: break;
449: case 1:
450: actsets_cfg();
451: break;
452: case 2:
453: chan_cfg();
454: break;
455: case 3:
456: page_cfg();
457: break; } }
458: free_chat_cfg(&cfg);
459: break;
460: case 6:
461: uifc.pop("Reading MAIN.CNF...");
462: if(!read_main_cfg(&cfg,error)) {
463: uifc.pop(0);
464: sprintf(errormsg,"ERROR: %s",error);
465: uifc.msg(errormsg);
466: break;
467: }
468: uifc.pop("Reading MSGS.CNF...");
469: if(!read_msgs_cfg(&cfg,error)) {
470: uifc.pop(0);
471: sprintf(errormsg,"ERROR: %s",error);
472: uifc.msg(errormsg);
473: break;
474: }
475: uifc.pop(0);
476: msgs_cfg();
477: free_msgs_cfg(&cfg);
478: free_main_cfg(&cfg);
479: break;
480: case 7:
481: uifc.pop("Reading MAIN.CNF...");
482: if(!read_main_cfg(&cfg,error)) {
483: uifc.pop(0);
484: sprintf(errormsg,"ERROR: %s",error);
485: uifc.msg(errormsg);
486: break;
487: }
488: uifc.pop("Reading MSGS.CNF...");
489: if(!read_msgs_cfg(&cfg,error)) {
490: uifc.pop(0);
491: sprintf(errormsg,"ERROR: %s",error);
492: uifc.msg(errormsg);
493: break;
494: }
495: uifc.pop(0);
496: msg_opts();
497: free_msgs_cfg(&cfg);
498: free_main_cfg(&cfg);
499: break;
500: case 8:
501: uifc.pop("Reading MAIN.CNF...");
502: if(!read_main_cfg(&cfg,error)) {
503: uifc.pop(0);
504: sprintf(errormsg,"ERROR: %s",error);
505: uifc.msg(errormsg);
506: break;
507: }
508: uifc.pop(0);
509: shell_cfg();
510: free_main_cfg(&cfg);
511: break;
512: case 9:
513: uifc.pop("Reading MAIN.CNF...");
514: if(!read_main_cfg(&cfg,error)) {
515: uifc.pop(0);
516: sprintf(errormsg,"ERROR: %s",error);
517: uifc.msg(errormsg);
518: break;
519: }
520: uifc.pop("Reading XTRN.CNF...");
521: if(!read_xtrn_cfg(&cfg,error)) {
522: uifc.pop(0);
523: sprintf(errormsg,"ERROR: %s",error);
524: uifc.msg(errormsg);
525: break;
526: }
527: uifc.pop(0);
528: xprogs_cfg();
529: free_xtrn_cfg(&cfg);
530: free_main_cfg(&cfg);
531: break;
532: case 10:
533: uifc.pop("Reading MAIN.CNF...");
534: if(!read_main_cfg(&cfg,error)) {
535: uifc.pop(0);
536: sprintf(errormsg,"ERROR: %s",error);
537: uifc.msg(errormsg);
538: break;
539: }
540: uifc.pop("Reading FILE.CNF...");
541: if(!read_file_cfg(&cfg,error)) {
542: uifc.pop(0);
543: sprintf(errormsg,"ERROR: %s",error);
544: uifc.msg(errormsg);
545: break;
546: }
547: uifc.pop(0);
548: txt_cfg();
549: free_file_cfg(&cfg);
550: free_main_cfg(&cfg);
551: break;
552: case -1:
553: i=0;
554: strcpy(opt[0],"Yes");
555: strcpy(opt[1],"No");
556: opt[2][0]=0;
557: SETHELP(WHERE);
558: /*
559: &Exit SCFG:&
560:
561: If you want to exit the Synchronet configuration utility, select &Yes&.
562: Otherwise, select &No& or hit ESC .
563: */
564: i=uifc.list(WIN_MID,0,0,0,&i,0,"Exit SCFG",opt);
565: if(!i)
566: bail(0);
567: break; } }
568: }
569:
570: /****************************************************************************/
571: /* Checks the uifc.changes variable. If there have been no uifc.changes, returns 2. */
572: /* If there have been uifc.changes, it prompts the user to change or not. If the */
573: /* user escapes the menu, returns -1, selects Yes, 0, and selects no, 1 */
574: /****************************************************************************/
575: int save_changes(int mode)
576: {
577: int i=0;
578:
579: if(!uifc.changes)
580: return(2);
581: if(auto_save==TRUE) { /* -y switch used, return "Yes" */
582: uifc.changes=0;
583: return(0);
584: }
585: strcpy(opt[0],"Yes");
586: strcpy(opt[1],"No");
587: opt[2][0]=0;
588: if(mode&WIN_SAV && uifc.savdepth)
589: uifc.savnum++;
590: SETHELP(WHERE);
591: /*
592: &Save uifc.changes:&
593:
594: You have made some uifc.changes to the configuration. If you want to save
595: these uifc.changes, select &Yes&. If you are positive you DO NOT want to save
596: these uifc.changes, select &No&. If you are not sure and want to review the
597: configuration before deciding, hit ESC .
598: */
599: i=uifc.list(mode|WIN_ACT,0,0,0,&i,0,"Save Changes",opt);
600: if(mode&WIN_SAV && uifc.savdepth && uifc.savnum)
601: uifc.savnum--;
602: if(i!=-1)
603: uifc.changes=0;
604: return(i);
605: }
606:
607: void txt_cfg()
608: {
609: static int txt_dflt,bar;
610: char str[81],code[9],done=0,*p;
611: int j,k;
612: uint i;
613: static txtsec_t savtxtsec;
614:
615: while(1) {
616: for(i=0;i<cfg.total_txtsecs;i++)
617: sprintf(opt[i],"%-25s",cfg.txtsec[i]->name);
618: opt[i][0]=0;
619: j=WIN_ORG|WIN_ACT|WIN_CHE;
620: if(cfg.total_txtsecs)
621: j|=WIN_DEL|WIN_GET;
622: if(cfg.total_txtsecs<MAX_OPTS)
623: j|=WIN_INS|WIN_INSACT|WIN_XTR;
624: if(savtxtsec.name[0])
625: j|=WIN_PUT;
626: SETHELP(WHERE);
627: /*
628: &Text File Sections:&
629:
630: This is a list of &General Text File (G-File) Sections& configured for
631: your system. G-File sections are used to store text files that can be
632: viewed freely by the users. Common text file section topics include
633: &ANSI Artwork&, &System Information&, &Game Help Files&, and other special
634: interest topics.
635:
636: To add a text file section, select the desired location with the arrow
637: keys and hit INS .
638:
639: To delete a text file section, select it and hit DEL .
640:
641: To configure a text file, select it and hit ENTER .
642: */
643: i=uifc.list(j,0,0,45,&txt_dflt,&bar,"Text File Sections",opt);
644: if((signed)i==-1) {
645: j=save_changes(WIN_MID);
646: if(j==-1)
647: continue;
648: if(!j) {
649: write_file_cfg(&cfg,backup_level);
650: refresh_cfg(&cfg);
651: }
652: return;
653: }
654: if((i&MSK_ON)==MSK_INS) {
655: i&=MSK_OFF;
656: strcpy(str,"ANSI Artwork");
657: SETHELP(WHERE);
658: /*
659: &Text Section Name:&
660:
661: This is the name of this text section.
662: */
663: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Text Section Name",str,40
664: ,K_EDIT)<1)
665: continue;
666: sprintf(code,"%.8s",str);
667: p=strchr(code,' ');
668: if(p) *p=0;
669: strupr(code);
670: SETHELP(WHERE);
671: /*
672: &Text Section Internal Code:&
673:
674: Every text file section must have its own unique internal code for
675: Synchronet to reference it by. It is helpful if this code is an
676: abreviation of the name.
677: */
678: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Text Section Internal Code",code,LEN_CODE
679: ,K_EDIT)<1)
680: continue;
681: if(!code_ok(code)) {
682: uifc.helpbuf=invalid_code;
683: uifc.msg("Invalid Code");
684: uifc.helpbuf=0;
685: continue; }
686: if((cfg.txtsec=(txtsec_t **)REALLOC(cfg.txtsec
687: ,sizeof(txtsec_t *)*(cfg.total_txtsecs+1)))==NULL) {
688: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_txtsecs+1);
689: cfg.total_txtsecs=0;
690: bail(1);
691: continue; }
692: if(cfg.total_txtsecs)
693: for(j=cfg.total_txtsecs;j>i;j--)
694: cfg.txtsec[j]=cfg.txtsec[j-1];
695: if((cfg.txtsec[i]=(txtsec_t *)MALLOC(sizeof(txtsec_t)))==NULL) {
696: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(txtsec_t));
697: continue; }
698: memset((txtsec_t *)cfg.txtsec[i],0,sizeof(txtsec_t));
699: strcpy(cfg.txtsec[i]->name,str);
700: strcpy(cfg.txtsec[i]->code,code);
701: cfg.total_txtsecs++;
702: uifc.changes=1;
703: continue; }
704: if((i&MSK_ON)==MSK_DEL) {
705: i&=MSK_OFF;
706: FREE(cfg.txtsec[i]);
707: cfg.total_txtsecs--;
708: for(j=i;j<cfg.total_txtsecs;j++)
709: cfg.txtsec[j]=cfg.txtsec[j+1];
710: uifc.changes=1;
711: continue; }
712: if((i&MSK_ON)==MSK_GET) {
713: i&=MSK_OFF;
714: savtxtsec=*cfg.txtsec[i];
715: continue; }
716: if((i&MSK_ON)==MSK_PUT) {
717: i&=MSK_OFF;
718: *cfg.txtsec[i]=savtxtsec;
719: uifc.changes=1;
720: continue; }
721: i=txt_dflt;
722: j=0;
723: done=0;
724: while(!done) {
725: k=0;
726: sprintf(opt[k++],"%-27.27s%s","Name",cfg.txtsec[i]->name);
727: sprintf(opt[k++],"%-27.27s%s","Access Requirements"
728: ,cfg.txtsec[i]->arstr);
729: sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.txtsec[i]->code);
730: opt[k][0]=0;
731: switch(uifc.list(WIN_ACT|WIN_MID,0,0,60,&j,0,cfg.txtsec[i]->name
732: ,opt)) {
733: case -1:
734: done=1;
735: break;
736: case 0:
737: SETHELP(WHERE);
738: /*
739: &Text Section Name:&
740:
741: This is the name of this text section.
742: */
743: strcpy(str,cfg.txtsec[i]->name); /* save */
744: if(!uifc.input(WIN_MID|WIN_SAV,0,10
745: ,"Text File Section Name"
746: ,cfg.txtsec[i]->name,sizeof(cfg.txtsec[i]->name)-1,K_EDIT))
747: strcpy(cfg.txtsec[i]->name,str);
748: break;
749: case 1:
750: sprintf(str,"%s Text Section",cfg.txtsec[i]->name);
751: getar(str,cfg.txtsec[i]->arstr);
752: break;
753: case 2:
754: strcpy(str,cfg.txtsec[i]->code);
755: SETHELP(WHERE);
756: /*
757: &Text Section Internal Code:&
758:
759: Every text file section must have its own unique internal code for
760: Synchronet to reference it by. It is helpful if this code is an
761: abreviation of the name.
762: */
763: uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)"
764: ,str,LEN_CODE,K_EDIT);
765: if(code_ok(str))
766: strcpy(cfg.txtsec[i]->code,str);
767: else {
768: uifc.helpbuf=invalid_code;
769: uifc.msg("Invalid Code");
770: uifc.helpbuf=0; }
771: break; } } }
772: }
773:
774: void shell_cfg()
775: {
776: static int shell_dflt,shell_bar;
777: char str[81],code[9],done=0,*p;
778: int j,k;
779: uint i;
780: static shell_t savshell;
781:
782: while(1) {
783: for(i=0;i<cfg.total_shells;i++)
784: sprintf(opt[i],"%-25s",cfg.shell[i]->name);
785: opt[i][0]=0;
786: j=WIN_ORG|WIN_ACT|WIN_CHE;
787: if(cfg.total_shells)
788: j|=WIN_DEL|WIN_GET;
789: if(cfg.total_shells<MAX_OPTS)
790: j|=WIN_INS|WIN_INSACT|WIN_XTR;
791: if(savshell.name[0])
792: j|=WIN_PUT;
793: SETHELP(WHERE);
794: /*
795: &Command Shells:&
796:
797: This is a list of &Command Shells& configured for your system.
798: Command shells are the programmable command and menu structures which
799: are available for your BBS.
800:
801: To add a command shell section, select the desired location with the
802: arrow keys and hit INS .
803:
804: To delete a command shell, select it and hit DEL .
805:
806: To configure a command shell, select it and hit ENTER .
807: */
808: i=uifc.list(j,0,0,45,&shell_dflt,&shell_bar,"Command Shells",opt);
809: if((signed)i==-1) {
810: j=save_changes(WIN_MID);
811: if(j==-1)
812: continue;
813: if(!j) {
814: cfg.new_install=new_install;
815: write_main_cfg(&cfg,backup_level);
816: refresh_cfg(&cfg);
817: }
818: return;
819: }
820: if((i&MSK_ON)==MSK_INS) {
821: i&=MSK_OFF;
822: strcpy(str,"Menu Shell");
823: SETHELP(WHERE);
824: /*
825: &Command Shell Name:&
826:
827: This is the descriptive name of this command shell.
828: */
829: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Command Shell Name",str,40
830: ,K_EDIT)<1)
831: continue;
832: sprintf(code,"%.8s",str);
833: p=strchr(code,' ');
834: if(p) *p=0;
835: strupr(code);
836: SETHELP(WHERE);
837: /*
838: &Command Shell Internal Code:&
839:
840: Every command shell must have its own unique internal code for
841: Synchronet to reference it by. It is helpful if this code is an
842: abreviation of the name.
843:
844: This code will be the base filename used to load the shell from your
845: EXEC directory. e.g. A shell with an internal code of &MYBBS& would
846: indicate a Baja shell file named &MYBBS.BIN& in your EXEC directory.
847: */
848: if(uifc.input(WIN_MID|WIN_SAV,0,0,"Command Shell Internal Code",code,LEN_CODE
849: ,K_EDIT)<1)
850: continue;
851: if(!code_ok(code)) {
852: uifc.helpbuf=invalid_code;
853: uifc.msg("Invalid Code");
854: uifc.helpbuf=0;
855: continue; }
856: if((cfg.shell=(shell_t **)REALLOC(cfg.shell
857: ,sizeof(shell_t *)*(cfg.total_shells+1)))==NULL) {
858: errormsg(WHERE,ERR_ALLOC,nulstr,cfg.total_shells+1);
859: cfg.total_shells=0;
860: bail(1);
861: continue; }
862: if(cfg.total_shells)
863: for(j=cfg.total_shells;j>i;j--)
864: cfg.shell[j]=cfg.shell[j-1];
865: if((cfg.shell[i]=(shell_t *)MALLOC(sizeof(shell_t)))==NULL) {
866: errormsg(WHERE,ERR_ALLOC,nulstr,sizeof(shell_t));
867: continue; }
868: memset((shell_t *)cfg.shell[i],0,sizeof(shell_t));
869: strcpy(cfg.shell[i]->name,str);
870: strcpy(cfg.shell[i]->code,code);
871: cfg.total_shells++;
872: uifc.changes=1;
873: continue; }
874: if((i&MSK_ON)==MSK_DEL) {
875: i&=MSK_OFF;
876: FREE(cfg.shell[i]);
877: cfg.total_shells--;
878: for(j=i;j<cfg.total_shells;j++)
879: cfg.shell[j]=cfg.shell[j+1];
880: uifc.changes=1;
881: continue; }
882: if((i&MSK_ON)==MSK_GET) {
883: i&=MSK_OFF;
884: savshell=*cfg.shell[i];
885: continue; }
886: if((i&MSK_ON)==MSK_PUT) {
887: i&=MSK_OFF;
888: *cfg.shell[i]=savshell;
889: uifc.changes=1;
890: continue; }
891: i=shell_dflt;
892: j=0;
893: done=0;
894: while(!done) {
895: k=0;
896: sprintf(opt[k++],"%-27.27s%s","Name",cfg.shell[i]->name);
897: sprintf(opt[k++],"%-27.27s%s","Access Requirements"
898: ,cfg.shell[i]->arstr);
899: sprintf(opt[k++],"%-27.27s%s","Internal Code",cfg.shell[i]->code);
900: opt[k][0]=0;
901: SETHELP(WHERE);
902: /*
903: &Command Shell:&
904:
905: A command shell is a programmed command and menu structure that you or
906: your users can use to navigate the BBS. For every command shell
907: configured here, there must be an associated .BIN file in your EXEC
908: directory for Synchronet to execute.
909:
910: Command shell files are created by using the Baja command shell compiler
911: to turn Baja source code (.SRC) files into binary files (.BIN) for
912: Synchronet to interpret. See the example .SRC files in the TEXT
913: directory and the documentation for the Baja compiler for more details.
914: */
915: switch(uifc.list(WIN_ACT|WIN_MID,0,0,60,&j,0,cfg.shell[i]->name
916: ,opt)) {
917: case -1:
918: done=1;
919: break;
920: case 0:
921: SETHELP(WHERE);
922: /*
923: &Command Shell Name:&
924:
925: This is the descriptive name of this command shell.
926: */
927: strcpy(str,cfg.shell[i]->name); /* save */
928: if(!uifc.input(WIN_MID|WIN_SAV,0,10
929: ,"Command Shell Name"
930: ,cfg.shell[i]->name,sizeof(cfg.shell[i]->name)-1,K_EDIT))
931: strcpy(cfg.shell[i]->name,str);
932: break;
933: case 1:
934: sprintf(str,"%s Command Shell",cfg.shell[i]->name);
935: getar(str,cfg.shell[i]->arstr);
936: break;
937: case 2:
938: strcpy(str,cfg.shell[i]->code);
939: SETHELP(WHERE);
940: /*
941: &Command Shell Internal Code:&
942:
943: Every command shell must have its own unique internal code for
944: Synchronet to reference it by. It is helpful if this code is an
945: abreviation of the name.
946:
947: This code will be the base filename used to load the shell from your
948: EXEC directory. e.g. A shell with an internal code of &MYBBS& would
949: indicate a Baja shell file named &MYBBS.BIN& in your EXEC directory.
950: */
951: uifc.input(WIN_MID|WIN_SAV,0,17,"Internal Code (unique)"
952: ,str,LEN_CODE,K_EDIT);
953: if(code_ok(str))
954: strcpy(cfg.shell[i]->code,str);
955: else {
956: uifc.helpbuf=invalid_code;
957: uifc.msg("Invalid Code");
958: uifc.helpbuf=0; }
959: break; } } }
960: }
961:
962: int whichlogic(void)
963: {
964: int i;
965:
966: i=0;
967: strcpy(opt[0],"Greater than or Equal");
968: strcpy(opt[1],"Equal");
969: strcpy(opt[2],"Not Equal");
970: strcpy(opt[3],"Less than");
971: opt[4][0]=0;
972: if(uifc.savdepth)
973: uifc.savnum++;
974: SETHELP(WHERE);
975: /*
976: &Select Logic for Requirement:&
977:
978: This menu allows you to choose the type of logic evaluation to use
979: in determining if the requirement is met. If, for example, the user's
980: level is being evaluated and you select &Greater than or Equal& from
981: this menu and set the required level to &50&, the user must have level
982: &50 or higher& to meet this requirement. If you selected &Equal& from
983: this menu and set the required level to &50&, the user must have level
984: &50 exactly&. If you select &Not equal& and level &50&, then the user
985: must have &any level BUT 50&. And if you select &Less than& from this
986: menu and level &50&, the user must have a level &below 50&.
987: */
988: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Select Logic",opt);
989: if(uifc.savdepth && uifc.savnum)
990: uifc.savnum--;
991: return(i);
992: }
993:
994: int whichcond(void)
995: {
996: int i;
997:
998: i=0;
999: strcpy(opt[0],"AND (Both/All)");
1000: strcpy(opt[1],"OR (Either/Any)");
1001: opt[2][0]=0;
1002: if(uifc.savdepth)
1003: uifc.savnum++;
1004: SETHELP(WHERE);
1005: /*
1006: &Select Logic for Multiple Requirements:&
1007:
1008: If you wish this new parameter to be required along with the other
1009: parameters, select &AND& to specify that &both& or &all& of the
1010: parameter requirments must be met.
1011:
1012: If you wish this new parameter to only be required if the other
1013: parameter requirements aren't met, select &OR& to specify that &either&
1014: or &any& of the parameter requirements must be met.
1015: */
1016: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Multiple Requirement Logic",opt);
1017: if(uifc.savdepth && uifc.savnum)
1018: uifc.savnum--;
1019: return(i);
1020: }
1021:
1022:
1023: void getar(char *desc, char *inar)
1024: {
1025: static int curar;
1026: char str[128],ar[128];
1027: int i,j,len,done=0,n;
1028:
1029: strcpy(ar,inar);
1030: while(!done) {
1031: len=strlen(ar);
1032: if(len>=30) { /* Needs to be shortened */
1033: str[0]=0;
1034: n=strlen(ar);
1035: for(i=0;i<n;i++) { /* Shorten operators */
1036: if(!strncmp(ar+i,"AND",3)) {
1037: strcat(str,"&");
1038: i+=2; }
1039: else if(!strncmp(ar+i,"NOT",3)) {
1040: strcat(str,"!");
1041: i+=2; }
1042: else if(!strncmp(ar+i,"EQUAL",5)) {
1043: strcat(str,"=");
1044: i+=4; }
1045: else if(!strncmp(ar+i,"EQUALS",6)) {
1046: strcat(str,"=");
1047: i+=5; }
1048: else if(!strncmp(ar+i,"EQUAL TO",8)) {
1049: strcat(str,"=");
1050: i+=7; }
1051: else if(!strncmp(ar+i,"OR",2)) {
1052: strcat(str,"|");
1053: i+=1; }
1054: else
1055: strncat(str,ar+i,1); }
1056: strcpy(ar,str);
1057: len=strlen(ar); }
1058:
1059: if(len>=30) {
1060: str[0]=0;
1061: n=strlen(ar);
1062: for(i=0;i<n;i++) { /* Remove spaces from ! and = */
1063: if(!strncmp(ar+i," ! ",3)) {
1064: strcat(str,"!");
1065: i+=2; }
1066: else if(!strncmp(ar+i,"= ",2)) {
1067: strcat(str,"=");
1068: i++; }
1069: else if(!strncmp(ar+i," = ",3)) {
1070: strcat(str,"=");
1071: i+=2; }
1072: else
1073: strncat(str,ar+i,1); }
1074: strcpy(ar,str);
1075: len=strlen(ar); }
1076:
1077: if(len>=30) {
1078: str[0]=0;
1079: n=strlen(ar);
1080: for(i=0;i<n;i++) { /* Remove spaces from & and | */
1081: if(!strncmp(ar+i," & ",3)) {
1082: strcat(str," ");
1083: i+=2; }
1084: else if(!strncmp(ar+i," | ",3)) {
1085: strcat(str,"|");
1086: i+=2; }
1087: else
1088: strncat(str,ar+i,1); }
1089: strcpy(ar,str);
1090: len=strlen(ar); }
1091:
1092: if(len>=30) { /* change week days to numbers */
1093: str[0]=0;
1094: n=strlen(ar);
1095: for(i=0;i<n;i++) {
1096: for(j=0;j<7;j++)
1097: if(!strnicmp(ar+i,wday[j],3)) {
1098: strcat(str,ultoa(j,tmp,10));
1099: i+=2;
1100: break; }
1101: if(j==7)
1102: strncat(str,ar+i,1); }
1103: strcpy(ar,str);
1104: len=strlen(ar); }
1105:
1106: if(len>=30) { /* Shorten parameters */
1107: str[0]=0;
1108: n=strlen(ar);
1109: for(i=0;i<n;i++) {
1110: if(!strncmp(ar+i,"AGE",3)) {
1111: strcat(str,"$A");
1112: i+=2; }
1113: else if(!strncmp(ar+i,"BPS",3)) {
1114: strcat(str,"$B");
1115: i+=2; }
1116: else if(!strncmp(ar+i,"PCR",3)) {
1117: strcat(str,"$P");
1118: i+=2; }
1119: else if(!strncmp(ar+i,"RIP",3)) {
1120: strcat(str,"$*");
1121: i+=2; }
1122: else if(!strncmp(ar+i,"SEX",3)) {
1123: strcat(str,"$S");
1124: i+=2; }
1125: else if(!strncmp(ar+i,"UDR",3)) {
1126: strcat(str,"$K");
1127: i+=2; }
1128: else if(!strncmp(ar+i,"DAY",3)) {
1129: strcat(str,"$W");
1130: i+=2; }
1131: else if(!strncmp(ar+i,"ANSI",4)) {
1132: strcat(str,"$[");
1133: i+=3; }
1134: else if(!strncmp(ar+i,"UDFR",4)) {
1135: strcat(str,"$D");
1136: i+=3; }
1137: else if(!strncmp(ar+i,"FLAG",4)) {
1138: strcat(str,"$F");
1139: i+=3; }
1140: else if(!strncmp(ar+i,"NODE",4)) {
1141: strcat(str,"$N");
1142: i+=3; }
1143: else if(!strncmp(ar+i,"NULL",4)) {
1144: strcat(str,"$0");
1145: i+=3; }
1146: else if(!strncmp(ar+i,"TIME",4)) {
1147: strcat(str,"$T");
1148: i+=3; }
1149: else if(!strncmp(ar+i,"USER",4)) {
1150: strcat(str,"$U");
1151: i+=3; }
1152: else if(!strncmp(ar+i,"REST",4)) {
1153: strcat(str,"$Z");
1154: i+=3; }
1155: else if(!strncmp(ar+i,"LOCAL",5)) {
1156: strcat(str,"$G");
1157: i+=4; }
1158: else if(!strncmp(ar+i,"LEVEL",5)) {
1159: strcat(str,"$L");
1160: i+=4; }
1161: else if(!strncmp(ar+i,"TLEFT",5)) {
1162: strcat(str,"$R");
1163: i+=4; }
1164: else if(!strncmp(ar+i,"TUSED",5)) {
1165: strcat(str,"$O");
1166: i+=4; }
1167: else if(!strncmp(ar+i,"EXPIRE",6)) {
1168: strcat(str,"$E");
1169: i+=5; }
1170: else if(!strncmp(ar+i,"CREDIT",6)) {
1171: strcat(str,"$C");
1172: i+=5; }
1173: else if(!strncmp(ar+i,"EXEMPT",6)) {
1174: strcat(str,"$X");
1175: i+=5; }
1176: else if(!strncmp(ar+i,"RANDOM",6)) {
1177: strcat(str,"$Q");
1178: i+=5; }
1179: else if(!strncmp(ar+i,"LASTON",6)) {
1180: strcat(str,"$Y");
1181: i+=5; }
1182: else if(!strncmp(ar+i,"LOGONS",6)) {
1183: strcat(str,"$V");
1184: i+=5; }
1185: else if(!strncmp(ar+i,":00",3)) {
1186: i+=2; }
1187: else
1188: strncat(str,ar+i,1); }
1189: strcpy(ar,str);
1190: len=strlen(ar); }
1191: if(len>=30) { /* Remove all spaces and &s */
1192: str[0]=0;
1193: n=strlen(ar);
1194: for(i=0;i<n;i++)
1195: if(ar[i]!=' ' && ar[i]!='&')
1196: strncat(str,ar+i,1);
1197: strcpy(ar,str);
1198: len=strlen(ar); }
1199: i=0;
1200: sprintf(opt[i++],"Requirement String (%s)",ar);
1201: strcpy(opt[i++],"Clear Requirements");
1202: strcpy(opt[i++],"Set Required Level");
1203: strcpy(opt[i++],"Set Required Flag");
1204: strcpy(opt[i++],"Set Required Age");
1205: strcpy(opt[i++],"Set Required Sex");
1206: strcpy(opt[i++],"Set Required Connect Rate");
1207: strcpy(opt[i++],"Set Required Post/Call Ratio (percentage)");
1208: strcpy(opt[i++],"Set Required Number of Credits");
1209: strcpy(opt[i++],"Set Required Upload/Download Byte Ratio (percentage)");
1210: strcpy(opt[i++],"Set Required Upload/Download File Ratio (percentage)");
1211: strcpy(opt[i++],"Set Required Time of Day");
1212: strcpy(opt[i++],"Set Required Day of Week");
1213: strcpy(opt[i++],"Set Required Node Number");
1214: strcpy(opt[i++],"Set Required User Number");
1215: strcpy(opt[i++],"Set Required Time Remaining");
1216: strcpy(opt[i++],"Set Required Days Till Expiration");
1217: opt[i][0]=0;
1218: SETHELP(WHERE);
1219: /*
1220: &Access Requirements:&
1221:
1222: This menu allows you to edit the access requirement string for the
1223: selected feature/section of your BBS. You can edit the string
1224: directly (see documentation for details) or use the &Set Required...&
1225: options from this menu to automatically fill in the string for you.
1226: */
1227: sprintf(str,"%s Requirements",desc);
1228: switch(uifc.list(WIN_ACT|WIN_MID|WIN_SAV,0,0,60,&curar,0,str,opt)) {
1229: case -1:
1230: done=1;
1231: break;
1232: case 0:
1233: SETHELP(WHERE);
1234: /*
1235: Key word Symbol Description
1236: ������������������������������������������������������������������������
1237: AND & More than one requirement (optional)
1238: NOT ! Logical negation (i.e. NOT EQUAL)
1239: EQUAL = Equality required
1240: OR | Either of two or more parameters is required
1241: AGE $A User's age (years since birthdate, 0-255)
1242: BPS $B User's current connect rate (bps)
1243: FLAG $F User's flag (A-Z)
1244: LEVEL $L User's level (0-99)
1245: NODE $N Current node (1-250)
1246: PCR $P User's post/call ratio (0-100)
1247: SEX $S User's sex/gender (M or F)
1248: TIME $T Time of day (HH:MM, 00:00-23:59)
1249: TLEFT $R User's time left online (minutes, 0-255)
1250: TUSED $O User's time online this call (minutes, 0-255)
1251: USER $U User's number (1-xxxx)
1252: */
1253: uifc.input(WIN_MID|WIN_SAV,0,0,"Requirement String",ar,LEN_ARSTR
1254: ,K_EDIT|K_UPPER);
1255: break;
1256: case 1:
1257: i=1;
1258: strcpy(opt[0],"Yes");
1259: strcpy(opt[1],"No");
1260: opt[2][0]=0;
1261: if(uifc.savdepth)
1262: uifc.savnum++;
1263: SETHELP(WHERE);
1264: /*
1265: &Clear Requirements:&
1266:
1267: If you wish to clear the current requirement string, select &Yes&.
1268: Otherwise, select &No&.
1269: */
1270: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Are You Sure",opt);
1271: if(uifc.savdepth && uifc.savnum)
1272: uifc.savnum--;
1273: if(!i) {
1274: ar[0]=0;
1275: uifc.changes=1; }
1276: break;
1277: case 2:
1278: if(strlen(ar)>=30) {
1279: uifc.msg("Maximum string length reached");
1280: break; }
1281: i=whichlogic();
1282: if(i==-1)
1283: break;
1284: str[0]=0;
1285: SETHELP(WHERE);
1286: /*
1287: &Required Level:&
1288:
1289: You are being prompted to enter the security level to be used in this
1290: requirement evaluation. The valid range is 0 (zero) through 99.
1291: */
1292: uifc.input(WIN_MID|WIN_SAV,0,0,"Level",str,2,K_NUMBER);
1293: if(!str[0])
1294: break;
1295: if(ar[0]) {
1296: j=whichcond();
1297: if(j==-1)
1298: break;
1299: if(!j)
1300: strcat(ar," AND ");
1301: else
1302: strcat(ar," OR "); }
1303: strcat(ar,"LEVEL ");
1304: switch(i) {
1305: case 1:
1306: strcat(ar,"= ");
1307: break;
1308: case 2:
1309: strcat(ar,"NOT = ");
1310: break;
1311: case 3:
1312: strcat(ar,"NOT ");
1313: break; }
1314: strcat(ar,str);
1315: break;
1316: case 3:
1317: if(strlen(ar)>=30) {
1318: uifc.msg("Maximum string length reached");
1319: break; }
1320:
1321: for(i=0;i<4;i++)
1322: sprintf(opt[i],"Flag Set #%d",i+1);
1323: opt[i][0]=0;
1324: i=0;
1325: if(uifc.savdepth)
1326: uifc.savnum++;
1327: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Select Flag Set",opt);
1328: if(uifc.savdepth && uifc.savnum)
1329: uifc.savnum--;
1330: if(i==-1)
1331: break;
1332: str[0]=0;
1333: SETHELP(WHERE);
1334: /*
1335: &Required Flag:&
1336:
1337: You are being prompted to enter the security flag to be used in this
1338: requirement evaluation. The valid range is A through Z.
1339: */
1340: uifc.input(WIN_MID|WIN_SAV,0,0,"Flag (A-Z)",str,1
1341: ,K_UPPER|K_ALPHA);
1342: if(!str[0])
1343: break;
1344: if(ar[0]) {
1345: j=whichcond();
1346: if(j==-1)
1347: break;
1348: if(!j)
1349: strcat(ar," AND ");
1350: else
1351: strcat(ar," OR "); }
1352: strcat(ar,"FLAG ");
1353: if(i)
1354: strcat(ar,ultoa(i+1,tmp,10));
1355: strcat(ar,str);
1356: break;
1357: case 4:
1358: if(strlen(ar)>=30) {
1359: uifc.msg("Maximum string length reached");
1360: break; }
1361: i=whichlogic();
1362: if(i==-1)
1363: break;
1364: str[0]=0;
1365: SETHELP(WHERE);
1366: /*
1367: &Required Age:&
1368:
1369: You are being prompted to enter the user's age to be used in this
1370: requirement evaluation. The valid range is 0 through 255.
1371: */
1372: uifc.input(WIN_MID|WIN_SAV,0,0,"Age",str,3,K_NUMBER);
1373: if(!str[0])
1374: break;
1375: if(ar[0]) {
1376: j=whichcond();
1377: if(j==-1)
1378: break;
1379: if(!j)
1380: strcat(ar," AND ");
1381: else
1382: strcat(ar," OR "); }
1383: strcat(ar,"AGE ");
1384: switch(i) {
1385: case 1:
1386: strcat(ar,"= ");
1387: break;
1388: case 2:
1389: strcat(ar,"NOT = ");
1390: break;
1391: case 3:
1392: strcat(ar,"NOT ");
1393: break; }
1394: strcat(ar,str);
1395: break;
1396: case 5:
1397: if(strlen(ar)>=30) {
1398: uifc.msg("Maximum string length reached");
1399: break; }
1400: str[0]=0;
1401: SETHELP(WHERE);
1402: /*
1403: &Required Sex:&
1404:
1405: You are being prompted to enter the user's gender to be used in this
1406: requirement evaluation. The valid values are M or F (for male or
1407: female).
1408: */
1409: uifc.input(WIN_MID|WIN_SAV,0,0,"Sex (M or F)",str,1
1410: ,K_UPPER|K_ALPHA);
1411: if(!str[0])
1412: break;
1413: if(ar[0]) {
1414: j=whichcond();
1415: if(j==-1)
1416: break;
1417: if(!j)
1418: strcat(ar," AND ");
1419: else
1420: strcat(ar," OR "); }
1421: strcat(ar,"SEX ");
1422: strcat(ar,str);
1423: break;
1424: case 6:
1425: if(strlen(ar)>=30) {
1426: uifc.msg("Maximum string length reached");
1427: break; }
1428: i=whichlogic();
1429: if(i==-1)
1430: break;
1431: str[0]=0;
1432: SETHELP(WHERE);
1433: /*
1434: &Required Connect Rate (BPS):&
1435:
1436: You are being prompted to enter the connect rate to be used in this
1437: requirement evaluation. The valid range is 300 through 57600.
1438: */
1439: uifc.input(WIN_MID|WIN_SAV,0,0,"Connect Rate (BPS)",str,5,K_NUMBER);
1440: if(!str[0])
1441: break;
1442: j=atoi(str);
1443: if(j>=300 && j<30000) {
1444: j/=100;
1445: sprintf(str,"%d",j); }
1446: if(ar[0]) {
1447: j=whichcond();
1448: if(j==-1)
1449: break;
1450: if(!j)
1451: strcat(ar," AND ");
1452: else
1453: strcat(ar," OR "); }
1454: strcat(ar,"BPS ");
1455: switch(i) {
1456: case 1:
1457: strcat(ar,"= ");
1458: break;
1459: case 2:
1460: strcat(ar,"NOT = ");
1461: break;
1462: case 3:
1463: strcat(ar,"NOT ");
1464: break; }
1465: strcat(ar,str);
1466: break;
1467: case 7:
1468: if(strlen(ar)>=30) {
1469: uifc.msg("Maximum string length reached");
1470: break; }
1471: i=whichlogic();
1472: if(i==-1)
1473: break;
1474: str[0]=0;
1475: SETHELP(WHERE);
1476: /*
1477: &Required Post/Call Ratio:&
1478:
1479: You are being prompted to enter the post/call ratio to be used in this
1480: requirement evaluation (percentage). The valid range is 0 through 100.
1481: */
1482: uifc.input(WIN_MID|WIN_SAV,0,0,"Post/Call Ratio (percentage)"
1483: ,str,3,K_NUMBER);
1484: if(!str[0])
1485: break;
1486: if(ar[0]) {
1487: j=whichcond();
1488: if(j==-1)
1489: break;
1490: if(!j)
1491: strcat(ar," AND ");
1492: else
1493: strcat(ar," OR "); }
1494: strcat(ar,"PCR ");
1495: switch(i) {
1496: case 1:
1497: strcat(ar,"= ");
1498: break;
1499: case 2:
1500: strcat(ar,"NOT = ");
1501: break;
1502: case 3:
1503: strcat(ar,"NOT ");
1504: break; }
1505: strcat(ar,str);
1506: break;
1507: case 8:
1508: if(strlen(ar)>=30) {
1509: uifc.msg("Maximum string length reached");
1510: break; }
1511: i=whichlogic();
1512: if(i==-1)
1513: break;
1514: str[0]=0;
1515: SETHELP(WHERE);
1516: /*
1517: &Required Number of Credits:&
1518:
1519: You are being prompted to enter the number of credits (in &kilobytes&) to
1520: be used in this requirement evaluation. The valid range is 0 through
1521: 65535.
1522: */
1523: uifc.input(WIN_MID|WIN_SAV,0,0,"Required Credits",str,5,K_NUMBER);
1524: if(!str[0])
1525: break;
1526: if(ar[0]) {
1527: j=whichcond();
1528: if(j==-1)
1529: break;
1530: if(!j)
1531: strcat(ar," AND ");
1532: else
1533: strcat(ar," OR "); }
1534: strcat(ar,"CREDIT ");
1535: switch(i) {
1536: case 1:
1537: strcat(ar,"= ");
1538: break;
1539: case 2:
1540: strcat(ar,"NOT = ");
1541: break;
1542: case 3:
1543: strcat(ar,"NOT ");
1544: break; }
1545: strcat(ar,str);
1546: break;
1547: case 9:
1548: if(strlen(ar)>=30) {
1549: uifc.msg("Maximum string length reached");
1550: break; }
1551: i=whichlogic();
1552: if(i==-1)
1553: break;
1554: str[0]=0;
1555: SETHELP(WHERE);
1556: /*
1557: &Required Upload/Download Byte Ratio:&
1558:
1559: You are being prompted to enter the upload/download ratio to be used in
1560: this requirement evaluation (percentage). The valid range is 0 through
1561: 100. This ratio is based on the number of &bytes& uploaded by the user
1562: divided by the number of bytes downloaded.
1563: */
1564: uifc.input(WIN_MID|WIN_SAV,0,0,"Upload/Download Byte Ratio (percentage)"
1565: ,str,3,K_NUMBER);
1566: if(!str[0])
1567: break;
1568: if(ar[0]) {
1569: j=whichcond();
1570: if(j==-1)
1571: break;
1572: if(!j)
1573: strcat(ar," AND ");
1574: else
1575: strcat(ar," OR "); }
1576: strcat(ar,"UDR ");
1577: switch(i) {
1578: case 1:
1579: strcat(ar,"= ");
1580: break;
1581: case 2:
1582: strcat(ar,"NOT = ");
1583: break;
1584: case 3:
1585: strcat(ar,"NOT ");
1586: break; }
1587: strcat(ar,str);
1588: break;
1589: case 10:
1590: if(strlen(ar)>=30) {
1591: uifc.msg("Maximum string length reached");
1592: break; }
1593: i=whichlogic();
1594: if(i==-1)
1595: break;
1596: str[0]=0;
1597: SETHELP(WHERE);
1598: /*
1599: &Required Upload/Download File Ratio:&
1600:
1601: You are being prompted to enter the upload/download ratio to be used in
1602: this requirement evaluation (percentage). The valid range is 0 through
1603: 100. This ratio is based on the number of &files& uploaded by the user
1604: divided by the number of files downloaded.
1605: */
1606: uifc.input(WIN_MID|WIN_SAV,0,0
1607: ,"Upload/Download File Ratio (percentage)"
1608: ,str,3,K_NUMBER);
1609: if(!str[0])
1610: break;
1611: if(ar[0]) {
1612: j=whichcond();
1613: if(j==-1)
1614: break;
1615: if(!j)
1616: strcat(ar," AND ");
1617: else
1618: strcat(ar," OR "); }
1619: strcat(ar,"UDFR ");
1620: switch(i) {
1621: case 1:
1622: strcat(ar,"= ");
1623: break;
1624: case 2:
1625: strcat(ar,"NOT = ");
1626: break;
1627: case 3:
1628: strcat(ar,"NOT ");
1629: break; }
1630: strcat(ar,str);
1631: break;
1632: case 11:
1633: if(strlen(ar)>=30) {
1634: uifc.msg("Maximum string length reached");
1635: break; }
1636: i=0;
1637: strcpy(opt[0],"Before");
1638: strcpy(opt[1],"After");
1639: opt[2][0]=0;
1640: if(uifc.savdepth)
1641: uifc.savnum++;
1642: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0,"Time Relationship",opt);
1643: if(uifc.savdepth && uifc.savnum)
1644: uifc.savnum--;
1645: if(i==-1)
1646: break;
1647: str[0]=0;
1648: SETHELP(WHERE);
1649: /*
1650: &Required Time of Day:&
1651:
1652: You are being prompted to enter the time of day to be used in this
1653: requirement evaluation (24 hour HH:MM format). The valid range is 0
1654: through 23:59.
1655: */
1656: uifc.input(WIN_MID|WIN_SAV,0,0,"Time of Day (HH:MM)",str,5,K_UPPER);
1657: if(!str[0])
1658: break;
1659: if(ar[0]) {
1660: j=whichcond();
1661: if(j==-1)
1662: break;
1663: if(!j)
1664: strcat(ar," AND ");
1665: else
1666: strcat(ar," OR "); }
1667: strcat(ar,"TIME ");
1668: if(!i)
1669: strcat(ar,"NOT ");
1670: strcat(ar,str);
1671: break;
1672: case 12:
1673: if(strlen(ar)>=30) {
1674: uifc.msg("Maximum string length reached");
1675: break; }
1676: i=whichlogic();
1677: if(i==-1)
1678: break;
1679: SETHELP(WHERE);
1680: /*
1681: &Required Day of Week:&
1682:
1683: You are being prompted to select a day of the week as an access
1684: requirement value.
1685: */
1686: for(n=0;n<7;n++)
1687: strcpy(opt[n],wday[n]);
1688: opt[n][0]=0;
1689: n=0;
1690: if(uifc.savdepth)
1691: uifc.savnum++;
1692: n=uifc.list(WIN_MID|WIN_SAV,0,0,0,&n,0,"Select Day of Week",opt);
1693: if(uifc.savdepth && uifc.savnum)
1694: uifc.savnum--;
1695: if(n==-1)
1696: break;
1697: strcpy(str,wday[n]);
1698: strupr(str);
1699: if(ar[0]) {
1700: j=whichcond();
1701: if(j==-1)
1702: break;
1703: if(!j)
1704: strcat(ar," AND ");
1705: else
1706: strcat(ar," OR "); }
1707: strcat(ar,"DAY ");
1708: switch(i) {
1709: case 1:
1710: strcat(ar,"= ");
1711: break;
1712: case 2:
1713: strcat(ar,"NOT = ");
1714: break;
1715: case 3:
1716: strcat(ar,"NOT ");
1717: break; }
1718: strcat(ar,str);
1719: break;
1720: case 13:
1721: if(strlen(ar)>=30) {
1722: uifc.msg("Maximum string length reached");
1723: break; }
1724: i=whichlogic();
1725: if(i==-1)
1726: break;
1727: str[0]=0;
1728: SETHELP(WHERE);
1729: /*
1730: &Required Node:&
1731:
1732: You are being prompted to enter the number of a node to be used in this
1733: requirement evaluation. The valid range is 1 through 250.
1734: */
1735: uifc.input(WIN_MID|WIN_SAV,0,0,"Node Number",str,3,K_NUMBER);
1736: if(!str[0])
1737: break;
1738: if(ar[0]) {
1739: j=whichcond();
1740: if(j==-1)
1741: break;
1742: if(!j)
1743: strcat(ar," AND ");
1744: else
1745: strcat(ar," OR "); }
1746: strcat(ar,"NODE ");
1747: switch(i) {
1748: case 1:
1749: strcat(ar,"= ");
1750: break;
1751: case 2:
1752: strcat(ar,"NOT = ");
1753: break;
1754: case 3:
1755: strcat(ar,"NOT ");
1756: break; }
1757: strcat(ar,str);
1758: break;
1759: case 14:
1760: if(strlen(ar)>=30) {
1761: uifc.msg("Maximum string length reached");
1762: break; }
1763: i=whichlogic();
1764: if(i==-1)
1765: break;
1766: str[0]=0;
1767: SETHELP(WHERE);
1768: /*
1769: &Required User Number:&
1770:
1771: You are being prompted to enter the user's number to be used in this
1772: requirement evaluation.
1773: */
1774: uifc.input(WIN_MID|WIN_SAV,0,0,"User Number",str,5,K_NUMBER);
1775: if(!str[0])
1776: break;
1777: if(ar[0]) {
1778: j=whichcond();
1779: if(j==-1)
1780: break;
1781: if(!j)
1782: strcat(ar," AND ");
1783: else
1784: strcat(ar," OR "); }
1785: strcat(ar,"USER ");
1786: switch(i) {
1787: case 1:
1788: strcat(ar,"= ");
1789: break;
1790: case 2:
1791: strcat(ar,"NOT = ");
1792: break;
1793: case 3:
1794: strcat(ar,"NOT ");
1795: break; }
1796: strcat(ar,str);
1797: break;
1798:
1799: case 15:
1800: if(strlen(ar)>=30) {
1801: uifc.msg("Maximum string length reached");
1802: break; }
1803: i=whichlogic();
1804: if(i==-1)
1805: break;
1806: str[0]=0;
1807: SETHELP(WHERE);
1808: /*
1809: &Required Time Remaining:&
1810:
1811: You are being prompted to enter the time remaining to be used in this
1812: requirement evaluation (in &minutes&). The valid range is 0 through 255.
1813: */
1814: uifc.input(WIN_MID|WIN_SAV,0,0,"Time Remaining (minutes)"
1815: ,str,3,K_NUMBER);
1816: if(!str[0])
1817: break;
1818: if(ar[0]) {
1819: j=whichcond();
1820: if(j==-1)
1821: break;
1822: if(!j)
1823: strcat(ar," AND ");
1824: else
1825: strcat(ar," OR "); }
1826: strcat(ar,"TLEFT ");
1827: switch(i) {
1828: case 1:
1829: strcat(ar,"= ");
1830: break;
1831: case 2:
1832: strcat(ar,"NOT = ");
1833: break;
1834: case 3:
1835: strcat(ar,"NOT ");
1836: break; }
1837: strcat(ar,str);
1838: break;
1839:
1840: case 16:
1841: if(strlen(ar)>=30) {
1842: uifc.msg("Maximum string length reached");
1843: break; }
1844: i=whichlogic();
1845: if(i==-1)
1846: break;
1847: str[0]=0;
1848: SETHELP(WHERE);
1849: /*
1850: &Required Days Till User Account Expiration:&
1851:
1852: You are being prompted to enter the required number of days till the
1853: user's account will expire.
1854: */
1855: uifc.input(WIN_MID|WIN_SAV,0,0,"Days Till Expiration"
1856: ,str,5,K_NUMBER);
1857: if(!str[0])
1858: break;
1859: if(ar[0]) {
1860: j=whichcond();
1861: if(j==-1)
1862: break;
1863: if(!j)
1864: strcat(ar," AND ");
1865: else
1866: strcat(ar," OR "); }
1867: strcat(ar,"EXPIRE ");
1868: switch(i) {
1869: case 1:
1870: strcat(ar,"= ");
1871: break;
1872: case 2:
1873: strcat(ar,"NOT = ");
1874: break;
1875: case 3:
1876: strcat(ar,"NOT ");
1877: break; }
1878: strcat(ar,str);
1879: break;
1880: } }
1881: sprintf(inar,"%.*s",LEN_ARSTR,ar);
1882: }
1883:
1884: int code_ok(char *str)
1885: {
1886:
1887: if(!strlen(str))
1888: return(0);
1889: if(strcspn(str," \\/|<>*?+[]:=\";,")!=strlen(str))
1890: return(0);
1891: return(1);
1892: }
1893:
1894: #ifdef __BORLANDC__
1895: #pragma argsused
1896: #endif
1897: int lprintf(int level, char *fmt, ...)
1898: {
1899: va_list argptr;
1900: char sbuf[1024];
1901:
1902: va_start(argptr,fmt);
1903: vsnprintf(sbuf,sizeof(sbuf),fmt,argptr);
1904: sbuf[sizeof(sbuf)-1]=0;
1905: va_end(argptr);
1906: strip_ctrl(sbuf);
1907: uifc.msg(sbuf);
1908: return(0);
1909: }
1910:
1911: void bail(int code)
1912: {
1913: if(code) {
1914: printf("\nHit enter to continue...");
1915: getchar();
1916: }
1917: else if(forcesave) {
1918: uifc.pop("Loading Configs...");
1919: read_main_cfg(&cfg,error);
1920: read_msgs_cfg(&cfg,error);
1921: read_file_cfg(&cfg,error);
1922: read_chat_cfg(&cfg,error);
1923: read_xtrn_cfg(&cfg,error);
1924: uifc.pop(0);
1925: cfg.new_install=new_install;
1926: write_main_cfg(&cfg,backup_level);
1927: write_msgs_cfg(&cfg,backup_level);
1928: write_file_cfg(&cfg,backup_level);
1929: write_chat_cfg(&cfg,backup_level);
1930: write_xtrn_cfg(&cfg,backup_level); }
1931:
1932: uifc.bail();
1933:
1934: exit(code);
1935: }
1936:
1937: /****************************************************************************/
1938: /* Error handling routine. Prints to local and remote screens the error */
1939: /* information, function, action, object and access and then attempts to */
1940: /* write the error information into the file ERROR.LOG in the text dir. */
1941: /****************************************************************************/
1942: void errormsg(int line, char *source, char action, char *object, ulong access)
1943: {
1944: char actstr[256];
1945:
1946: char scrn_buf[MAX_BFLN];
1947: gettext(1,1,80,uifc.scrn_len,scrn_buf);
1948: clrscr();
1949:
1950: switch(action) {
1951: case ERR_OPEN:
1952: strcpy(actstr,"opening");
1953: break;
1954: case ERR_CLOSE:
1955: strcpy(actstr,"closeing");
1956: break;
1957: case ERR_FDOPEN:
1958: strcpy(actstr,"fdopen");
1959: break;
1960: case ERR_READ:
1961: strcpy(actstr,"reading");
1962: break;
1963: case ERR_WRITE:
1964: strcpy(actstr,"writing");
1965: break;
1966: case ERR_REMOVE:
1967: strcpy(actstr,"removing");
1968: break;
1969: case ERR_ALLOC:
1970: strcpy(actstr,"allocating memory");
1971: break;
1972: case ERR_CHK:
1973: strcpy(actstr,"checking");
1974: break;
1975: case ERR_LEN:
1976: strcpy(actstr,"checking length");
1977: break;
1978: case ERR_EXEC:
1979: strcpy(actstr,"executing");
1980: break;
1981: default:
1982: strcpy(actstr,"UNKNOWN"); }
1983: printf("ERROR - line: %d\n",line);
1984: printf(" file: %s\n",source);
1985: printf(" action: %s\n",actstr);
1986: printf(" object: %s\n",object);
1987: printf(" access: %ld (%lx)\n",access,access);
1988: printf("\nHit enter to continue...");
1989: getchar();
1990: puttext(1,1,80,uifc.scrn_len,scrn_buf);
1991: }
1992:
1993: /* Prepare a string to be used as an internal code */
1994: char* prep_code(char *str)
1995: {
1996: char tmp[1024];
1997: int i,j;
1998:
1999: for(i=j=0;str[i] && i<sizeof(tmp);i++)
2000: if(str[i]>' ' && !(str[i]&0x80) && str[i]!='*' && str[i]!='?'
2001: && strchr(ILLEGAL_FILENAME_CHARS,str[i])==NULL)
2002: tmp[j++]=str[i];
2003: tmp[j]=0;
2004: strcpy(str,tmp);
2005: if(j>=LEN_CODE) { /* Extra chars? Strip symbolic chars */
2006: for(i=j=0;str[i];i++)
2007: if(isalnum(str[i]))
2008: tmp[j++]=str[i];
2009: tmp[j]=0;
2010: strcpy(str,tmp);
2011: }
2012: return(str);
2013: }
2014:
2015: /* End of SCFG.C */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.