Annotation of sbbs/src/sbbs3/chat.cpp, revision 1.1

1.1     ! root        1: /* chat.cpp */
        !             2: 
        !             3: /* Synchronet real-time chat functions */
        !             4: 
        !             5: /* $Id: chat.cpp,v 1.47 2006/08/23 01:45:05 rswindell Exp $ */
        !             6: 
        !             7: /****************************************************************************
        !             8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
        !             9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
        !            10:  *                                                                                                                                                     *
        !            11:  * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html         *
        !            12:  *                                                                                                                                                     *
        !            13:  * This program is free software; you can redistribute it and/or                       *
        !            14:  * modify it under the terms of the GNU General Public License                         *
        !            15:  * as published by the Free Software Foundation; either version 2                      *
        !            16:  * of the License, or (at your option) any later version.                                      *
        !            17:  * See the GNU General Public License for more details: gpl.txt or                     *
        !            18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
        !            19:  *                                                                                                                                                     *
        !            20:  * Anonymous FTP access to the most recent released source is available at     *
        !            21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
        !            22:  *                                                                                                                                                     *
        !            23:  * Anonymous CVS access to the development source and modification history     *
        !            24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
        !            25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
        !            26:  *     (just hit return, no password is necessary)                                                     *
        !            27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
        !            28:  *                                                                                                                                                     *
        !            29:  * For Synchronet coding style and modification guidelines, see                                *
        !            30:  * http://www.synchro.net/source.html                                                                          *
        !            31:  *                                                                                                                                                     *
        !            32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
        !            33:  * format) via e-mail to [email protected]                                                                      *
        !            34:  *                                                                                                                                                     *
        !            35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
        !            36:  ****************************************************************************/
        !            37: 
        !            38: #include "sbbs.h"
        !            39: 
        !            40: #define PCHAT_LEN 1000         /* Size of Private chat file */
        !            41: 
        !            42: const char *weekday[]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday"
        !            43:                                ,"Saturday"};
        !            44: const char *month[]={"January","February","March","April","May","June"
        !            45:                                ,"July","August","September","October","November","December"};
        !            46: 
        !            47: /****************************************************************************/
        !            48: /****************************************************************************/
        !            49: void sbbs_t::multinodechat(int channel)
        !            50: {
        !            51:        char    line[256],str[256],ch,done
        !            52:                        ,usrs,preusrs,qusrs,*gurubuf=NULL,savch,*p
        !            53:                        ,pgraph[400],buf[400]
        !            54:                        ,usr[MAX_NODES],preusr[MAX_NODES],qusr[MAX_NODES];
        !            55:        char    guru_lastanswer[512];
        !            56:        char    tmp[512];
        !            57:        int     file;
        !            58:        long    i,j,k,n;
        !            59:        node_t  node;
        !            60: 
        !            61:        if(useron.rest&FLAG('C')) {
        !            62:                bputs(text[R_Chat]);
        !            63:                return; 
        !            64:        }
        !            65: 
        !            66:        if(channel<1 || channel>cfg.total_chans)
        !            67:                channel=1;
        !            68: 
        !            69:        if(!chan_access(channel-1))
        !            70:                return;
        !            71:        if(useron.misc&(RIP|WIP|HTML) ||!(useron.misc&EXPERT))
        !            72:                menu("multchat");
        !            73:        bputs(text[WelcomeToMultiChat]);
        !            74:        if(getnodedat(cfg.node_num,&thisnode,true)==0) {
        !            75:                thisnode.aux=channel;           
        !            76:                putnodedat(cfg.node_num,&thisnode);
        !            77:        }
        !            78:        bprintf(text[WelcomeToChannelN],channel,cfg.chan[channel-1]->name);
        !            79:        if(gurubuf) {
        !            80:                free(gurubuf);
        !            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: 
        !           565:        action=NODE_CHAT;
        !           566:        if(useron.misc&(RIP|WIP|HTML) || !(useron.misc&EXPERT))
        !           567:                menu("chat");
        !           568:        ASYNC;
        !           569:        bputs(text[ChatPrompt]);
        !           570:        while(online) {
        !           571:                no_rip_menu=0;
        !           572:                ch=(char)getkeys("ACDJPQST?\r",0);
        !           573:                if(ch>' ')
        !           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));
        !           588:                                if(getnodedat(cfg.node_num,&thisnode,true)==0) {
        !           589:                                        thisnode.misc^=NODE_AOFF;
        !           590:                                        printnodedat(cfg.node_num,&thisnode);
        !           591:                                }
        !           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));
        !           600:                                if(getnodedat(cfg.node_num,&thisnode,true)==0) {
        !           601:                                        thisnode.misc^=NODE_POFF;
        !           602:                                        printnodedat(cfg.node_num,&thisnode);
        !           603:                                }
        !           604:                                putnodedat(cfg.node_num,&thisnode);
        !           605:                                no_rip_menu=true;
        !           606:                                break;
        !           607:                        case 'J':
        !           608:                                multinodechat();
        !           609:                                break;
        !           610:                        case 'P':   /* private node-to-node chat */
        !           611:                                privchat();
        !           612:                                break;
        !           613:                        case 'C':
        !           614:                                no_rip_menu=1;
        !           615:                                if(sysop_page())
        !           616:                                        break;
        !           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;
        !           623:                                /* FALL-THROUGH */
        !           624:                        case 'T':
        !           625:                                guru_page();
        !           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;
        !           634: //                             if(gurubuf)
        !           635: //                                     free(gurubuf);
        !           636:                                return; }
        !           637:                action=NODE_CHAT;
        !           638:                if(!(useron.misc&EXPERT) || useron.misc&(WIP|HTML)
        !           639:                        || (useron.misc&RIP && !no_rip_menu)) {
        !           640:                        menu("chat"); 
        !           641:                }
        !           642:                ASYNC;
        !           643:                bputs(text[ChatPrompt]); }
        !           644: //     if(gurubuf)
        !           645: //             free(gurubuf);
        !           646: }
        !           647: 
        !           648: /****************************************************************************/
        !           649: /****************************************************************************/
        !           650: bool sbbs_t::sysop_page(void)
        !           651: {
        !           652:        char    str[256];
        !           653:        int             i;
        !           654: 
        !           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);
        !           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
        !           719:                        ,*sep=text[PrivateChatSeparator]
        !           720:                        ,*local_sep=text[SysopChatSeparator]
        !           721:                        ;
        !           722:        char    tmp[512];
        !           723:        char    outpath[MAX_PATH+1];
        !           724:        char    inpath[MAX_PATH+1];
        !           725:        uchar   ch;
        !           726:        int     in,out,i,n,echo=1,x,y,activity,remote_activity;
        !           727:     int                local_y=1,remote_y=1;
        !           728:        node_t  node;
        !           729:        time_t  last_nodechk=0;
        !           730: 
        !           731:        if(useron.rest&FLAG('C')) {
        !           732:                bputs(text[R_Chat]);
        !           733:                return; 
        !           734:        }
        !           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) {
        !           755:                        bprintf(text[PagingUser]
        !           756:                                ,node.misc&NODE_ANON ? text[UNKNOWN_USER] : username(&cfg,node.useron,tmp)
        !           757:                                ,node.misc&NODE_ANON ? 0 : node.useron);
        !           758:                        sprintf(str,text[NodePChatPageMsg]
        !           759:                                ,cfg.node_num,thisnode.misc&NODE_ANON
        !           760:                                        ? text[UNKNOWN_USER] : useron.alias);
        !           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);
        !           764:                        logline("C",str); }
        !           765: 
        !           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:                }
        !           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));
        !           781:                                        break; 
        !           782:                                }
        !           783:                                action=NODE_PAGE;
        !           784:                                checkline();
        !           785:                                gettimeleft();
        !           786:                                SYNC; 
        !           787:                                inkey(K_NONE,500);
        !           788:                        } 
        !           789:                }
        !           790:        }
        !           791: 
        !           792:        gettimeleft();
        !           793: 
        !           794:        if(getnodedat(cfg.node_num,&thisnode,true)==0) {
        !           795:                thisnode.action=action=NODE_PCHT;
        !           796:                thisnode.aux=n;
        !           797:                thisnode.misc&=~NODE_LCHAT;
        !           798:                putnodedat(cfg.node_num,&thisnode);
        !           799:        }
        !           800: 
        !           801:        if(!online || sys_status&SS_ABORT)
        !           802:                return;
        !           803: 
        !           804:        if(((sys_status&SS_USERON && useron.chat&CHAT_SPLITP) || !(sys_status&SS_USERON))
        !           805:                && term_supports(ANSI) && rows>=24)
        !           806:                sys_status|=SS_SPLITP;
        !           807:        else
        !           808:                sys_status&=~SS_SPLITP;
        !           809:        /*
        !           810:        if(!(useron.misc&EXPERT))
        !           811:                menu("privchat");
        !           812:        */
        !           813: 
        !           814:        if(!(sys_status&SS_SPLITP)) {
        !           815:                if(local)
        !           816:                        bprintf(text[SysopIsHere],cfg.sys_op);
        !           817:                else
        !           818:                        bputs(text[WelcomeToPrivateChat]);
        !           819:        }
        !           820: 
        !           821:        sprintf(outpath,"%schat.dab",cfg.node_dir);
        !           822:        if((out=sopen(outpath,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO,S_IREAD|S_IWRITE))==-1) {
        !           823:                errormsg(WHERE,ERR_OPEN,outpath,O_RDWR|O_DENYNONE|O_CREAT);
        !           824:                return; 
        !           825:        }
        !           826: 
        !           827:        if(local)
        !           828:                sprintf(inpath,"%slchat.dab",cfg.node_dir);
        !           829:        else
        !           830:                sprintf(inpath,"%schat.dab",cfg.node_path[n-1]);
        !           831:        if(!fexist(inpath))             /* Wait while it's created for the first time */
        !           832:                mswait(2000);
        !           833:        if((in=sopen(inpath,O_RDWR|O_CREAT|O_BINARY,SH_DENYNO,S_IREAD|S_IWRITE))==-1) {
        !           834:                close(out);
        !           835:                errormsg(WHERE,ERR_OPEN,str,O_RDWR|O_DENYNONE|O_CREAT);
        !           836:                return; }
        !           837: 
        !           838:        if((p=(char *)malloc(PCHAT_LEN))==NULL) {
        !           839:                close(in);
        !           840:                close(out);
        !           841:                errormsg(WHERE,ERR_ALLOC,str,PCHAT_LEN);
        !           842:                return; }
        !           843:        memset(p,0,PCHAT_LEN);
        !           844:        write(in,p,PCHAT_LEN);
        !           845:        write(out,p,PCHAT_LEN);
        !           846:        free(p);
        !           847:        lseek(in,0L,SEEK_SET);
        !           848:        lseek(out,0L,SEEK_SET);
        !           849: 
        !           850:        if(getnodedat(cfg.node_num,&thisnode,true)==0) {
        !           851:                thisnode.misc&=~NODE_RPCHT;             /* Clear "reset pchat flag" */
        !           852:                putnodedat(cfg.node_num,&thisnode);
        !           853:        }
        !           854: 
        !           855:        if(!local) {
        !           856:                if(getnodedat(n,&node,true)==0) {
        !           857:                        node.misc|=NODE_RPCHT;                          /* Set "reset pchat flag" */
        !           858:                        putnodedat(n,&node);                            /* on other node */
        !           859:                }
        !           860: 
        !           861:                                                                                        /* Wait for other node */
        !           862:                                                                                        /* to acknowledge and reset */
        !           863:                while(online && !(sys_status&SS_ABORT)) {
        !           864:                        getnodedat(n,&node,0);
        !           865:                        if(!(node.misc&NODE_RPCHT))
        !           866:                                break;
        !           867:                        getnodedat(cfg.node_num,&thisnode,0);
        !           868:                        if(thisnode.misc&NODE_RPCHT)
        !           869:                                break;
        !           870:                        checkline();
        !           871:                        gettimeleft();
        !           872:                        SYNC;
        !           873:                        SLEEP(500); 
        !           874:                }
        !           875:        }
        !           876: 
        !           877:        action=NODE_PCHT;
        !           878:        SYNC;
        !           879: 
        !           880:        if(sys_status&SS_SPLITP) {
        !           881:                lncntr=0;
        !           882:                CLS;
        !           883:                ANSI_SAVE();
        !           884: #if 0
        !           885:                if(local)
        !           886:                        bprintf(text[SysopIsHere],cfg.sys_op);
        !           887: #endif
        !           888:                GOTOXY(1,13);
        !           889:                remote_y=1;
        !           890:                bprintf(local ? local_sep : sep
        !           891:                        ,thisnode.misc&NODE_MSGW ? 'T':' '
        !           892:                        ,sectostr(timeleft,tmp)
        !           893:                        ,thisnode.misc&NODE_NMSG ? 'M':' ');
        !           894:                CRLF;
        !           895:                local_y=14; }
        !           896: 
        !           897:        while(online && (local || !(sys_status&SS_ABORT))) {
        !           898:                lncntr=0;
        !           899:                if(sys_status&SS_SPLITP)
        !           900:                        lbuflen=0;
        !           901:                action=NODE_PCHT;
        !           902:                activity=0;
        !           903:                remote_activity=0;
        !           904:                if((ch=inkey(K_GETSTR,100))!=0) {
        !           905:                        activity=1;
        !           906:                        if(echo)
        !           907:                                attr(cfg.color[clr_chatlocal]);
        !           908:                        if(ch==BS || ch==DEL) {
        !           909:                                if(localchar) {
        !           910:                                        if(echo)
        !           911:                                                backspace();
        !           912:                                        localchar--;
        !           913:                                        localbuf[localline][localchar]=0; } }
        !           914:                        else if(ch==TAB) {
        !           915:                                if(echo)
        !           916:                                        outchar(' ');
        !           917:                                localbuf[localline][localchar]=' ';
        !           918:                                localchar++;
        !           919:                                while(localchar<78 && localchar%8) {
        !           920:                                        if(echo)
        !           921:                                                outchar(' ');
        !           922:                                        localbuf[localline][localchar++]=' '; } }
        !           923:                        else if(ch==CTRL_R) {
        !           924:                                if(sys_status&SS_SPLITP) {
        !           925:                                        CLS;
        !           926:                                        attr(cfg.color[clr_chatremote]);
        !           927:                                        remotebuf[remoteline][remotechar]=0;
        !           928:                                        for(i=0;i<=remoteline;i++) {
        !           929:                                                bputs(remotebuf[i]); 
        !           930:                                                if(i!=remoteline) 
        !           931:                                                        bputs(crlf);
        !           932:                                        }
        !           933:                                        remote_y=1+remoteline;
        !           934:                                        bputs("\1i_\1n");  /* Fake cursor */
        !           935:                                        ANSI_SAVE();
        !           936:                                        GOTOXY(1,13);
        !           937:                                        bprintf(local ? local_sep : sep
        !           938:                                                ,thisnode.misc&NODE_MSGW ? 'T':' '
        !           939:                                                ,sectostr(timeleft,tmp)
        !           940:                                                ,thisnode.misc&NODE_NMSG ? 'M':' ');
        !           941:                                        CRLF;
        !           942:                                        attr(cfg.color[clr_chatlocal]);
        !           943:                                        localbuf[localline][localchar]=0;
        !           944:                                        for(i=0;i<=localline;i++) {
        !           945:                                                bputs(localbuf[i]);
        !           946:                                                if(i!=localline) 
        !           947:                                                        bputs(crlf);
        !           948:                                        }
        !           949:                                        local_y=15+localline;
        !           950:                                }
        !           951:                                continue;
        !           952:                        }
        !           953:                        else if(ch>=' ' || ch==CR) {
        !           954:                                if(ch!=CR) {
        !           955:                                        if(echo)
        !           956:                                                outchar(ch);
        !           957:                                        localbuf[localline][localchar]=ch; }
        !           958: 
        !           959:                                if(ch==CR || (localchar>68 && ch==' ') || ++localchar>78) {
        !           960: 
        !           961:                                        localbuf[localline][localchar]=0;
        !           962:                                        localchar=0;
        !           963: 
        !           964:                                        if(sys_status&SS_SPLITP && local_y==24) {
        !           965:                                                GOTOXY(1,13);
        !           966:                                                bprintf(local ? local_sep : sep
        !           967:                                                        ,thisnode.misc&NODE_MSGW ? 'T':' '
        !           968:                                                        ,sectostr(timeleft,tmp)
        !           969:                                                        ,thisnode.misc&NODE_NMSG ? 'M':' ');
        !           970:                                                attr(cfg.color[clr_chatlocal]);
        !           971:                                                for(x=13,y=0;x<rows;x++,y++) {
        !           972:                                                        rprintf("\x1b[%d;1H\x1b[K",x+1);
        !           973:                                                        if(y<=localline)
        !           974:                                                                bprintf("%s\r\n",localbuf[y]); }
        !           975:                                                GOTOXY(1,local_y=(15+localline));
        !           976:                                                localline=0; }
        !           977:                                        else {
        !           978:                                                if(localline>=4)
        !           979:                                                        for(i=0;i<4;i++)
        !           980:                                                                memcpy(localbuf[i],localbuf[i+1],81);
        !           981:                                                else
        !           982:                                                        localline++;
        !           983:                                                if(echo) {
        !           984:                                                        CRLF;
        !           985:                                        local_y++;
        !           986:                                                        if(sys_status&SS_SPLITP)
        !           987:                                                                cleartoeol(); 
        !           988:                                                } 
        !           989:                                        }
        !           990:                                        // SYNC;
        !           991:                                } 
        !           992:                        }
        !           993: 
        !           994:                        read(out,&c,1);
        !           995:                        lseek(out,-1L,SEEK_CUR);
        !           996:                        if(!c)          /* hasn't wrapped */
        !           997:                                write(out,&ch,1);
        !           998:                        else {
        !           999:                                if(!tell(out))
        !          1000:                                        lseek(out,0L,SEEK_END);
        !          1001:                                lseek(out,-1L,SEEK_CUR);
        !          1002:                                ch=0;
        !          1003:                                write(out,&ch,1);
        !          1004:                                lseek(out,-1L,SEEK_CUR); 
        !          1005:                        }
        !          1006:                        utime(outpath,NULL);    /* update mod time for NFS/smbfs nodes */
        !          1007:                        if(tell(out)>=PCHAT_LEN)
        !          1008:                                lseek(out,0L,SEEK_SET);
        !          1009:                }
        !          1010:                else while(online) {
        !          1011:                        if(!(sys_status&SS_SPLITP))
        !          1012:                                remotechar=localchar;
        !          1013:                        if(tell(in)>=PCHAT_LEN)
        !          1014:                                lseek(in,0L,SEEK_SET);
        !          1015:                        ch=0;
        !          1016:                        utime(inpath,NULL);
        !          1017:                        read(in,&ch,1);
        !          1018:                        lseek(in,-1L,SEEK_CUR);
        !          1019:                        if(!ch) break;                                    /* char from other node */
        !          1020:                        activity=1;
        !          1021:                        if(sys_status&SS_SPLITP && !remote_activity) {
        !          1022:                                ansi_getxy(&x,&y);
        !          1023:                                ANSI_RESTORE();
        !          1024:                        }
        !          1025:                        attr(cfg.color[clr_chatremote]);
        !          1026:                        if(sys_status&SS_SPLITP && !remote_activity)
        !          1027:                                backspace();             /* Delete fake cursor */
        !          1028:                        remote_activity=1;
        !          1029:                        if(ch==BS || ch==DEL) {
        !          1030:                                if(remotechar) {
        !          1031:                                        backspace();
        !          1032:                                        remotechar--;
        !          1033:                                        remotebuf[remoteline][remotechar]=0; } }
        !          1034:                        else if(ch==TAB) {
        !          1035:                                outchar(' ');
        !          1036:                                remotebuf[remoteline][remotechar]=' ';
        !          1037:                                remotechar++;
        !          1038:                                while(remotechar<78 && remotechar%8) {
        !          1039:                                        outchar(' ');
        !          1040:                                        remotebuf[remoteline][remotechar++]=' '; } }
        !          1041:                        else if(ch>=' ' || ch==CR) {
        !          1042:                                if(ch!=CR) {
        !          1043:                                        outchar(ch);
        !          1044:                                        remotebuf[remoteline][remotechar]=ch; }
        !          1045: 
        !          1046:                                if(ch==CR || (remotechar>68 && ch==' ') || ++remotechar>78) {
        !          1047: 
        !          1048:                                        remotebuf[remoteline][remotechar]=0;
        !          1049:                                        remotechar=0;
        !          1050: 
        !          1051:                                        if(sys_status&SS_SPLITP && remote_y==12) {
        !          1052:                                                CRLF;
        !          1053:                                                bprintf(local ? local_sep : sep
        !          1054:                                                        ,thisnode.misc&NODE_MSGW ? 'T':' '
        !          1055:                                                        ,sectostr(timeleft,tmp)
        !          1056:                                                        ,thisnode.misc&NODE_NMSG ? 'M':' ');
        !          1057:                                                attr(cfg.color[clr_chatremote]);
        !          1058:                                                for(i=0;i<12;i++) {
        !          1059:                                                        bprintf("\x1b[%d;1H\x1b[K",i+1);
        !          1060:                                                        if(i<=remoteline)
        !          1061:                                                                bprintf("%s\r\n",remotebuf[i]); }
        !          1062:                                                remoteline=0;
        !          1063:                                                GOTOXY(1, remote_y=6); }
        !          1064:                                        else {
        !          1065:                                                if(remoteline>=4)
        !          1066:                                                        for(i=0;i<4;i++)
        !          1067:                                                                memcpy(remotebuf[i],remotebuf[i+1],81);
        !          1068:                                                else
        !          1069:                                                        remoteline++;
        !          1070:                                                if(echo) {
        !          1071:                                                        CRLF;
        !          1072:                                        remote_y++;
        !          1073:                                                        if(sys_status&SS_SPLITP)
        !          1074:                                                                cleartoeol(); 
        !          1075:                                                } 
        !          1076:                                        } 
        !          1077:                                } 
        !          1078:                        }
        !          1079:                        ch=0;
        !          1080:                        write(in,&ch,1);
        !          1081: 
        !          1082:                        if(!(sys_status&SS_SPLITP))
        !          1083:                                localchar=remotechar;
        !          1084:                        }
        !          1085: 
        !          1086:                if(sys_status&SS_SPLITP && remote_activity) {
        !          1087:                        bputs("\1i_\1n");  /* Fake cursor */
        !          1088:                        ANSI_SAVE();
        !          1089:                        GOTOXY(x,y); 
        !          1090:                }
        !          1091: 
        !          1092:                now=time(NULL);
        !          1093:                if(!activity && now!=last_nodechk) {    /* no activity so chk node.dab */
        !          1094: 
        !          1095:                        if(!localchar) {
        !          1096:                                if(sys_status&SS_SPLITP) {
        !          1097:                                        getnodedat(cfg.node_num,&thisnode,0);
        !          1098:                                        if(thisnode.misc&NODE_INTR)
        !          1099:                                                break;
        !          1100:                                        if(thisnode.misc&NODE_UDAT && !(useron.rest&FLAG('G'))) {
        !          1101:                                                getuserdat(&cfg,&useron);
        !          1102:                                                if(getnodedat(cfg.node_num,&thisnode,true)==0) {
        !          1103:                                                        thisnode.misc&=~NODE_UDAT;
        !          1104:                                                        putnodedat(cfg.node_num,&thisnode); 
        !          1105:                                                }
        !          1106:                                        } 
        !          1107:                                }
        !          1108:                                else
        !          1109:                                        nodesync(); 
        !          1110:                        }
        !          1111: 
        !          1112:                        if(!local) {
        !          1113:                                getnodedat(n,&node,0);
        !          1114:                                if((node.action!=NODE_PCHT && node.action!=NODE_PAGE)
        !          1115:                                        || node.aux!=cfg.node_num) {
        !          1116:                                        bprintf(text[NodeLeftPrivateChat]
        !          1117:                                                ,n,node.misc&NODE_ANON ? text[UNKNOWN_USER]
        !          1118:                                                : username(&cfg,node.useron,tmp));
        !          1119:                                        break; 
        !          1120:                                }
        !          1121:                        }
        !          1122:                        getnodedat(cfg.node_num,&thisnode,0);
        !          1123:                        if(thisnode.action!=NODE_PCHT) {
        !          1124:                                action=thisnode.action;
        !          1125:                                bputs(text[EndOfChat]);
        !          1126:                                break;
        !          1127:                        }
        !          1128:                        if(thisnode.misc&NODE_RPCHT) {          /* pchat has been reset */
        !          1129:                                lseek(in,0L,SEEK_SET);                  /* so seek to beginning */
        !          1130:                                lseek(out,0L,SEEK_SET);
        !          1131:                                if(getnodedat(cfg.node_num,&thisnode,true)==0) {
        !          1132:                                        thisnode.misc&=~NODE_RPCHT;
        !          1133:                                        putnodedat(cfg.node_num,&thisnode); 
        !          1134:                                }
        !          1135:                        }
        !          1136:                        last_nodechk=now;
        !          1137:                        gettimeleft(); 
        !          1138:                }
        !          1139:        }
        !          1140:        if(sys_status&SS_SPLITP)
        !          1141:                CLS;
        !          1142:        sys_status&=~(SS_SPLITP|SS_ABORT);
        !          1143:        close(in);
        !          1144:        close(out);
        !          1145: }
        !          1146: 
        !          1147: 
        !          1148: int sbbs_t::getnodetopage(int all, int telegram)
        !          1149: {
        !          1150:        char    str[128];
        !          1151:        char    tmp[512];
        !          1152:        uint    i,j;
        !          1153:        ulong   l;
        !          1154:        node_t  node;
        !          1155: 
        !          1156:        if(!lastnodemsg)
        !          1157:                lastnodemsguser[0]=0;
        !          1158:        if(lastnodemsg) {
        !          1159:                getnodedat(lastnodemsg,&node,0);
        !          1160:                if(node.status!=NODE_INUSE && !SYSOP)
        !          1161:                        lastnodemsg=1; }
        !          1162:        for(j=0,i=1;i<=cfg.sys_nodes && i<=cfg.sys_lastnode;i++) {
        !          1163:                getnodedat(i,&node,0);
        !          1164:                if(i==cfg.node_num)
        !          1165:                        continue;
        !          1166:                if(node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET)) {
        !          1167:                        if(!lastnodemsg)
        !          1168:                                lastnodemsg=i;
        !          1169:                        j++; } }
        !          1170: 
        !          1171:        if(!lastnodemsguser[0])
        !          1172:                sprintf(lastnodemsguser,"%u",lastnodemsg);
        !          1173: 
        !          1174:        if(!j && !telegram) {
        !          1175:                bputs(text[NoOtherActiveNodes]);
        !          1176:                return(0); }
        !          1177: 
        !          1178:        if(all)
        !          1179:                sprintf(str,text[NodeToSendMsgTo],lastnodemsg);
        !          1180:        else
        !          1181:                sprintf(str,text[NodeToPrivateChat],lastnodemsg);
        !          1182:        mnemonics(str);
        !          1183: 
        !          1184:        strcpy(str,lastnodemsguser);
        !          1185:        getstr(str,LEN_ALIAS,K_UPRLWR|K_LINE|K_EDIT|K_AUTODEL);
        !          1186:        if(sys_status&SS_ABORT)
        !          1187:                return(0);
        !          1188:        if(!str[0])
        !          1189:                return(0);
        !          1190: 
        !          1191:        j=atoi(str);
        !          1192:        if(j && j<=cfg.sys_lastnode && j<=cfg.sys_nodes) {
        !          1193:                getnodedat(j,&node,0);
        !          1194:                if(node.status!=NODE_INUSE && !SYSOP) {
        !          1195:                        bprintf(text[NodeNIsNotInUse],j);
        !          1196:                        return(0); }
        !          1197:                if(telegram && node.misc&(NODE_POFF|NODE_ANON) && !SYSOP) {
        !          1198:                        bprintf(text[CantPageNode],node.misc&NODE_ANON
        !          1199:                                ? text[UNKNOWN_USER] : username(&cfg,node.useron,tmp));
        !          1200:                        return(0); }
        !          1201:                strcpy(lastnodemsguser,str);
        !          1202:                if(telegram)
        !          1203:                        return(node.useron);
        !          1204:                return(j); }
        !          1205:        if(all && !stricmp(str,"ALL"))
        !          1206:                return(-1);
        !          1207: 
        !          1208:        if(str[0]=='\'') {
        !          1209:                j=userdatdupe(0,U_HANDLE,LEN_HANDLE,str+1,0);
        !          1210:                if(!j) {
        !          1211:                        bputs(text[UnknownUser]);
        !          1212:                        return(0); } }
        !          1213:        else if(str[0]=='#')
        !          1214:                j=atoi(str+1);
        !          1215:        else
        !          1216:                j=finduser(str);
        !          1217:        if(!j)
        !          1218:                return(0);
        !          1219:        if(j>lastuser(&cfg))
        !          1220:                return(0);
        !          1221:        getuserrec(&cfg,j,U_MISC,8,tmp);
        !          1222:        l=ahtoul(tmp);
        !          1223:        if(l&(DELETED|INACTIVE)) {              /* Deleted or Inactive User */
        !          1224:                bputs(text[UnknownUser]);
        !          1225:                return(0); }
        !          1226: 
        !          1227:        for(i=1;i<=cfg.sys_nodes && i<=cfg.sys_lastnode;i++) {
        !          1228:                getnodedat(i,&node,0);
        !          1229:                if((node.status==NODE_INUSE || (SYSOP && node.status==NODE_QUIET))
        !          1230:                        && node.useron==j) {
        !          1231:                        if(telegram && node.misc&NODE_POFF && !SYSOP) {
        !          1232:                                bprintf(text[CantPageNode],node.misc&NODE_ANON
        !          1233:                                        ? text[UNKNOWN_USER] : username(&cfg,node.useron,tmp));
        !          1234:                                return(0); }
        !          1235:                        if(telegram)
        !          1236:                                return(j);
        !          1237:                        strcpy(lastnodemsguser,str);
        !          1238:                        return(i); } }
        !          1239:        if(telegram) {
        !          1240:                strcpy(lastnodemsguser,str);
        !          1241:                return(j); }
        !          1242:        bputs(text[UserNotFound]);
        !          1243:        return(0);
        !          1244: }
        !          1245: 
        !          1246: 
        !          1247: /****************************************************************************/
        !          1248: /* Sending single line messages between nodes                               */
        !          1249: /****************************************************************************/
        !          1250: void sbbs_t::nodemsg()
        !          1251: {
        !          1252:        char    str[256],line[256],buf[512],logbuf[512],ch=0;
        !          1253:        char    tmp[512];
        !          1254:        int     i,usernumber,done=0;
        !          1255:        node_t  node,savenode;
        !          1256: 
        !          1257:        if(nodemsg_inside>1)    /* nested once only */
        !          1258:                return;
        !          1259:        sys_status|=SS_IN_CTRLP;
        !          1260:        getnodedat(cfg.node_num,&savenode,0);
        !          1261:        nodemsg_inside++;
        !          1262:        wordwrap[0]=0;
        !          1263:        while(online && !done) {
        !          1264:                if(useron.rest&FLAG('C')) {
        !          1265:                        bputs(text[R_SendMessages]);
        !          1266:                        break; 
        !          1267:                }
        !          1268:                SYNC;
        !          1269:                mnemonics(text[PrivateMsgPrompt]);
        !          1270:                sys_status&=~SS_ABORT;
        !          1271:                while(online) {          /* Watch for incoming messages */
        !          1272:                        ch=toupper(inkey(K_NONE,1000));
        !          1273:                        if(ch && strchr("TMCQ\r",ch))
        !          1274:                                break;
        !          1275:                        if(sys_status&SS_ABORT)
        !          1276:                                break;
        !          1277:                        if(getnodedat(cfg.node_num,&thisnode,false)==0) {
        !          1278:                                if(thisnode.misc&(NODE_MSGW|NODE_NMSG)) {
        !          1279:                                        lncntr=0;       /* prevent pause prompt */
        !          1280:                                        SAVELINE;
        !          1281:                                        CRLF;
        !          1282:                                        if(thisnode.misc&NODE_NMSG)
        !          1283:                                                getnmsg();
        !          1284:                                        if(thisnode.misc&NODE_MSGW)
        !          1285:                                                getsmsg(useron.number);
        !          1286:                                        CRLF;
        !          1287:                                        RESTORELINE; }
        !          1288:                                else
        !          1289:                                        nodesync();
        !          1290:                        }
        !          1291:                        gettimeleft();
        !          1292:                }
        !          1293: 
        !          1294:                if(!online || sys_status&SS_ABORT) {
        !          1295:                        sys_status&=~SS_ABORT;
        !          1296:                        CRLF;
        !          1297:                        break; 
        !          1298:                }
        !          1299: 
        !          1300:                switch(toupper(ch)) {
        !          1301:                        case 'T':   /* Telegram */
        !          1302:                                bputs("Telegram\r\n");
        !          1303:                                usernumber=getnodetopage(0,1);
        !          1304:                                if(!usernumber)
        !          1305:                                        break;
        !          1306: 
        !          1307:                                if(usernumber==1 && useron.rest&FLAG('S')) { /* ! val fback */
        !          1308:                                        bprintf(text[R_Feedback],cfg.sys_op);
        !          1309:                                        break; }
        !          1310:                                if(usernumber!=1 && useron.rest&FLAG('E')) {
        !          1311:                                        bputs(text[R_Email]);
        !          1312:                                        break; }
        !          1313:                                now=time(NULL);
        !          1314:                                bprintf(text[SendingTelegramToUser]
        !          1315:                                        ,username(&cfg,usernumber,tmp),usernumber);
        !          1316:                                sprintf(buf,text[TelegramFmt]
        !          1317:                                        ,thisnode.misc&NODE_ANON ? text[UNKNOWN_USER] : useron.alias
        !          1318:                                        ,timestr(&now));
        !          1319:                                i=0;
        !          1320:                                logbuf[0]=0;
        !          1321:                                while(online && i<5) {
        !          1322:                                        bprintf("%4s",nulstr);
        !          1323:                                        if(!getstr(line,70,K_WRAP|K_MSG))
        !          1324:                                                break;
        !          1325:                                        sprintf(str,"%4s%s\r\n",nulstr,line);
        !          1326:                                        strcat(buf,str);
        !          1327:                                        if(line[0]) {
        !          1328:                                                if(i)
        !          1329:                                                        strcat(logbuf,"   ");
        !          1330:                                                strcat(logbuf,line);
        !          1331:                                        }
        !          1332:                                        i++; }
        !          1333:                                if(!i)
        !          1334:                                        break;
        !          1335:                                if(sys_status&SS_ABORT) {
        !          1336:                                        CRLF;
        !          1337:                                        break; }
        !          1338:                                putsmsg(&cfg,usernumber,buf);
        !          1339:                                sprintf(str,"%s sent telegram to %s #%u"
        !          1340:                                        ,useron.alias,username(&cfg,usernumber,tmp),usernumber);
        !          1341:                                logline("C",str);
        !          1342:                                logline(nulstr,logbuf);
        !          1343:                                bprintf(text[MsgSentToUser],"Telegram"
        !          1344:                                        ,username(&cfg,usernumber,tmp),usernumber);
        !          1345:                                break;
        !          1346:                        case 'M':   /* Message */
        !          1347:                                bputs("Message\r\n");
        !          1348:                                i=getnodetopage(1,0);
        !          1349:                                if(!i)
        !          1350:                                        break;
        !          1351:                                if(i!=-1) {
        !          1352:                                        getnodedat(i,&node,0);
        !          1353:                                        usernumber=node.useron;
        !          1354:                                        if(node.misc&NODE_POFF && !SYSOP)
        !          1355:                                                bprintf(text[CantPageNode],node.misc&NODE_ANON
        !          1356:                                                        ? text[UNKNOWN_USER] : username(&cfg,node.useron,tmp));
        !          1357:                                        else {
        !          1358:                                                bprintf(text[SendingMessageToUser]
        !          1359:                                                        ,node.misc&NODE_ANON ? text[UNKNOWN_USER]
        !          1360:                                                        : username(&cfg,node.useron,tmp)
        !          1361:                                                        ,node.misc&NODE_ANON ? 0 : node.useron);
        !          1362:                                                bputs(text[NodeMsgPrompt]);
        !          1363:                                                if(!getstr(line,69,K_LINE))
        !          1364:                                                        break;
        !          1365:                                                sprintf(buf,text[NodeMsgFmt],cfg.node_num
        !          1366:                                                        ,thisnode.misc&NODE_ANON
        !          1367:                                                                ? text[UNKNOWN_USER] : useron.alias,line);
        !          1368:                                                putnmsg(&cfg,i,buf);
        !          1369:                                                if(!(node.misc&NODE_ANON))
        !          1370:                                                        bprintf(text[MsgSentToUser],"Message"
        !          1371:                                                                ,username(&cfg,usernumber,tmp),usernumber);
        !          1372:                                                sprintf(str,"%s sent message to %s on node %d:"
        !          1373:                                                        ,useron.alias,username(&cfg,usernumber,tmp),i);
        !          1374:                                                logline("C",str);
        !          1375:                                                logline(nulstr,line); } }
        !          1376:                                else {  /* ALL */
        !          1377:                                        bputs(text[NodeMsgPrompt]);
        !          1378:                                        if(!getstr(line,70,K_LINE))
        !          1379:                                                break;
        !          1380:                                        sprintf(buf,text[AllNodeMsgFmt],cfg.node_num
        !          1381:                                                ,thisnode.misc&NODE_ANON
        !          1382:                                                        ? text[UNKNOWN_USER] : useron.alias,line);
        !          1383:                                        for(i=1;i<=cfg.sys_nodes;i++) {
        !          1384:                                                if(i==cfg.node_num)
        !          1385:                                                        continue;
        !          1386:                                                getnodedat(i,&node,0);
        !          1387:                                                if((node.status==NODE_INUSE
        !          1388:                                                        || (SYSOP && node.status==NODE_QUIET))
        !          1389:                                                        && (SYSOP || !(node.misc&NODE_POFF)))
        !          1390:                                                        putnmsg(&cfg,i,buf); }
        !          1391:                                        sprintf(str,"%s sent message to all nodes",useron.alias);
        !          1392:                                        logline("C",str);
        !          1393:                                        logline(nulstr,line); 
        !          1394:                                }
        !          1395:                                break;
        !          1396:                        case 'C':   /* Chat */
        !          1397:                                bputs("Chat\r\n");
        !          1398:                                if(action==NODE_PCHT) { /* already in pchat */
        !          1399:                                        done=1;
        !          1400:                                        break; }
        !          1401:                                privchat();
        !          1402:                                action=savenode.action;
        !          1403:                                break;
        !          1404:                        default:
        !          1405:                                bputs("Quit\r\n");
        !          1406:                                done=1;
        !          1407:                                break; } }
        !          1408:        nodemsg_inside--;
        !          1409:        if(!nodemsg_inside)
        !          1410:                sys_status&=~SS_IN_CTRLP;
        !          1411:        if(getnodedat(cfg.node_num,&thisnode,true)==0) {
        !          1412:                thisnode.action=action=savenode.action;
        !          1413:                thisnode.aux=savenode.aux;
        !          1414:                thisnode.extaux=savenode.extaux;
        !          1415:                putnodedat(cfg.node_num,&thisnode);
        !          1416:        }
        !          1417: }
        !          1418: 
        !          1419: /****************************************************************************/
        !          1420: /* The guru will respond from the 'guru' buffer to 'line'                   */
        !          1421: /****************************************************************************/
        !          1422: void sbbs_t::guruchat(char* line, char* gurubuf, int gurunum, char* last_answer)
        !          1423: {
        !          1424:        char    str[512],cstr[512],*ptr,*answer[100],theanswer[1024]
        !          1425:                        ,mistakes=1,hu=0;
        !          1426:        char    tmp[512];
        !          1427:        int             file;
        !          1428:        uint    c,i,j,k,answers;
        !          1429:        long    len;
        !          1430:        struct  tm tm;
        !          1431: 
        !          1432:        now=time(NULL);
        !          1433:        localtime_r(&now,&tm);
        !          1434: 
        !          1435:        for(i=0;i<100;i++) {
        !          1436:                if((answer[i]=(char *)malloc(512))==NULL) {
        !          1437:                        errormsg(WHERE,ERR_ALLOC,nulstr,512);
        !          1438:                        while(i) {
        !          1439:                                i--;
        !          1440:                                free(answer[i]); }
        !          1441:                        sys_status&=~SS_GURUCHAT;
        !          1442:                        return; } }
        !          1443:        ptr=gurubuf;
        !          1444:        len=strlen(gurubuf);
        !          1445:        strupr(line);
        !          1446:        j=strlen(line);
        !          1447:        k=0;
        !          1448:        for(i=0;i<j;i++) {
        !          1449:                if(!isalnum(line[i]) && !k)     /* beginning non-alphanumeric */
        !          1450:                        continue;
        !          1451:                if(!isalnum(line[i]) && line[i]==line[i+1])     /* redundant non-alnum */
        !          1452:                        continue;
        !          1453:                if(!isalnum(line[i]) && line[i+1]=='?') /* fix "WHAT ?" */
        !          1454:                        continue;
        !          1455:                cstr[k++]=line[i]; }
        !          1456:        cstr[k]=0;
        !          1457:        while(k) {
        !          1458:                k--;
        !          1459:                if(!isalnum(cstr[k]))
        !          1460:                        continue;
        !          1461:                break; }
        !          1462:        if(k<1) {
        !          1463:                for(i=0;i<100;i++)
        !          1464:                        free(answer[i]);
        !          1465:                return; }
        !          1466:        if(cstr[k+1]=='?')
        !          1467:                k++;
        !          1468:        cstr[k+1]=0;
        !          1469:        while(*ptr && ptr<gurubuf+len) {
        !          1470:                if(*ptr=='(') {
        !          1471:                        ptr++;
        !          1472:                        if(!guruexp(&ptr,cstr)) {
        !          1473:                                while(*ptr && *ptr!='(' && ptr<gurubuf+len)
        !          1474:                                        ptr++;
        !          1475:                                continue; } }
        !          1476:                else {
        !          1477:                        while(*ptr && *ptr!=LF && ptr<gurubuf+len) /* skip LF after ')' */
        !          1478:                                ptr++;
        !          1479:                        ptr++;
        !          1480:                        answers=0;
        !          1481:                        while(*ptr && answers<100 && ptr<gurubuf+len) {
        !          1482:                                i=0;
        !          1483:                                while(*ptr && *ptr!=CR && *ptr!=LF && i<511 && ptr<gurubuf+len) {
        !          1484:                                        answer[answers][i]=*ptr;
        !          1485:                                        ptr++;
        !          1486:                                        i++;
        !          1487:                                        /* multi-line answer */
        !          1488:                                        if(*ptr=='\\' && (*(ptr+1)==CR || *(ptr+1)==LF)) {
        !          1489:                                                ptr++;  /* skip \ */
        !          1490:                                                while(*ptr && *ptr<' ') ptr++;  /* skip [CR]LF */
        !          1491:                                                answer[answers][i++]=CR;
        !          1492:                                                answer[answers][i++]=LF; } }
        !          1493:                                answer[answers][i]=0;
        !          1494:                                if(!strlen(answer[answers]) || answer[answers][0]=='(') {
        !          1495:                                        ptr-=strlen(answer[answers]);
        !          1496:                                        break; }
        !          1497:                                while(*ptr && *ptr<' ') ptr++;  /* skip [CR]LF */
        !          1498:                                answers++; }
        !          1499:                        if(answers==100)
        !          1500:                                while(*ptr && *ptr!='(' && ptr<gurubuf+len)
        !          1501:                                        ptr++;
        !          1502:                        /* Try to not repeat yourself */
        !          1503:                        for(j=0;j<answers;j++) {
        !          1504:                                i=sbbs_random(answers);
        !          1505:                                if(stricmp(answer[i],last_answer))
        !          1506:                                        break;
        !          1507:                        }
        !          1508:                        strcpy(last_answer,answer[i]);
        !          1509:                        for(j=0,k=0;answer[i][j];j++) {
        !          1510:                                if(answer[i][j]=='`') {
        !          1511:                                        j++;
        !          1512:                                        theanswer[k]=0;
        !          1513:                                        switch(toupper(answer[i][j])) {
        !          1514:                                                case 'A':
        !          1515:                                                        if(sys_status&SS_USERON)
        !          1516:                                                                strcat(theanswer,useron.alias);
        !          1517:                                                        else
        !          1518:                                                                strcat(theanswer,text[UNKNOWN_USER]);
        !          1519:                                                        break;
        !          1520:                                                case 'B':
        !          1521:                                                        if(sys_status&SS_USERON)
        !          1522:                                                                strcat(theanswer,useron.birth);
        !          1523:                                                        else
        !          1524:                                                                strcat(theanswer,"00/00/00");
        !          1525:                                                        break;
        !          1526:                                                case 'C':
        !          1527:                                if(sys_status&SS_USERON)
        !          1528:                                                                strcat(theanswer,useron.comp);
        !          1529:                                                        else
        !          1530:                                                                strcat(theanswer,"PC Jr.");
        !          1531:                                                        break;
        !          1532:                                                case 'D':
        !          1533:                                if(sys_status&SS_USERON)
        !          1534:                                                                strcat(theanswer,ultoac(useron.dlb,tmp));
        !          1535:                                                        else
        !          1536:                                                                strcat(theanswer,"0");
        !          1537:                                                        break;
        !          1538:                                                case 'G':
        !          1539:                                                        strcat(theanswer,cfg.guru[gurunum]->name);
        !          1540:                                                        break;
        !          1541:                                                case 'H':
        !          1542:                                                        hu=1;
        !          1543:                                                        break;
        !          1544:                                                case 'I':
        !          1545:                                                        strcat(theanswer,cfg.sys_id);
        !          1546:                                                        break;
        !          1547:                                                case 'J':
        !          1548:                                                        sprintf(tmp,"%u",tm.tm_mday);
        !          1549:                                                        break;
        !          1550:                                                case 'L':
        !          1551:                                if(sys_status&SS_USERON)
        !          1552:                                                                strcat(theanswer,ultoa(useron.level,tmp,10));
        !          1553:                                                        else
        !          1554:                                                                strcat(theanswer,"0");
        !          1555:                                                        break;
        !          1556:                                                case 'M':
        !          1557:                                                        strcat(theanswer,month[tm.tm_mon]);
        !          1558:                                                        break;
        !          1559:                                                case 'N':   /* Note */
        !          1560:                                if(sys_status&SS_USERON)
        !          1561:                                                                strcat(theanswer,useron.note);
        !          1562:                                                        else
        !          1563:                                                                strcat(theanswer,text[UNKNOWN_USER]);
        !          1564:                                                        break;
        !          1565:                                                case 'O':
        !          1566:                                                        strcat(theanswer,cfg.sys_op);
        !          1567:                                                        break;
        !          1568:                                                case 'P':
        !          1569:                                if(sys_status&SS_USERON)
        !          1570:                                                                strcat(theanswer,useron.phone);
        !          1571:                                                        else
        !          1572:                                                                strcat(theanswer,"000-000-0000");
        !          1573:                                                        break;
        !          1574:                                                case 'Q':
        !          1575:                                                                sys_status&=~SS_GURUCHAT;
        !          1576:                                                        break;
        !          1577:                                                case 'R':
        !          1578:                                if(sys_status&SS_USERON)
        !          1579:                                                                strcat(theanswer,useron.name);
        !          1580:                                                        else
        !          1581:                                                                strcat(theanswer,text[UNKNOWN_USER]);
        !          1582:                                                        break;
        !          1583:                                                case 'S':
        !          1584:                                                        strcat(theanswer,cfg.sys_name);
        !          1585:                                                        break;
        !          1586:                                                case 'T':
        !          1587:                                                        sprintf(tmp,"%u:%02u",tm.tm_hour>12 ? tm.tm_hour-12
        !          1588:                                                                : tm.tm_hour,tm.tm_min);
        !          1589:                                                        strcat(theanswer,tmp);
        !          1590:                                                        break;
        !          1591:                                                case 'U':
        !          1592:                                if(sys_status&SS_USERON)
        !          1593:                                                                strcat(theanswer,ultoac(useron.ulb,tmp));
        !          1594:                                                        else
        !          1595:                                                                strcat(theanswer,"0");
        !          1596:                                                        break;
        !          1597:                                                case 'W':
        !          1598:                                                        strcat(theanswer,weekday[tm.tm_wday]);
        !          1599:                                                        break;
        !          1600:                                                case 'Y':   /* Current year */
        !          1601:                                                        sprintf(tmp,"%u",1900+tm.tm_year);
        !          1602:                                                        strcat(theanswer,tmp);
        !          1603:                                                        break;
        !          1604:                                                case 'Z':
        !          1605:                                                        if(sys_status&SS_USERON)
        !          1606:                                                                strcat(theanswer,useron.zipcode);
        !          1607:                                                        else
        !          1608:                                                                strcat(theanswer,"90210");
        !          1609:                                                        break;
        !          1610:                                                case '$':   /* Credits */
        !          1611:                                if(sys_status&SS_USERON)
        !          1612:                                                                strcat(theanswer,ultoac(useron.cdt,tmp));
        !          1613:                                                        else
        !          1614:                                                                strcat(theanswer,"0");
        !          1615:                                                        break;
        !          1616:                                                case '#':
        !          1617:                                if(sys_status&SS_USERON)
        !          1618:                                                                strcat(theanswer,ultoa(getage(&cfg,useron.birth)
        !          1619:                                                                        ,tmp,10));
        !          1620:                                                        else
        !          1621:                                                                strcat(theanswer,"0");
        !          1622:                                                        break;
        !          1623:                                                case '!':
        !          1624:                                                        mistakes=!mistakes;
        !          1625:                                                        break;
        !          1626:                                                case '_':
        !          1627:                                                        mswait(500);
        !          1628:                                                        break; }
        !          1629:                                        k=strlen(theanswer); }
        !          1630:                                else
        !          1631:                                        theanswer[k++]=answer[i][j]; }
        !          1632:                        theanswer[k]=0;
        !          1633:                        mswait(500+sbbs_random(1000));   /* thinking time */
        !          1634:                        if(action!=NODE_MCHT) {
        !          1635:                                for(i=0;i<k;i++) {
        !          1636:                                        if(mistakes && theanswer[i]!=theanswer[i-1] &&
        !          1637:                                                ((!isalnum(theanswer[i]) && !sbbs_random(100))
        !          1638:                                                || (isalnum(theanswer[i]) && !sbbs_random(30)))) {
        !          1639:                                                c=j=((uint)sbbs_random(3)+1);   /* 1 to 3 chars */
        !          1640:                                                if(c<strcspn(theanswer+(i+1),"\0., "))
        !          1641:                                                        c=j=1;
        !          1642:                                                while(j) {
        !          1643:                                                        outchar(97+sbbs_random(26));
        !          1644:                                                        mswait(25+sbbs_random(150));
        !          1645:                                                        j--; }
        !          1646:                                                if(sbbs_random(100)) {
        !          1647:                                                        mswait(100+sbbs_random(300));
        !          1648:                                                        while(c) {
        !          1649:                                                                backspace();
        !          1650:                                                                mswait(50+sbbs_random(50));
        !          1651:                                                                c--; } } }
        !          1652:                                        outchar(theanswer[i]);
        !          1653:                                        if(theanswer[i]==theanswer[i+1])
        !          1654:                                                mswait(25+sbbs_random(50));
        !          1655:                                        else
        !          1656:                                                mswait(25+sbbs_random(150));
        !          1657:                                        if(theanswer[i]==' ')
        !          1658:                                                mswait(sbbs_random(50)); 
        !          1659:                                        } }
        !          1660:                        else {
        !          1661:                                mswait(strlen(theanswer)*100);
        !          1662:                                bprintf(text[ChatLineFmt],cfg.guru[gurunum]->name
        !          1663:                                        ,cfg.sys_nodes+1,':',theanswer); }
        !          1664:                        CRLF;
        !          1665:                        sprintf(str,"%sguru.log",cfg.logs_dir);
        !          1666:                        if((file=nopen(str,O_WRONLY|O_CREAT|O_APPEND))==-1)
        !          1667:                                errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_APPEND);
        !          1668:                        else {
        !          1669:                                if(action==NODE_MCHT) {
        !          1670:                                        sprintf(str,"[Multi] ");
        !          1671:                                        write(file,str,strlen(str)); }
        !          1672:                                sprintf(str,"%s:\r\n",sys_status&SS_USERON
        !          1673:                                        ? useron.alias : "UNKNOWN");
        !          1674:                                write(file,str,strlen(str));
        !          1675:                                write(file,line,strlen(line));
        !          1676:                                if(action!=NODE_MCHT)
        !          1677:                                        write(file,crlf,2);
        !          1678:                                sprintf(str,"%s:\r\n",cfg.guru[gurunum]->name);
        !          1679:                                write(file,str,strlen(str));
        !          1680:                                write(file,theanswer,strlen(theanswer));
        !          1681:                                write(file,crlf,2);
        !          1682:                                close(file); }
        !          1683:                        if(hu)
        !          1684:                                hangup();
        !          1685:                        break; } }
        !          1686:        for(i=0;i<100;i++)
        !          1687:                free(answer[i]);
        !          1688: }
        !          1689: 
        !          1690: /****************************************************************************/
        !          1691: /* An expression from the guru's buffer 'ptrptr' is evaluated and true or   */
        !          1692: /* false is returned.                                                       */
        !          1693: /****************************************************************************/
        !          1694: bool sbbs_t::guruexp(char **ptrptr, char *line)
        !          1695: {
        !          1696:        char    c,*cp,str[256];
        !          1697:        int             nest;
        !          1698:        bool    result=false,_and=false,_or=false;
        !          1699:        uchar   *ar;
        !          1700: 
        !          1701:        if((**ptrptr)==')') {   /* expressions of () are always result */
        !          1702:                (*ptrptr)++;
        !          1703:                return(true); }
        !          1704:        while((**ptrptr)!=')' && (**ptrptr)) {
        !          1705:                if((**ptrptr)=='[') {
        !          1706:                        (*ptrptr)++;
        !          1707:                        SAFECOPY(str,*ptrptr);
        !          1708:                        while(**ptrptr && (**ptrptr)!=']')
        !          1709:                                (*ptrptr)++;
        !          1710:                        (*ptrptr)++;
        !          1711:                        cp=strchr(str,']');
        !          1712:                        if(cp) *cp=0;
        !          1713:                        ar=arstr(NULL,str,&cfg);
        !          1714:                        c=chk_ar(ar,&useron);
        !          1715:                        if(ar[0]!=AR_NULL)
        !          1716:                                free(ar);
        !          1717:                        if(!c && _and) {
        !          1718:                                result=false;
        !          1719:                                break; }
        !          1720:                        if(c && _or) {
        !          1721:                                result=true;
        !          1722:                                break; }
        !          1723:                        if(c)
        !          1724:                                result=true;
        !          1725:                        continue; }
        !          1726:                if((**ptrptr)=='(') {
        !          1727:                        (*ptrptr)++;
        !          1728:                        c=guruexp(&(*ptrptr),line);
        !          1729:                        if(!c && _and) {
        !          1730:                                result=false;
        !          1731:                                break; }
        !          1732:                        if(c && _or) {
        !          1733:                                result=true;
        !          1734:                                break; }
        !          1735:                        if(c)
        !          1736:                                result=true; }
        !          1737:                if((**ptrptr)==')')
        !          1738:                        break;
        !          1739:                c=0;
        !          1740:                while((**ptrptr) && isspace(**ptrptr))
        !          1741:                        (*ptrptr)++;
        !          1742:                while((**ptrptr)!='|' && (**ptrptr)!='&' && (**ptrptr)!=')' &&(**ptrptr)) {
        !          1743:                        str[c++]=(**ptrptr);
        !          1744:                        (*ptrptr)++; }
        !          1745:                str[c]=0;
        !          1746:                if((**ptrptr)=='|') {
        !          1747:                        if(!c && result)
        !          1748:                                break;
        !          1749:                        _and=false;
        !          1750:                        _or=true; }
        !          1751:                else if((**ptrptr)=='&') {
        !          1752:                        if(!c && !result)
        !          1753:                                break;
        !          1754:                        _and=true;
        !          1755:                        _or=false; }
        !          1756:                if(!c) {                                /* support ((exp)op(exp)) */
        !          1757:                        (*ptrptr)++;
        !          1758:                        continue; }
        !          1759:                if((**ptrptr)!=')')
        !          1760:                        (*ptrptr)++;
        !          1761:                c=0;                                    /* c now used for start line flag */
        !          1762:                if(str[strlen(str)-1]=='^') {   /* ^signifies start of line only */
        !          1763:                        str[strlen(str)-1]=0;
        !          1764:                        c=true; }
        !          1765:                if(str[strlen(str)-1]=='~') {   /* ~signifies non-isolated word */
        !          1766:                        str[strlen(str)-1]=0;
        !          1767:                        cp=strstr(line,str);
        !          1768:                        if(c && cp!=line)
        !          1769:                                cp=0; }
        !          1770:                else {
        !          1771:                        cp=strstr(line,str);
        !          1772:                        if(cp && c) {
        !          1773:                                if(cp!=line || isalnum(*(cp+strlen(str))))
        !          1774:                                        cp=0; }
        !          1775:                        else {  /* must be isolated word */
        !          1776:                                while(cp)
        !          1777:                                        if((cp!=line && isalnum(*(cp-1)))
        !          1778:                                                || isalnum(*(cp+strlen(str))))
        !          1779:                                                cp=strstr(cp+strlen(str),str);
        !          1780:                                        else
        !          1781:                                                break; } }
        !          1782:                if(!cp && _and) {
        !          1783:                        result=false;
        !          1784:                        break; }
        !          1785:                if(cp && _or) {
        !          1786:                        result=true;
        !          1787:                        break; }
        !          1788:                if(cp)
        !          1789:                        result=true; }
        !          1790:        nest=0;
        !          1791:        while((**ptrptr)!=')' && (**ptrptr)) {          /* handle nested exp */
        !          1792:                if((**ptrptr)=='(')                                             /* (TRUE|(IGNORE)) */
        !          1793:                        nest++;
        !          1794:                (*ptrptr)++;
        !          1795:                while((**ptrptr)==')' && nest && (**ptrptr)) {
        !          1796:                        nest--;
        !          1797:                        (*ptrptr)++; } }
        !          1798:        (*ptrptr)++;    /* skip over ')' */
        !          1799:        return(result);
        !          1800: }
        !          1801: 
        !          1802: /****************************************************************************/
        !          1803: /* Guru chat with the appearance of Local chat with sysop.                  */
        !          1804: /****************************************************************************/
        !          1805: void sbbs_t::localguru(char *gurubuf, int gurunum)
        !          1806: {
        !          1807:        char    ch,str[256];
        !          1808:        int     con=console;             /* save console state */
        !          1809:        char    lastanswer[512];
        !          1810: 
        !          1811:        if(sys_status&SS_GURUCHAT || !cfg.total_gurus)
        !          1812:                return;
        !          1813:        sys_status|=SS_GURUCHAT;
        !          1814:        console&=~(CON_L_ECHOX|CON_R_ECHOX);    /* turn off X's */
        !          1815:        console|=(CON_L_ECHO|CON_R_ECHO);                                       /* make sure echo is on */
        !          1816:        if(action==NODE_CHAT) { /* only page if from chat section */
        !          1817:                bprintf(text[PagingGuru],cfg.guru[gurunum]->name);
        !          1818:                ch=sbbs_random(25)+25;
        !          1819:                while(ch--) {
        !          1820:                        mswait(200);
        !          1821:                        outchar('.'); } }
        !          1822:        bprintf(text[SysopIsHere],cfg.guru[gurunum]->name);
        !          1823:        if(getnodedat(cfg.node_num,&thisnode,true)==0) {
        !          1824:                thisnode.aux=gurunum;
        !          1825:                putnodedat(cfg.node_num,&thisnode);
        !          1826:        }
        !          1827:        attr(cfg.color[clr_chatlocal]);
        !          1828:        strcpy(str,"HELLO");
        !          1829:        guruchat(str,gurubuf,gurunum,lastanswer);
        !          1830:        str[0]=0;
        !          1831:        while(online && (sys_status&SS_GURUCHAT)) {
        !          1832:                checkline();
        !          1833:                action=NODE_GCHT;
        !          1834:                SYNC;
        !          1835:                if(wordwrap[0]==0) {
        !          1836:                        if((ch=inkey(K_NONE,1000))==0) {
        !          1837:                                if(str[0]) {
        !          1838:                                        attr(cfg.color[clr_chatlocal]);
        !          1839:                                        guruchat(str,gurubuf,gurunum,lastanswer); 
        !          1840:                                        str[0]=0;
        !          1841:                                }
        !          1842:                                continue;
        !          1843:                        }
        !          1844:                        ungetkey(ch);
        !          1845:                }
        !          1846:                attr(cfg.color[clr_chatremote]);
        !          1847:                getstr(str,78,K_WRAP|K_CHAT);
        !          1848:        }
        !          1849:        bputs(text[EndOfChat]);
        !          1850:        sys_status&=~SS_GURUCHAT;
        !          1851:        console=con;                            /* restore console state */
        !          1852: }
        !          1853: 
        !          1854: 

unix.superglobalmegacorp.com

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