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

unix.superglobalmegacorp.com

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