|
|
1.1 root 1: /* scfgnode.c */
2:
3: /* $Id: scfgnode.c,v 1.23 2004/12/21 01:40:04 rswindell Exp $ */
4:
5: /****************************************************************************
6: * @format.tab-size 4 (Plain Text/Source Code File Header) *
7: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
8: * *
9: * Copyright 2002 Rob Swindell - http://www.synchro.net/copyright.html *
10: * *
11: * This program is free software; you can redistribute it and/or *
12: * modify it under the terms of the GNU General Public License *
13: * as published by the Free Software Foundation; either version 2 *
14: * of the License, or (at your option) any later version. *
15: * See the GNU General Public License for more details: gpl.txt or *
16: * http://www.fsf.org/copyleft/gpl.html *
17: * *
18: * Anonymous FTP access to the most recent released source is available at *
19: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
20: * *
21: * Anonymous CVS access to the development source and modification history *
22: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
23: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
24: * (just hit return, no password is necessary) *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
26: * *
27: * For Synchronet coding style and modification guidelines, see *
28: * http://www.synchro.net/source.html *
29: * *
30: * You are encouraged to submit any modifications (preferably in Unix diff *
31: * format) via e-mail to [email protected] *
32: * *
33: * Note: If this box doesn't appear square, then you need to fix your tabs. *
34: ****************************************************************************/
35:
36: #include "scfg.h"
37:
38: void node_menu()
39: {
40: char str[81],savnode=0;
41: int i,j;
42: static int node_menu_dflt, node_bar;
43:
44: while(1) {
45: for(i=0;i<cfg.sys_nodes;i++)
46: sprintf(opt[i],"Node %d",i+1);
47: opt[i][0]=0;
48: j=WIN_ORG|WIN_ACT|WIN_INSACT|WIN_DELACT;
49: if(cfg.sys_nodes>1)
50: j|=WIN_DEL|WIN_GET;
51: if(cfg.sys_nodes<MAX_NODES && cfg.sys_nodes<MAX_OPTS)
52: j|=WIN_INS;
53: if(savnode)
54: j|=WIN_PUT;
55: SETHELP(WHERE);
56: /*
57: &Node List:&
58:
59: This is the list of configured nodes in your system.
60:
61: To add a node, hit INS .
62:
63: To delete a node, hit DEL .
64:
65: To configure a node, select it using the arrow keys and hit ENTER .
66:
67: To copy a node's configuration to another node, first select the source
68: node with the arrow keys and hit F5 . Then select the destination
69: node and hit F6 .
70: */
71:
72: i=uifc.list(j,0,0,13,&node_menu_dflt,&node_bar,"Nodes",opt);
73: if(i==-1) {
74: if(savnode) {
75: free_node_cfg(&cfg);
76: savnode=0; }
77: return; }
78:
79: if((i&MSK_ON)==MSK_DEL) {
80: strcpy(opt[0],"Yes");
81: strcpy(opt[1],"No");
82: opt[2][0]=0;
83: sprintf(str,"Delete Node %d",cfg.sys_nodes);
84: i=1;
85: SETHELP(WHERE);
86: /*
87: &Delete Node:&
88:
89: If you are positive you want to delete this node, select &Yes&. Otherwise,
90: select &No& or hit ESC .
91: */
92: i=uifc.list(WIN_MID,0,0,0,&i,0,str,opt);
93: if(!i) {
94: --cfg.sys_nodes;
95: /* FREE(cfg.node_path[cfg.sys_nodes]); */
96: cfg.new_install=new_install;
97: write_main_cfg(&cfg,backup_level);
98: refresh_cfg(&cfg);
99: }
100: continue; }
101: if((i&MSK_ON)==MSK_INS) {
102: strcpy(cfg.node_dir,cfg.node_path[cfg.sys_nodes-1]);
103: i=cfg.sys_nodes+1;
104: uifc.pop("Reading NODE.CNF...");
105: read_node_cfg(&cfg,error);
106: uifc.pop(0);
107: sprintf(str,"../node%d/",i);
108: sprintf(tmp,"Node %d Path",i);
109: SETHELP(WHERE);
110: /*
111: &Node Path:&
112:
113: This is the path to this node's private directory where its separate
114: configuration and data files are stored.
115:
116: The drive and directory of this path can be set to any valid DOS
117: directory that can be accessed by &ALL& nodes and &MUST NOT& be on a RAM disk
118: or other volatile media.
119:
120: If you want to abort the creation of this new node, hit ESC .
121: */
122: j=uifc.input(WIN_MID,0,0,tmp,str,50,K_EDIT);
123: uifc.changes=0;
124: if(j<2)
125: continue;
126: truncsp(str);
127: strcpy(cfg.node_path[i-1],str);
128: if(str[strlen(str)-1]=='\\' || str[strlen(str)-1]=='/')
129: str[strlen(str)-1]=0;
130: MKDIR(str);
131: cfg.node_num=++cfg.sys_nodes;
132: sprintf(cfg.node_name,"Node %u",cfg.node_num);
133: cfg.new_install=new_install;
134: write_node_cfg(&cfg,backup_level);
135: write_main_cfg(&cfg,backup_level);
136: free_node_cfg(&cfg);
137: refresh_cfg(&cfg);
138: continue;
139: }
140: if((i&MSK_ON)==MSK_GET) {
141: if(savnode)
142: free_node_cfg(&cfg);
143: i&=MSK_OFF;
144: strcpy(cfg.node_dir,cfg.node_path[i]);
145: uifc.pop("Reading NODE.CNF...");
146: read_node_cfg(&cfg,error);
147: uifc.pop(0);
148: savnode=1;
149: continue; }
150: if((i&MSK_ON)==MSK_PUT) {
151: i&=MSK_OFF;
152: strcpy(cfg.node_dir,cfg.node_path[i]);
153: cfg.node_num=i+1;
154: write_node_cfg(&cfg,backup_level);
155: refresh_cfg(&cfg);
156: uifc.changes=1;
157: continue;
158: }
159:
160: if(savnode) {
161: free_node_cfg(&cfg);
162: savnode=0; }
163: strcpy(cfg.node_dir,cfg.node_path[i]);
164: prep_dir(cfg.ctrl_dir, cfg.node_dir, sizeof(cfg.node_dir));
165:
166: uifc.pop("Reading NODE.CNF...");
167: read_node_cfg(&cfg,error);
168: uifc.pop(0);
169: if(cfg.node_num!=i+1) { /* Node number isn't right? */
170: cfg.node_num=i+1; /* so fix it */
171: write_node_cfg(&cfg,backup_level); } /* and write it back */
172: node_cfg();
173:
174: free_node_cfg(&cfg); }
175: }
176:
177: void node_cfg()
178: {
179: static int node_dflt;
180: char done,str[81];
181: static int adv_dflt,tog_dflt,tog_bar;
182: int i;
183:
184: while(1) {
185: i=0;
186: sprintf(opt[i++],"%-27.27s%.40s","Logon Requirements",cfg.node_arstr);
187: strcpy(opt[i++],"Toggle Options...");
188: strcpy(opt[i++],"Advanced Options...");
189: opt[i][0]=0;
190: sprintf(str,"Node %d Configuration",cfg.node_num);
191: SETHELP(WHERE);
192: /*
193: &Node Configuration Menu:&
194:
195: This is the node configuration menu. The options available from this
196: menu will only affect the selected node's configuration.
197:
198: Options with a trailing &...& will produce a sub-menu of more options.
199: */
200: switch(uifc.list(WIN_ACT|WIN_CHE|WIN_BOT|WIN_RHT,0,0,60,&node_dflt,0
201: ,str,opt)) {
202: case -1:
203: i=save_changes(WIN_MID|WIN_SAV);
204: if(!i) {
205: write_node_cfg(&cfg,backup_level);
206: refresh_cfg(&cfg);
207: }
208: if(i!=-1)
209: return;
210: break;
211: case 0:
212: sprintf(str,"Node %u Logon",cfg.node_num);
213: getar(str,cfg.node_arstr);
214: break;
215: case 1:
216: done=0;
217: while(!done) {
218: i=0;
219: #if 0 /* no longer used */
220: sprintf(opt[i++],"%-27.27s%s","Low Priority String Input"
221: ,cfg.node_misc&NM_LOWPRIO ? "Yes":"No");
222: #endif
223: sprintf(opt[i++],"%-27.27s%s","Allow Login by User Number"
224: ,cfg.node_misc&NM_NO_NUM ? "No":"Yes");
225: sprintf(opt[i++],"%-27.27s%s","Allow Login by Real Name"
226: ,cfg.node_misc&NM_LOGON_R ? "Yes":"No");
227: sprintf(opt[i++],"%-27.27s%s","Always Prompt for Password"
228: ,cfg.node_misc&NM_LOGON_P ? "Yes":"No");
229: sprintf(opt[i++],"%-27.27s%s","Allow 8-bit Remote Logins"
230: ,cfg.node_misc&NM_7BITONLY ? "No":"Yes");
231: sprintf(opt[i++],"%-27.27s%s","Spinning Pause Prompt"
232: ,cfg.node_misc&NM_NOPAUSESPIN ? "No":"Yes");
233: sprintf(opt[i++],"%-27.27s%s","Keep Node File Open"
234: ,cfg.node_misc&NM_CLOSENODEDAB ? "No":"Yes");
235:
236: opt[i][0]=0;
237: uifc.savnum=0;
238: SETHELP(WHERE);
239: /*
240: &Node Toggle Options:&
241:
242: This is the toggle options menu for the selected node's configuration.
243:
244: The available options from this menu can all be toggled between two or
245: more states, such as &Yes& and &No&.
246: */
247: switch(uifc.list(WIN_BOT|WIN_RHT|WIN_ACT|WIN_SAV,3,2,35,&tog_dflt
248: ,&tog_bar,"Toggle Options",opt)) {
249: case -1:
250: done=1;
251: break;
252: #if 0 /* no longer used */
253: case 0:
254: i=cfg.node_misc&NM_LOWPRIO ? 0:1;
255: strcpy(opt[0],"Yes");
256: strcpy(opt[1],"No");
257: opt[2][0]=0;
258: uifc.savnum=1;
259: SETHELP(WHERE);
260: /*
261: &Low Priority String Input:&
262:
263: Normally, Synchronet will not give up time slices (under a multitasker)
264: when users are prompted for a string of characters. This is considered
265: a high priority task.
266:
267: Setting this option to &Yes& will force Synchronet to give up time slices
268: during string input, possibly causing jerky keyboard input from the
269: user, but improving aggregate system performance under multitaskers.
270: */
271: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
272: ,"Low Priority String Input",opt);
273: if(i==0 && !(cfg.node_misc&NM_LOWPRIO)) {
274: cfg.node_misc|=NM_LOWPRIO;
275: uifc.changes=1; }
276: else if(i==1 && (cfg.node_misc&NM_LOWPRIO)) {
277: cfg.node_misc&=~NM_LOWPRIO;
278: uifc.changes=1; }
279: break;
280: #endif
281: case 0:
282: i=cfg.node_misc&NM_NO_NUM ? 1:0;
283: strcpy(opt[0],"Yes");
284: strcpy(opt[1],"No");
285: opt[2][0]=0;
286: uifc.savnum=1;
287: SETHELP(WHERE);
288: /*
289: &Allow Login by User Number:&
290:
291: If you want users to be able login using their user number at the &NN:&
292: set this option to &Yes&.
293: */
294: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
295: ,"Allow Login by User Number",opt);
296: if(i==0 && cfg.node_misc&NM_NO_NUM) {
297: cfg.node_misc&=~NM_NO_NUM;
298: uifc.changes=1; }
299: else if(i==1 && !(cfg.node_misc&NM_NO_NUM)) {
300: cfg.node_misc|=NM_NO_NUM;
301: uifc.changes=1; }
302: break;
303: case 1:
304: i=cfg.node_misc&NM_LOGON_R ? 0:1;
305: strcpy(opt[0],"Yes");
306: strcpy(opt[1],"No");
307: opt[2][0]=0;
308: uifc.savnum=1;
309: SETHELP(WHERE);
310: /*
311: &Allow Login by Real Name:&
312:
313: If you want users to be able login using their real name as well as
314: their alias, set this option to &Yes&.
315: */
316: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
317: ,"Allow Login by Real Name",opt);
318: if(i==0 && !(cfg.node_misc&NM_LOGON_R)) {
319: cfg.node_misc|=NM_LOGON_R;
320: uifc.changes=1; }
321: else if(i==1 && (cfg.node_misc&NM_LOGON_R)) {
322: cfg.node_misc&=~NM_LOGON_R;
323: uifc.changes=1; }
324: break;
325: case 2:
326: i=cfg.node_misc&NM_LOGON_P ? 0:1;
327: strcpy(opt[0],"Yes");
328: strcpy(opt[1],"No");
329: opt[2][0]=0;
330: uifc.savnum=1;
331: SETHELP(WHERE);
332: /*
333: &Always Prompt for Password:&
334:
335: If you want to have attempted logins using an unknown user name still
336: prompt for a password, set this option to &Yes&.
337: */
338: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
339: ,"Always Prompt for Password",opt);
340: if(i==0 && !(cfg.node_misc&NM_LOGON_P)) {
341: cfg.node_misc|=NM_LOGON_P;
342: uifc.changes=1; }
343: else if(i==1 && (cfg.node_misc&NM_LOGON_P)) {
344: cfg.node_misc&=~NM_LOGON_P;
345: uifc.changes=1; }
346: break;
347: case 3:
348: i=cfg.node_misc&NM_7BITONLY ? 0:1;
349: strcpy(opt[0],"Yes");
350: strcpy(opt[1],"No");
351: opt[2][0]=0;
352: uifc.savnum=1;
353: SETHELP(WHERE);
354: /*
355: &Allow 8-bit Remote Input During Login:&
356:
357: If you wish to allow E-7-1 terminals to use this node, you must set this
358: option to &No&. This will also eliminate the ability of 8-bit remote users
359: to send IBM extended ASCII characters during the login sequence.
360: */
361: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
362: ,"Allow 8-bit Remote Input During Login",opt);
363: if(i==1 && !(cfg.node_misc&NM_7BITONLY)) {
364: cfg.node_misc|=NM_7BITONLY;
365: uifc.changes=1; }
366: else if(i==0 && (cfg.node_misc&NM_7BITONLY)) {
367: cfg.node_misc&=~NM_7BITONLY;
368: uifc.changes=1; }
369: break;
370: case 4:
371: i=cfg.node_misc&NM_NOPAUSESPIN ? 1:0;
372: strcpy(opt[0],"Yes");
373: strcpy(opt[1],"No");
374: opt[2][0]=0;
375: uifc.savnum=1;
376: SETHELP(WHERE);
377: /*
378: &Spinning Pause Prompt:&
379:
380: If you want to have a spinning cursor at the [Hit a key] prompt, set
381: this option to &Yes&.
382: */
383: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
384: ,"Spinning Cursor at Pause Prompt",opt);
385: if(i==0 && cfg.node_misc&NM_NOPAUSESPIN) {
386: cfg.node_misc&=~NM_NOPAUSESPIN;
387: uifc.changes=1; }
388: else if(i==1 && !(cfg.node_misc&NM_NOPAUSESPIN)) {
389: cfg.node_misc|=NM_NOPAUSESPIN;
390: uifc.changes=1; }
391: break;
392: case 5:
393: i=cfg.node_misc&NM_CLOSENODEDAB ? 1:0;
394: strcpy(opt[0],"Yes");
395: strcpy(opt[1],"No");
396: opt[2][0]=0;
397: uifc.savnum=1;
398: SETHELP(WHERE);
399: /*
400: &Keep Node File Open:&
401:
402: If you want to keep the shared node file (&ctrl/node.dab&) open,
403: (for better performance and reliability) set this option to &Yes&.
404: If want to keep the file closed (for &Samba& compatiblity), set this
405: option to &No&.
406: */
407: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
408: ,"Keep Node File Open",opt);
409: if(i==0 && cfg.node_misc&NM_CLOSENODEDAB) {
410: cfg.node_misc&=~NM_CLOSENODEDAB;
411: uifc.changes=1; }
412: else if(i==1 && !(cfg.node_misc&NM_CLOSENODEDAB)) {
413: cfg.node_misc|=NM_CLOSENODEDAB;
414: uifc.changes=1; }
415: break;
416: } }
417: break;
418: case 2:
419: done=0;
420: while(!done) {
421: i=0;
422: sprintf(opt[i++],"%-27.27s%s","Validation User"
423: ,cfg.node_valuser ? ultoa(cfg.node_valuser,tmp,10) : "Nobody");
424: sprintf(opt[i++],"%-27.27s%u seconds","Semaphore Frequency"
425: ,cfg.node_sem_check);
426: sprintf(opt[i++],"%-27.27s%u seconds","Statistics Frequency"
427: ,cfg.node_stat_check);
428: sprintf(opt[i++],"%-27.27s%u seconds","Inactivity Warning"
429: ,cfg.sec_warn);
430: sprintf(opt[i++],"%-27.27s%u seconds","Inactivity Disconnection"
431: ,cfg.sec_hangup);
432: sprintf(tmp,"$%d.00",cfg.node_dollars_per_call);
433: sprintf(opt[i++],"%-27.27s%.40s","Daily Event",cfg.node_daily);
434: sprintf(opt[i++],"%-27.27s%.40s","Text Directory",cfg.text_dir);
435: opt[i][0]=0;
436: uifc.savnum=0;
437: SETHELP(WHERE);
438: /*
439: &Node Advanced Options:&
440:
441: This is the advanced options menu for the selected node. The available
442: options are of an advanced nature and should not be modified unless you
443: are sure of the consequences and necessary preparation.
444: */
445: switch(uifc.list(WIN_T2B|WIN_RHT|WIN_ACT|WIN_SAV,2,0,60,&adv_dflt,0
446: ,"Advanced Options",opt)) {
447: case -1:
448: done=1;
449: break;
450: case 0:
451: ultoa(cfg.node_valuser,str,10);
452: SETHELP(WHERE);
453: /*
454: &Validation User Number:&
455:
456: When a caller logs onto the system as &New&, he or she must send
457: validation feedback to the sysop. This feature can be disabled by
458: setting this value to &0&, allowing new users to logon without sending
459: validation feedback. If you want new users on this node to be forced to
460: send validation feedback, set this value to the number of the user to
461: whom the feedback is sent. The normal value of this option is &1& for
462: user number one.
463: */
464: uifc.input(WIN_MID,0,13,"Validation User Number (0=Nobody)"
465: ,str,4,K_NUMBER|K_EDIT);
466: cfg.node_valuser=atoi(str);
467: break;
468: case 1:
469: ultoa(cfg.node_sem_check,str,10);
470: SETHELP(WHERE);
471: /*
472: &Semaphore Check Frequency While Waiting for Call (in seconds):&
473:
474: This is the number of seconds between semaphore checks while this node
475: is waiting for a caller. Default is &60& seconds.
476: */
477: uifc.input(WIN_MID|WIN_SAV,0,14
478: ,"Seconds Between Semaphore Checks"
479: ,str,3,K_NUMBER|K_EDIT);
480: cfg.node_sem_check=atoi(str);
481: break;
482: case 2:
483: ultoa(cfg.node_stat_check,str,10);
484: SETHELP(WHERE);
485: /*
486: &Statistics Check Frequency While Waiting for Call (in seconds):&
487:
488: This is the number of seconds between static checks while this node
489: is waiting for a caller. Default is &10& seconds.
490: */
491: uifc.input(WIN_MID|WIN_SAV,0,14
492: ,"Seconds Between Statistic Checks"
493: ,str,3,K_NUMBER|K_EDIT);
494: cfg.node_stat_check=atoi(str);
495: break;
496: case 3:
497: ultoa(cfg.sec_warn,str,10);
498: SETHELP(WHERE);
499: /*
500: &Seconds Before Inactivity Warning:&
501:
502: This is the number of seconds the user must be inactive before a
503: warning will be given. Default is &180& seconds.
504: */
505: uifc.input(WIN_MID|WIN_SAV,0,14
506: ,"Seconds Before Inactivity Warning"
507: ,str,4,K_NUMBER|K_EDIT);
508: cfg.sec_warn=atoi(str);
509: break;
510: case 4:
511: ultoa(cfg.sec_hangup,str,10);
512: SETHELP(WHERE);
513: /*
514: &Seconds Before Inactivity Disconnection:&
515:
516: This is the number of seconds the user must be inactive before they
517: will be automatically disconnected. Default is &300& seconds.
518: */
519: uifc.input(WIN_MID|WIN_SAV,0,14
520: ,"Seconds Before Inactivity Disconnection"
521: ,str,4,K_NUMBER|K_EDIT);
522: cfg.sec_hangup=atoi(str);
523: break;
524: case 5:
525: SETHELP(WHERE);
526: /*
527: &Daily Event:&
528:
529: If you have an event that this node should run every day, enter the
530: command line for that event here.
531:
532: An event can be any valid DOS command line. If multiple programs or
533: commands are required, use a batch file.
534:
535: Remember: The &%!& command line specifier is an abreviation for your
536: configured &EXEC& directory path.
537: */
538: uifc.input(WIN_MID|WIN_SAV,0,10,"Daily Event"
539: ,cfg.node_daily,sizeof(cfg.node_daily)-1,K_EDIT);
540: break;
541: case 6:
542: SETHELP(WHERE);
543: /*
544: &Text Directory:&
545:
546: Your text directory contains &read-only& text files. Synchronet never
547: &writes& to any files in this directory so it &CAN& be placed on a RAM
548: disk or other volatile media. This directory contains the system's menus
549: and other important text files, so be sure the files and directories are
550: moved to this directory if you decide to change it.
551:
552: This option allows you to change the location of your control directory.
553: The &\TEXT\& suffix (sub-directory) cannot be changed or removed.
554: */
555: uifc.input(WIN_MID|WIN_SAV,0,10,"Text Directory"
556: ,cfg.text_dir,sizeof(cfg.text_dir)-1,K_EDIT);
557: break;
558: }
559: }
560: break;
561: }
562: }
563: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.