home *** CD-ROM | disk | FTP | other *** search
- #line 1 "CHAT.C"
-
- /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
-
- /****************************************/
- /* Local and Node-to-Node Chat routines */
- /****************************************/
-
- #include "sbbs.h"
-
- #define PCHAT_LEN 1000 /* Size of Private chat file */
-
- int getnodetopage(int all, int telegram);
-
-
- char *weekday[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"
- ,"Saturday"};
- char *month[]={"January","February","March","April","May","June"
- ,"July","August","September","October","November","December"};
-
-
- /****************************************************************************/
- /* Chat between local keyboard and remote user on current node. */
- /* Called from inkey (inkey is then re-entrant) */
- /****************************************************************************/
- void localchat()
- {
- uchar str[256],act;
- int con=console; /* save console state */
- time_t beg=time(NULL);
-
- console&=~(CON_L_ECHOX|CON_R_ECHOX); /* turn off X's */
- console|=(CON_L_ECHO|CON_R_ECHO); /* make sure echo is enabled */
- nosound();
- sys_status&=~SS_SYSPAGE;
- act=action; /* save the user's current action */
- action=NODE_LCHT;
- bprintf(text[SysopIsHere],sys_op);
- while(sys_status&SS_LCHAT && online) {
- SYNC;
- getstr(str,78,K_WRAP|K_MSG); }
- bputs(text[EndOfChat]);
- now=time(NULL);
- if(!(sys_status&SS_USERON))
- answertime=now;
- starttime+=now-beg; /* credit user for time in chat */
- RESTORELINE;
- action=act;
- console=con; /* restore console */
- }
-
- void sysop_page(void)
- {
- int i;
-
- for(i=0;i<total_pages;i++)
- if(chk_ar(page[i]->ar,useron))
- break;
- if(i<total_pages) {
- bprintf(text[PagingGuru],sys_op);
- external(cmdstr(page[i]->cmd,nulstr,nulstr,NULL)
- ,page[i]->misc&IO_INTS ? EX_OUTL|EX_OUTR|EX_INR
- : EX_OUTL); }
- else if(sys_misc&SM_SHRTPAGE) {
- bprintf(text[PagingGuru],sys_op);
- for(i=0;i<10 && !lkbrd(1);i++) {
- beep(1000,200);
- mswait(200);
- outchar('.'); }
- CRLF; }
- else {
- sys_status^=SS_SYSPAGE;
- bprintf(text[SysopPageIsNow]
- ,sys_status&SS_SYSPAGE ? text[ON] : text[OFF]);
- nosound(); }
- }
-
- /****************************************************************************/
- /* Returns 1 if user online has access to channel "channum" */
- /****************************************************************************/
- char chan_access(uint cnum)
- {
-
- if(!total_chans || cnum>=total_chans || !chk_ar(chan[cnum]->ar,useron)) {
- bputs(text[CantAccessThatChannel]);
- return(0); }
- if(!(useron.exempt&FLAG('J')) && chan[cnum]->cost>useron.cdt+useron.freecdt) {
- bputs(text[NotEnoughCredits]);
- return(0); }
- return(1);
- }
-
- void privchat(void)
- {
- uchar str[128],ch,c,*p,localbuf[5][81],remotebuf[5][81]
- ,localline=0,remoteline=0,localchar=0,remotechar=0
- ,*sep="\1w\1h─────[\1i\1r%c\1n\1h]────┤ "
- "\1yPrivate Chat - \1rCtrl-C to Quit \1y- "
- "Time Left: \1g%-8s\1w"
- " ├────[\1i\1b%c\1n\1h]─────";
- int in,out,i,j,n,done,echo=1,x,y,activity;
- node_t node;
-
- n=getnodetopage(0,0);
- if(!n)
- return;
- if(n==node_num) {
- bputs(text[NoNeedToPageSelf]);
- return; }
- getnodedat(n,&node,0);
- if(node.action==NODE_PCHT && node.aux!=node_num) {
- bprintf(text[NodeNAlreadyInPChat],n);
- return; }
- if((node.action!=NODE_PAGE || node.aux!=node_num)
- && node.misc&NODE_POFF && !SYSOP) {
- bprintf(text[CantPageNode],node.misc&NODE_ANON
- ? text[UNKNOWN_USER] : username(node.useron,tmp));
- return; }
- if(node.action!=NODE_PAGE) {
- bprintf("\r\n\1n\1mPaging \1h%s #%u\1n\1m for private chat\r\n"
- ,node.misc&NODE_ANON ? text[UNKNOWN_USER] : username(node.useron,tmp)
- ,node.useron);
- sprintf(str,text[NodePChatPageMsg]
- ,node_num,thisnode.misc&NODE_ANON
- ? text[UNKNOWN_USER] : useron.alias);
- putnmsg(n,str);
- sprintf(str,"Paged %s on node %d to private chat"
- ,username(node.useron,tmp),n);
- logline("C",str); }
-
- getnodedat(node_num,&thisnode,1);
- thisnode.action=action=NODE_PAGE;
- thisnode.aux=n;
- putnodedat(node_num,thisnode);
-
- if(node.action!=NODE_PAGE || node.aux!=node_num) {
- bprintf(text[WaitingForNodeInPChat],n);
- while(online && !(sys_status&SS_ABORT)) {
- getnodedat(n,&node,0);
- if((node.action==NODE_PAGE || node.action==NODE_PCHT)
- && node.aux==node_num) {
- bprintf(text[NodeJoinedPrivateChat]
- ,n,node.misc&NODE_ANON ? text[UNKNOWN_USER]
- : username(node.useron,tmp));
- break; }
- if(!inkey(0))
- mswait(1);
- action=NODE_PAGE;
- checkline();
- gettimeleft();
- SYNC; } }
-
- getnodedat(node_num,&thisnode,1);
- thisnode.action=action=NODE_PCHT;
- putnodedat(node_num,thisnode);
-
- if(!online || sys_status&SS_ABORT)
- return;
-
- if(useron.chat&CHAT_SPLITP && useron.misc&ANSI && rows>=24)
- sys_status|=SS_SPLITP;
- /*
- if(!(useron.misc&EXPERT))
- menu("PRIVCHAT");
- */
-
- if(!(sys_status&SS_SPLITP))
- bputs(text[WelcomeToPrivateChat]);
-
- sprintf(str,"%sCHAT.DAB",node_dir);
- if((out=open(str,O_RDWR|O_DENYNONE|O_CREAT|O_BINARY
- ,S_IREAD|S_IWRITE))==-1) {
- errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_DENYNONE|O_CREAT);
- return; }
-
- sprintf(str,"%sCHAT.DAB",node_path[n-1]);
- if(!fexist(str)) /* Wait while it's created for the first time */
- mswait(2000);
- if((in=open(str,O_RDWR|O_DENYNONE|O_CREAT|O_BINARY
- ,S_IREAD|S_IWRITE))==-1) {
- close(out);
- errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_DENYNONE|O_CREAT);
- return; }
-
- if((p=(char *)MALLOC(PCHAT_LEN))==NULL) {
- close(in);
- close(out);
- errormsg(WHERE,ERR_ALLOC,str,PCHAT_LEN);
- return; }
- memset(p,0,PCHAT_LEN);
- write(in,p,PCHAT_LEN);
- write(out,p,PCHAT_LEN);
- FREE(p);
- lseek(in,0L,SEEK_SET);
- lseek(out,0L,SEEK_SET);
-
- getnodedat(node_num,&thisnode,1);
- thisnode.misc&=~NODE_RPCHT; /* Clear "reset pchat flag" */
- putnodedat(node_num,thisnode);
-
- getnodedat(n,&node,1);
- node.misc|=NODE_RPCHT; /* Set "reset pchat flag" */
- putnodedat(n,node); /* on other node */
-
- /* Wait for other node */
- /* to acknowledge and reset */
- while(online && !(sys_status&SS_ABORT)) {
- getnodedat(n,&node,0);
- if(!(node.misc&NODE_RPCHT))
- break;
- getnodedat(node_num,&thisnode,0);
- if(thisnode.misc&NODE_RPCHT)
- break;
- checkline();
- gettimeleft();
- SYNC;
- inkey(0);
- mswait(1); }
-
-
- action=NODE_PCHT;
- SYNC;
-
- if(sys_status&SS_SPLITP) {
- lncntr=0;
- CLS;
- ANSI_SAVE();
- GOTOXY(1,13);
- bprintf(sep
- ,thisnode.misc&NODE_MSGW ? 'T':SP
- ,sectostr(timeleft,tmp)
- ,thisnode.misc&NODE_NMSG ? 'M':SP);
- CRLF; }
-
- done=0;
-
- while(online && !(sys_status&SS_ABORT) && !done) {
- RIOSYNC(0);
- lncntr=0;
- if(sys_status&SS_SPLITP)
- lbuflen=0;
- action=NODE_PCHT;
- if(!localchar) {
- if(sys_status&SS_SPLITP) {
- getnodedat(node_num,&thisnode,0);
- if(thisnode.misc&NODE_INTR)
- break;
- if(thisnode.misc&NODE_UDAT && !(useron.rest&FLAG('G'))) {
- getuserdat(&useron);
- getnodedat(node_num,&thisnode,1);
- thisnode.misc&=~NODE_UDAT;
- putnodedat(node_num,thisnode); } }
- else
- nodesync(); }
- activity=0;
- if((ch=inkey(K_GETSTR))!=0) {
- activity=1;
- if(echo)
- attr(color[clr_chatlocal]);
- else
- lclatr(color[clr_chatlocal]);
- if(ch==BS) {
- if(localchar) {
- if(echo)
- bputs("\b \b");
- else
- lputs("\b \b");
- localchar--;
- localbuf[localline][localchar]=0; } }
- else if(ch==TAB) {
- if(echo)
- outchar(SP);
- else
- lputc(SP);
- localbuf[localline][localchar]=SP;
- localchar++;
- while(localchar<78 && localchar%8) {
- if(echo)
- outchar(SP);
- else
- lputc(SP);
- localbuf[localline][localchar++]=SP; } }
- else if(ch>=SP || ch==CR) {
- if(ch!=CR) {
- if(echo)
- outchar(ch);
- else
- lputc(ch);
- localbuf[localline][localchar]=ch; }
-
- if(ch==CR || (localchar>68 && ch==SP) || ++localchar>78) {
-
- localbuf[localline][localchar]=0;
- localchar=0;
-
- if(sys_status&SS_SPLITP && lclwy()==24) {
- GOTOXY(1,13);
- bprintf(sep
- ,thisnode.misc&NODE_MSGW ? 'T':SP
- ,sectostr(timeleft,tmp)
- ,thisnode.misc&NODE_NMSG ? 'M':SP);
- attr(color[clr_chatlocal]);
- for(x=13,y=0;x<rows;x++,y++) {
- bprintf("\x1b[%d;1H\x1b[K",x+1);
- if(y<=localline)
- bprintf("%s\r\n",localbuf[y]); }
- GOTOXY(1,15+localline);
- localline=0; }
- else {
- if(localline>=4)
- for(i=0;i<4;i++)
- memcpy(localbuf[i],localbuf[i+1],81);
- else
- localline++;
- if(echo) {
- CRLF;
- if(sys_status&SS_SPLITP)
- bputs("\x1b[K"); }
- else
- lputs(crlf); }
- // SYNC;
- } }
-
- read(out,&c,1);
- lseek(out,-1L,SEEK_CUR);
- if(!c) /* hasn't wrapped */
- write(out,&ch,1);
- else {
- if(!tell(out))
- lseek(out,0L,SEEK_END);
- lseek(out,-1L,SEEK_CUR);
- ch=0;
- write(out,&ch,1);
- lseek(out,-1L,SEEK_CUR); }
- if(tell(out)>=PCHAT_LEN)
- lseek(out,0L,SEEK_SET);
- }
- else while(online) {
- if(!(sys_status&SS_SPLITP))
- remotechar=localchar;
- if(tell(in)>=PCHAT_LEN)
- lseek(in,0L,SEEK_SET);
- ch=0;
- read(in,&ch,1);
- lseek(in,-1L,SEEK_CUR);
- if(!ch) break; /* char from other node */
- activity=1;
- x=lclwx();
- y=lclwy();
- if(sys_status&SS_SPLITP)
- ANSI_RESTORE();
- attr(color[clr_chatremote]);
- if(sys_status&SS_SPLITP)
- bputs("\b \b"); /* Delete fake cursor */
- if(ch==BS) {
- if(remotechar) {
- bputs("\b \b");
- remotechar--;
- remotebuf[remoteline][remotechar]=0; } }
- else if(ch==TAB) {
- outchar(SP);
- remotebuf[remoteline][remotechar]=SP;
- remotechar++;
- while(remotechar<78 && remotechar%8) {
- outchar(SP);
- remotebuf[remoteline][remotechar++]=SP; } }
- else if(ch>=SP || ch==CR) {
- if(ch!=CR) {
- outchar(ch);
- remotebuf[remoteline][remotechar]=ch; }
-
- if(ch==CR || (remotechar>68 && ch==SP) || ++remotechar>78) {
-
- remotebuf[remoteline][remotechar]=0;
- remotechar=0;
-
- if(sys_status&SS_SPLITP && lclwy()==12) {
- CRLF;
- bprintf(sep
- ,thisnode.misc&NODE_MSGW ? 'T':SP
- ,sectostr(timeleft,tmp)
- ,thisnode.misc&NODE_NMSG ? 'M':SP);
- attr(color[clr_chatremote]);
- for(i=0;i<12;i++) {
- bprintf("\x1b[%d;1H\x1b[K",i+1);
- if(i<=remoteline)
- bprintf("%s\r\n",remotebuf[i]); }
- remoteline=0;
- GOTOXY(1,6); }
- else {
- if(remoteline>=4)
- for(i=0;i<4;i++)
- memcpy(remotebuf[i],remotebuf[i+1],81);
- else
- remoteline++;
- if(echo) {
- CRLF;
- if(sys_status&SS_SPLITP)
- bputs("\x1b[K"); }
- else
- lputs(crlf); } } }
- if(sys_status&SS_SPLITP) {
- bputs("\1i_\1n"); /* Fake cursor */
- ANSI_SAVE();
- GOTOXY(x,y); }
- ch=0;
- write(in,&ch,1);
-
- if(!(sys_status&SS_SPLITP))
- localchar=remotechar;
- }
- if(!activity) { /* no activity so chk node.dab */
- getnodedat(n,&node,0);
- if((node.action!=NODE_PCHT && node.action!=NODE_PAGE)
- || node.aux!=node_num) {
- bprintf(text[NodeLeftPrivateChat]
- ,n,node.misc&NODE_ANON ? text[UNKNOWN_USER]
- : username(node.useron,tmp));
- break; }
- getnodedat(node_num,&thisnode,0);
- if(thisnode.misc&NODE_RPCHT) { /* pchat has been reset */
- lseek(in,0L,SEEK_SET); /* so seek to beginning */
- lseek(out,0L,SEEK_SET);
- getnodedat(node_num,&thisnode,1);
- thisnode.misc&=~NODE_RPCHT;
- putnodedat(node_num,thisnode); }
- mswait(0); }
- checkline();
- gettimeleft(); }
- if(sys_status&SS_SPLITP)
- CLS;
- sys_status&=~SS_SPLITP;
- close(in);
- close(out);
- }
-
- /****************************************************************************/
- /* The chat section */
- /****************************************************************************/
- void chatsection()
- {
- uchar line[256],str[256],ch,c,done,no_rip_menu
- ,usrs,preusrs,qusrs,*gurubuf=NULL,channel,savch,*p
- ,pgraph[400],buf[400]
- ,usr[MAX_NODES],preusr[MAX_NODES],qusr[MAX_NODES];
- int file,in,out;
- long i,j,k,n;
- node_t node;
-
- action=NODE_CHAT;
- if(useron.misc&(RIP|WIP) || !(useron.misc&EXPERT))
- menu("CHAT");
- ASYNC;
- bputs(text[ChatPrompt]);
- while(online) {
- no_rip_menu=0;
- ch=getkeys("ACDJPQST?\r",0);
- if(ch>SP)
- logch(ch,0);
- switch(ch) {
- case 'S':
- useron.chat^=CHAT_SPLITP;
- putuserrec(useron.number,U_CHAT,8
- ,ltoa(useron.chat,str,16));
- bprintf("\r\nPrivate split-screen chat is now: %s\r\n"
- ,useron.chat&CHAT_SPLITP ? text[ON]:text[OFF]);
- break;
- case 'A':
- CRLF;
- useron.chat^=CHAT_NOACT;
- putuserrec(useron.number,U_CHAT,8
- ,ltoa(useron.chat,str,16));
- getnodedat(node_num,&thisnode,1);
- thisnode.misc^=NODE_AOFF;
- printnodedat(node_num,thisnode);
- putnodedat(node_num,thisnode);
- no_rip_menu=1;
- break;
- case 'D':
- CRLF;
- useron.chat^=CHAT_NOPAGE;
- putuserrec(useron.number,U_CHAT,8
- ,ltoa(useron.chat,str,16));
- getnodedat(node_num,&thisnode,1);
- thisnode.misc^=NODE_POFF;
- printnodedat(node_num,thisnode);
- putnodedat(node_num,thisnode);
- no_rip_menu=1;
- break;
- case 'J':
- if(!chan_access(0))
- break;
- if(useron.misc&(RIP|WIP) ||!(useron.misc&EXPERT))
- menu("MULTCHAT");
- getnodedat(node_num,&thisnode,1);
- bputs(text[WelcomeToMultiChat]);
- channel=thisnode.aux=1; /* default channel 1 */
- putnodedat(node_num,thisnode);
- bprintf(text[WelcomeToChannelN],channel,chan[0]->name);
- if(gurubuf) {
- FREE(gurubuf);
- gurubuf=NULL; }
- if(chan[0]->misc&CHAN_GURU && chan[0]->guru<total_gurus
- && chk_ar(guru[chan[0]->guru]->ar,useron)) {
- sprintf(str,"%s%s.DAT",ctrl_dir,guru[chan[0]->guru]->code);
- if((file=nopen(str,O_RDONLY))==-1) {
- errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
- break; }
- if((gurubuf=MALLOC(filelength(file)+1))==NULL) {
- close(file);
- errormsg(WHERE,ERR_ALLOC,str,filelength(file)+1);
- break; }
- read(file,gurubuf,filelength(file));
- gurubuf[filelength(file)]=0;
- close(file); }
- usrs=0;
- for(i=1;i<=sys_nodes && i<=sys_lastnode;i++) {
- if(i==node_num)
- continue;
- getnodedat(i,&node,0);
- if(node.action!=NODE_MCHT || node.status!=NODE_INUSE)
- continue;
- if(node.aux && (node.aux&0xff)!=channel)
- continue;
- printnodedat(i,node);
- preusr[usrs]=usr[usrs++]=i; }
- preusrs=usrs;
- if(gurubuf)
- bprintf(text[NodeInMultiChatLocally]
- ,sys_nodes+1,guru[chan[channel-1]->guru]->name,channel);
- bputs(text[YoureOnTheAir]);
- done=0;
- while(online && !done) {
- checkline();
- gettimeleft();
- action=NODE_MCHT;
- qusrs=usrs=0;
- for(i=1;i<=sys_nodes;i++) {
- if(i==node_num)
- continue;
- getnodedat(i,&node,0);
- if(node.action!=NODE_MCHT
- || (node.aux && channel && (node.aux&0xff)!=channel))
- continue;
- if(node.status==NODE_QUIET)
- qusr[qusrs++]=i;
- else if(node.status==NODE_INUSE)
- usr[usrs++]=i; }
- if(preusrs>usrs) {
- if(!usrs && channel && chan[channel-1]->misc&CHAN_GURU
- && chan[channel-1]->guru<total_gurus)
- bprintf(text[NodeJoinedMultiChat]
- ,sys_nodes+1,guru[chan[channel-1]->guru]->name
- ,channel);
- outchar(7);
- for(i=0;i<preusrs;i++) {
- for(j=0;j<usrs;j++)
- if(preusr[i]==usr[j])
- break;
- if(j==usrs) {
- getnodedat(preusr[i],&node,0);
- if(node.misc&NODE_ANON)
- sprintf(str,"%.80s",text[UNKNOWN_USER]);
- else
- username(node.useron,str);
- bprintf(text[NodeLeftMultiChat]
- ,preusr[i],str,channel); } } }
- else if(preusrs<usrs) {
- if(!preusrs && channel && chan[channel-1]->misc&CHAN_GURU
- && chan[channel-1]->guru<total_gurus)
- bprintf(text[NodeLeftMultiChat]
- ,sys_nodes+1,guru[chan[channel-1]->guru]->name
- ,channel);
- outchar(7);
- for(i=0;i<usrs;i++) {
- for(j=0;j<preusrs;j++)
- if(usr[i]==preusr[j])
- break;
- if(j==preusrs) {
- getnodedat(usr[i],&node,0);
- if(node.misc&NODE_ANON)
- sprintf(str,"%.80s",text[UNKNOWN_USER]);
- else
- username(node.useron,str);
- bprintf(text[NodeJoinedMultiChat]
- ,usr[i],str,channel); } } }
- preusrs=usrs;
- for(i=0;i<usrs;i++)
- preusr[i]=usr[i];
- attr(color[clr_multichat]);
- SYNC;
- sys_status&=~SS_ABORT;
- if((ch=inkey(0))!=0 || wordwrap[0]) {
- if(ch=='/') {
- bputs(text[MultiChatCommandPrompt]);
- strcpy(str,"ACELWQ?*");
- if(SYSOP)
- strcat(str,"0");
- i=getkeys(str,total_chans);
- if(i&0x80000000L) { /* change channel */
- savch=i&~0x80000000L;
- if(savch==channel)
- continue;
- if(!chan_access(savch-1))
- continue;
- bprintf(text[WelcomeToChannelN]
- ,savch,chan[savch-1]->name);
-
- usrs=0;
- for(i=1;i<=sys_nodes;i++) {
- if(i==node_num)
- continue;
- getnodedat(i,&node,0);
- if(node.action!=NODE_MCHT
- || node.status!=NODE_INUSE)
- continue;
- if(node.aux && (node.aux&0xff)!=savch)
- continue;
- printnodedat(i,node);
- if(node.aux&0x1f00) { /* password */
- bprintf(text[PasswordProtected]
- ,node.misc&NODE_ANON
- ? text[UNKNOWN_USER]
- : username(node.useron,tmp));
- if(!getstr(str,8,K_UPPER|K_ALPHA|K_LINE))
- break;
- if(strcmp(str,unpackchatpass(tmp,node)))
- break;
- bputs(text[CorrectPassword]); }
- preusr[usrs]=usr[usrs++]=i; }
- if(i<=sys_nodes) { /* failed password */
- bputs(text[WrongPassword]);
- continue; }
- if(gurubuf) {
- FREE(gurubuf);
- gurubuf=NULL; }
- if(chan[savch-1]->misc&CHAN_GURU
- && chan[savch-1]->guru<total_gurus
- && chk_ar(guru[chan[savch-1]->guru]->ar,useron
- )) {
- sprintf(str,"%s%s.DAT",ctrl_dir
- ,guru[chan[savch-1]->guru]->code);
- if((file=nopen(str,O_RDONLY))==-1) {
- errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
- break; }
- if((gurubuf=MALLOC(filelength(file)+1))==NULL) {
- close(file);
- errormsg(WHERE,ERR_ALLOC,str
- ,filelength(file)+1);
- break; }
- read(file,gurubuf,filelength(file));
- gurubuf[filelength(file)]=0;
- close(file); }
- preusrs=usrs;
- if(gurubuf)
- bprintf(text[NodeInMultiChatLocally]
- ,sys_nodes+1
- ,guru[chan[savch-1]->guru]->name
- ,savch);
- channel=savch;
- if(!usrs && chan[savch-1]->misc&CHAN_PW
- && !noyes(text[PasswordProtectChanQ])) {
- bputs(text[PasswordPrompt]);
- if(getstr(str,8,K_UPPER|K_ALPHA|K_LINE)) {
- getnodedat(node_num,&thisnode,1);
- thisnode.aux=channel;
- packchatpass(str,&thisnode); }
- else {
- getnodedat(node_num,&thisnode,1);
- thisnode.aux=channel; } }
- else {
- getnodedat(node_num,&thisnode,1);
- thisnode.aux=channel; }
- putnodedat(node_num,thisnode);
- bputs(text[YoureOnTheAir]);
- if(chan[channel-1]->cost
- && !(useron.exempt&FLAG('J')))
- subtract_cdt(chan[channel-1]->cost); }
- else switch(i) { /* other command */
- case '0': /* Global channel */
- if(!SYSOP)
- break;
- usrs=0;
- for(i=1;i<=sys_nodes;i++) {
- if(i==node_num)
- continue;
- getnodedat(i,&node,0);
- if(node.action!=NODE_MCHT
- || node.status!=NODE_INUSE)
- continue;
- printnodedat(i,node);
- preusr[usrs]=usr[usrs++]=i; }
- preusrs=usrs;
- getnodedat(node_num,&thisnode,1);
- thisnode.aux=channel=0;
- putnodedat(node_num,thisnode);
- break;
- case 'A': /* Action commands */
- useron.chat^=CHAT_ACTION;
- bprintf("\r\nAction commands are now %s\r\n"
- ,useron.chat&CHAT_ACTION
- ? text[ON]:text[OFF]);
- putuserrec(useron.number,U_CHAT,8
- ,ltoa(useron.chat,str,16));
- break;
- case 'C': /* List of action commands */
- CRLF;
- for(i=0;i<total_chatacts;i++) {
- if(chatact[i]->actset
- !=chan[channel-1]->actset)
- continue;
- bprintf("%-*.*s",LEN_CHATACTCMD
- ,LEN_CHATACTCMD,chatact[i]->cmd);
- if(!((i+1)%8)) {
- CRLF; }
- else
- bputs(" "); }
- CRLF;
- break;
- case 'E': /* Toggle echo */
- useron.chat^=CHAT_ECHO;
- bprintf(text[EchoIsNow]
- ,useron.chat&CHAT_ECHO
- ? text[ON]:text[OFF]);
- putuserrec(useron.number,U_CHAT,8
- ,ltoa(useron.chat,str,16));
- break;
- case 'L': /* list nodes */
- CRLF;
- for(i=1;i<=sys_nodes && i<=sys_lastnode;i++) {
- getnodedat(i,&node,0);
- printnodedat(i,node); }
- CRLF;
- break;
- case 'W': /* page node(s) */
- j=getnodetopage(0,0);
- if(!j)
- break;
- for(i=0;i<usrs;i++)
- if(usr[i]==j)
- break;
- if(i>=usrs) {
- bputs(text[UserNotFound]);
- break; }
-
- bputs(text[NodeMsgPrompt]);
- if(!getstr(line,66,K_LINE|K_MSG))
- break;
-
- sprintf(buf,text[ChatLineFmt]
- ,thisnode.misc&NODE_ANON
- ? text[AnonUserChatHandle]
- : useron.handle
- ,node_num,'*',line);
- strcat(buf,crlf);
- if(useron.chat&CHAT_ECHO)
- bputs(buf);
- putnmsg(j,buf);
- break;
- case 'Q': /* quit */
- done=1;
- break;
- case '*':
- sprintf(str,"%sMENU\\CHAN.*",text_dir);
- if(fexist(str))
- menu("CHAN");
- else {
- bputs(text[ChatChanLstHdr]);
- bputs(text[ChatChanLstTitles]);
- if(total_chans>=10) {
- bputs(" ");
- bputs(text[ChatChanLstTitles]); }
- CRLF;
- bputs(text[ChatChanLstUnderline]);
- if(total_chans>=10) {
- bputs(" ");
- bputs(text[ChatChanLstUnderline]); }
- CRLF;
- if(total_chans>=10)
- j=(total_chans/2)+(total_chans&1);
- else
- j=total_chans;
- for(i=0;i<j && !msgabort();i++) {
- bprintf(text[ChatChanLstFmt],i+1
- ,chan[i]->name
- ,chan[i]->cost);
- if(total_chans>=10) {
- k=(total_chans/2)
- +i+(total_chans&1);
- if(k<total_chans) {
- bputs(" ");
- bprintf(text[ChatChanLstFmt]
- ,k+1
- ,chan[k]->name
- ,chan[k]->cost); } }
- CRLF; }
- CRLF; }
- break;
- case '?': /* menu */
- menu("MULTCHAT");
- break; } }
- else {
- ungetkey(ch);
- j=0;
- pgraph[0]=0;
- while(j<5) {
- if(!getstr(line,66,K_WRAP|K_MSG|K_CHAT))
- break;
- if(j) {
- sprintf(str,text[ChatLineFmt]
- ,thisnode.misc&NODE_ANON
- ? text[AnonUserChatHandle]
- : useron.handle
- ,node_num,':',nulstr);
- sprintf(tmp,"%*s",bstrlen(str),nulstr);
- strcat(pgraph,tmp); }
- strcat(pgraph,line);
- strcat(pgraph,crlf);
- if(!wordwrap[0])
- break;
- j++; }
- if(pgraph[0]) {
- if(useron.chat&CHAT_ACTION) {
- for(i=0;i<total_chatacts;i++) {
- if(chatact[i]->actset
- !=chan[channel-1]->actset)
- continue;
- sprintf(str,"%s ",chatact[i]->cmd);
- if(!strnicmp(str,pgraph,strlen(str)))
- break;
- sprintf(str,"%.*s"
- ,LEN_CHATACTCMD+2,pgraph);
- str[strlen(str)-2]=0;
- if(!stricmp(chatact[i]->cmd,str))
- break; }
-
- if(i<total_chatacts) {
- p=pgraph+strlen(str);
- n=atoi(p);
- for(j=0;j<usrs;j++) {
- getnodedat(usr[j],&node,0);
- if(usrs==1) /* no need to search */
- break;
- if(n) {
- if(usr[j]==n)
- break;
- continue; }
- username(node.useron,str);
- if(!strnicmp(str,p,strlen(str)))
- break;
- getuserrec(node.useron,U_HANDLE
- ,LEN_HANDLE,str);
- if(!strnicmp(str,p,strlen(str)))
- break; }
- if(!usrs
- && chan[channel-1]->guru<total_gurus)
- strcpy(str
- ,guru[chan[channel-1]->guru]->name);
- else if(j>=usrs)
- strcpy(str,"everyone");
- else if(node.misc&NODE_ANON)
- strcpy(str,text[UNKNOWN_USER]);
- else
- username(node.useron,str);
-
- /* Display on same node */
- bprintf(chatact[i]->out
- ,thisnode.misc&NODE_ANON
- ? text[UNKNOWN_USER] : useron.alias
- ,str);
- CRLF;
-
- if(usrs && j<usrs) {
- /* Display to dest user */
- sprintf(buf,chatact[i]->out
- ,thisnode.misc&NODE_ANON
- ? text[UNKNOWN_USER] : useron.alias
- ,"you");
- strcat(buf,crlf);
- putnmsg(usr[j],buf); }
-
-
- /* Display to all other users */
- sprintf(buf,chatact[i]->out
- ,thisnode.misc&NODE_ANON
- ? text[UNKNOWN_USER] : useron.alias
- ,str);
- strcat(buf,crlf);
-
- for(i=0;i<usrs;i++) {
- if(i==j)
- continue;
- getnodedat(usr[i],&node,0);
- putnmsg(usr[i],buf); }
- for(i=0;i<qusrs;i++) {
- getnodedat(qusr[i],&node,0);
- putnmsg(qusr[i],buf); }
- continue; } }
-
- sprintf(buf,text[ChatLineFmt]
- ,thisnode.misc&NODE_ANON
- ? text[AnonUserChatHandle]
- : useron.handle
- ,node_num,':',pgraph);
- if(useron.chat&CHAT_ECHO)
- bputs(buf);
- for(i=0;i<usrs;i++) {
- getnodedat(usr[i],&node,0);
- putnmsg(usr[i],buf); }
- for(i=0;i<qusrs;i++) {
- getnodedat(qusr[i],&node,0);
- putnmsg(qusr[i],buf); }
- if(!usrs && channel && gurubuf
- && chan[channel-1]->misc&CHAN_GURU)
- guruchat(pgraph,gurubuf,chan[channel-1]->guru);
- } } }
- else
- mswait(1);
- if(sys_status&SS_ABORT)
- break; }
- lncntr=0;
- break;
- case 'P': /* private node-to-node chat */
- privchat();
- break;
- case 'C':
- no_rip_menu=1;
- ch=kbd_state(); /* Check scroll lock */
- if(ch&16 || (sys_chat_ar[0] && chk_ar(sys_chat_ar,useron))
- || useron.exempt&FLAG('C')) {
- sysop_page();
- break; }
- bprintf(text[SysopIsNotAvailable],sys_op);
- if(total_gurus && chk_ar(guru[0]->ar,useron)) {
- sprintf(str,text[ChatWithGuruInsteadQ],guru[0]->name);
- if(!yesno(str))
- break; }
- else
- break;
- case 'T':
- if(!total_gurus) {
- bprintf(text[SysopIsNotAvailable],"The Guru");
- break; }
- if(total_gurus==1 && chk_ar(guru[0]->ar,useron))
- i=0;
- else {
- for(i=0;i<total_gurus;i++)
- uselect(1,i,nulstr,guru[i]->name,guru[i]->ar);
- i=uselect(0,0,0,0,0);
- if(i<0)
- break; }
- if(gurubuf)
- FREE(gurubuf);
- sprintf(str,"%s%s.DAT",ctrl_dir,guru[i]->code);
- if((file=nopen(str,O_RDONLY))==-1) {
- errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
- return; }
- if((gurubuf=MALLOC(filelength(file)+1))==NULL) {
- close(file);
- errormsg(WHERE,ERR_ALLOC,str,filelength(file)+1);
- return; }
- read(file,gurubuf,filelength(file));
- gurubuf[filelength(file)]=0;
- close(file);
- localguru(gurubuf,i);
- no_rip_menu=1;
- FREE(gurubuf);
- gurubuf=NULL;
- break;
- case '?':
- if(useron.misc&EXPERT)
- menu("CHAT");
- break;
- default: /* 'Q' or <CR> */
- lncntr=0;
- if(gurubuf)
- FREE(gurubuf);
- return; }
- action=NODE_CHAT;
- if(!(useron.misc&EXPERT) || useron.misc&WIP
- || (useron.misc&RIP && !no_rip_menu)) {
- #if 0
- sys_status&=~SS_ABORT;
- if(lncntr) {
- SYNC;
- CRLF;
- if(lncntr) /* CRLF or SYNC can cause pause */
- pause(); }
- #endif
- menu("CHAT"); }
- ASYNC;
- bputs(text[ChatPrompt]); }
- if(gurubuf)
- FREE(gurubuf);
- }
-
- int getnodetopage(int all, int telegram)
- {
- static uchar last[26];
- char str[128];
- int i,j;
- ulong l;
- node_t node;
-
- if(!lastnodemsg)
- last[0]=0;
- if(lastnodemsg) {
- getnodedat(lastnodemsg,&node,0);
- if(node.status!=NODE_INUSE && !SYSOP)
- lastnodemsg=1; }
- for(j=0,i=1;i<=sys_nodes && i<=sys_lastnode;i++) {
- getnodedat(i,&node,0);
- if(i==node_num)
- continue;
- if(node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET)) {
- if(!lastnodemsg)
- lastnodemsg=i;
- j++; } }
-
- if(!last[0])
- sprintf(last,"%u",lastnodemsg);
-
- if(!j && !telegram) {
- bputs(text[NoOtherActiveNodes]);
- return(0); }
-
- if(all)
- sprintf(str,text[NodeToSendMsgTo],lastnodemsg);
- else
- sprintf(str,text[NodeToPrivateChat],lastnodemsg);
- mnemonics(str);
-
- strcpy(str,last);
- getstr(str,25,K_UPRLWR|K_LINE|K_EDIT|K_AUTODEL);
- if(sys_status&SS_ABORT)
- return(0);
- if(!str[0])
- return(0);
-
- j=atoi(str);
- if(j && j<=sys_lastnode && j<=sys_nodes) {
- getnodedat(j,&node,0);
- if(node.status!=NODE_INUSE && !SYSOP) {
- bprintf(text[NodeNIsNotInUse],j);
- return(0); }
- if(telegram && node.misc&(NODE_POFF|NODE_ANON) && !SYSOP) {
- bprintf(text[CantPageNode],node.misc&NODE_ANON
- ? text[UNKNOWN_USER] : username(node.useron,tmp));
- return(0); }
- strcpy(last,str);
- if(telegram)
- return(node.useron);
- return(j); }
- if(all && !stricmp(str,"ALL"))
- return(-1);
-
- if(str[0]=='\'') {
- j=userdatdupe(0,U_HANDLE,LEN_HANDLE,str+1,0);
- if(!j) {
- bputs(text[UnknownUser]);
- return(0); } }
- else if(str[0]=='#')
- j=atoi(str+1);
- else
- j=finduser(str);
- if(!j)
- return(0);
- if(j>lastuser())
- return(0);
- getuserrec(j,U_MISC,8,tmp);
- l=ahtoul(tmp);
- if(l&(DELETED|INACTIVE)) { /* Deleted or Inactive User */
- bputs(text[UnknownUser]);
- return(0); }
-
- for(i=1;i<=sys_nodes && i<=sys_lastnode;i++) {
- getnodedat(i,&node,0);
- if((node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET))
- && node.useron==j) {
- if(telegram && node.misc&NODE_POFF && !SYSOP) {
- bprintf(text[CantPageNode],node.misc&NODE_ANON
- ? text[UNKNOWN_USER] : username(node.useron,tmp));
- return(0); }
- if(telegram)
- return(j);
- strcpy(last,str);
- return(i); } }
- if(telegram) {
- strcpy(last,str);
- return(j); }
- bputs(text[UserNotFound]);
- return(0);
- }
-
-
- /****************************************************************************/
- /* Sending single line messages between nodes */
- /****************************************************************************/
- void nodemsg()
- {
- static inside;
- char str[256],line[256],buf[512],ch;
- int i,j,usernumber,done=0;
- node_t node,savenode;
-
- if(inside>1) /* nested once only */
- return;
- sys_status|=SS_IN_CTRLP;
- getnodedat(node_num,&savenode,0);
- inside++;
- wordwrap[0]=0;
- while(online && !done) {
- if(useron.rest&FLAG('C')) {
- bputs(text[R_SendMessages]);
- break; }
- SYNC;
- mnemonics(text[PrivateMsgPrompt]);
- sys_status&=~SS_ABORT;
- while(online) { /* Watch for incoming messages */
- ch=toupper(inkey(0));
- if(ch && strchr("TMCQ\r",ch))
- break;
- if(sys_status&SS_ABORT)
- break;
- if(online==ON_REMOTE && rioctl(IOSTATE)&ABORT) {
- sys_status|=SS_ABORT;
- break; }
- getnodedat(node_num,&thisnode,0);
- if(thisnode.misc&(NODE_MSGW|NODE_NMSG)) {
- SAVELINE;
- CRLF;
- if(thisnode.misc&NODE_NMSG)
- getnmsg();
- if(thisnode.misc&NODE_MSGW)
- getsmsg(useron.number);
- CRLF;
- RESTORELINE; }
- else
- nodesync();
- gettimeleft();
- checkline(); }
-
- if(!online || sys_status&SS_ABORT) {
- sys_status&=~SS_ABORT;
- CRLF;
- break; }
-
- switch(toupper(ch)) {
- case 'T': /* Telegram */
- bputs("Telegram\r\n");
- usernumber=getnodetopage(0,1);
- if(!usernumber)
- break;
-
- if(usernumber==1 && useron.rest&FLAG('S')) { /* ! val fback */
- bprintf(text[R_Feedback],sys_op);
- break; }
- if(usernumber!=1 && useron.rest&FLAG('E')) {
- bputs(text[R_Email]);
- break; }
- now=time(NULL);
- bprintf("\1n\r\n\1mSending telegram to \1h%s #%u\1n\1m (Max 5 "
- "lines, Blank line ends):\r\n\r\n\1g\1h"
- ,username(usernumber,tmp),usernumber);
- sprintf(buf,"\1n\1g\7Telegram from \1n\1h%s\1n\1g on %s:\r\n\1h"
- ,thisnode.misc&NODE_ANON ? text[UNKNOWN_USER] : useron.alias
- ,timestr(&now));
- i=0;
- while(online && i<5) {
- bprintf("%4s",nulstr);
- if(!getstr(line,70,K_WRAP|K_MSG))
- break;
- sprintf(str,"%4s%s\r\n",nulstr,line);
- strcat(buf,str);
- i++; }
- if(!i)
- break;
- if(sys_status&SS_ABORT) {
- CRLF;
- break; }
- putsmsg(usernumber,buf);
- sprintf(str,"Sent telegram to %s #%u"
- ,username(usernumber,tmp),usernumber);
- logline("C",str);
- logline(nulstr,line);
- bprintf("\1n\1mTelegram sent to \1h%s\r\n"
- ,username(usernumber,tmp));
- break;
- case 'M': /* Message */
- bputs("Message\r\n");
- i=getnodetopage(1,0);
- if(!i)
- break;
- if(i!=-1) {
- getnodedat(i,&node,0);
- usernumber=node.useron;
- if(node.misc&NODE_POFF && !SYSOP)
- bprintf(text[CantPageNode],node.misc&NODE_ANON
- ? text[UNKNOWN_USER] : username(node.useron,tmp));
- else {
- bprintf("\r\n\1n\1mSending message to \1h%s\r\n"
- ,node.misc&NODE_ANON ? text[UNKNOWN_USER]
- : username(node.useron,tmp));
- bputs(text[NodeMsgPrompt]);
- if(!getstr(line,69,K_LINE))
- break;
- sprintf(buf,text[NodeMsgFmt],node_num
- ,thisnode.misc&NODE_ANON
- ? text[UNKNOWN_USER] : useron.alias,line);
- putnmsg(i,buf);
- if(!(node.misc&NODE_ANON))
- bprintf("\r\n\1n\1mMessage sent to \1h%s #%u\r\n"
- ,username(usernumber,tmp),usernumber);
- sprintf(str,"Sent message to %s on node %d:"
- ,username(usernumber,tmp),i);
- logline("C",str);
- logline(nulstr,line); } }
- else { /* ALL */
- bputs(text[NodeMsgPrompt]);
- if(!getstr(line,70,K_LINE))
- break;
- sprintf(buf,text[AllNodeMsgFmt],node_num
- ,thisnode.misc&NODE_ANON
- ? text[UNKNOWN_USER] : useron.alias,line);
- for(i=1;i<=sys_nodes;i++) {
- if(i==node_num)
- continue;
- getnodedat(i,&node,0);
- if((node.status==NODE_INUSE
- || (SYSOP && node.status==NODE_QUIET))
- && (SYSOP || !(node.misc&NODE_POFF)))
- putnmsg(i,buf); }
- logline("C","Sent message to all nodes");
- logline(nulstr,line); }
- break;
- case 'C': /* Chat */
- bputs("Chat\r\n");
- if(action==NODE_PCHT) { /* already in pchat */
- done=1;
- break; }
- privchat();
- action=savenode.action;
- break;
- default:
- bputs("Quit\r\n");
- done=1;
- break; } }
- inside--;
- if(!inside)
- sys_status&=~SS_IN_CTRLP;
- getnodedat(node_num,&thisnode,1);
- thisnode.action=action=savenode.action;
- thisnode.aux=savenode.aux;
- thisnode.extaux=savenode.extaux;
- putnodedat(node_num,thisnode);
- }
-
- /****************************************************************************/
- /* The guru will respond from the 'guru' buffer to 'line' */
- /****************************************************************************/
- void guruchat(char *line, char *gurubuf, int gurunum)
- {
- char str[256],cstr[256],*ptr,c,*answer[100],answers,theanswer[769]
- ,mistakes=1,hu=0;
- int i,j,k,file;
- long len;
- struct tm *tm;
-
- now=time(NULL);
- tm=localtime(&now);
-
- for(i=0;i<100;i++) {
- if((answer[i]=MALLOC(513))==NULL) {
- errormsg(WHERE,ERR_ALLOC,nulstr,513);
- while(i) {
- i--;
- FREE(answer[i]); }
- sys_status&=~SS_GURUCHAT;
- return; } }
- ptr=gurubuf;
- len=strlen(gurubuf);
- strupr(line);
- j=strlen(line);
- k=0;
- for(i=0;i<j;i++) {
- if(!isalnum(line[i]) && !k) /* beginning non-alphanumeric */
- continue;
- if(!isalnum(line[i]) && line[i]==line[i+1]) /* redundant non-alnum */
- continue;
- if(!isalnum(line[i]) && line[i+1]=='?') /* fix "WHAT ?" */
- continue;
- cstr[k++]=line[i]; }
- cstr[k]=0;
- while(--k) {
- if(!isalnum(cstr[k]))
- continue;
- break; }
- if(k<1) {
- for(i=0;i<100;i++)
- FREE(answer[i]);
- return; }
- if(cstr[k+1]=='?')
- k++;
- cstr[k+1]=0;
- while(*ptr && ptr<gurubuf+len) {
- if(*ptr=='(') {
- ptr++;
- if(!guruexp(&ptr,cstr)) {
- while(*ptr && *ptr!='(' && ptr<gurubuf+len)
- ptr++;
- continue; } }
- else {
- while(*ptr && *ptr!=LF && ptr<gurubuf+len) /* skip LF after ')' */
- ptr++;
- ptr++;
- answers=0;
- while(*ptr && answers<100 && ptr<gurubuf+len) {
- i=0;
- while(*ptr && *ptr!=CR && i<512 && ptr<gurubuf+len) {
- answer[answers][i]=*ptr;
- ptr++;
- i++;
- if(*ptr=='\\' && *(ptr+1)==CR) { /* multi-line answer */
- ptr+=3; /* skip \CRLF */
- answer[answers][i++]=CR;
- answer[answers][i++]=LF; } }
- answer[answers][i]=0;
- if(!strlen(answer[answers]) || answer[answers][0]=='(') {
- ptr-=strlen(answer[answers]);
- break; }
- ptr+=2; /* skip CRLF */
- answers++; }
- if(answers==100)
- while(*ptr && *ptr!='(' && ptr<gurubuf+len)
- ptr++;
- i=random(answers);
- for(j=0,k=0;j<strlen(answer[i]);j++) {
- if(answer[i][j]=='`') {
- j++;
- theanswer[k]=0;
- switch(toupper(answer[i][j])) {
- case 'A':
- if(sys_status&SS_USERON)
- strcat(theanswer,useron.alias);
- else
- strcat(theanswer,text[UNKNOWN_USER]);
- break;
- case 'B':
- if(sys_status&SS_USERON)
- strcat(theanswer,useron.birth);
- else
- strcat(theanswer,"00/00/00");
- break;
- case 'C':
- if(sys_status&SS_USERON)
- strcat(theanswer,useron.comp);
- else
- strcat(theanswer,"PC Jr.");
- break;
- case 'D':
- if(sys_status&SS_USERON)
- strcat(theanswer,ultoac(useron.dlb,tmp));
- else
- strcat(theanswer,"0");
- break;
- case 'G':
- strcat(theanswer,guru[gurunum]->name);
- break;
- case 'H':
- hu=1;
- break;
- case 'I':
- strcat(theanswer,sys_id);
- break;
- case 'J':
- sprintf(tmp,"%u",tm->tm_mday);
- break;
- case 'L':
- if(sys_status&SS_USERON)
- strcat(theanswer,itoa(useron.level,tmp,10));
- else
- strcat(theanswer,"0");
- break;
- case 'M':
- strcat(theanswer,month[tm->tm_mon]);
- break;
- case 'N': /* Note */
- if(sys_status&SS_USERON)
- strcat(theanswer,useron.note);
- else
- strcat(theanswer,text[UNKNOWN_USER]);
- break;
- case 'O':
- strcat(theanswer,sys_op);
- break;
- case 'P':
- if(sys_status&SS_USERON)
- strcat(theanswer,useron.phone);
- else
- strcat(theanswer,"000-000-0000");
- break;
- case 'Q':
- sys_status&=~SS_GURUCHAT;
- break;
- case 'R':
- if(sys_status&SS_USERON)
- strcat(theanswer,useron.name);
- else
- strcat(theanswer,text[UNKNOWN_USER]);
- break;
- case 'S':
- strcat(theanswer,sys_name);
- break;
- case 'T':
- sprintf(tmp,"%u:%02u",tm->tm_hour>12 ? tm->tm_hour-12
- : tm->tm_hour,tm->tm_min);
- strcat(theanswer,tmp);
- break;
- case 'U':
- if(sys_status&SS_USERON)
- strcat(theanswer,ultoac(useron.ulb,tmp));
- else
- strcat(theanswer,"0");
- break;
- case 'W':
- strcat(theanswer,weekday[tm->tm_wday]);
- break;
- case 'Y': /* Current year */
- sprintf(tmp,"%u",1900+tm->tm_year);
- strcat(theanswer,tmp);
- break;
- case 'Z':
- if(sys_status&SS_USERON)
- strcat(theanswer,useron.zipcode);
- else
- strcat(theanswer,"90210");
- break;
- case '$': /* Credits */
- if(sys_status&SS_USERON)
- strcat(theanswer,ultoac(useron.cdt,tmp));
- else
- strcat(theanswer,"0");
- break;
- case '#':
- if(sys_status&SS_USERON)
- strcat(theanswer,itoa(getage(useron.birth)
- ,tmp,10));
- else
- strcat(theanswer,"0");
- break;
- case '!':
- mistakes=!mistakes;
- break;
- case '_':
- mswait(500);
- break; }
- k=strlen(theanswer); }
- else
- theanswer[k++]=answer[i][j]; }
- theanswer[k]=0;
- mswait(500+random(1000)); /* thinking time */
- if(action!=NODE_MCHT) {
- for(i=0;i<k;i++) {
- if(mistakes && theanswer[i]!=theanswer[i-1] &&
- ((!isalnum(theanswer[i]) && !random(100))
- || (isalnum(theanswer[i]) && !random(30)))) {
- c=j=random(3)+1; /* 1 to 3 chars */
- if(c<strcspn(theanswer+(i+1),"\0., "))
- c=j=1;
- while(j) {
- outchar(97+random(26));
- mswait(25+random(150));
- j--; }
- if(random(100)) {
- mswait(100+random(300));
- while(c) {
- bputs("\b \b");
- mswait(50+random(50));
- c--; } } }
- outchar(theanswer[i]);
- if(theanswer[i]==theanswer[i+1])
- mswait(25+random(50));
- else
- mswait(25+random(150));
- if(theanswer[i]==SP)
- mswait(random(50)); } }
- else {
- mswait(strlen(theanswer)*100);
- bprintf(text[ChatLineFmt],guru[gurunum]->name
- ,sys_nodes+1,':',theanswer); }
- CRLF;
- sprintf(str,"%sGURU.LOG",data_dir);
- if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1)
- errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND);
- else {
- if(action==NODE_MCHT) {
- sprintf(str,"[Multi] ");
- write(file,str,strlen(str)); }
- sprintf(str,"%s:\r\n",sys_status&SS_USERON
- ? useron.alias : "UNKNOWN");
- write(file,str,strlen(str));
- write(file,line,strlen(line));
- if(action!=NODE_MCHT)
- write(file,crlf,2);
- sprintf(str,"%s:\r\n",guru[gurunum]->name);
- write(file,str,strlen(str));
- write(file,theanswer,strlen(theanswer));
- write(file,crlf,2);
- close(file); }
- if(hu)
- hangup();
- break; } }
- for(i=0;i<100;i++)
- FREE(answer[i]);
- }
-
- /****************************************************************************/
- /* An expression from the guru's buffer 'ptrptr' is evaluated and true or */
- /* false is returned. */
- /****************************************************************************/
- char guruexp(char **ptrptr, char *line)
- {
- char c,*cp,str[256],true=0,and=0,or=0,nest,*ar;
-
- if((**ptrptr)==')') { /* expressions of () are always true */
- (*ptrptr)++;
- return(1); }
- while((**ptrptr)!=')' && (**ptrptr)) {
- if((**ptrptr)=='[') {
- (*ptrptr)++;
- sprintf(str,"%.128s",*ptrptr);
- while(**ptrptr && (**ptrptr)!=']')
- (*ptrptr)++;
- (*ptrptr)++;
- cp=strchr(str,']');
- if(cp) *cp=0;
- ar=arstr(NULL,str);
- c=chk_ar(ar,useron);
- if(ar[0]!=AR_NULL)
- FREE(ar);
- if(!c && and) {
- true=0;
- break; }
- if(c && or) {
- true=1;
- break; }
- if(c)
- true=1;
- continue; }
- if((**ptrptr)=='(') {
- (*ptrptr)++;
- c=guruexp(&(*ptrptr),line);
- if(!c && and) {
- true=0;
- break; }
- if(c && or) {
- true=1;
- break; }
- if(c)
- true=1; }
- if((**ptrptr)==')')
- break;
- c=0;
- while((**ptrptr) && isspace(**ptrptr))
- (*ptrptr)++;
- while((**ptrptr)!='|' && (**ptrptr)!='&' && (**ptrptr)!=')' &&(**ptrptr)) {
- str[c++]=(**ptrptr);
- (*ptrptr)++; }
- str[c]=0;
- if((**ptrptr)=='|') {
- if(!c && true)
- break;
- and=0;
- or=1; }
- else if((**ptrptr)=='&') {
- if(!c && !true)
- break;
- and=1;
- or=0; }
- if(!c) { /* support ((exp)op(exp)) */
- (*ptrptr)++;
- continue; }
- if((**ptrptr)!=')')
- (*ptrptr)++;
- c=0; /* c now used for start line flag */
- if(str[strlen(str)-1]=='^') { /* ^signifies start of line only */
- str[strlen(str)-1]=0;
- c=1; }
- if(str[strlen(str)-1]=='~') { /* ~signifies non-isolated word */
- str[strlen(str)-1]=0;
- cp=strstr(line,str);
- if(c && cp!=line)
- cp=0; }
- else {
- cp=strstr(line,str);
- if(cp && c) {
- if(cp!=line || isalnum(*(cp+strlen(str))))
- cp=0; }
- else { /* must be isolated word */
- while(cp)
- if((cp!=line && isalnum(*(cp-1)))
- || isalnum(*(cp+strlen(str))))
- cp=strstr(cp+strlen(str),str);
- else
- break; } }
- if(!cp && and) {
- true=0;
- break; }
- if(cp && or) {
- true=1;
- break; }
- if(cp)
- true=1; }
- nest=0;
- while((**ptrptr)!=')' && (**ptrptr)) { /* handle nested exp */
- if((**ptrptr)=='(') /* (TRUE|(IGNORE)) */
- nest++;
- (*ptrptr)++;
- while((**ptrptr)==')' && nest && (**ptrptr)) {
- nest--;
- (*ptrptr)++; } }
- (*ptrptr)++; /* skip over ')' */
- return(true);
- }
-
- /****************************************************************************/
- /* Guru chat with the appearance of Local chat with sysop. */
- /****************************************************************************/
- void localguru(char *gurubuf, int gurunum)
- {
- char ch,str[256];
- int con=console; /* save console state */
-
- if(sys_status&SS_GURUCHAT || !total_gurus)
- return;
- sys_status|=SS_GURUCHAT;
- console&=~(CON_L_ECHOX|CON_R_ECHOX); /* turn off X's */
- console|=(CON_L_ECHO|CON_R_ECHO); /* make sure echo is on */
- if(action==NODE_CHAT) { /* only page if from chat section */
- bprintf(text[PagingGuru],guru[gurunum]->name);
- ch=random(25)+25;
- while(ch--) {
- mswait(200);
- outchar('.'); } }
- bprintf(text[SysopIsHere],guru[gurunum]->name);
- getnodedat(node_num,&thisnode,1);
- thisnode.aux=gurunum;
- putnodedat(node_num,thisnode);
- attr(color[clr_chatlocal]);
- guruchat("HELLO",gurubuf,gurunum);
- while(online && (sys_status&SS_GURUCHAT)) {
- checkline();
- action=NODE_GCHT;
- SYNC;
- if((ch=inkey(0))!=0) {
- ungetkey(ch);
- attr(color[clr_chatremote]);
- if(getstr(str,78,K_WRAP|K_CHAT)) {
- attr(color[clr_chatlocal]);
- guruchat(str,gurubuf,gurunum); } }
- else
- mswait(1); }
- bputs(text[EndOfChat]);
- sys_status&=~SS_GURUCHAT;
- console=con; /* restore console state */
- }
-
- /****************************************************************************/
- /* Packs the password 'pass' into 5bit ASCII inside node_t. 32bits in */
- /* node.extaux, and the other 8bits in the upper byte of node.aux */
- /****************************************************************************/
- void packchatpass(char *pass, node_t *node)
- {
- char bits;
- int i,j;
-
- node->aux&=~0xff00; /* clear the password */
- node->extaux=0L;
- if((j=strlen(pass))==0) /* there isn't a password */
- return;
- node->aux|=(int)((pass[0]-64)<<8); /* 1st char goes in low 5bits of aux */
- if(j==1) /* password is only one char, we're done */
- return;
- node->aux|=(int)((pass[1]-64)<<13); /* low 3bits of 2nd char go in aux */
- node->extaux|=(long)((pass[1]-64)>>3); /* high 2bits of 2nd char go extaux */
- bits=2;
- for(i=2;i<j;i++) { /* now process the 3rd char through the last */
- node->extaux|=(long)((long)(pass[i]-64)<<bits);
- bits+=5; }
- }
-
- /****************************************************************************/
- /* Unpacks the password 'pass' from the 5bit ASCII inside node_t. 32bits in */
- /* node.extaux, and the other 8bits in the upper byte of node.aux */
- /****************************************************************************/
- char *unpackchatpass(char *pass, node_t node)
- {
- char bits;
- int i;
-
- pass[0]=(node.aux&0x1f00)>>8;
- pass[1]=((node.aux&0xe000)>>13)|((node.extaux&0x3)<<3);
- bits=2;
- for(i=2;i<8;i++) {
- pass[i]=(node.extaux>>bits)&0x1f;
- bits+=5; }
- pass[8]=0;
- for(i=0;i<8;i++)
- if(pass[i])
- pass[i]+=64;
- return(pass);
- }
-