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