|
|
1.1 root 1: /* scfgnode.c */
2:
1.1.1.2 ! root 3: /* $Id: scfgnode.c,v 1.27 2011/07/21 10:53:08 rswindell Exp $ */
1.1 root 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: * *
1.1.1.2 ! root 9: * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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;
1.1.1.2 ! root 132: SAFEPRINTF(cfg.node_name,"Node %u",cfg.node_num);
! 133: SAFECOPY(cfg.node_phone,"N/A");
1.1 root 134: cfg.new_install=new_install;
135: write_node_cfg(&cfg,backup_level);
136: write_main_cfg(&cfg,backup_level);
137: free_node_cfg(&cfg);
138: refresh_cfg(&cfg);
139: continue;
140: }
141: if((i&MSK_ON)==MSK_GET) {
142: if(savnode)
143: free_node_cfg(&cfg);
144: i&=MSK_OFF;
145: strcpy(cfg.node_dir,cfg.node_path[i]);
146: uifc.pop("Reading NODE.CNF...");
147: read_node_cfg(&cfg,error);
148: uifc.pop(0);
149: savnode=1;
150: continue; }
151: if((i&MSK_ON)==MSK_PUT) {
152: i&=MSK_OFF;
153: strcpy(cfg.node_dir,cfg.node_path[i]);
154: cfg.node_num=i+1;
155: write_node_cfg(&cfg,backup_level);
156: refresh_cfg(&cfg);
157: uifc.changes=1;
158: continue;
159: }
160:
161: if(savnode) {
162: free_node_cfg(&cfg);
163: savnode=0; }
164: strcpy(cfg.node_dir,cfg.node_path[i]);
165: prep_dir(cfg.ctrl_dir, cfg.node_dir, sizeof(cfg.node_dir));
166:
167: uifc.pop("Reading NODE.CNF...");
168: read_node_cfg(&cfg,error);
169: uifc.pop(0);
170: if(cfg.node_num!=i+1) { /* Node number isn't right? */
171: cfg.node_num=i+1; /* so fix it */
172: write_node_cfg(&cfg,backup_level); } /* and write it back */
173: node_cfg();
174:
175: free_node_cfg(&cfg); }
176: }
177:
178: void node_cfg()
179: {
180: static int node_dflt;
181: char done,str[81];
182: static int adv_dflt,tog_dflt,tog_bar;
183: int i;
184:
185: while(1) {
186: i=0;
1.1.1.2 ! root 187: sprintf(opt[i++],"%-27.27s%s","Phone Number",cfg.node_phone);
1.1 root 188: sprintf(opt[i++],"%-27.27s%.40s","Logon Requirements",cfg.node_arstr);
189: strcpy(opt[i++],"Toggle Options...");
190: strcpy(opt[i++],"Advanced Options...");
191: opt[i][0]=0;
192: sprintf(str,"Node %d Configuration",cfg.node_num);
193: SETHELP(WHERE);
194: /*
195: &Node Configuration Menu:&
196:
197: This is the node configuration menu. The options available from this
198: menu will only affect the selected node's configuration.
199:
200: Options with a trailing &...& will produce a sub-menu of more options.
201: */
202: switch(uifc.list(WIN_ACT|WIN_CHE|WIN_BOT|WIN_RHT,0,0,60,&node_dflt,0
203: ,str,opt)) {
204: case -1:
205: i=save_changes(WIN_MID|WIN_SAV);
206: if(!i) {
207: write_node_cfg(&cfg,backup_level);
208: refresh_cfg(&cfg);
209: }
210: if(i!=-1)
211: return;
212: break;
213: case 0:
1.1.1.2 ! root 214: SETHELP(WHERE);
! 215: /*
! 216: `Node Phone Number:`
! 217: This is the phone number to access the selected node (e.g. for SEXPOTS).
! 218: This value is used for documentary purposes only.
! 219: */
! 220: uifc.input(WIN_MID|WIN_SAV,0,10,"Phone Number",cfg.node_phone,sizeof(cfg.node_phone)-1,K_EDIT);
! 221: break;
! 222: case 1:
1.1 root 223: sprintf(str,"Node %u Logon",cfg.node_num);
224: getar(str,cfg.node_arstr);
225: break;
1.1.1.2 ! root 226: case 2:
1.1 root 227: done=0;
228: while(!done) {
229: i=0;
230: #if 0 /* no longer used */
231: sprintf(opt[i++],"%-27.27s%s","Low Priority String Input"
232: ,cfg.node_misc&NM_LOWPRIO ? "Yes":"No");
233: #endif
234: sprintf(opt[i++],"%-27.27s%s","Allow Login by User Number"
235: ,cfg.node_misc&NM_NO_NUM ? "No":"Yes");
236: sprintf(opt[i++],"%-27.27s%s","Allow Login by Real Name"
237: ,cfg.node_misc&NM_LOGON_R ? "Yes":"No");
238: sprintf(opt[i++],"%-27.27s%s","Always Prompt for Password"
239: ,cfg.node_misc&NM_LOGON_P ? "Yes":"No");
240: sprintf(opt[i++],"%-27.27s%s","Allow 8-bit Remote Logins"
241: ,cfg.node_misc&NM_7BITONLY ? "No":"Yes");
242: sprintf(opt[i++],"%-27.27s%s","Spinning Pause Prompt"
243: ,cfg.node_misc&NM_NOPAUSESPIN ? "No":"Yes");
244: sprintf(opt[i++],"%-27.27s%s","Keep Node File Open"
245: ,cfg.node_misc&NM_CLOSENODEDAB ? "No":"Yes");
246:
247: opt[i][0]=0;
248: SETHELP(WHERE);
249: /*
250: &Node Toggle Options:&
251:
252: This is the toggle options menu for the selected node's configuration.
253:
254: The available options from this menu can all be toggled between two or
255: more states, such as &Yes& and &No&.
256: */
257: switch(uifc.list(WIN_BOT|WIN_RHT|WIN_ACT|WIN_SAV,3,2,35,&tog_dflt
258: ,&tog_bar,"Toggle Options",opt)) {
259: case -1:
260: done=1;
261: break;
262: #if 0 /* no longer used */
263: case 0:
264: i=cfg.node_misc&NM_LOWPRIO ? 0:1;
265: strcpy(opt[0],"Yes");
266: strcpy(opt[1],"No");
267: opt[2][0]=0;
268: SETHELP(WHERE);
269: /*
270: &Low Priority String Input:&
271:
272: Normally, Synchronet will not give up time slices (under a multitasker)
273: when users are prompted for a string of characters. This is considered
274: a high priority task.
275:
276: Setting this option to &Yes& will force Synchronet to give up time slices
277: during string input, possibly causing jerky keyboard input from the
278: user, but improving aggregate system performance under multitaskers.
279: */
280: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
281: ,"Low Priority String Input",opt);
282: if(i==0 && !(cfg.node_misc&NM_LOWPRIO)) {
283: cfg.node_misc|=NM_LOWPRIO;
284: uifc.changes=1; }
285: else if(i==1 && (cfg.node_misc&NM_LOWPRIO)) {
286: cfg.node_misc&=~NM_LOWPRIO;
287: uifc.changes=1; }
288: break;
289: #endif
290: case 0:
291: i=cfg.node_misc&NM_NO_NUM ? 1:0;
292: strcpy(opt[0],"Yes");
293: strcpy(opt[1],"No");
294: opt[2][0]=0;
295: SETHELP(WHERE);
296: /*
297: &Allow Login by User Number:&
298:
299: If you want users to be able login using their user number at the &NN:&
300: set this option to &Yes&.
301: */
302: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
303: ,"Allow Login by User Number",opt);
304: if(i==0 && cfg.node_misc&NM_NO_NUM) {
305: cfg.node_misc&=~NM_NO_NUM;
306: uifc.changes=1; }
307: else if(i==1 && !(cfg.node_misc&NM_NO_NUM)) {
308: cfg.node_misc|=NM_NO_NUM;
309: uifc.changes=1; }
310: break;
311: case 1:
312: i=cfg.node_misc&NM_LOGON_R ? 0:1;
313: strcpy(opt[0],"Yes");
314: strcpy(opt[1],"No");
315: opt[2][0]=0;
316: SETHELP(WHERE);
317: /*
318: &Allow Login by Real Name:&
319:
320: If you want users to be able login using their real name as well as
321: their alias, set this option to &Yes&.
322: */
323: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
324: ,"Allow Login by Real Name",opt);
325: if(i==0 && !(cfg.node_misc&NM_LOGON_R)) {
326: cfg.node_misc|=NM_LOGON_R;
327: uifc.changes=1; }
328: else if(i==1 && (cfg.node_misc&NM_LOGON_R)) {
329: cfg.node_misc&=~NM_LOGON_R;
330: uifc.changes=1; }
331: break;
332: case 2:
333: i=cfg.node_misc&NM_LOGON_P ? 0:1;
334: strcpy(opt[0],"Yes");
335: strcpy(opt[1],"No");
336: opt[2][0]=0;
337: SETHELP(WHERE);
338: /*
339: &Always Prompt for Password:&
340:
341: If you want to have attempted logins using an unknown user name still
342: prompt for a password, set this option to &Yes&.
343: */
344: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
345: ,"Always Prompt for Password",opt);
346: if(i==0 && !(cfg.node_misc&NM_LOGON_P)) {
347: cfg.node_misc|=NM_LOGON_P;
348: uifc.changes=1; }
349: else if(i==1 && (cfg.node_misc&NM_LOGON_P)) {
350: cfg.node_misc&=~NM_LOGON_P;
351: uifc.changes=1; }
352: break;
353: case 3:
354: i=cfg.node_misc&NM_7BITONLY ? 0:1;
355: strcpy(opt[0],"Yes");
356: strcpy(opt[1],"No");
357: opt[2][0]=0;
358: SETHELP(WHERE);
359: /*
360: &Allow 8-bit Remote Input During Login:&
361:
362: If you wish to allow E-7-1 terminals to use this node, you must set this
363: option to &No&. This will also eliminate the ability of 8-bit remote users
364: to send IBM extended ASCII characters during the login sequence.
365: */
366: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
367: ,"Allow 8-bit Remote Input During Login",opt);
368: if(i==1 && !(cfg.node_misc&NM_7BITONLY)) {
369: cfg.node_misc|=NM_7BITONLY;
370: uifc.changes=1; }
371: else if(i==0 && (cfg.node_misc&NM_7BITONLY)) {
372: cfg.node_misc&=~NM_7BITONLY;
373: uifc.changes=1; }
374: break;
375: case 4:
376: i=cfg.node_misc&NM_NOPAUSESPIN ? 1:0;
377: strcpy(opt[0],"Yes");
378: strcpy(opt[1],"No");
379: opt[2][0]=0;
380: SETHELP(WHERE);
381: /*
382: &Spinning Pause Prompt:&
383:
384: If you want to have a spinning cursor at the [Hit a key] prompt, set
385: this option to &Yes&.
386: */
387: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
388: ,"Spinning Cursor at Pause Prompt",opt);
389: if(i==0 && cfg.node_misc&NM_NOPAUSESPIN) {
390: cfg.node_misc&=~NM_NOPAUSESPIN;
391: uifc.changes=1; }
392: else if(i==1 && !(cfg.node_misc&NM_NOPAUSESPIN)) {
393: cfg.node_misc|=NM_NOPAUSESPIN;
394: uifc.changes=1; }
395: break;
396: case 5:
397: i=cfg.node_misc&NM_CLOSENODEDAB ? 1:0;
398: strcpy(opt[0],"Yes");
399: strcpy(opt[1],"No");
400: opt[2][0]=0;
401: SETHELP(WHERE);
402: /*
403: &Keep Node File Open:&
404:
405: If you want to keep the shared node file (&ctrl/node.dab&) open,
406: (for better performance and reliability) set this option to &Yes&.
407: If want to keep the file closed (for &Samba& compatiblity), set this
408: option to &No&.
409: */
410: i=uifc.list(WIN_MID|WIN_SAV,0,10,0,&i,0
411: ,"Keep Node File Open",opt);
412: if(i==0 && cfg.node_misc&NM_CLOSENODEDAB) {
413: cfg.node_misc&=~NM_CLOSENODEDAB;
414: uifc.changes=1; }
415: else if(i==1 && !(cfg.node_misc&NM_CLOSENODEDAB)) {
416: cfg.node_misc|=NM_CLOSENODEDAB;
417: uifc.changes=1; }
418: break;
419: } }
420: break;
1.1.1.2 ! root 421: case 3:
1.1 root 422: done=0;
423: while(!done) {
424: i=0;
425: sprintf(opt[i++],"%-27.27s%s","Validation User"
426: ,cfg.node_valuser ? ultoa(cfg.node_valuser,tmp,10) : "Nobody");
427: sprintf(opt[i++],"%-27.27s%u seconds","Semaphore Frequency"
428: ,cfg.node_sem_check);
429: sprintf(opt[i++],"%-27.27s%u seconds","Statistics Frequency"
430: ,cfg.node_stat_check);
431: sprintf(opt[i++],"%-27.27s%u seconds","Inactivity Warning"
432: ,cfg.sec_warn);
433: sprintf(opt[i++],"%-27.27s%u seconds","Inactivity Disconnection"
434: ,cfg.sec_hangup);
435: sprintf(opt[i++],"%-27.27s%.40s","Daily Event",cfg.node_daily);
436: sprintf(opt[i++],"%-27.27s%.40s","Text Directory",cfg.text_dir);
437: opt[i][0]=0;
438: SETHELP(WHERE);
439: /*
440: &Node Advanced Options:&
441:
442: This is the advanced options menu for the selected node. The available
443: options are of an advanced nature and should not be modified unless you
444: are sure of the consequences and necessary preparation.
445: */
446: switch(uifc.list(WIN_T2B|WIN_RHT|WIN_ACT|WIN_SAV,2,0,60,&adv_dflt,0
447: ,"Advanced Options",opt)) {
448: case -1:
449: done=1;
450: break;
451: case 0:
452: ultoa(cfg.node_valuser,str,10);
453: SETHELP(WHERE);
454: /*
455: &Validation User Number:&
456:
457: When a caller logs onto the system as &New&, he or she must send
458: validation feedback to the sysop. This feature can be disabled by
459: setting this value to &0&, allowing new users to logon without sending
460: validation feedback. If you want new users on this node to be forced to
461: send validation feedback, set this value to the number of the user to
462: whom the feedback is sent. The normal value of this option is &1& for
463: user number one.
464: */
465: uifc.input(WIN_MID,0,13,"Validation User Number (0=Nobody)"
466: ,str,4,K_NUMBER|K_EDIT);
467: cfg.node_valuser=atoi(str);
468: break;
469: case 1:
470: ultoa(cfg.node_sem_check,str,10);
471: SETHELP(WHERE);
472: /*
473: &Semaphore Check Frequency While Waiting for Call (in seconds):&
474:
475: This is the number of seconds between semaphore checks while this node
476: is waiting for a caller. Default is &60& seconds.
477: */
478: uifc.input(WIN_MID|WIN_SAV,0,14
479: ,"Seconds Between Semaphore Checks"
480: ,str,3,K_NUMBER|K_EDIT);
481: cfg.node_sem_check=atoi(str);
482: break;
483: case 2:
484: ultoa(cfg.node_stat_check,str,10);
485: SETHELP(WHERE);
486: /*
487: &Statistics Check Frequency While Waiting for Call (in seconds):&
488:
489: This is the number of seconds between static checks while this node
490: is waiting for a caller. Default is &10& seconds.
491: */
492: uifc.input(WIN_MID|WIN_SAV,0,14
493: ,"Seconds Between Statistic Checks"
494: ,str,3,K_NUMBER|K_EDIT);
495: cfg.node_stat_check=atoi(str);
496: break;
497: case 3:
498: ultoa(cfg.sec_warn,str,10);
499: SETHELP(WHERE);
500: /*
501: &Seconds Before Inactivity Warning:&
502:
503: This is the number of seconds the user must be inactive before a
504: warning will be given. Default is &180& seconds.
505: */
506: uifc.input(WIN_MID|WIN_SAV,0,14
507: ,"Seconds Before Inactivity Warning"
508: ,str,4,K_NUMBER|K_EDIT);
509: cfg.sec_warn=atoi(str);
510: break;
511: case 4:
512: ultoa(cfg.sec_hangup,str,10);
513: SETHELP(WHERE);
514: /*
515: &Seconds Before Inactivity Disconnection:&
516:
517: This is the number of seconds the user must be inactive before they
518: will be automatically disconnected. Default is &300& seconds.
519: */
520: uifc.input(WIN_MID|WIN_SAV,0,14
521: ,"Seconds Before Inactivity Disconnection"
522: ,str,4,K_NUMBER|K_EDIT);
523: cfg.sec_hangup=atoi(str);
524: break;
525: case 5:
526: SETHELP(WHERE);
527: /*
528: &Daily Event:&
529:
530: If you have an event that this node should run every day, enter the
531: command line for that event here.
532:
533: An event can be any valid DOS command line. If multiple programs or
534: commands are required, use a batch file.
535:
536: Remember: The &%!& command line specifier is an abreviation for your
537: configured &EXEC& directory path.
538: */
539: uifc.input(WIN_MID|WIN_SAV,0,10,"Daily Event"
540: ,cfg.node_daily,sizeof(cfg.node_daily)-1,K_EDIT);
541: break;
542: case 6:
543: SETHELP(WHERE);
544: /*
545: &Text Directory:&
546:
547: Your text directory contains &read-only& text files. Synchronet never
548: &writes& to any files in this directory so it &CAN& be placed on a RAM
549: disk or other volatile media. This directory contains the system's menus
550: and other important text files, so be sure the files and directories are
551: moved to this directory if you decide to change it.
552:
553: This option allows you to change the location of your control directory.
554: The &\TEXT\& suffix (sub-directory) cannot be changed or removed.
555: */
556: uifc.input(WIN_MID|WIN_SAV,0,10,"Text Directory"
557: ,cfg.text_dir,sizeof(cfg.text_dir)-1,K_EDIT);
558: break;
559: }
560: }
561: break;
562: }
563: }
564: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.