|
|
1.1 root 1: /* node.c */
2:
3: /* Synchronet BBS Node control program */
4:
5: /* $id$ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2000 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: /* Platform-specific headers */
39: #ifdef _WIN32
40: #include <io.h> /* open/close */
41: #include <windows.h>
42: #endif
43:
44: #include <stdio.h>
45: #include <stdlib.h>
46: #include <fcntl.h>
47: #include <string.h>
48:
49: /* Synchronet-specific */
50: #include "sbbsdefs.h"
51: #include "smbwrap.h" /* lock/unlock/sopen */
52:
53: enum {
54: MODE_LIST
55: ,MODE_ANON
56: ,MODE_LOCK
57: ,MODE_INTR
58: ,MODE_RRUN
59: ,MODE_DOWN
60: ,MODE_EVENT
61: ,MODE_NOPAGE
62: ,MODE_NOALERTS
63: ,MODE_STATUS
64: ,MODE_USERON
65: ,MODE_ACTION
66: ,MODE_ERRORS
67: ,MODE_MISC
68: ,MODE_CONN
69: ,MODE_AUX
70: ,MODE_EXTAUX
71: };
72:
73: char tmp[256];
74: int nodefile;
75:
76: #if !defined _MSC_VER && !defined __BORLANDC__
77: char* itoa(int val, char* str, int radix)
78: {
79: switch(radix) {
80: case 8:
81: sprintf(str,"%o",val);
82: break;
83: case 10:
84: sprintf(str,"%u",val);
85: break;
86: case 16:
87: sprintf(str,"%x",val);
88: break;
89: default:
90: sprintf(str,"bad radix: %d",radix);
91: break;
92: }
93: return(str);
94: }
95: #endif
96:
97: /****************************************************************************/
98: /* Reads the data for node number 'number' into the structure 'node' */
99: /* from NODE.DAB */
100: /* if lockit is non-zero, locks this node's record. putnodedat() unlocks it */
101: /****************************************************************************/
102: void getnodedat(uchar number, node_t *node, char lockit)
103: {
104: int count=0;
105:
106: number--; /* make zero based */
107: while(count<LOOP_NODEDAB) {
108: lseek(nodefile,(long)number*sizeof(node_t),SEEK_SET);
109: if(lockit
110: && lock(nodefile,(long)number*sizeof(node_t),sizeof(node_t))==-1) {
111: count++;
112: continue; }
113: if(read(nodefile,node,sizeof(node_t))==sizeof(node_t))
114: break;
115: count++; }
116: if(count)
117: printf("NODE.DAB COLLISION (READ) - Count:%d\n",count);
118: if(count==LOOP_NODEDAB) {
119: printf("Error reading nodefile for node %d\n",number+1);
120: return; }
121: }
122:
123: /****************************************************************************/
124: /* Write the data from the structure 'node' into NODE.DAB */
125: /* getnodedat(num,&node,1); must have been called before calling this func */
126: /* NOTE: ------^ the indicates the node record has been locked */
127: /****************************************************************************/
128: void putnodedat(uchar number, node_t node)
129: {
130: number--; /* make zero based */
131: lseek(nodefile,(long)number*sizeof(node_t),SEEK_SET);
132: if(write(nodefile,&node,sizeof(node_t))!=sizeof(node_t)) {
133: unlock(nodefile,(long)number*sizeof(node_t),sizeof(node_t));
134: printf("Error writing to nodefile for node %d\n",number+1);
135: return; }
136: unlock(nodefile,(long)number*sizeof(node_t),sizeof(node_t));
137: }
138:
139: /****************************************************************************/
140: /* Unpacks the password 'pass' from the 5bit ASCII inside node_t. 32bits in */
141: /* node.extaux, and the other 8bits in the upper byte of node.aux */
142: /****************************************************************************/
143: char *unpackchatpass(char *pass, node_t node)
144: {
145: char bits;
146: int i;
147:
148: pass[0]=(node.aux&0x1f00)>>8;
149: pass[1]=(char)(((node.aux&0xe000)>>13)|((node.extaux&0x3)<<3));
150: bits=2;
151: for(i=2;i<8;i++) {
152: pass[i]=(char)((node.extaux>>bits)&0x1f);
153: bits+=5; }
154: pass[8]=0;
155: for(i=0;i<8;i++)
156: if(pass[i])
157: pass[i]+=64;
158: return(pass);
159: }
160:
161: /****************************************************************************/
162: /* Displays the information for node number 'number' contained in 'node' */
163: /****************************************************************************/
164: void printnodedat(uchar number, node_t node)
165: {
166: char hour,mer[3];
167:
168: printf("Node %2d: ",number);
169: switch(node.status) {
170: case NODE_WFC:
171: printf("Waiting for call");
172: break;
173: case NODE_OFFLINE:
174: printf("Offline");
175: break;
176: case NODE_NETTING:
177: printf("Networking");
178: break;
179: case NODE_LOGON:
180: printf("At logon prompt");
181: break;
182: case NODE_EVENT_WAITING:
183: printf("Waiting for all nodes to become inactive");
184: break;
185: case NODE_EVENT_LIMBO:
186: printf("Waiting for node %d to finish external event",node.aux);
187: break;
188: case NODE_EVENT_RUNNING:
189: printf("Running external event");
190: break;
191: case NODE_NEWUSER:
192: printf("New user");
193: printf(" applying for access ");
194: if(!node.connection)
195: printf("locally");
196: else if(node.connection==0xffff)
197: printf("via telnet");
198: else
199: printf("at %ubps",node.connection);
200: break;
201: case NODE_QUIET:
202: case NODE_INUSE:
203: printf("User #%d",node.useron);
204: printf(" ");
205: switch(node.action) {
206: case NODE_MAIN:
207: printf("at main menu");
208: break;
209: case NODE_RMSG:
210: printf("reading messages");
211: break;
212: case NODE_RMAL:
213: printf("reading mail");
214: break;
215: case NODE_RSML:
216: printf("reading sent mail");
217: break;
218: case NODE_RTXT:
219: printf("reading text files");
220: break;
221: case NODE_PMSG:
222: printf("posting message");
223: break;
224: case NODE_SMAL:
225: printf("sending mail");
226: break;
227: case NODE_AMSG:
228: printf("posting auto-message");
229: break;
230: case NODE_XTRN:
231: if(!node.aux)
232: printf("at external program menu");
233: else
234: printf("running external program #%d",node.aux);
235: break;
236: case NODE_DFLT:
237: printf("changing defaults");
238: break;
239: case NODE_XFER:
240: printf("at transfer menu");
241: break;
242: case NODE_RFSD:
243: printf("retrieving from device #%d",node.aux);
244: break;
245: case NODE_DLNG:
246: printf("downloading");
247: break;
248: case NODE_ULNG:
249: printf("uploading");
250: break;
251: case NODE_BXFR:
252: printf("transferring bidirectional");
253: break;
254: case NODE_LFIL:
255: printf("listing files");
256: break;
257: case NODE_LOGN:
258: printf("logging on");
259: break;
260: case NODE_LCHT:
261: printf("in local chat with sysop");
262: break;
263: case NODE_MCHT:
264: if(node.aux) {
265: printf("in multinode chat channel %d",node.aux&0xff);
266: if(node.aux&0x1f00) { /* password */
267: putchar('*');
268: printf(" %s",unpackchatpass(tmp,node)); } }
269: else
270: printf("in multinode global chat channel");
271: break;
272: case NODE_PAGE:
273: printf("paging node %u for private chat",node.aux);
274: break;
275: case NODE_PCHT:
276: printf("in private chat with node %u",node.aux);
277: break;
278: case NODE_GCHT:
279: printf("chatting with The Guru");
280: break;
281: case NODE_CHAT:
282: printf("in chat section");
283: break;
284: case NODE_TQWK:
285: printf("transferring QWK packet");
286: break;
287: case NODE_SYSP:
288: printf("performing sysop activities");
289: break;
290: default:
291: printf(itoa(node.action,tmp,10));
292: break; }
293: if(!node.connection)
294: printf(" locally");
295: else if(node.connection==0xffff)
296: printf(" via telnet");
297: else
298: printf(" at %ubps",node.connection);
299: if(node.action==NODE_DLNG) {
300: if((node.aux/60)>=12) {
301: if(node.aux/60==12)
302: hour=12;
303: else
304: hour=(node.aux/60)-12;
305: strcpy(mer,"pm"); }
306: else {
307: if((node.aux/60)==0) /* 12 midnite */
308: hour=12;
309: else hour=node.aux/60;
310: strcpy(mer,"am"); }
311: printf(" ETA %02d:%02d %s"
312: ,hour,node.aux-((node.aux/60)*60),mer); }
313: break; }
314: if(node.misc&(NODE_LOCK|NODE_POFF|NODE_AOFF|NODE_MSGW|NODE_NMSG)) {
315: printf(" (");
316: if(node.misc&NODE_AOFF)
317: putchar('A');
318: if(node.misc&NODE_LOCK)
319: putchar('L');
320: if(node.misc&(NODE_MSGW|NODE_NMSG))
321: putchar('M');
322: if(node.misc&NODE_POFF)
323: putchar('P');
324: putchar(')'); }
325: if(((node.misc
326: &(NODE_ANON|NODE_UDAT|NODE_INTR|NODE_RRUN|NODE_EVENT|NODE_DOWN))
327: || node.status==NODE_QUIET)) {
328: printf(" [");
329: if(node.misc&NODE_ANON)
330: putchar('A');
331: if(node.misc&NODE_INTR)
332: putchar('I');
333: if(node.misc&NODE_RRUN)
334: putchar('R');
335: if(node.misc&NODE_UDAT)
336: putchar('U');
337: if(node.status==NODE_QUIET)
338: putchar('Q');
339: if(node.misc&NODE_EVENT)
340: putchar('E');
341: if(node.misc&NODE_DOWN)
342: putchar('D');
343: if(node.misc&NODE_LCHAT)
344: putchar('C');
345: putchar(']'); }
346: if(node.errors)
347: printf(" %d error%c",node.errors, node.errors>1 ? 's' : '\0' );
348: printf("\n");
349: }
350:
351:
352: /****************************/
353: /* Main program entry point */
354: /****************************/
355: int main(int argc, char **argv)
356: {
357: char str[256],ctrl_dir[41],*p,debug=0;
358: int sys_nodes,node_num=0,onoff=0;
359: int i,j,mode=0,misc;
360: long value;
361: node_t node;
362:
363: printf("\nSynchronet Node Display/Control Utility v1.10 Copyright 2000 Rob Swindell\n\n");
364:
365: if(sizeof(node_t)!=SIZEOF_NODE_T) {
366: printf("COMPILER ERROR: sizeof(node_t)=%d instead of %d\n"
367: ,sizeof(node_t),SIZEOF_NODE_T);
368: return(-1);
369: }
370:
371: if(argc<2) {
372: printf("usage: node [/debug] [action [on|off]] [node numbers] [...]"
373: "\n\n");
374: printf("actions (default is list):\n\n");
375: printf("list = list status\n");
376: printf("anon = anonymous user\n");
377: printf("lock = locked\n");
378: printf("intr = interrupt\n");
379: printf("down = shut-down\n");
380: printf("rerun = rerun\n");
381: printf("event = run event\n");
382: printf("nopage = page disable\n");
383: printf("noalerts = activity alerts disable\n");
384: printf("status=# = set status value\n");
385: printf("useron=# = set useron number\n");
386: printf("action=# = set action value\n");
387: printf("errors=# = set error counter\n");
388: printf("conn=# = set connection value\n");
389: printf("misc=# = set misc value\n");
390: printf("aux=# = set aux value\n");
391: printf("extaux=# = set extended aux value\n");
392: exit(0); }
393:
394: p=getenv("SBBSCTRL");
395: if(p==NULL) {
396: printf("\7\nSBBSCTRL environment variable is not set.\n");
397: printf("This environment variable must be set to your CTRL directory.");
398: printf("\nExample: SET SBBSCTRL=/sbbs/ctrl\n");
399: exit(1); }
400: sprintf(ctrl_dir,"%.40s",p);
401: if(ctrl_dir[strlen(ctrl_dir)-1]!='\\'
402: && ctrl_dir[strlen(ctrl_dir)-1]!='/')
403: strcat(ctrl_dir,"/");
404:
405: sprintf(str,"%snode.dab",ctrl_dir);
406: if((nodefile=sopen(str,O_RDWR|O_BINARY,SH_DENYNO))==-1) {
407: printf("\7\nError opening %s.\n",str);
408: exit(1); }
409:
410: sys_nodes=filelength(nodefile)/sizeof(node_t);
411: if(!sys_nodes) {
412: printf("%s reflects 0 nodes!\n",str);
413: exit(1); }
414:
415: for(i=1;i<argc;i++) {
416: if(isdigit(argv[i][0]))
417: node_num=atoi(argv[i]);
418: else {
419: node_num=onoff=value=0;
420: if(!stricmp(argv[i],"/DEBUG"))
421: debug=1;
422: else if(!stricmp(argv[i],"LOCK"))
423: mode=MODE_LOCK;
424: else if(!stricmp(argv[i],"ANON"))
425: mode=MODE_ANON;
426: else if(!stricmp(argv[i],"INTR"))
427: mode=MODE_INTR;
428: else if(!stricmp(argv[i],"DOWN"))
429: mode=MODE_DOWN;
430: else if(!stricmp(argv[i],"RERUN"))
431: mode=MODE_RRUN;
432: else if(!stricmp(argv[i],"EVENT"))
433: mode=MODE_EVENT;
434: else if(!stricmp(argv[i],"NOPAGE"))
435: mode=MODE_NOPAGE;
436: else if(!stricmp(argv[i],"NOALERTS"))
437: mode=MODE_NOALERTS;
438: else if(!stricmp(argv[i],"ON"))
439: onoff=1;
440: else if(!stricmp(argv[i],"OFF"))
441: onoff=2;
442: else if(!strnicmp(argv[i],"STATUS=",7)) {
443: mode=MODE_STATUS;
444: value=atoi(argv[i]+7); }
445: else if(!strnicmp(argv[i],"ERRORS=",7)) {
446: mode=MODE_ERRORS;
447: value=atoi(argv[i]+7); }
448: else if(!strnicmp(argv[i],"USERON=",7)) {
449: mode=MODE_USERON;
450: value=atoi(argv[i]+7); }
451: else if(!strnicmp(argv[i],"ACTION=",7)) {
452: mode=MODE_ACTION;
453: value=atoi(argv[i]+7); }
454: else if(!strnicmp(argv[i],"CONN=",5)) {
455: mode=MODE_CONN;
456: value=atoi(argv[i]+5); }
457: else if(!strnicmp(argv[i],"MISC=",5)) {
458: mode=MODE_MISC;
459: value=atoi(argv[i]+5); }
460: else if(!strnicmp(argv[i],"AUX=",4)) {
461: mode=MODE_AUX;
462: value=atoi(argv[i]+4); }
463: else if(!strnicmp(argv[i],"EXTAUX=",7)) {
464: mode=MODE_EXTAUX;
465: value=atoi(argv[i]+7); }
466: }
467: if((mode && node_num) || i+1==argc)
468: for(j=1;j<=sys_nodes;j++)
469: if(!node_num || j==node_num) {
470: getnodedat(j,&node,1);
471: misc=0;
472: switch(mode) {
473: case MODE_ANON:
474: misc=NODE_ANON;
475: break;
476: case MODE_LOCK:
477: misc=NODE_LOCK;
478: break;
479: case MODE_INTR:
480: misc=NODE_INTR;
481: break;
482: case MODE_DOWN:
483: misc=NODE_DOWN;
484: break;
485: case MODE_RRUN:
486: misc=NODE_RRUN;
487: break;
488: case MODE_EVENT:
489: misc=NODE_EVENT;
490: break;
491: case MODE_NOPAGE:
492: misc=NODE_POFF;
493: break;
494: case MODE_NOALERTS:
495: misc=NODE_AOFF;
496: break;
497: case MODE_STATUS:
498: node.status=value;
499: break;
500: case MODE_ERRORS:
501: node.errors=value;
502: break;
503: case MODE_ACTION:
504: node.action=value;
505: break;
506: case MODE_USERON:
507: node.useron=value;
508: break;
509: case MODE_MISC:
510: node.misc=value;
511: break;
512: case MODE_CONN:
513: node.connection=value;
514: break;
515: case MODE_AUX:
516: node.aux=value;
517: break;
518: case MODE_EXTAUX:
519: node.extaux=value;
520: break; }
521: if(misc) {
522: if(onoff==0)
523: node.misc^=misc;
524: else if(onoff==1)
525: node.misc|=misc;
526: else if(onoff==2)
527: node.misc&=~misc; }
528: putnodedat(j,node);
529: printnodedat(j,node);
530: if(debug) {
531: printf("status=%u\n",node.status);
532: printf("errors=%u\n",node.errors);
533: printf("action=%d\n",node.action);
534: printf("useron=%u\n",node.useron);
535: printf("conn=%u\n",node.connection);
536: printf("misc=%u\n",node.misc);
537: printf("aux=%u\n",node.aux);
538: printf("extaux=%lu\n",node.extaux); } } }
539:
540: close(nodefile);
541: return(0);
542: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.