|
|
1.1 root 1: /* scfgnode.c */
2:
3: /* $Id: scfgnode.c,v 1.26 2006/05/03 00:27:37 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 2006 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: SETHELP(WHERE);
238: /*
239: &Node Toggle Options:&
240:
241: This is the toggle options menu for the selected node's configuration.
242:
243: The available options from this menu can all be toggled between two or
244: more states, such as &Yes& and &No&.
245: */
246: switch(uifc.list(WIN_BOT|WIN_RHT|WIN_ACT|WIN_SAV,3,2,35,&tog_dflt
247: ,&tog_bar,"Toggle Options",opt)) {
248: case -1:
249: done=1;
250: break;
251: #if 0 /* no longer used */
252: case 0:
253: i=cfg.node_misc&NM_LOWPRIO ? 0:1;
254: strcpy(opt[0],"Yes");
255: strcpy(opt[1],"No");
256: opt[2][0]=0;
257: SETHELP(WHERE);
258: /*
259: &Low Priority String Input:&
260:
261: Normally, Synchronet will not give up time slices (under a multitasker)
262: when users are prompted for a string of characters. This is considered
263: a high priority task.
264:
265: Setting this option to &Yes& will force Synchronet to give up time slices
266: during string input, possibly causing jerky keyboard input from the
267: user, but improving aggregate system performance under multitaskers.
268: */
269: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
270: ,"Low Priority String Input",opt);
271: if(i==0 && !(cfg.node_misc&NM_LOWPRIO)) {
272: cfg.node_misc|=NM_LOWPRIO;
273: uifc.changes=1; }
274: else if(i==1 && (cfg.node_misc&NM_LOWPRIO)) {
275: cfg.node_misc&=~NM_LOWPRIO;
276: uifc.changes=1; }
277: break;
278: #endif
279: case 0:
280: i=cfg.node_misc&NM_NO_NUM ? 1:0;
281: strcpy(opt[0],"Yes");
282: strcpy(opt[1],"No");
283: opt[2][0]=0;
284: SETHELP(WHERE);
285: /*
286: &Allow Login by User Number:&
287:
288: If you want users to be able login using their user number at the &NN:&
289: set this option to &Yes&.
290: */
291: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
292: ,"Allow Login by User Number",opt);
293: if(i==0 && cfg.node_misc&NM_NO_NUM) {
294: cfg.node_misc&=~NM_NO_NUM;
295: uifc.changes=1; }
296: else if(i==1 && !(cfg.node_misc&NM_NO_NUM)) {
297: cfg.node_misc|=NM_NO_NUM;
298: uifc.changes=1; }
299: break;
300: case 1:
301: i=cfg.node_misc&NM_LOGON_R ? 0:1;
302: strcpy(opt[0],"Yes");
303: strcpy(opt[1],"No");
304: opt[2][0]=0;
305: SETHELP(WHERE);
306: /*
307: &Allow Login by Real Name:&
308:
309: If you want users to be able login using their real name as well as
310: their alias, set this option to &Yes&.
311: */
312: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
313: ,"Allow Login by Real Name",opt);
314: if(i==0 && !(cfg.node_misc&NM_LOGON_R)) {
315: cfg.node_misc|=NM_LOGON_R;
316: uifc.changes=1; }
317: else if(i==1 && (cfg.node_misc&NM_LOGON_R)) {
318: cfg.node_misc&=~NM_LOGON_R;
319: uifc.changes=1; }
320: break;
321: case 2:
322: i=cfg.node_misc&NM_LOGON_P ? 0:1;
323: strcpy(opt[0],"Yes");
324: strcpy(opt[1],"No");
325: opt[2][0]=0;
326: SETHELP(WHERE);
327: /*
328: &Always Prompt for Password:&
329:
330: If you want to have attempted logins using an unknown user name still
331: prompt for a password, set this option to &Yes&.
332: */
333: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
334: ,"Always Prompt for Password",opt);
335: if(i==0 && !(cfg.node_misc&NM_LOGON_P)) {
336: cfg.node_misc|=NM_LOGON_P;
337: uifc.changes=1; }
338: else if(i==1 && (cfg.node_misc&NM_LOGON_P)) {
339: cfg.node_misc&=~NM_LOGON_P;
340: uifc.changes=1; }
341: break;
342: case 3:
343: i=cfg.node_misc&NM_7BITONLY ? 0:1;
344: strcpy(opt[0],"Yes");
345: strcpy(opt[1],"No");
346: opt[2][0]=0;
347: SETHELP(WHERE);
348: /*
349: &Allow 8-bit Remote Input During Login:&
350:
351: If you wish to allow E-7-1 terminals to use this node, you must set this
352: option to &No&. This will also eliminate the ability of 8-bit remote users
353: to send IBM extended ASCII characters during the login sequence.
354: */
355: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
356: ,"Allow 8-bit Remote Input During Login",opt);
357: if(i==1 && !(cfg.node_misc&NM_7BITONLY)) {
358: cfg.node_misc|=NM_7BITONLY;
359: uifc.changes=1; }
360: else if(i==0 && (cfg.node_misc&NM_7BITONLY)) {
361: cfg.node_misc&=~NM_7BITONLY;
362: uifc.changes=1; }
363: break;
364: case 4:
365: i=cfg.node_misc&NM_NOPAUSESPIN ? 1:0;
366: strcpy(opt[0],"Yes");
367: strcpy(opt[1],"No");
368: opt[2][0]=0;
369: SETHELP(WHERE);
370: /*
371: &Spinning Pause Prompt:&
372:
373: If you want to have a spinning cursor at the [Hit a key] prompt, set
374: this option to &Yes&.
375: */
376: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
377: ,"Spinning Cursor at Pause Prompt",opt);
378: if(i==0 && cfg.node_misc&NM_NOPAUSESPIN) {
379: cfg.node_misc&=~NM_NOPAUSESPIN;
380: uifc.changes=1; }
381: else if(i==1 && !(cfg.node_misc&NM_NOPAUSESPIN)) {
382: cfg.node_misc|=NM_NOPAUSESPIN;
383: uifc.changes=1; }
384: break;
385: case 5:
386: i=cfg.node_misc&NM_CLOSENODEDAB ? 1:0;
387: strcpy(opt[0],"Yes");
388: strcpy(opt[1],"No");
389: opt[2][0]=0;
390: SETHELP(WHERE);
391: /*
392: &Keep Node File Open:&
393:
394: If you want to keep the shared node file (&ctrl/node.dab&) open,
395: (for better performance and reliability) set this option to &Yes&.
396: If want to keep the file closed (for &Samba& compatiblity), set this
397: option to &No&.
398: */
399: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
400: ,"Keep Node File Open",opt);
401: if(i==0 && cfg.node_misc&NM_CLOSENODEDAB) {
402: cfg.node_misc&=~NM_CLOSENODEDAB;
403: uifc.changes=1; }
404: else if(i==1 && !(cfg.node_misc&NM_CLOSENODEDAB)) {
405: cfg.node_misc|=NM_CLOSENODEDAB;
406: uifc.changes=1; }
407: break;
408: } }
409: break;
410: case 2:
411: done=0;
412: while(!done) {
413: i=0;
414: sprintf(opt[i++],"%-27.27s%s","Validation User"
415: ,cfg.node_valuser ? ultoa(cfg.node_valuser,tmp,10) : "Nobody");
416: sprintf(opt[i++],"%-27.27s%u seconds","Semaphore Frequency"
417: ,cfg.node_sem_check);
418: sprintf(opt[i++],"%-27.27s%u seconds","Statistics Frequency"
419: ,cfg.node_stat_check);
420: sprintf(opt[i++],"%-27.27s%u seconds","Inactivity Warning"
421: ,cfg.sec_warn);
422: sprintf(opt[i++],"%-27.27s%u seconds","Inactivity Disconnection"
423: ,cfg.sec_hangup);
424: sprintf(opt[i++],"%-27.27s%.40s","Daily Event",cfg.node_daily);
425: sprintf(opt[i++],"%-27.27s%.40s","Text Directory",cfg.text_dir);
426: opt[i][0]=0;
427: SETHELP(WHERE);
428: /*
429: &Node Advanced Options:&
430:
431: This is the advanced options menu for the selected node. The available
432: options are of an advanced nature and should not be modified unless you
433: are sure of the consequences and necessary preparation.
434: */
435: switch(uifc.list(WIN_T2B|WIN_RHT|WIN_ACT|WIN_SAV,2,0,60,&adv_dflt,0
436: ,"Advanced Options",opt)) {
437: case -1:
438: done=1;
439: break;
440: case 0:
441: ultoa(cfg.node_valuser,str,10);
442: SETHELP(WHERE);
443: /*
444: &Validation User Number:&
445:
446: When a caller logs onto the system as &New&, he or she must send
447: validation feedback to the sysop. This feature can be disabled by
448: setting this value to &0&, allowing new users to logon without sending
449: validation feedback. If you want new users on this node to be forced to
450: send validation feedback, set this value to the number of the user to
451: whom the feedback is sent. The normal value of this option is &1& for
452: user number one.
453: */
454: uifc.input(WIN_MID,0,13,"Validation User Number (0=Nobody)"
455: ,str,4,K_NUMBER|K_EDIT);
456: cfg.node_valuser=atoi(str);
457: break;
458: case 1:
459: ultoa(cfg.node_sem_check,str,10);
460: SETHELP(WHERE);
461: /*
462: &Semaphore Check Frequency While Waiting for Call (in seconds):&
463:
464: This is the number of seconds between semaphore checks while this node
465: is waiting for a caller. Default is &60& seconds.
466: */
467: uifc.input(WIN_MID|WIN_SAV,0,14
468: ,"Seconds Between Semaphore Checks"
469: ,str,3,K_NUMBER|K_EDIT);
470: cfg.node_sem_check=atoi(str);
471: break;
472: case 2:
473: ultoa(cfg.node_stat_check,str,10);
474: SETHELP(WHERE);
475: /*
476: &Statistics Check Frequency While Waiting for Call (in seconds):&
477:
478: This is the number of seconds between static checks while this node
479: is waiting for a caller. Default is &10& seconds.
480: */
481: uifc.input(WIN_MID|WIN_SAV,0,14
482: ,"Seconds Between Statistic Checks"
483: ,str,3,K_NUMBER|K_EDIT);
484: cfg.node_stat_check=atoi(str);
485: break;
486: case 3:
487: ultoa(cfg.sec_warn,str,10);
488: SETHELP(WHERE);
489: /*
490: &Seconds Before Inactivity Warning:&
491:
492: This is the number of seconds the user must be inactive before a
493: warning will be given. Default is &180& seconds.
494: */
495: uifc.input(WIN_MID|WIN_SAV,0,14
496: ,"Seconds Before Inactivity Warning"
497: ,str,4,K_NUMBER|K_EDIT);
498: cfg.sec_warn=atoi(str);
499: break;
500: case 4:
501: ultoa(cfg.sec_hangup,str,10);
502: SETHELP(WHERE);
503: /*
504: &Seconds Before Inactivity Disconnection:&
505:
506: This is the number of seconds the user must be inactive before they
507: will be automatically disconnected. Default is &300& seconds.
508: */
509: uifc.input(WIN_MID|WIN_SAV,0,14
510: ,"Seconds Before Inactivity Disconnection"
511: ,str,4,K_NUMBER|K_EDIT);
512: cfg.sec_hangup=atoi(str);
513: break;
514: case 5:
515: SETHELP(WHERE);
516: /*
517: &Daily Event:&
518:
519: If you have an event that this node should run every day, enter the
520: command line for that event here.
521:
522: An event can be any valid DOS command line. If multiple programs or
523: commands are required, use a batch file.
524:
525: Remember: The &%!& command line specifier is an abreviation for your
526: configured &EXEC& directory path.
527: */
528: uifc.input(WIN_MID|WIN_SAV,0,10,"Daily Event"
529: ,cfg.node_daily,sizeof(cfg.node_daily)-1,K_EDIT);
530: break;
531: case 6:
532: SETHELP(WHERE);
533: /*
534: &Text Directory:&
535:
536: Your text directory contains &read-only& text files. Synchronet never
537: &writes& to any files in this directory so it &CAN& be placed on a RAM
538: disk or other volatile media. This directory contains the system's menus
539: and other important text files, so be sure the files and directories are
540: moved to this directory if you decide to change it.
541:
542: This option allows you to change the location of your control directory.
543: The &\TEXT\& suffix (sub-directory) cannot be changed or removed.
544: */
545: uifc.input(WIN_MID|WIN_SAV,0,10,"Text Directory"
546: ,cfg.text_dir,sizeof(cfg.text_dir)-1,K_EDIT);
547: break;
548: }
549: }
550: break;
551: }
552: }
553: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.