|
|
1.1 ! root 1: /* getnode.cpp */ ! 2: ! 3: /* Synchronet node information retrieval functions */ ! 4: ! 5: /* $Id: getnode.cpp,v 1.6 2000/12/11 23:21:11 rswindell Exp $ */ ! 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: #include "sbbs.h" ! 39: #include "cmdshell.h" ! 40: ! 41: /****************************************************************************/ ! 42: /* Reads the data for node number 'number' into the structure 'node' */ ! 43: /* from NODE.DAB */ ! 44: /* if lockit is non-zero, locks this node's record. putnodedat() unlocks it */ ! 45: /****************************************************************************/ ! 46: void sbbs_t::getnodedat(uint number, node_t *node, bool lockit) ! 47: { ! 48: char str[256]; ! 49: int count=0; ! 50: ! 51: if(!number || number>cfg.sys_nodes) { ! 52: errormsg(WHERE,ERR_CHK,"node number",number); ! 53: return; } ! 54: ! 55: if(nodefile==-1) { ! 56: sprintf(str,"%snode.dab",cfg.ctrl_dir); ! 57: if((nodefile=nopen(str,O_RDWR|O_DENYNONE))==-1) { ! 58: memset(node,0,sizeof(node_t)); ! 59: errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_DENYNONE); ! 60: return; ! 61: } ! 62: } ! 63: ! 64: number--; /* make zero based */ ! 65: while(count<LOOP_NODEDAB) { ! 66: if(count>10) ! 67: mswait(100); ! 68: lseek(nodefile,(long)number*sizeof(node_t),SEEK_SET); ! 69: if(lockit ! 70: && lock(nodefile,(long)number*sizeof(node_t),sizeof(node_t))==-1) { ! 71: count++; ! 72: continue; } ! 73: if(read(nodefile,node,sizeof(node_t))==sizeof(node_t)) ! 74: break; ! 75: count++; ! 76: } ! 77: if(!lockit) { ! 78: close(nodefile); ! 79: nodefile=-1; ! 80: } ! 81: ! 82: if(count>(LOOP_NODEDAB/2) && count!=LOOP_NODEDAB) { ! 83: sprintf(str,"NODE.DAB COLLISION - Count: %d",count); ! 84: logline("!!",str); } ! 85: if(count==LOOP_NODEDAB) { ! 86: errormsg(WHERE,ERR_READ,"node.dab",number+1); ! 87: return; ! 88: } ! 89: } ! 90: ! 91: /****************************************************************************/ ! 92: /* Synchronizes all the nodes knowledge of the other nodes' actions, mode, */ ! 93: /* status and other flags. */ ! 94: /* Assumes that getnodedat(node_num,&thisnode,0) was called right before it */ ! 95: /* is called. */ ! 96: /****************************************************************************/ ! 97: void sbbs_t::nodesync() ! 98: { ! 99: char str[256],today[32]; ! 100: int atr=curatr; /* was lclatr(-1) 01/29/96 */ ! 101: ! 102: if(nodesync_inside) return; ! 103: nodesync_inside=1; ! 104: ! 105: if(thisnode.action!=action) { ! 106: getnodedat(cfg.node_num,&thisnode,1); ! 107: thisnode.action=action; ! 108: putnodedat(cfg.node_num,&thisnode); } ! 109: ! 110: criterrs=thisnode.errors; ! 111: ! 112: if(sys_status&SS_USERON) { ! 113: if(!(sys_status&SS_NEWDAY)) { ! 114: now=time(NULL); ! 115: unixtodstr(&cfg,logontime,str); ! 116: unixtodstr(&cfg,now,today); ! 117: if(strcmp(str,today)) { /* New day, clear "today" user vars */ ! 118: sys_status|=SS_NEWDAY; // So we don't keep doing this over&over ! 119: putuserrec(&cfg,useron.number,U_ETODAY,5,"0"); ! 120: putuserrec(&cfg,useron.number,U_PTODAY,5,"0"); ! 121: putuserrec(&cfg,useron.number,U_TTODAY,5,"0"); ! 122: putuserrec(&cfg,useron.number,U_LTODAY,5,"0"); ! 123: putuserrec(&cfg,useron.number,U_TEXTRA,5,"0"); ! 124: putuserrec(&cfg,useron.number,U_FREECDT,10 ! 125: ,ultoa(cfg.level_freecdtperday[useron.level],str,10)); ! 126: getuserdat(&cfg, &useron); } } ! 127: if(thisnode.misc&NODE_UDAT && !(useron.rest&FLAG('G'))) { /* not guest */ ! 128: getuserdat(&cfg, &useron); ! 129: getnodedat(cfg.node_num,&thisnode,1); ! 130: thisnode.misc&=~NODE_UDAT; ! 131: putnodedat(cfg.node_num,&thisnode); } ! 132: if(thisnode.misc&NODE_MSGW) ! 133: getsmsg(useron.number); /* getsmsg clears MSGW flag */ ! 134: if(thisnode.misc&NODE_NMSG) ! 135: getnmsg(); } /* getnmsg clears NMSG flag */ ! 136: ! 137: if(cfg.sync_mod[0]) ! 138: exec_bin(cfg.sync_mod,&main_csi); ! 139: ! 140: if(thisnode.misc&NODE_INTR) { ! 141: bputs(text[NodeLocked]); ! 142: logline(nulstr,"Interrupted"); ! 143: hangup(); ! 144: nodesync_inside=0; ! 145: return; } ! 146: ! 147: if(thisnode.misc&NODE_LCHAT) { // pulled into local chat with sysop ! 148: SAVELINE; ! 149: privchat(true); ! 150: RESTORELINE; ! 151: } ! 152: ! 153: if(sys_status&SS_USERON && memcmp(&nodesync_user,&useron,sizeof(user_t))) { ! 154: getusrdirs(); ! 155: getusrsubs(); ! 156: memcpy(&nodesync_user,&useron,sizeof(nodesync_user)); } ! 157: ! 158: if(sys_status&SS_USERON && online && (timeleft/60)<(5-timeleft_warn) ! 159: && !SYSOP) { ! 160: timeleft_warn=5-(timeleft/60); ! 161: attr(LIGHTGRAY); ! 162: bprintf(text[OnlyXminutesLeft] ! 163: ,((ushort)timeleft/60)+1,(timeleft/60) ? "s" : nulstr); } ! 164: ! 165: attr(atr); /* replace original attributes */ ! 166: nodesync_inside=0; ! 167: } ! 168: ! 169: /****************************************************************************/ ! 170: /* Prints short messages waiting for this node, if any... */ ! 171: /****************************************************************************/ ! 172: void sbbs_t::getnmsg() ! 173: { ! 174: char str[256], HUGE16 *buf; ! 175: int file; ! 176: long length; ! 177: ! 178: getnodedat(cfg.node_num,&thisnode,1); ! 179: thisnode.misc&=~NODE_NMSG; /* clear the NMSG flag */ ! 180: putnodedat(cfg.node_num,&thisnode); ! 181: ! 182: sprintf(str,"%smsgs/n%3.3u.msg",cfg.data_dir,cfg.node_num); ! 183: if(flength(str)<1L) ! 184: return; ! 185: if((file=nopen(str,O_RDWR))==-1) { ! 186: /** ! 187: errormsg(WHERE,ERR_OPEN,str,O_RDWR); ! 188: **/ ! 189: return; } ! 190: length=filelength(file); ! 191: if(!length) { ! 192: close(file); ! 193: return; } ! 194: if((buf=(char *)LMALLOC(length+1))==NULL) { ! 195: close(file); ! 196: errormsg(WHERE,ERR_ALLOC,str,length+1); ! 197: return; } ! 198: if(lread(file,buf,length)!=length) { ! 199: close(file); ! 200: FREE(buf); ! 201: errormsg(WHERE,ERR_READ,str,length); ! 202: return; } ! 203: chsize(file,0L); ! 204: close(file); ! 205: buf[length]=0; ! 206: ! 207: if(thisnode.action==NODE_MAIN || thisnode.action==NODE_XFER ! 208: || sys_status&SS_IN_CTRLP) { ! 209: CRLF; } ! 210: putmsg(buf,P_NOATCODES); ! 211: LFREE(buf); ! 212: } ! 213: ! 214: /****************************************************************************/ ! 215: /* 'ext' must be at least 128 bytes! */ ! 216: /****************************************************************************/ ! 217: void sbbs_t::getnodeext(uint number, char *ext) ! 218: { ! 219: char str[256]; ! 220: int count=0; ! 221: ! 222: if(!number || number>cfg.sys_nodes) { ! 223: errormsg(WHERE,ERR_CHK,"node number",number); ! 224: return; } ! 225: ! 226: sprintf(str,"%snode.exb",cfg.ctrl_dir); ! 227: if((node_ext=nopen(str,O_RDONLY|O_DENYNONE))==-1) { ! 228: memset(ext,0,128); ! 229: errormsg(WHERE,ERR_OPEN,str,O_RDONLY|O_DENYNONE); ! 230: return; ! 231: } ! 232: ! 233: number--; /* make zero based */ ! 234: while(count<LOOP_NODEDAB) { ! 235: if(count>10) ! 236: mswait(100); ! 237: if(lock(node_ext,(long)number*128L,128)==-1) { ! 238: count++; ! 239: continue; } ! 240: lseek(node_ext,(long)number*128L,SEEK_SET); ! 241: if(read(node_ext,ext,128)==128) ! 242: break; ! 243: count++; } ! 244: unlock(node_ext,(long)number*128L,128); ! 245: close(node_ext); ! 246: node_ext=-1; ! 247: ! 248: if(count>(LOOP_NODEDAB/2) && count!=LOOP_NODEDAB) { ! 249: sprintf(str,"NODE.EXB COLLISION - Count: %d",count); ! 250: logline("!!",str); ! 251: } ! 252: if(count==LOOP_NODEDAB) { ! 253: errormsg(WHERE,ERR_READ,"node.exb",number+1); ! 254: return; ! 255: } ! 256: } ! 257: ! 258: ! 259: /****************************************************************************/ ! 260: /* Prints short messages waiting for 'usernumber', if any... */ ! 261: /* then deletes them. */ ! 262: /****************************************************************************/ ! 263: void sbbs_t::getsmsg(int usernumber) ! 264: { ! 265: char str[256], HUGE16 *buf; ! 266: int file; ! 267: long length; ! 268: ! 269: sprintf(str,"%smsgs/%4.4u.msg",cfg.data_dir,usernumber); ! 270: if(flength(str)<1L) ! 271: return; ! 272: if((file=nopen(str,O_RDWR))==-1) { ! 273: errormsg(WHERE,ERR_OPEN,str,O_RDWR); ! 274: return; } ! 275: length=filelength(file); ! 276: if((buf=(char *)LMALLOC(length+1))==NULL) { ! 277: close(file); ! 278: errormsg(WHERE,ERR_ALLOC,str,length+1); ! 279: return; } ! 280: if(lread(file,buf,length)!=length) { ! 281: close(file); ! 282: FREE(buf); ! 283: errormsg(WHERE,ERR_READ,str,length); ! 284: return; } ! 285: chsize(file,0L); ! 286: close(file); ! 287: buf[length]=0; ! 288: getnodedat(cfg.node_num,&thisnode,0); ! 289: if(thisnode.action==NODE_MAIN || thisnode.action==NODE_XFER ! 290: || sys_status&SS_IN_CTRLP) { ! 291: CRLF; } ! 292: if(thisnode.misc&NODE_MSGW) { ! 293: getnodedat(cfg.node_num,&thisnode,1); ! 294: thisnode.misc&=~NODE_MSGW; ! 295: putnodedat(cfg.node_num,&thisnode); } ! 296: putmsg(buf,P_NOATCODES); ! 297: LFREE(buf); ! 298: } ! 299: ! 300: /****************************************************************************/ ! 301: /* This function lists users that are online. */ ! 302: /* If listself is true, it will list the current node. */ ! 303: /* Returns number of active nodes (not including current node). */ ! 304: /****************************************************************************/ ! 305: int sbbs_t::whos_online(bool listself) ! 306: { ! 307: int i,j; ! 308: node_t node; ! 309: ! 310: CRLF; ! 311: bputs(text[NodeLstHdr]); ! 312: for(j=0,i=1;i<=cfg.sys_nodes && i<=cfg.sys_lastnode;i++) { ! 313: getnodedat(i,&node,0); ! 314: if(i==cfg.node_num) { ! 315: if(listself) ! 316: printnodedat(i,&node); ! 317: continue; } ! 318: if(node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET)) { ! 319: printnodedat(i,&node); ! 320: if(!lastnodemsg) ! 321: lastnodemsg=i; ! 322: j++; } } ! 323: if(!j) ! 324: bputs(text[NoOtherActiveNodes]); ! 325: return(j); ! 326: } ! 327: ! 328: /****************************************************************************/ ! 329: /* Displays the information for node number 'number' contained in 'node' */ ! 330: /****************************************************************************/ ! 331: void sbbs_t::printnodedat(uint number, node_t* node) ! 332: { ! 333: uint i; ! 334: char hour,mer[3]; ! 335: char tmp[512]; ! 336: ! 337: attr(cfg.color[clr_nodenum]); ! 338: bprintf("%3d ",number); ! 339: attr(cfg.color[clr_nodestatus]); ! 340: switch(node->status) { ! 341: case NODE_WFC: ! 342: bputs("Waiting for call"); ! 343: break; ! 344: case NODE_OFFLINE: ! 345: bputs("Offline"); ! 346: break; ! 347: case NODE_NETTING: ! 348: bputs("Networking"); ! 349: break; ! 350: case NODE_LOGON: ! 351: bputs("At logon prompt"); ! 352: break; ! 353: case NODE_EVENT_WAITING: ! 354: bputs("Waiting for all nodes to become inactive"); ! 355: break; ! 356: case NODE_EVENT_LIMBO: ! 357: bprintf("Waiting for node %d to finish external event",node->aux); ! 358: break; ! 359: case NODE_EVENT_RUNNING: ! 360: bputs("Running external event"); ! 361: break; ! 362: case NODE_NEWUSER: ! 363: attr(cfg.color[clr_nodeuser]); ! 364: bputs("New user"); ! 365: attr(cfg.color[clr_nodestatus]); ! 366: bputs(" applying for access "); ! 367: if(!node->connection) ! 368: bputs("Locally"); ! 369: else if(node->connection==0xffff) ! 370: bprintf("via telnet"); ! 371: else ! 372: bprintf("at %ubps",node->connection); ! 373: break; ! 374: case NODE_QUIET: ! 375: if(!SYSOP) { ! 376: bputs("Waiting for call"); ! 377: break; } ! 378: case NODE_INUSE: ! 379: if(node->misc&NODE_EXT) { ! 380: getnodeext(number,tmp); ! 381: bputs(tmp); ! 382: break; } ! 383: attr(cfg.color[clr_nodeuser]); ! 384: if(node->misc&NODE_ANON && !SYSOP) ! 385: bputs("UNKNOWN USER"); ! 386: else ! 387: bputs(username(&cfg,node->useron,tmp)); ! 388: attr(cfg.color[clr_nodestatus]); ! 389: bputs(" "); ! 390: switch(node->action) { ! 391: case NODE_MAIN: ! 392: bputs("at main menu"); ! 393: break; ! 394: case NODE_RMSG: ! 395: bputs("reading messages"); ! 396: break; ! 397: case NODE_RMAL: ! 398: bputs("reading mail"); ! 399: break; ! 400: case NODE_RSML: ! 401: bputs("reading sent mail"); ! 402: break; ! 403: case NODE_RTXT: ! 404: bputs("reading text files"); ! 405: break; ! 406: case NODE_PMSG: ! 407: bputs("posting message"); ! 408: break; ! 409: case NODE_SMAL: ! 410: bputs("sending mail"); ! 411: break; ! 412: case NODE_AMSG: ! 413: bputs("posting auto-message"); ! 414: break; ! 415: case NODE_XTRN: ! 416: if(node->aux<1 || node->aux>cfg.total_xtrns) ! 417: bputs("at external program menu"); ! 418: else { ! 419: bputs("running "); ! 420: i=node->aux-1; ! 421: if(SYSOP || chk_ar(cfg.xtrn[i]->ar,&useron)) ! 422: bputs(cfg.xtrn[node->aux-1]->name); ! 423: else ! 424: bputs("external program"); } ! 425: break; ! 426: case NODE_DFLT: ! 427: bputs("changing defaults"); ! 428: break; ! 429: case NODE_XFER: ! 430: bputs("at transfer menu"); ! 431: break; ! 432: case NODE_RFSD: ! 433: bprintf("retrieving from device #%d",node->aux); ! 434: break; ! 435: case NODE_DLNG: ! 436: bprintf("downloading"); ! 437: break; ! 438: case NODE_ULNG: ! 439: bputs("uploading"); ! 440: break; ! 441: case NODE_BXFR: ! 442: bputs("transferring bidirectional"); ! 443: break; ! 444: case NODE_LFIL: ! 445: bputs("listing files"); ! 446: break; ! 447: case NODE_LOGN: ! 448: bputs("logging on"); ! 449: break; ! 450: case NODE_LCHT: ! 451: bprintf("in local chat with %s",cfg.sys_op); ! 452: break; ! 453: case NODE_MCHT: ! 454: if(node->aux) { ! 455: bprintf("in multinode chat channel %d",node->aux&0xff); ! 456: if(node->aux&0x1f00) { /* password */ ! 457: outchar('*'); ! 458: if(SYSOP) ! 459: bprintf(" %s",unpackchatpass(tmp,node)); } } ! 460: else ! 461: bputs("in multinode global chat channel"); ! 462: break; ! 463: case NODE_PAGE: ! 464: bprintf("paging node %u for private chat",node->aux); ! 465: break; ! 466: case NODE_PCHT: ! 467: if(node->aux) ! 468: bprintf("in private chat with node %u",node->aux); ! 469: else ! 470: bprintf("in local chat with %s",cfg.sys_op); ! 471: break; ! 472: case NODE_GCHT: ! 473: i=node->aux; ! 474: if(i>=cfg.total_gurus) ! 475: i=0; ! 476: bprintf("chatting with %s",cfg.guru[i]->name); ! 477: break; ! 478: case NODE_CHAT: ! 479: bputs("in chat section"); ! 480: break; ! 481: case NODE_TQWK: ! 482: bputs("transferring QWK packet"); ! 483: break; ! 484: case NODE_SYSP: ! 485: bputs("performing sysop activities"); ! 486: break; ! 487: default: ! 488: bputs(ultoa(node->action,tmp,10)); ! 489: break; } ! 490: if(!node->connection) ! 491: bputs(" locally"); ! 492: else if(node->connection==0xffff) ! 493: bprintf(" via telnet"); ! 494: else ! 495: bprintf(" at %ubps",node->connection); ! 496: if(node->action==NODE_DLNG) { ! 497: if(cfg.sys_misc&SM_MILITARY) { ! 498: hour=node->aux/60; ! 499: mer[0]=0; } ! 500: else if((node->aux/60)>=12) { ! 501: if(node->aux/60==12) ! 502: hour=12; ! 503: else ! 504: hour=(node->aux/60)-12; ! 505: strcpy(mer,"pm"); } ! 506: else { ! 507: if((node->aux/60)==0) /* 12 midnite */ ! 508: hour=12; ! 509: else hour=node->aux/60; ! 510: strcpy(mer,"am"); } ! 511: bprintf(" ETA %02d:%02d %s" ! 512: ,hour,node->aux%60,mer); } ! 513: break; } ! 514: i=NODE_LOCK; ! 515: if(node->status==NODE_INUSE || SYSOP) ! 516: i|=NODE_POFF|NODE_AOFF|NODE_MSGW|NODE_NMSG; ! 517: if(node->misc&i) { ! 518: bputs(" ("); ! 519: if(node->misc&(i&NODE_AOFF)) ! 520: outchar('A'); ! 521: if(node->misc&NODE_LOCK) ! 522: outchar('L'); ! 523: if(node->misc&(i&(NODE_MSGW|NODE_NMSG))) ! 524: outchar('M'); ! 525: if(node->misc&(i&NODE_POFF)) ! 526: outchar('P'); ! 527: outchar(')'); } ! 528: if(SYSOP && ((node->misc ! 529: &(NODE_ANON|NODE_UDAT|NODE_INTR|NODE_RRUN|NODE_EVENT|NODE_DOWN|NODE_LCHAT)) ! 530: || node->status==NODE_QUIET)) { ! 531: bputs(" ["); ! 532: if(node->misc&NODE_ANON) ! 533: outchar('A'); ! 534: if(node->misc&NODE_INTR) ! 535: outchar('I'); ! 536: if(node->misc&NODE_RRUN) ! 537: outchar('R'); ! 538: if(node->misc&NODE_UDAT) ! 539: outchar('U'); ! 540: if(node->status==NODE_QUIET) ! 541: outchar('Q'); ! 542: if(node->misc&NODE_EVENT) ! 543: outchar('E'); ! 544: if(node->misc&NODE_DOWN) ! 545: outchar('D'); ! 546: if(node->misc&NODE_LCHAT) ! 547: outchar('C'); ! 548: outchar(']'); } ! 549: if(node->errors && SYSOP) { ! 550: attr(cfg.color[clr_err]); ! 551: bprintf(" %d error%c",node->errors, node->errors>1 ? 's' : '\0' ); } ! 552: attr(LIGHTGRAY); ! 553: CRLF; ! 554: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.