|
|
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.