|
|
1.1 ! root 1: #line 1 "CHAT.C" ! 2: ! 3: /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */ ! 4: ! 5: /****************************************/ ! 6: /* Local and Node-to-Node Chat routines */ ! 7: /****************************************/ ! 8: ! 9: #include "sbbs.h" ! 10: ! 11: #define PCHAT_LEN 1000 /* Size of Private chat file */ ! 12: ! 13: int getnodetopage(int all, int telegram); ! 14: ! 15: ! 16: char *weekday[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday" ! 17: ,"Saturday"}; ! 18: char *month[]={"January","February","March","April","May","June" ! 19: ,"July","August","September","October","November","December"}; ! 20: ! 21: ! 22: /****************************************************************************/ ! 23: /* Chat between local keyboard and remote user on current node. */ ! 24: /* Called from inkey (inkey is then re-entrant) */ ! 25: /****************************************************************************/ ! 26: void localchat() ! 27: { ! 28: uchar str[256],act; ! 29: int con=console; /* save console state */ ! 30: time_t beg=time(NULL); ! 31: ! 32: console&=~(CON_L_ECHOX|CON_R_ECHOX); /* turn off X's */ ! 33: console|=(CON_L_ECHO|CON_R_ECHO); /* make sure echo is enabled */ ! 34: nosound(); ! 35: sys_status&=~SS_SYSPAGE; ! 36: act=action; /* save the user's current action */ ! 37: action=NODE_LCHT; ! 38: bprintf(text[SysopIsHere],sys_op); ! 39: while(sys_status&SS_LCHAT && online) { ! 40: SYNC; ! 41: getstr(str,78,K_WRAP|K_MSG); } ! 42: bputs(text[EndOfChat]); ! 43: now=time(NULL); ! 44: if(!(sys_status&SS_USERON)) ! 45: answertime=now; ! 46: starttime+=now-beg; /* credit user for time in chat */ ! 47: RESTORELINE; ! 48: action=act; ! 49: console=con; /* restore console */ ! 50: } ! 51: ! 52: void sysop_page(void) ! 53: { ! 54: int i; ! 55: ! 56: for(i=0;i<total_pages;i++) ! 57: if(chk_ar(page[i]->ar,useron)) ! 58: break; ! 59: if(i<total_pages) { ! 60: bprintf(text[PagingGuru],sys_op); ! 61: external(cmdstr(page[i]->cmd,nulstr,nulstr,NULL) ! 62: ,page[i]->misc&IO_INTS ? EX_OUTL|EX_OUTR|EX_INR ! 63: : EX_OUTL); } ! 64: else if(sys_misc&SM_SHRTPAGE) { ! 65: bprintf(text[PagingGuru],sys_op); ! 66: for(i=0;i<10 && !lkbrd(1);i++) { ! 67: beep(1000,200); ! 68: mswait(200); ! 69: outchar('.'); } ! 70: CRLF; } ! 71: else { ! 72: sys_status^=SS_SYSPAGE; ! 73: bprintf(text[SysopPageIsNow] ! 74: ,sys_status&SS_SYSPAGE ? text[ON] : text[OFF]); ! 75: nosound(); } ! 76: } ! 77: ! 78: /****************************************************************************/ ! 79: /* Returns 1 if user online has access to channel "channum" */ ! 80: /****************************************************************************/ ! 81: char chan_access(uint cnum) ! 82: { ! 83: ! 84: if(!total_chans || cnum>=total_chans || !chk_ar(chan[cnum]->ar,useron)) { ! 85: bputs(text[CantAccessThatChannel]); ! 86: return(0); } ! 87: if(!(useron.exempt&FLAG('J')) && chan[cnum]->cost>useron.cdt+useron.freecdt) { ! 88: bputs(text[NotEnoughCredits]); ! 89: return(0); } ! 90: return(1); ! 91: } ! 92: ! 93: void privchat(void) ! 94: { ! 95: uchar str[128],ch,c,*p,localbuf[5][81],remotebuf[5][81] ! 96: ,localline=0,remoteline=0,localchar=0,remotechar=0 ! 97: ,*sep="\1w\1h�����[\1i\1r%c\1n\1h]���Ĵ " ! 98: "\1yPrivate Chat - \1rCtrl-C to Quit \1y- " ! 99: "Time Left: \1g%-8s\1w" ! 100: " �����[\1i\1b%c\1n\1h]�����"; ! 101: int in,out,i,j,n,done,echo=1,x,y,activity; ! 102: node_t node; ! 103: ! 104: n=getnodetopage(0,0); ! 105: if(!n) ! 106: return; ! 107: if(n==node_num) { ! 108: bputs(text[NoNeedToPageSelf]); ! 109: return; } ! 110: getnodedat(n,&node,0); ! 111: if(node.action==NODE_PCHT && node.aux!=node_num) { ! 112: bprintf(text[NodeNAlreadyInPChat],n); ! 113: return; } ! 114: if((node.action!=NODE_PAGE || node.aux!=node_num) ! 115: && node.misc&NODE_POFF && !SYSOP) { ! 116: bprintf(text[CantPageNode],node.misc&NODE_ANON ! 117: ? text[UNKNOWN_USER] : username(node.useron,tmp)); ! 118: return; } ! 119: if(node.action!=NODE_PAGE) { ! 120: bprintf("\r\n\1n\1mPaging \1h%s #%u\1n\1m for private chat\r\n" ! 121: ,node.misc&NODE_ANON ? text[UNKNOWN_USER] : username(node.useron,tmp) ! 122: ,node.useron); ! 123: sprintf(str,text[NodePChatPageMsg] ! 124: ,node_num,thisnode.misc&NODE_ANON ! 125: ? text[UNKNOWN_USER] : useron.alias); ! 126: putnmsg(n,str); ! 127: sprintf(str,"Paged %s on node %d to private chat" ! 128: ,username(node.useron,tmp),n); ! 129: logline("C",str); } ! 130: ! 131: getnodedat(node_num,&thisnode,1); ! 132: thisnode.action=action=NODE_PAGE; ! 133: thisnode.aux=n; ! 134: putnodedat(node_num,thisnode); ! 135: ! 136: if(node.action!=NODE_PAGE || node.aux!=node_num) { ! 137: bprintf(text[WaitingForNodeInPChat],n); ! 138: while(online && !(sys_status&SS_ABORT)) { ! 139: getnodedat(n,&node,0); ! 140: if((node.action==NODE_PAGE || node.action==NODE_PCHT) ! 141: && node.aux==node_num) { ! 142: bprintf(text[NodeJoinedPrivateChat] ! 143: ,n,node.misc&NODE_ANON ? text[UNKNOWN_USER] ! 144: : username(node.useron,tmp)); ! 145: break; } ! 146: if(!inkey(0)) ! 147: mswait(1); ! 148: action=NODE_PAGE; ! 149: checkline(); ! 150: gettimeleft(); ! 151: SYNC; } } ! 152: ! 153: getnodedat(node_num,&thisnode,1); ! 154: thisnode.action=action=NODE_PCHT; ! 155: putnodedat(node_num,thisnode); ! 156: ! 157: if(!online || sys_status&SS_ABORT) ! 158: return; ! 159: ! 160: if(useron.chat&CHAT_SPLITP && useron.misc&ANSI && rows>=24) ! 161: sys_status|=SS_SPLITP; ! 162: /* ! 163: if(!(useron.misc&EXPERT)) ! 164: menu("PRIVCHAT"); ! 165: */ ! 166: ! 167: if(!(sys_status&SS_SPLITP)) ! 168: bputs(text[WelcomeToPrivateChat]); ! 169: ! 170: sprintf(str,"%sCHAT.DAB",node_dir); ! 171: if((out=open(str,O_RDWR|O_DENYNONE|O_CREAT|O_BINARY ! 172: ,S_IREAD|S_IWRITE))==-1) { ! 173: errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_DENYNONE|O_CREAT); ! 174: return; } ! 175: ! 176: sprintf(str,"%sCHAT.DAB",node_path[n-1]); ! 177: if(!fexist(str)) /* Wait while it's created for the first time */ ! 178: mswait(2000); ! 179: if((in=open(str,O_RDWR|O_DENYNONE|O_CREAT|O_BINARY ! 180: ,S_IREAD|S_IWRITE))==-1) { ! 181: close(out); ! 182: errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_DENYNONE|O_CREAT); ! 183: return; } ! 184: ! 185: if((p=(char *)MALLOC(PCHAT_LEN))==NULL) { ! 186: close(in); ! 187: close(out); ! 188: errormsg(WHERE,ERR_ALLOC,str,PCHAT_LEN); ! 189: return; } ! 190: memset(p,0,PCHAT_LEN); ! 191: write(in,p,PCHAT_LEN); ! 192: write(out,p,PCHAT_LEN); ! 193: FREE(p); ! 194: lseek(in,0L,SEEK_SET); ! 195: lseek(out,0L,SEEK_SET); ! 196: ! 197: getnodedat(node_num,&thisnode,1); ! 198: thisnode.misc&=~NODE_RPCHT; /* Clear "reset pchat flag" */ ! 199: putnodedat(node_num,thisnode); ! 200: ! 201: getnodedat(n,&node,1); ! 202: node.misc|=NODE_RPCHT; /* Set "reset pchat flag" */ ! 203: putnodedat(n,node); /* on other node */ ! 204: ! 205: /* Wait for other node */ ! 206: /* to acknowledge and reset */ ! 207: while(online && !(sys_status&SS_ABORT)) { ! 208: getnodedat(n,&node,0); ! 209: if(!(node.misc&NODE_RPCHT)) ! 210: break; ! 211: getnodedat(node_num,&thisnode,0); ! 212: if(thisnode.misc&NODE_RPCHT) ! 213: break; ! 214: checkline(); ! 215: gettimeleft(); ! 216: SYNC; ! 217: inkey(0); ! 218: mswait(1); } ! 219: ! 220: ! 221: action=NODE_PCHT; ! 222: SYNC; ! 223: ! 224: if(sys_status&SS_SPLITP) { ! 225: lncntr=0; ! 226: CLS; ! 227: ANSI_SAVE(); ! 228: GOTOXY(1,13); ! 229: bprintf(sep ! 230: ,thisnode.misc&NODE_MSGW ? 'T':SP ! 231: ,sectostr(timeleft,tmp) ! 232: ,thisnode.misc&NODE_NMSG ? 'M':SP); ! 233: CRLF; } ! 234: ! 235: done=0; ! 236: ! 237: while(online && !(sys_status&SS_ABORT) && !done) { ! 238: RIOSYNC(0); ! 239: lncntr=0; ! 240: if(sys_status&SS_SPLITP) ! 241: lbuflen=0; ! 242: action=NODE_PCHT; ! 243: if(!localchar) { ! 244: if(sys_status&SS_SPLITP) { ! 245: getnodedat(node_num,&thisnode,0); ! 246: if(thisnode.misc&NODE_INTR) ! 247: break; ! 248: if(thisnode.misc&NODE_UDAT && !(useron.rest&FLAG('G'))) { ! 249: getuserdat(&useron); ! 250: getnodedat(node_num,&thisnode,1); ! 251: thisnode.misc&=~NODE_UDAT; ! 252: putnodedat(node_num,thisnode); } } ! 253: else ! 254: nodesync(); } ! 255: activity=0; ! 256: if((ch=inkey(K_GETSTR))!=0) { ! 257: activity=1; ! 258: if(echo) ! 259: attr(color[clr_chatlocal]); ! 260: else ! 261: lclatr(color[clr_chatlocal]); ! 262: if(ch==BS) { ! 263: if(localchar) { ! 264: if(echo) ! 265: bputs("\b \b"); ! 266: else ! 267: lputs("\b \b"); ! 268: localchar--; ! 269: localbuf[localline][localchar]=0; } } ! 270: else if(ch==TAB) { ! 271: if(echo) ! 272: outchar(SP); ! 273: else ! 274: lputc(SP); ! 275: localbuf[localline][localchar]=SP; ! 276: localchar++; ! 277: while(localchar<78 && localchar%8) { ! 278: if(echo) ! 279: outchar(SP); ! 280: else ! 281: lputc(SP); ! 282: localbuf[localline][localchar++]=SP; } } ! 283: else if(ch>=SP || ch==CR) { ! 284: if(ch!=CR) { ! 285: if(echo) ! 286: outchar(ch); ! 287: else ! 288: lputc(ch); ! 289: localbuf[localline][localchar]=ch; } ! 290: ! 291: if(ch==CR || (localchar>68 && ch==SP) || ++localchar>78) { ! 292: ! 293: localbuf[localline][localchar]=0; ! 294: localchar=0; ! 295: ! 296: if(sys_status&SS_SPLITP && lclwy()==24) { ! 297: GOTOXY(1,13); ! 298: bprintf(sep ! 299: ,thisnode.misc&NODE_MSGW ? 'T':SP ! 300: ,sectostr(timeleft,tmp) ! 301: ,thisnode.misc&NODE_NMSG ? 'M':SP); ! 302: attr(color[clr_chatlocal]); ! 303: for(x=13,y=0;x<rows;x++,y++) { ! 304: bprintf("\x1b[%d;1H\x1b[K",x+1); ! 305: if(y<=localline) ! 306: bprintf("%s\r\n",localbuf[y]); } ! 307: GOTOXY(1,15+localline); ! 308: localline=0; } ! 309: else { ! 310: if(localline>=4) ! 311: for(i=0;i<4;i++) ! 312: memcpy(localbuf[i],localbuf[i+1],81); ! 313: else ! 314: localline++; ! 315: if(echo) { ! 316: CRLF; ! 317: if(sys_status&SS_SPLITP) ! 318: bputs("\x1b[K"); } ! 319: else ! 320: lputs(crlf); } ! 321: // SYNC; ! 322: } } ! 323: ! 324: read(out,&c,1); ! 325: lseek(out,-1L,SEEK_CUR); ! 326: if(!c) /* hasn't wrapped */ ! 327: write(out,&ch,1); ! 328: else { ! 329: if(!tell(out)) ! 330: lseek(out,0L,SEEK_END); ! 331: lseek(out,-1L,SEEK_CUR); ! 332: ch=0; ! 333: write(out,&ch,1); ! 334: lseek(out,-1L,SEEK_CUR); } ! 335: if(tell(out)>=PCHAT_LEN) ! 336: lseek(out,0L,SEEK_SET); ! 337: } ! 338: else while(online) { ! 339: if(!(sys_status&SS_SPLITP)) ! 340: remotechar=localchar; ! 341: if(tell(in)>=PCHAT_LEN) ! 342: lseek(in,0L,SEEK_SET); ! 343: ch=0; ! 344: read(in,&ch,1); ! 345: lseek(in,-1L,SEEK_CUR); ! 346: if(!ch) break; /* char from other node */ ! 347: activity=1; ! 348: x=lclwx(); ! 349: y=lclwy(); ! 350: if(sys_status&SS_SPLITP) ! 351: ANSI_RESTORE(); ! 352: attr(color[clr_chatremote]); ! 353: if(sys_status&SS_SPLITP) ! 354: bputs("\b \b"); /* Delete fake cursor */ ! 355: if(ch==BS) { ! 356: if(remotechar) { ! 357: bputs("\b \b"); ! 358: remotechar--; ! 359: remotebuf[remoteline][remotechar]=0; } } ! 360: else if(ch==TAB) { ! 361: outchar(SP); ! 362: remotebuf[remoteline][remotechar]=SP; ! 363: remotechar++; ! 364: while(remotechar<78 && remotechar%8) { ! 365: outchar(SP); ! 366: remotebuf[remoteline][remotechar++]=SP; } } ! 367: else if(ch>=SP || ch==CR) { ! 368: if(ch!=CR) { ! 369: outchar(ch); ! 370: remotebuf[remoteline][remotechar]=ch; } ! 371: ! 372: if(ch==CR || (remotechar>68 && ch==SP) || ++remotechar>78) { ! 373: ! 374: remotebuf[remoteline][remotechar]=0; ! 375: remotechar=0; ! 376: ! 377: if(sys_status&SS_SPLITP && lclwy()==12) { ! 378: CRLF; ! 379: bprintf(sep ! 380: ,thisnode.misc&NODE_MSGW ? 'T':SP ! 381: ,sectostr(timeleft,tmp) ! 382: ,thisnode.misc&NODE_NMSG ? 'M':SP); ! 383: attr(color[clr_chatremote]); ! 384: for(i=0;i<12;i++) { ! 385: bprintf("\x1b[%d;1H\x1b[K",i+1); ! 386: if(i<=remoteline) ! 387: bprintf("%s\r\n",remotebuf[i]); } ! 388: remoteline=0; ! 389: GOTOXY(1,6); } ! 390: else { ! 391: if(remoteline>=4) ! 392: for(i=0;i<4;i++) ! 393: memcpy(remotebuf[i],remotebuf[i+1],81); ! 394: else ! 395: remoteline++; ! 396: if(echo) { ! 397: CRLF; ! 398: if(sys_status&SS_SPLITP) ! 399: bputs("\x1b[K"); } ! 400: else ! 401: lputs(crlf); } } } ! 402: if(sys_status&SS_SPLITP) { ! 403: bputs("\1i_\1n"); /* Fake cursor */ ! 404: ANSI_SAVE(); ! 405: GOTOXY(x,y); } ! 406: ch=0; ! 407: write(in,&ch,1); ! 408: ! 409: if(!(sys_status&SS_SPLITP)) ! 410: localchar=remotechar; ! 411: } ! 412: if(!activity) { /* no activity so chk node.dab */ ! 413: getnodedat(n,&node,0); ! 414: if((node.action!=NODE_PCHT && node.action!=NODE_PAGE) ! 415: || node.aux!=node_num) { ! 416: bprintf(text[NodeLeftPrivateChat] ! 417: ,n,node.misc&NODE_ANON ? text[UNKNOWN_USER] ! 418: : username(node.useron,tmp)); ! 419: break; } ! 420: getnodedat(node_num,&thisnode,0); ! 421: if(thisnode.misc&NODE_RPCHT) { /* pchat has been reset */ ! 422: lseek(in,0L,SEEK_SET); /* so seek to beginning */ ! 423: lseek(out,0L,SEEK_SET); ! 424: getnodedat(node_num,&thisnode,1); ! 425: thisnode.misc&=~NODE_RPCHT; ! 426: putnodedat(node_num,thisnode); } ! 427: mswait(0); } ! 428: checkline(); ! 429: gettimeleft(); } ! 430: if(sys_status&SS_SPLITP) ! 431: CLS; ! 432: sys_status&=~SS_SPLITP; ! 433: close(in); ! 434: close(out); ! 435: } ! 436: ! 437: /****************************************************************************/ ! 438: /* The chat section */ ! 439: /****************************************************************************/ ! 440: void chatsection() ! 441: { ! 442: uchar line[256],str[256],ch,c,done,no_rip_menu ! 443: ,usrs,preusrs,qusrs,*gurubuf=NULL,channel,savch,*p ! 444: ,pgraph[400],buf[400] ! 445: ,usr[MAX_NODES],preusr[MAX_NODES],qusr[MAX_NODES]; ! 446: int file,in,out; ! 447: long i,j,k,n; ! 448: node_t node; ! 449: ! 450: action=NODE_CHAT; ! 451: if(useron.misc&(RIP|WIP) || !(useron.misc&EXPERT)) ! 452: menu("CHAT"); ! 453: ASYNC; ! 454: bputs(text[ChatPrompt]); ! 455: while(online) { ! 456: no_rip_menu=0; ! 457: ch=getkeys("ACDJPQST?\r",0); ! 458: if(ch>SP) ! 459: logch(ch,0); ! 460: switch(ch) { ! 461: case 'S': ! 462: useron.chat^=CHAT_SPLITP; ! 463: putuserrec(useron.number,U_CHAT,8 ! 464: ,ltoa(useron.chat,str,16)); ! 465: bprintf("\r\nPrivate split-screen chat is now: %s\r\n" ! 466: ,useron.chat&CHAT_SPLITP ? text[ON]:text[OFF]); ! 467: break; ! 468: case 'A': ! 469: CRLF; ! 470: useron.chat^=CHAT_NOACT; ! 471: putuserrec(useron.number,U_CHAT,8 ! 472: ,ltoa(useron.chat,str,16)); ! 473: getnodedat(node_num,&thisnode,1); ! 474: thisnode.misc^=NODE_AOFF; ! 475: printnodedat(node_num,thisnode); ! 476: putnodedat(node_num,thisnode); ! 477: no_rip_menu=1; ! 478: break; ! 479: case 'D': ! 480: CRLF; ! 481: useron.chat^=CHAT_NOPAGE; ! 482: putuserrec(useron.number,U_CHAT,8 ! 483: ,ltoa(useron.chat,str,16)); ! 484: getnodedat(node_num,&thisnode,1); ! 485: thisnode.misc^=NODE_POFF; ! 486: printnodedat(node_num,thisnode); ! 487: putnodedat(node_num,thisnode); ! 488: no_rip_menu=1; ! 489: break; ! 490: case 'J': ! 491: if(!chan_access(0)) ! 492: break; ! 493: if(useron.misc&(RIP|WIP) ||!(useron.misc&EXPERT)) ! 494: menu("MULTCHAT"); ! 495: getnodedat(node_num,&thisnode,1); ! 496: bputs(text[WelcomeToMultiChat]); ! 497: channel=thisnode.aux=1; /* default channel 1 */ ! 498: putnodedat(node_num,thisnode); ! 499: bprintf(text[WelcomeToChannelN],channel,chan[0]->name); ! 500: if(gurubuf) { ! 501: FREE(gurubuf); ! 502: gurubuf=NULL; } ! 503: if(chan[0]->misc&CHAN_GURU && chan[0]->guru<total_gurus ! 504: && chk_ar(guru[chan[0]->guru]->ar,useron)) { ! 505: sprintf(str,"%s%s.DAT",ctrl_dir,guru[chan[0]->guru]->code); ! 506: if((file=nopen(str,O_RDONLY))==-1) { ! 507: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 508: break; } ! 509: if((gurubuf=MALLOC(filelength(file)+1))==NULL) { ! 510: close(file); ! 511: errormsg(WHERE,ERR_ALLOC,str,filelength(file)+1); ! 512: break; } ! 513: read(file,gurubuf,filelength(file)); ! 514: gurubuf[filelength(file)]=0; ! 515: close(file); } ! 516: usrs=0; ! 517: for(i=1;i<=sys_nodes && i<=sys_lastnode;i++) { ! 518: if(i==node_num) ! 519: continue; ! 520: getnodedat(i,&node,0); ! 521: if(node.action!=NODE_MCHT || node.status!=NODE_INUSE) ! 522: continue; ! 523: if(node.aux && (node.aux&0xff)!=channel) ! 524: continue; ! 525: printnodedat(i,node); ! 526: preusr[usrs]=usr[usrs++]=i; } ! 527: preusrs=usrs; ! 528: if(gurubuf) ! 529: bprintf(text[NodeInMultiChatLocally] ! 530: ,sys_nodes+1,guru[chan[channel-1]->guru]->name,channel); ! 531: bputs(text[YoureOnTheAir]); ! 532: done=0; ! 533: while(online && !done) { ! 534: checkline(); ! 535: gettimeleft(); ! 536: action=NODE_MCHT; ! 537: qusrs=usrs=0; ! 538: for(i=1;i<=sys_nodes;i++) { ! 539: if(i==node_num) ! 540: continue; ! 541: getnodedat(i,&node,0); ! 542: if(node.action!=NODE_MCHT ! 543: || (node.aux && channel && (node.aux&0xff)!=channel)) ! 544: continue; ! 545: if(node.status==NODE_QUIET) ! 546: qusr[qusrs++]=i; ! 547: else if(node.status==NODE_INUSE) ! 548: usr[usrs++]=i; } ! 549: if(preusrs>usrs) { ! 550: if(!usrs && channel && chan[channel-1]->misc&CHAN_GURU ! 551: && chan[channel-1]->guru<total_gurus) ! 552: bprintf(text[NodeJoinedMultiChat] ! 553: ,sys_nodes+1,guru[chan[channel-1]->guru]->name ! 554: ,channel); ! 555: outchar(7); ! 556: for(i=0;i<preusrs;i++) { ! 557: for(j=0;j<usrs;j++) ! 558: if(preusr[i]==usr[j]) ! 559: break; ! 560: if(j==usrs) { ! 561: getnodedat(preusr[i],&node,0); ! 562: if(node.misc&NODE_ANON) ! 563: sprintf(str,"%.80s",text[UNKNOWN_USER]); ! 564: else ! 565: username(node.useron,str); ! 566: bprintf(text[NodeLeftMultiChat] ! 567: ,preusr[i],str,channel); } } } ! 568: else if(preusrs<usrs) { ! 569: if(!preusrs && channel && chan[channel-1]->misc&CHAN_GURU ! 570: && chan[channel-1]->guru<total_gurus) ! 571: bprintf(text[NodeLeftMultiChat] ! 572: ,sys_nodes+1,guru[chan[channel-1]->guru]->name ! 573: ,channel); ! 574: outchar(7); ! 575: for(i=0;i<usrs;i++) { ! 576: for(j=0;j<preusrs;j++) ! 577: if(usr[i]==preusr[j]) ! 578: break; ! 579: if(j==preusrs) { ! 580: getnodedat(usr[i],&node,0); ! 581: if(node.misc&NODE_ANON) ! 582: sprintf(str,"%.80s",text[UNKNOWN_USER]); ! 583: else ! 584: username(node.useron,str); ! 585: bprintf(text[NodeJoinedMultiChat] ! 586: ,usr[i],str,channel); } } } ! 587: preusrs=usrs; ! 588: for(i=0;i<usrs;i++) ! 589: preusr[i]=usr[i]; ! 590: attr(color[clr_multichat]); ! 591: SYNC; ! 592: sys_status&=~SS_ABORT; ! 593: if((ch=inkey(0))!=0 || wordwrap[0]) { ! 594: if(ch=='/') { ! 595: bputs(text[MultiChatCommandPrompt]); ! 596: strcpy(str,"ACELWQ?*"); ! 597: if(SYSOP) ! 598: strcat(str,"0"); ! 599: i=getkeys(str,total_chans); ! 600: if(i&0x80000000L) { /* change channel */ ! 601: savch=i&~0x80000000L; ! 602: if(savch==channel) ! 603: continue; ! 604: if(!chan_access(savch-1)) ! 605: continue; ! 606: bprintf(text[WelcomeToChannelN] ! 607: ,savch,chan[savch-1]->name); ! 608: ! 609: usrs=0; ! 610: for(i=1;i<=sys_nodes;i++) { ! 611: if(i==node_num) ! 612: continue; ! 613: getnodedat(i,&node,0); ! 614: if(node.action!=NODE_MCHT ! 615: || node.status!=NODE_INUSE) ! 616: continue; ! 617: if(node.aux && (node.aux&0xff)!=savch) ! 618: continue; ! 619: printnodedat(i,node); ! 620: if(node.aux&0x1f00) { /* password */ ! 621: bprintf(text[PasswordProtected] ! 622: ,node.misc&NODE_ANON ! 623: ? text[UNKNOWN_USER] ! 624: : username(node.useron,tmp)); ! 625: if(!getstr(str,8,K_UPPER|K_ALPHA|K_LINE)) ! 626: break; ! 627: if(strcmp(str,unpackchatpass(tmp,node))) ! 628: break; ! 629: bputs(text[CorrectPassword]); } ! 630: preusr[usrs]=usr[usrs++]=i; } ! 631: if(i<=sys_nodes) { /* failed password */ ! 632: bputs(text[WrongPassword]); ! 633: continue; } ! 634: if(gurubuf) { ! 635: FREE(gurubuf); ! 636: gurubuf=NULL; } ! 637: if(chan[savch-1]->misc&CHAN_GURU ! 638: && chan[savch-1]->guru<total_gurus ! 639: && chk_ar(guru[chan[savch-1]->guru]->ar,useron ! 640: )) { ! 641: sprintf(str,"%s%s.DAT",ctrl_dir ! 642: ,guru[chan[savch-1]->guru]->code); ! 643: if((file=nopen(str,O_RDONLY))==-1) { ! 644: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 645: break; } ! 646: if((gurubuf=MALLOC(filelength(file)+1))==NULL) { ! 647: close(file); ! 648: errormsg(WHERE,ERR_ALLOC,str ! 649: ,filelength(file)+1); ! 650: break; } ! 651: read(file,gurubuf,filelength(file)); ! 652: gurubuf[filelength(file)]=0; ! 653: close(file); } ! 654: preusrs=usrs; ! 655: if(gurubuf) ! 656: bprintf(text[NodeInMultiChatLocally] ! 657: ,sys_nodes+1 ! 658: ,guru[chan[savch-1]->guru]->name ! 659: ,savch); ! 660: channel=savch; ! 661: if(!usrs && chan[savch-1]->misc&CHAN_PW ! 662: && !noyes(text[PasswordProtectChanQ])) { ! 663: bputs(text[PasswordPrompt]); ! 664: if(getstr(str,8,K_UPPER|K_ALPHA|K_LINE)) { ! 665: getnodedat(node_num,&thisnode,1); ! 666: thisnode.aux=channel; ! 667: packchatpass(str,&thisnode); } ! 668: else { ! 669: getnodedat(node_num,&thisnode,1); ! 670: thisnode.aux=channel; } } ! 671: else { ! 672: getnodedat(node_num,&thisnode,1); ! 673: thisnode.aux=channel; } ! 674: putnodedat(node_num,thisnode); ! 675: bputs(text[YoureOnTheAir]); ! 676: if(chan[channel-1]->cost ! 677: && !(useron.exempt&FLAG('J'))) ! 678: subtract_cdt(chan[channel-1]->cost); } ! 679: else switch(i) { /* other command */ ! 680: case '0': /* Global channel */ ! 681: if(!SYSOP) ! 682: break; ! 683: usrs=0; ! 684: for(i=1;i<=sys_nodes;i++) { ! 685: if(i==node_num) ! 686: continue; ! 687: getnodedat(i,&node,0); ! 688: if(node.action!=NODE_MCHT ! 689: || node.status!=NODE_INUSE) ! 690: continue; ! 691: printnodedat(i,node); ! 692: preusr[usrs]=usr[usrs++]=i; } ! 693: preusrs=usrs; ! 694: getnodedat(node_num,&thisnode,1); ! 695: thisnode.aux=channel=0; ! 696: putnodedat(node_num,thisnode); ! 697: break; ! 698: case 'A': /* Action commands */ ! 699: useron.chat^=CHAT_ACTION; ! 700: bprintf("\r\nAction commands are now %s\r\n" ! 701: ,useron.chat&CHAT_ACTION ! 702: ? text[ON]:text[OFF]); ! 703: putuserrec(useron.number,U_CHAT,8 ! 704: ,ltoa(useron.chat,str,16)); ! 705: break; ! 706: case 'C': /* List of action commands */ ! 707: CRLF; ! 708: for(i=0;i<total_chatacts;i++) { ! 709: if(chatact[i]->actset ! 710: !=chan[channel-1]->actset) ! 711: continue; ! 712: bprintf("%-*.*s",LEN_CHATACTCMD ! 713: ,LEN_CHATACTCMD,chatact[i]->cmd); ! 714: if(!((i+1)%8)) { ! 715: CRLF; } ! 716: else ! 717: bputs(" "); } ! 718: CRLF; ! 719: break; ! 720: case 'E': /* Toggle echo */ ! 721: useron.chat^=CHAT_ECHO; ! 722: bprintf(text[EchoIsNow] ! 723: ,useron.chat&CHAT_ECHO ! 724: ? text[ON]:text[OFF]); ! 725: putuserrec(useron.number,U_CHAT,8 ! 726: ,ltoa(useron.chat,str,16)); ! 727: break; ! 728: case 'L': /* list nodes */ ! 729: CRLF; ! 730: for(i=1;i<=sys_nodes && i<=sys_lastnode;i++) { ! 731: getnodedat(i,&node,0); ! 732: printnodedat(i,node); } ! 733: CRLF; ! 734: break; ! 735: case 'W': /* page node(s) */ ! 736: j=getnodetopage(0,0); ! 737: if(!j) ! 738: break; ! 739: for(i=0;i<usrs;i++) ! 740: if(usr[i]==j) ! 741: break; ! 742: if(i>=usrs) { ! 743: bputs(text[UserNotFound]); ! 744: break; } ! 745: ! 746: bputs(text[NodeMsgPrompt]); ! 747: if(!getstr(line,66,K_LINE|K_MSG)) ! 748: break; ! 749: ! 750: sprintf(buf,text[ChatLineFmt] ! 751: ,thisnode.misc&NODE_ANON ! 752: ? text[AnonUserChatHandle] ! 753: : useron.handle ! 754: ,node_num,'*',line); ! 755: strcat(buf,crlf); ! 756: if(useron.chat&CHAT_ECHO) ! 757: bputs(buf); ! 758: putnmsg(j,buf); ! 759: break; ! 760: case 'Q': /* quit */ ! 761: done=1; ! 762: break; ! 763: case '*': ! 764: sprintf(str,"%sMENU\\CHAN.*",text_dir); ! 765: if(fexist(str)) ! 766: menu("CHAN"); ! 767: else { ! 768: bputs(text[ChatChanLstHdr]); ! 769: bputs(text[ChatChanLstTitles]); ! 770: if(total_chans>=10) { ! 771: bputs(" "); ! 772: bputs(text[ChatChanLstTitles]); } ! 773: CRLF; ! 774: bputs(text[ChatChanLstUnderline]); ! 775: if(total_chans>=10) { ! 776: bputs(" "); ! 777: bputs(text[ChatChanLstUnderline]); } ! 778: CRLF; ! 779: if(total_chans>=10) ! 780: j=(total_chans/2)+(total_chans&1); ! 781: else ! 782: j=total_chans; ! 783: for(i=0;i<j && !msgabort();i++) { ! 784: bprintf(text[ChatChanLstFmt],i+1 ! 785: ,chan[i]->name ! 786: ,chan[i]->cost); ! 787: if(total_chans>=10) { ! 788: k=(total_chans/2) ! 789: +i+(total_chans&1); ! 790: if(k<total_chans) { ! 791: bputs(" "); ! 792: bprintf(text[ChatChanLstFmt] ! 793: ,k+1 ! 794: ,chan[k]->name ! 795: ,chan[k]->cost); } } ! 796: CRLF; } ! 797: CRLF; } ! 798: break; ! 799: case '?': /* menu */ ! 800: menu("MULTCHAT"); ! 801: break; } } ! 802: else { ! 803: ungetkey(ch); ! 804: j=0; ! 805: pgraph[0]=0; ! 806: while(j<5) { ! 807: if(!getstr(line,66,K_WRAP|K_MSG|K_CHAT)) ! 808: break; ! 809: if(j) { ! 810: sprintf(str,text[ChatLineFmt] ! 811: ,thisnode.misc&NODE_ANON ! 812: ? text[AnonUserChatHandle] ! 813: : useron.handle ! 814: ,node_num,':',nulstr); ! 815: sprintf(tmp,"%*s",bstrlen(str),nulstr); ! 816: strcat(pgraph,tmp); } ! 817: strcat(pgraph,line); ! 818: strcat(pgraph,crlf); ! 819: if(!wordwrap[0]) ! 820: break; ! 821: j++; } ! 822: if(pgraph[0]) { ! 823: if(useron.chat&CHAT_ACTION) { ! 824: for(i=0;i<total_chatacts;i++) { ! 825: if(chatact[i]->actset ! 826: !=chan[channel-1]->actset) ! 827: continue; ! 828: sprintf(str,"%s ",chatact[i]->cmd); ! 829: if(!strnicmp(str,pgraph,strlen(str))) ! 830: break; ! 831: sprintf(str,"%.*s" ! 832: ,LEN_CHATACTCMD+2,pgraph); ! 833: str[strlen(str)-2]=0; ! 834: if(!stricmp(chatact[i]->cmd,str)) ! 835: break; } ! 836: ! 837: if(i<total_chatacts) { ! 838: p=pgraph+strlen(str); ! 839: n=atoi(p); ! 840: for(j=0;j<usrs;j++) { ! 841: getnodedat(usr[j],&node,0); ! 842: if(usrs==1) /* no need to search */ ! 843: break; ! 844: if(n) { ! 845: if(usr[j]==n) ! 846: break; ! 847: continue; } ! 848: username(node.useron,str); ! 849: if(!strnicmp(str,p,strlen(str))) ! 850: break; ! 851: getuserrec(node.useron,U_HANDLE ! 852: ,LEN_HANDLE,str); ! 853: if(!strnicmp(str,p,strlen(str))) ! 854: break; } ! 855: if(!usrs ! 856: && chan[channel-1]->guru<total_gurus) ! 857: strcpy(str ! 858: ,guru[chan[channel-1]->guru]->name); ! 859: else if(j>=usrs) ! 860: strcpy(str,"everyone"); ! 861: else if(node.misc&NODE_ANON) ! 862: strcpy(str,text[UNKNOWN_USER]); ! 863: else ! 864: username(node.useron,str); ! 865: ! 866: /* Display on same node */ ! 867: bprintf(chatact[i]->out ! 868: ,thisnode.misc&NODE_ANON ! 869: ? text[UNKNOWN_USER] : useron.alias ! 870: ,str); ! 871: CRLF; ! 872: ! 873: if(usrs && j<usrs) { ! 874: /* Display to dest user */ ! 875: sprintf(buf,chatact[i]->out ! 876: ,thisnode.misc&NODE_ANON ! 877: ? text[UNKNOWN_USER] : useron.alias ! 878: ,"you"); ! 879: strcat(buf,crlf); ! 880: putnmsg(usr[j],buf); } ! 881: ! 882: ! 883: /* Display to all other users */ ! 884: sprintf(buf,chatact[i]->out ! 885: ,thisnode.misc&NODE_ANON ! 886: ? text[UNKNOWN_USER] : useron.alias ! 887: ,str); ! 888: strcat(buf,crlf); ! 889: ! 890: for(i=0;i<usrs;i++) { ! 891: if(i==j) ! 892: continue; ! 893: getnodedat(usr[i],&node,0); ! 894: putnmsg(usr[i],buf); } ! 895: for(i=0;i<qusrs;i++) { ! 896: getnodedat(qusr[i],&node,0); ! 897: putnmsg(qusr[i],buf); } ! 898: continue; } } ! 899: ! 900: sprintf(buf,text[ChatLineFmt] ! 901: ,thisnode.misc&NODE_ANON ! 902: ? text[AnonUserChatHandle] ! 903: : useron.handle ! 904: ,node_num,':',pgraph); ! 905: if(useron.chat&CHAT_ECHO) ! 906: bputs(buf); ! 907: for(i=0;i<usrs;i++) { ! 908: getnodedat(usr[i],&node,0); ! 909: putnmsg(usr[i],buf); } ! 910: for(i=0;i<qusrs;i++) { ! 911: getnodedat(qusr[i],&node,0); ! 912: putnmsg(qusr[i],buf); } ! 913: if(!usrs && channel && gurubuf ! 914: && chan[channel-1]->misc&CHAN_GURU) ! 915: guruchat(pgraph,gurubuf,chan[channel-1]->guru); ! 916: } } } ! 917: else ! 918: mswait(1); ! 919: if(sys_status&SS_ABORT) ! 920: break; } ! 921: lncntr=0; ! 922: break; ! 923: case 'P': /* private node-to-node chat */ ! 924: privchat(); ! 925: break; ! 926: case 'C': ! 927: no_rip_menu=1; ! 928: ch=kbd_state(); /* Check scroll lock */ ! 929: if(ch&16 || (sys_chat_ar[0] && chk_ar(sys_chat_ar,useron)) ! 930: || useron.exempt&FLAG('C')) { ! 931: sysop_page(); ! 932: break; } ! 933: bprintf(text[SysopIsNotAvailable],sys_op); ! 934: if(total_gurus && chk_ar(guru[0]->ar,useron)) { ! 935: sprintf(str,text[ChatWithGuruInsteadQ],guru[0]->name); ! 936: if(!yesno(str)) ! 937: break; } ! 938: else ! 939: break; ! 940: case 'T': ! 941: if(!total_gurus) { ! 942: bprintf(text[SysopIsNotAvailable],"The Guru"); ! 943: break; } ! 944: if(total_gurus==1 && chk_ar(guru[0]->ar,useron)) ! 945: i=0; ! 946: else { ! 947: for(i=0;i<total_gurus;i++) ! 948: uselect(1,i,nulstr,guru[i]->name,guru[i]->ar); ! 949: i=uselect(0,0,0,0,0); ! 950: if(i<0) ! 951: break; } ! 952: if(gurubuf) ! 953: FREE(gurubuf); ! 954: sprintf(str,"%s%s.DAT",ctrl_dir,guru[i]->code); ! 955: if((file=nopen(str,O_RDONLY))==-1) { ! 956: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 957: return; } ! 958: if((gurubuf=MALLOC(filelength(file)+1))==NULL) { ! 959: close(file); ! 960: errormsg(WHERE,ERR_ALLOC,str,filelength(file)+1); ! 961: return; } ! 962: read(file,gurubuf,filelength(file)); ! 963: gurubuf[filelength(file)]=0; ! 964: close(file); ! 965: localguru(gurubuf,i); ! 966: no_rip_menu=1; ! 967: FREE(gurubuf); ! 968: gurubuf=NULL; ! 969: break; ! 970: case '?': ! 971: if(useron.misc&EXPERT) ! 972: menu("CHAT"); ! 973: break; ! 974: default: /* 'Q' or <CR> */ ! 975: lncntr=0; ! 976: if(gurubuf) ! 977: FREE(gurubuf); ! 978: return; } ! 979: action=NODE_CHAT; ! 980: if(!(useron.misc&EXPERT) || useron.misc&WIP ! 981: || (useron.misc&RIP && !no_rip_menu)) { ! 982: #if 0 ! 983: sys_status&=~SS_ABORT; ! 984: if(lncntr) { ! 985: SYNC; ! 986: CRLF; ! 987: if(lncntr) /* CRLF or SYNC can cause pause */ ! 988: pause(); } ! 989: #endif ! 990: menu("CHAT"); } ! 991: ASYNC; ! 992: bputs(text[ChatPrompt]); } ! 993: if(gurubuf) ! 994: FREE(gurubuf); ! 995: } ! 996: ! 997: int getnodetopage(int all, int telegram) ! 998: { ! 999: static uchar last[26]; ! 1000: char str[128]; ! 1001: int i,j; ! 1002: ulong l; ! 1003: node_t node; ! 1004: ! 1005: if(!lastnodemsg) ! 1006: last[0]=0; ! 1007: if(lastnodemsg) { ! 1008: getnodedat(lastnodemsg,&node,0); ! 1009: if(node.status!=NODE_INUSE && !SYSOP) ! 1010: lastnodemsg=1; } ! 1011: for(j=0,i=1;i<=sys_nodes && i<=sys_lastnode;i++) { ! 1012: getnodedat(i,&node,0); ! 1013: if(i==node_num) ! 1014: continue; ! 1015: if(node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET)) { ! 1016: if(!lastnodemsg) ! 1017: lastnodemsg=i; ! 1018: j++; } } ! 1019: ! 1020: if(!last[0]) ! 1021: sprintf(last,"%u",lastnodemsg); ! 1022: ! 1023: if(!j && !telegram) { ! 1024: bputs(text[NoOtherActiveNodes]); ! 1025: return(0); } ! 1026: ! 1027: if(all) ! 1028: sprintf(str,text[NodeToSendMsgTo],lastnodemsg); ! 1029: else ! 1030: sprintf(str,text[NodeToPrivateChat],lastnodemsg); ! 1031: mnemonics(str); ! 1032: ! 1033: strcpy(str,last); ! 1034: getstr(str,25,K_UPRLWR|K_LINE|K_EDIT|K_AUTODEL); ! 1035: if(sys_status&SS_ABORT) ! 1036: return(0); ! 1037: if(!str[0]) ! 1038: return(0); ! 1039: ! 1040: j=atoi(str); ! 1041: if(j && j<=sys_lastnode && j<=sys_nodes) { ! 1042: getnodedat(j,&node,0); ! 1043: if(node.status!=NODE_INUSE && !SYSOP) { ! 1044: bprintf(text[NodeNIsNotInUse],j); ! 1045: return(0); } ! 1046: if(telegram && node.misc&(NODE_POFF|NODE_ANON) && !SYSOP) { ! 1047: bprintf(text[CantPageNode],node.misc&NODE_ANON ! 1048: ? text[UNKNOWN_USER] : username(node.useron,tmp)); ! 1049: return(0); } ! 1050: strcpy(last,str); ! 1051: if(telegram) ! 1052: return(node.useron); ! 1053: return(j); } ! 1054: if(all && !stricmp(str,"ALL")) ! 1055: return(-1); ! 1056: ! 1057: if(str[0]=='\'') { ! 1058: j=userdatdupe(0,U_HANDLE,LEN_HANDLE,str+1,0); ! 1059: if(!j) { ! 1060: bputs(text[UnknownUser]); ! 1061: return(0); } } ! 1062: else if(str[0]=='#') ! 1063: j=atoi(str+1); ! 1064: else ! 1065: j=finduser(str); ! 1066: if(!j) ! 1067: return(0); ! 1068: if(j>lastuser()) ! 1069: return(0); ! 1070: getuserrec(j,U_MISC,8,tmp); ! 1071: l=ahtoul(tmp); ! 1072: if(l&(DELETED|INACTIVE)) { /* Deleted or Inactive User */ ! 1073: bputs(text[UnknownUser]); ! 1074: return(0); } ! 1075: ! 1076: for(i=1;i<=sys_nodes && i<=sys_lastnode;i++) { ! 1077: getnodedat(i,&node,0); ! 1078: if((node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET)) ! 1079: && node.useron==j) { ! 1080: if(telegram && node.misc&NODE_POFF && !SYSOP) { ! 1081: bprintf(text[CantPageNode],node.misc&NODE_ANON ! 1082: ? text[UNKNOWN_USER] : username(node.useron,tmp)); ! 1083: return(0); } ! 1084: if(telegram) ! 1085: return(j); ! 1086: strcpy(last,str); ! 1087: return(i); } } ! 1088: if(telegram) { ! 1089: strcpy(last,str); ! 1090: return(j); } ! 1091: bputs(text[UserNotFound]); ! 1092: return(0); ! 1093: } ! 1094: ! 1095: ! 1096: /****************************************************************************/ ! 1097: /* Sending single line messages between nodes */ ! 1098: /****************************************************************************/ ! 1099: void nodemsg() ! 1100: { ! 1101: static inside; ! 1102: char str[256],line[256],buf[512],ch; ! 1103: int i,j,usernumber,done=0; ! 1104: node_t node,savenode; ! 1105: ! 1106: if(inside>1) /* nested once only */ ! 1107: return; ! 1108: sys_status|=SS_IN_CTRLP; ! 1109: getnodedat(node_num,&savenode,0); ! 1110: inside++; ! 1111: wordwrap[0]=0; ! 1112: while(online && !done) { ! 1113: if(useron.rest&FLAG('C')) { ! 1114: bputs(text[R_SendMessages]); ! 1115: break; } ! 1116: SYNC; ! 1117: mnemonics(text[PrivateMsgPrompt]); ! 1118: sys_status&=~SS_ABORT; ! 1119: while(online) { /* Watch for incoming messages */ ! 1120: ch=toupper(inkey(0)); ! 1121: if(ch && strchr("TMCQ\r",ch)) ! 1122: break; ! 1123: if(sys_status&SS_ABORT) ! 1124: break; ! 1125: if(online==ON_REMOTE && rioctl(IOSTATE)&ABORT) { ! 1126: sys_status|=SS_ABORT; ! 1127: break; } ! 1128: getnodedat(node_num,&thisnode,0); ! 1129: if(thisnode.misc&(NODE_MSGW|NODE_NMSG)) { ! 1130: SAVELINE; ! 1131: CRLF; ! 1132: if(thisnode.misc&NODE_NMSG) ! 1133: getnmsg(); ! 1134: if(thisnode.misc&NODE_MSGW) ! 1135: getsmsg(useron.number); ! 1136: CRLF; ! 1137: RESTORELINE; } ! 1138: else ! 1139: nodesync(); ! 1140: gettimeleft(); ! 1141: checkline(); } ! 1142: ! 1143: if(!online || sys_status&SS_ABORT) { ! 1144: sys_status&=~SS_ABORT; ! 1145: CRLF; ! 1146: break; } ! 1147: ! 1148: switch(toupper(ch)) { ! 1149: case 'T': /* Telegram */ ! 1150: bputs("Telegram\r\n"); ! 1151: usernumber=getnodetopage(0,1); ! 1152: if(!usernumber) ! 1153: break; ! 1154: ! 1155: if(usernumber==1 && useron.rest&FLAG('S')) { /* ! val fback */ ! 1156: bprintf(text[R_Feedback],sys_op); ! 1157: break; } ! 1158: if(usernumber!=1 && useron.rest&FLAG('E')) { ! 1159: bputs(text[R_Email]); ! 1160: break; } ! 1161: now=time(NULL); ! 1162: bprintf("\1n\r\n\1mSending telegram to \1h%s #%u\1n\1m (Max 5 " ! 1163: "lines, Blank line ends):\r\n\r\n\1g\1h" ! 1164: ,username(usernumber,tmp),usernumber); ! 1165: sprintf(buf,"\1n\1g\7Telegram from \1n\1h%s\1n\1g on %s:\r\n\1h" ! 1166: ,thisnode.misc&NODE_ANON ? text[UNKNOWN_USER] : useron.alias ! 1167: ,timestr(&now)); ! 1168: i=0; ! 1169: while(online && i<5) { ! 1170: bprintf("%4s",nulstr); ! 1171: if(!getstr(line,70,K_WRAP|K_MSG)) ! 1172: break; ! 1173: sprintf(str,"%4s%s\r\n",nulstr,line); ! 1174: strcat(buf,str); ! 1175: i++; } ! 1176: if(!i) ! 1177: break; ! 1178: if(sys_status&SS_ABORT) { ! 1179: CRLF; ! 1180: break; } ! 1181: putsmsg(usernumber,buf); ! 1182: sprintf(str,"Sent telegram to %s #%u" ! 1183: ,username(usernumber,tmp),usernumber); ! 1184: logline("C",str); ! 1185: logline(nulstr,line); ! 1186: bprintf("\1n\1mTelegram sent to \1h%s\r\n" ! 1187: ,username(usernumber,tmp)); ! 1188: break; ! 1189: case 'M': /* Message */ ! 1190: bputs("Message\r\n"); ! 1191: i=getnodetopage(1,0); ! 1192: if(!i) ! 1193: break; ! 1194: if(i!=-1) { ! 1195: getnodedat(i,&node,0); ! 1196: usernumber=node.useron; ! 1197: if(node.misc&NODE_POFF && !SYSOP) ! 1198: bprintf(text[CantPageNode],node.misc&NODE_ANON ! 1199: ? text[UNKNOWN_USER] : username(node.useron,tmp)); ! 1200: else { ! 1201: bprintf("\r\n\1n\1mSending message to \1h%s\r\n" ! 1202: ,node.misc&NODE_ANON ? text[UNKNOWN_USER] ! 1203: : username(node.useron,tmp)); ! 1204: bputs(text[NodeMsgPrompt]); ! 1205: if(!getstr(line,69,K_LINE)) ! 1206: break; ! 1207: sprintf(buf,text[NodeMsgFmt],node_num ! 1208: ,thisnode.misc&NODE_ANON ! 1209: ? text[UNKNOWN_USER] : useron.alias,line); ! 1210: putnmsg(i,buf); ! 1211: if(!(node.misc&NODE_ANON)) ! 1212: bprintf("\r\n\1n\1mMessage sent to \1h%s #%u\r\n" ! 1213: ,username(usernumber,tmp),usernumber); ! 1214: sprintf(str,"Sent message to %s on node %d:" ! 1215: ,username(usernumber,tmp),i); ! 1216: logline("C",str); ! 1217: logline(nulstr,line); } } ! 1218: else { /* ALL */ ! 1219: bputs(text[NodeMsgPrompt]); ! 1220: if(!getstr(line,70,K_LINE)) ! 1221: break; ! 1222: sprintf(buf,text[AllNodeMsgFmt],node_num ! 1223: ,thisnode.misc&NODE_ANON ! 1224: ? text[UNKNOWN_USER] : useron.alias,line); ! 1225: for(i=1;i<=sys_nodes;i++) { ! 1226: if(i==node_num) ! 1227: continue; ! 1228: getnodedat(i,&node,0); ! 1229: if((node.status==NODE_INUSE ! 1230: || (SYSOP && node.status==NODE_QUIET)) ! 1231: && (SYSOP || !(node.misc&NODE_POFF))) ! 1232: putnmsg(i,buf); } ! 1233: logline("C","Sent message to all nodes"); ! 1234: logline(nulstr,line); } ! 1235: break; ! 1236: case 'C': /* Chat */ ! 1237: bputs("Chat\r\n"); ! 1238: if(action==NODE_PCHT) { /* already in pchat */ ! 1239: done=1; ! 1240: break; } ! 1241: privchat(); ! 1242: action=savenode.action; ! 1243: break; ! 1244: default: ! 1245: bputs("Quit\r\n"); ! 1246: done=1; ! 1247: break; } } ! 1248: inside--; ! 1249: if(!inside) ! 1250: sys_status&=~SS_IN_CTRLP; ! 1251: getnodedat(node_num,&thisnode,1); ! 1252: thisnode.action=action=savenode.action; ! 1253: thisnode.aux=savenode.aux; ! 1254: thisnode.extaux=savenode.extaux; ! 1255: putnodedat(node_num,thisnode); ! 1256: } ! 1257: ! 1258: /****************************************************************************/ ! 1259: /* The guru will respond from the 'guru' buffer to 'line' */ ! 1260: /****************************************************************************/ ! 1261: void guruchat(char *line, char *gurubuf, int gurunum) ! 1262: { ! 1263: char str[256],cstr[256],*ptr,c,*answer[100],answers,theanswer[769] ! 1264: ,mistakes=1,hu=0; ! 1265: int i,j,k,file; ! 1266: long len; ! 1267: struct tm *tm; ! 1268: ! 1269: now=time(NULL); ! 1270: tm=localtime(&now); ! 1271: ! 1272: for(i=0;i<100;i++) { ! 1273: if((answer[i]=MALLOC(513))==NULL) { ! 1274: errormsg(WHERE,ERR_ALLOC,nulstr,513); ! 1275: while(i) { ! 1276: i--; ! 1277: FREE(answer[i]); } ! 1278: sys_status&=~SS_GURUCHAT; ! 1279: return; } } ! 1280: ptr=gurubuf; ! 1281: len=strlen(gurubuf); ! 1282: strupr(line); ! 1283: j=strlen(line); ! 1284: k=0; ! 1285: for(i=0;i<j;i++) { ! 1286: if(!isalnum(line[i]) && !k) /* beginning non-alphanumeric */ ! 1287: continue; ! 1288: if(!isalnum(line[i]) && line[i]==line[i+1]) /* redundant non-alnum */ ! 1289: continue; ! 1290: if(!isalnum(line[i]) && line[i+1]=='?') /* fix "WHAT ?" */ ! 1291: continue; ! 1292: cstr[k++]=line[i]; } ! 1293: cstr[k]=0; ! 1294: while(--k) { ! 1295: if(!isalnum(cstr[k])) ! 1296: continue; ! 1297: break; } ! 1298: if(k<1) { ! 1299: for(i=0;i<100;i++) ! 1300: FREE(answer[i]); ! 1301: return; } ! 1302: if(cstr[k+1]=='?') ! 1303: k++; ! 1304: cstr[k+1]=0; ! 1305: while(*ptr && ptr<gurubuf+len) { ! 1306: if(*ptr=='(') { ! 1307: ptr++; ! 1308: if(!guruexp(&ptr,cstr)) { ! 1309: while(*ptr && *ptr!='(' && ptr<gurubuf+len) ! 1310: ptr++; ! 1311: continue; } } ! 1312: else { ! 1313: while(*ptr && *ptr!=LF && ptr<gurubuf+len) /* skip LF after ')' */ ! 1314: ptr++; ! 1315: ptr++; ! 1316: answers=0; ! 1317: while(*ptr && answers<100 && ptr<gurubuf+len) { ! 1318: i=0; ! 1319: while(*ptr && *ptr!=CR && i<512 && ptr<gurubuf+len) { ! 1320: answer[answers][i]=*ptr; ! 1321: ptr++; ! 1322: i++; ! 1323: if(*ptr=='\\' && *(ptr+1)==CR) { /* multi-line answer */ ! 1324: ptr+=3; /* skip \CRLF */ ! 1325: answer[answers][i++]=CR; ! 1326: answer[answers][i++]=LF; } } ! 1327: answer[answers][i]=0; ! 1328: if(!strlen(answer[answers]) || answer[answers][0]=='(') { ! 1329: ptr-=strlen(answer[answers]); ! 1330: break; } ! 1331: ptr+=2; /* skip CRLF */ ! 1332: answers++; } ! 1333: if(answers==100) ! 1334: while(*ptr && *ptr!='(' && ptr<gurubuf+len) ! 1335: ptr++; ! 1336: i=random(answers); ! 1337: for(j=0,k=0;j<strlen(answer[i]);j++) { ! 1338: if(answer[i][j]=='`') { ! 1339: j++; ! 1340: theanswer[k]=0; ! 1341: switch(toupper(answer[i][j])) { ! 1342: case 'A': ! 1343: if(sys_status&SS_USERON) ! 1344: strcat(theanswer,useron.alias); ! 1345: else ! 1346: strcat(theanswer,text[UNKNOWN_USER]); ! 1347: break; ! 1348: case 'B': ! 1349: if(sys_status&SS_USERON) ! 1350: strcat(theanswer,useron.birth); ! 1351: else ! 1352: strcat(theanswer,"00/00/00"); ! 1353: break; ! 1354: case 'C': ! 1355: if(sys_status&SS_USERON) ! 1356: strcat(theanswer,useron.comp); ! 1357: else ! 1358: strcat(theanswer,"PC Jr."); ! 1359: break; ! 1360: case 'D': ! 1361: if(sys_status&SS_USERON) ! 1362: strcat(theanswer,ultoac(useron.dlb,tmp)); ! 1363: else ! 1364: strcat(theanswer,"0"); ! 1365: break; ! 1366: case 'G': ! 1367: strcat(theanswer,guru[gurunum]->name); ! 1368: break; ! 1369: case 'H': ! 1370: hu=1; ! 1371: break; ! 1372: case 'I': ! 1373: strcat(theanswer,sys_id); ! 1374: break; ! 1375: case 'J': ! 1376: sprintf(tmp,"%u",tm->tm_mday); ! 1377: break; ! 1378: case 'L': ! 1379: if(sys_status&SS_USERON) ! 1380: strcat(theanswer,itoa(useron.level,tmp,10)); ! 1381: else ! 1382: strcat(theanswer,"0"); ! 1383: break; ! 1384: case 'M': ! 1385: strcat(theanswer,month[tm->tm_mon]); ! 1386: break; ! 1387: case 'N': /* Note */ ! 1388: if(sys_status&SS_USERON) ! 1389: strcat(theanswer,useron.note); ! 1390: else ! 1391: strcat(theanswer,text[UNKNOWN_USER]); ! 1392: break; ! 1393: case 'O': ! 1394: strcat(theanswer,sys_op); ! 1395: break; ! 1396: case 'P': ! 1397: if(sys_status&SS_USERON) ! 1398: strcat(theanswer,useron.phone); ! 1399: else ! 1400: strcat(theanswer,"000-000-0000"); ! 1401: break; ! 1402: case 'Q': ! 1403: sys_status&=~SS_GURUCHAT; ! 1404: break; ! 1405: case 'R': ! 1406: if(sys_status&SS_USERON) ! 1407: strcat(theanswer,useron.name); ! 1408: else ! 1409: strcat(theanswer,text[UNKNOWN_USER]); ! 1410: break; ! 1411: case 'S': ! 1412: strcat(theanswer,sys_name); ! 1413: break; ! 1414: case 'T': ! 1415: sprintf(tmp,"%u:%02u",tm->tm_hour>12 ? tm->tm_hour-12 ! 1416: : tm->tm_hour,tm->tm_min); ! 1417: strcat(theanswer,tmp); ! 1418: break; ! 1419: case 'U': ! 1420: if(sys_status&SS_USERON) ! 1421: strcat(theanswer,ultoac(useron.ulb,tmp)); ! 1422: else ! 1423: strcat(theanswer,"0"); ! 1424: break; ! 1425: case 'W': ! 1426: strcat(theanswer,weekday[tm->tm_wday]); ! 1427: break; ! 1428: case 'Y': /* Current year */ ! 1429: sprintf(tmp,"%u",1900+tm->tm_year); ! 1430: strcat(theanswer,tmp); ! 1431: break; ! 1432: case 'Z': ! 1433: if(sys_status&SS_USERON) ! 1434: strcat(theanswer,useron.zipcode); ! 1435: else ! 1436: strcat(theanswer,"90210"); ! 1437: break; ! 1438: case '$': /* Credits */ ! 1439: if(sys_status&SS_USERON) ! 1440: strcat(theanswer,ultoac(useron.cdt,tmp)); ! 1441: else ! 1442: strcat(theanswer,"0"); ! 1443: break; ! 1444: case '#': ! 1445: if(sys_status&SS_USERON) ! 1446: strcat(theanswer,itoa(getage(useron.birth) ! 1447: ,tmp,10)); ! 1448: else ! 1449: strcat(theanswer,"0"); ! 1450: break; ! 1451: case '!': ! 1452: mistakes=!mistakes; ! 1453: break; ! 1454: case '_': ! 1455: mswait(500); ! 1456: break; } ! 1457: k=strlen(theanswer); } ! 1458: else ! 1459: theanswer[k++]=answer[i][j]; } ! 1460: theanswer[k]=0; ! 1461: mswait(500+random(1000)); /* thinking time */ ! 1462: if(action!=NODE_MCHT) { ! 1463: for(i=0;i<k;i++) { ! 1464: if(mistakes && theanswer[i]!=theanswer[i-1] && ! 1465: ((!isalnum(theanswer[i]) && !random(100)) ! 1466: || (isalnum(theanswer[i]) && !random(30)))) { ! 1467: c=j=random(3)+1; /* 1 to 3 chars */ ! 1468: if(c<strcspn(theanswer+(i+1),"\0., ")) ! 1469: c=j=1; ! 1470: while(j) { ! 1471: outchar(97+random(26)); ! 1472: mswait(25+random(150)); ! 1473: j--; } ! 1474: if(random(100)) { ! 1475: mswait(100+random(300)); ! 1476: while(c) { ! 1477: bputs("\b \b"); ! 1478: mswait(50+random(50)); ! 1479: c--; } } } ! 1480: outchar(theanswer[i]); ! 1481: if(theanswer[i]==theanswer[i+1]) ! 1482: mswait(25+random(50)); ! 1483: else ! 1484: mswait(25+random(150)); ! 1485: if(theanswer[i]==SP) ! 1486: mswait(random(50)); } } ! 1487: else { ! 1488: mswait(strlen(theanswer)*100); ! 1489: bprintf(text[ChatLineFmt],guru[gurunum]->name ! 1490: ,sys_nodes+1,':',theanswer); } ! 1491: CRLF; ! 1492: sprintf(str,"%sGURU.LOG",data_dir); ! 1493: if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1) ! 1494: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND); ! 1495: else { ! 1496: if(action==NODE_MCHT) { ! 1497: sprintf(str,"[Multi] "); ! 1498: write(file,str,strlen(str)); } ! 1499: sprintf(str,"%s:\r\n",sys_status&SS_USERON ! 1500: ? useron.alias : "UNKNOWN"); ! 1501: write(file,str,strlen(str)); ! 1502: write(file,line,strlen(line)); ! 1503: if(action!=NODE_MCHT) ! 1504: write(file,crlf,2); ! 1505: sprintf(str,"%s:\r\n",guru[gurunum]->name); ! 1506: write(file,str,strlen(str)); ! 1507: write(file,theanswer,strlen(theanswer)); ! 1508: write(file,crlf,2); ! 1509: close(file); } ! 1510: if(hu) ! 1511: hangup(); ! 1512: break; } } ! 1513: for(i=0;i<100;i++) ! 1514: FREE(answer[i]); ! 1515: } ! 1516: ! 1517: /****************************************************************************/ ! 1518: /* An expression from the guru's buffer 'ptrptr' is evaluated and true or */ ! 1519: /* false is returned. */ ! 1520: /****************************************************************************/ ! 1521: char guruexp(char **ptrptr, char *line) ! 1522: { ! 1523: char c,*cp,str[256],true=0,and=0,or=0,nest,*ar; ! 1524: ! 1525: if((**ptrptr)==')') { /* expressions of () are always true */ ! 1526: (*ptrptr)++; ! 1527: return(1); } ! 1528: while((**ptrptr)!=')' && (**ptrptr)) { ! 1529: if((**ptrptr)=='[') { ! 1530: (*ptrptr)++; ! 1531: sprintf(str,"%.128s",*ptrptr); ! 1532: while(**ptrptr && (**ptrptr)!=']') ! 1533: (*ptrptr)++; ! 1534: (*ptrptr)++; ! 1535: cp=strchr(str,']'); ! 1536: if(cp) *cp=0; ! 1537: ar=arstr(NULL,str); ! 1538: c=chk_ar(ar,useron); ! 1539: if(ar[0]!=AR_NULL) ! 1540: FREE(ar); ! 1541: if(!c && and) { ! 1542: true=0; ! 1543: break; } ! 1544: if(c && or) { ! 1545: true=1; ! 1546: break; } ! 1547: if(c) ! 1548: true=1; ! 1549: continue; } ! 1550: if((**ptrptr)=='(') { ! 1551: (*ptrptr)++; ! 1552: c=guruexp(&(*ptrptr),line); ! 1553: if(!c && and) { ! 1554: true=0; ! 1555: break; } ! 1556: if(c && or) { ! 1557: true=1; ! 1558: break; } ! 1559: if(c) ! 1560: true=1; } ! 1561: if((**ptrptr)==')') ! 1562: break; ! 1563: c=0; ! 1564: while((**ptrptr) && isspace(**ptrptr)) ! 1565: (*ptrptr)++; ! 1566: while((**ptrptr)!='|' && (**ptrptr)!='&' && (**ptrptr)!=')' &&(**ptrptr)) { ! 1567: str[c++]=(**ptrptr); ! 1568: (*ptrptr)++; } ! 1569: str[c]=0; ! 1570: if((**ptrptr)=='|') { ! 1571: if(!c && true) ! 1572: break; ! 1573: and=0; ! 1574: or=1; } ! 1575: else if((**ptrptr)=='&') { ! 1576: if(!c && !true) ! 1577: break; ! 1578: and=1; ! 1579: or=0; } ! 1580: if(!c) { /* support ((exp)op(exp)) */ ! 1581: (*ptrptr)++; ! 1582: continue; } ! 1583: if((**ptrptr)!=')') ! 1584: (*ptrptr)++; ! 1585: c=0; /* c now used for start line flag */ ! 1586: if(str[strlen(str)-1]=='^') { /* ^signifies start of line only */ ! 1587: str[strlen(str)-1]=0; ! 1588: c=1; } ! 1589: if(str[strlen(str)-1]=='~') { /* ~signifies non-isolated word */ ! 1590: str[strlen(str)-1]=0; ! 1591: cp=strstr(line,str); ! 1592: if(c && cp!=line) ! 1593: cp=0; } ! 1594: else { ! 1595: cp=strstr(line,str); ! 1596: if(cp && c) { ! 1597: if(cp!=line || isalnum(*(cp+strlen(str)))) ! 1598: cp=0; } ! 1599: else { /* must be isolated word */ ! 1600: while(cp) ! 1601: if((cp!=line && isalnum(*(cp-1))) ! 1602: || isalnum(*(cp+strlen(str)))) ! 1603: cp=strstr(cp+strlen(str),str); ! 1604: else ! 1605: break; } } ! 1606: if(!cp && and) { ! 1607: true=0; ! 1608: break; } ! 1609: if(cp && or) { ! 1610: true=1; ! 1611: break; } ! 1612: if(cp) ! 1613: true=1; } ! 1614: nest=0; ! 1615: while((**ptrptr)!=')' && (**ptrptr)) { /* handle nested exp */ ! 1616: if((**ptrptr)=='(') /* (TRUE|(IGNORE)) */ ! 1617: nest++; ! 1618: (*ptrptr)++; ! 1619: while((**ptrptr)==')' && nest && (**ptrptr)) { ! 1620: nest--; ! 1621: (*ptrptr)++; } } ! 1622: (*ptrptr)++; /* skip over ')' */ ! 1623: return(true); ! 1624: } ! 1625: ! 1626: /****************************************************************************/ ! 1627: /* Guru chat with the appearance of Local chat with sysop. */ ! 1628: /****************************************************************************/ ! 1629: void localguru(char *gurubuf, int gurunum) ! 1630: { ! 1631: char ch,str[256]; ! 1632: int con=console; /* save console state */ ! 1633: ! 1634: if(sys_status&SS_GURUCHAT || !total_gurus) ! 1635: return; ! 1636: sys_status|=SS_GURUCHAT; ! 1637: console&=~(CON_L_ECHOX|CON_R_ECHOX); /* turn off X's */ ! 1638: console|=(CON_L_ECHO|CON_R_ECHO); /* make sure echo is on */ ! 1639: if(action==NODE_CHAT) { /* only page if from chat section */ ! 1640: bprintf(text[PagingGuru],guru[gurunum]->name); ! 1641: ch=random(25)+25; ! 1642: while(ch--) { ! 1643: mswait(200); ! 1644: outchar('.'); } } ! 1645: bprintf(text[SysopIsHere],guru[gurunum]->name); ! 1646: getnodedat(node_num,&thisnode,1); ! 1647: thisnode.aux=gurunum; ! 1648: putnodedat(node_num,thisnode); ! 1649: attr(color[clr_chatlocal]); ! 1650: guruchat("HELLO",gurubuf,gurunum); ! 1651: while(online && (sys_status&SS_GURUCHAT)) { ! 1652: checkline(); ! 1653: action=NODE_GCHT; ! 1654: SYNC; ! 1655: if((ch=inkey(0))!=0) { ! 1656: ungetkey(ch); ! 1657: attr(color[clr_chatremote]); ! 1658: if(getstr(str,78,K_WRAP|K_CHAT)) { ! 1659: attr(color[clr_chatlocal]); ! 1660: guruchat(str,gurubuf,gurunum); } } ! 1661: else ! 1662: mswait(1); } ! 1663: bputs(text[EndOfChat]); ! 1664: sys_status&=~SS_GURUCHAT; ! 1665: console=con; /* restore console state */ ! 1666: } ! 1667: ! 1668: /****************************************************************************/ ! 1669: /* Packs the password 'pass' into 5bit ASCII inside node_t. 32bits in */ ! 1670: /* node.extaux, and the other 8bits in the upper byte of node.aux */ ! 1671: /****************************************************************************/ ! 1672: void packchatpass(char *pass, node_t *node) ! 1673: { ! 1674: char bits; ! 1675: int i,j; ! 1676: ! 1677: node->aux&=~0xff00; /* clear the password */ ! 1678: node->extaux=0L; ! 1679: if((j=strlen(pass))==0) /* there isn't a password */ ! 1680: return; ! 1681: node->aux|=(int)((pass[0]-64)<<8); /* 1st char goes in low 5bits of aux */ ! 1682: if(j==1) /* password is only one char, we're done */ ! 1683: return; ! 1684: node->aux|=(int)((pass[1]-64)<<13); /* low 3bits of 2nd char go in aux */ ! 1685: node->extaux|=(long)((pass[1]-64)>>3); /* high 2bits of 2nd char go extaux */ ! 1686: bits=2; ! 1687: for(i=2;i<j;i++) { /* now process the 3rd char through the last */ ! 1688: node->extaux|=(long)((long)(pass[i]-64)<<bits); ! 1689: bits+=5; } ! 1690: } ! 1691: ! 1692: /****************************************************************************/ ! 1693: /* Unpacks the password 'pass' from the 5bit ASCII inside node_t. 32bits in */ ! 1694: /* node.extaux, and the other 8bits in the upper byte of node.aux */ ! 1695: /****************************************************************************/ ! 1696: char *unpackchatpass(char *pass, node_t node) ! 1697: { ! 1698: char bits; ! 1699: int i; ! 1700: ! 1701: pass[0]=(node.aux&0x1f00)>>8; ! 1702: pass[1]=((node.aux&0xe000)>>13)|((node.extaux&0x3)<<3); ! 1703: bits=2; ! 1704: for(i=2;i<8;i++) { ! 1705: pass[i]=(node.extaux>>bits)&0x1f; ! 1706: bits+=5; } ! 1707: pass[8]=0; ! 1708: for(i=0;i<8;i++) ! 1709: if(pass[i]) ! 1710: pass[i]+=64; ! 1711: return(pass); ! 1712: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.