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