Annotation of sbbs/sbbs3/chat.cpp, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.