Annotation of sbbs/sbbs3/chat.cpp, revision 1.1.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.