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