Annotation of sbbs/sbbs3/writemsg.cpp, revision 1.1

1.1     ! root        1: /* writemsg.cpp */
        !             2: 
        !             3: /* Synchronet message creation routines */
        !             4: 
        !             5: /* $Id: writemsg.cpp,v 1.7 2000/12/31 03:41:55 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 MAX_LINE_LEN 82L
        !            41: 
        !            42: const char *qstr=" > %.76s\r\n";
        !            43: void quotestr(char *str);
        !            44: 
        !            45: /****************************************************************************/
        !            46: /* Creates a message (post or mail) using standard line editor. 'fname' is  */
        !            47: /* is name of file to create, 'top' is a buffer to place at beginning of    */
        !            48: /* message and 'title' is the title (70chars max) for the message.          */
        !            49: /* 'dest' contains a text description of where the message is going.        */
        !            50: /****************************************************************************/
        !            51: bool sbbs_t::writemsg(char *fname, char *top, char *title, long mode, int subnum
        !            52:        ,char *dest)
        !            53: {
        !            54:        char    str[256],quote[128],msgtmp[32],c,HUGE16 *buf,ex_mode=0,*p,*tp
        !            55:                                ,useron_level;
        !            56:        char    tmp[512];
        !            57:        int             i,j,file,linesquoted=0;
        !            58:        long    length,qlen,qtime;
        !            59:        ulong   l;
        !            60:        FILE *  stream;
        !            61: 
        !            62:        useron_level=useron.level;
        !            63: 
        !            64:        if((buf=(char HUGE16*)LMALLOC(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN))
        !            65:                ==NULL) {
        !            66:                errormsg(WHERE,ERR_ALLOC,fname
        !            67:                        ,cfg.level_linespermsg[useron_level]*MAX_LINE_LEN);
        !            68:                return(false); }
        !            69: 
        !            70:        if(mode&WM_NETMAIL ||
        !            71:                (!(mode&(WM_EMAIL|WM_NETMAIL)) && cfg.sub[subnum]->misc&SUB_PNET))
        !            72:                mode|=WM_NOTOP;
        !            73: 
        !            74:        if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&QUICKBBS)
        !            75:                strcpy(msgtmp,"MSGTMP");
        !            76:        else
        !            77:                strcpy(msgtmp,"INPUT.MSG");
        !            78: 
        !            79:        if(mode&WM_QUOTE && !(useron.rest&FLAG('J'))
        !            80:                && ((mode&(WM_EMAIL|WM_NETMAIL) && cfg.sys_misc&SM_QUOTE_EM)
        !            81:                || (!(mode&(WM_EMAIL|WM_NETMAIL)) && (uint)subnum!=INVALID_SUB
        !            82:                        && cfg.sub[subnum]->misc&SUB_QUOTE))) {
        !            83: 
        !            84:                /* Quote entire message to MSGTMP or INPUT.MSG */
        !            85: 
        !            86:                if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&QUOTEALL) {
        !            87:                        sprintf(str,"%sQUOTES.TXT",cfg.node_dir);
        !            88:                        if((stream=fnopen(NULL,str,O_RDONLY))==NULL) {
        !            89:                                errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
        !            90:                                LFREE(buf);
        !            91:                                return(false); 
        !            92:                        }
        !            93: 
        !            94:                        sprintf(str,"%s%s",cfg.node_dir,msgtmp);    /* file for quoted msg */
        !            95:                        if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !            96:                                errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
        !            97:                                LFREE(buf);
        !            98:                                fclose(stream);
        !            99:                                return(false); 
        !           100:                        }
        !           101: 
        !           102:                        while(!feof(stream) && !ferror(stream)) {
        !           103:                                if(!fgets(str,255,stream))
        !           104:                                        break;
        !           105:                                quotestr(str);
        !           106:                                sprintf(tmp,qstr,str);
        !           107:                                write(file,tmp,strlen(tmp));
        !           108:                                linesquoted++; 
        !           109:                        }
        !           110:                        fclose(stream);
        !           111:                        close(file); 
        !           112:                }
        !           113: 
        !           114:                /* Quote nothing to MSGTMP or INPUT.MSG automatically */
        !           115: 
        !           116:                else if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&QUOTENONE)
        !           117:                        ;
        !           118: 
        !           119:                else if(yesno(text[QuoteMessageQ])) {
        !           120:                        sprintf(str,"%sQUOTES.TXT",cfg.node_dir);
        !           121:                        if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
        !           122:                                errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
        !           123:                                LFREE(buf);
        !           124:                                return(false); }
        !           125: 
        !           126:                        sprintf(str,"%s%s",cfg.node_dir,msgtmp);    /* file for quoted msg */
        !           127:                        if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !           128:                                errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
        !           129:                                LFREE(buf);
        !           130:                                fclose(stream);
        !           131:                                return(false); }
        !           132: 
        !           133:                        l=ftell(stream);                        /* l now points to start of message */
        !           134: 
        !           135:                        while(online) {
        !           136:                                sprintf(str,text[QuoteLinesPrompt],linesquoted ? "Done":"All");
        !           137:                                mnemonics(str);
        !           138:                                i=getstr(quote,10,K_UPPER);
        !           139:                                if(sys_status&SS_ABORT) {
        !           140:                                        fclose(stream);
        !           141:                                        close(file);
        !           142:                                        LFREE(buf);
        !           143:                                        return(false); }
        !           144:                                if(!i && linesquoted)
        !           145:                                        break;
        !           146:                                if(!i || quote[0]=='A') {                   /* Quote all */
        !           147:                                        fseek(stream,l,SEEK_SET);
        !           148:                                        while(!feof(stream) && !ferror(stream)) {
        !           149:                                                if(!fgets(str,255,stream))
        !           150:                                                        break;
        !           151:                                                quotestr(str);
        !           152:                                                sprintf(tmp,qstr,str);
        !           153:                                                write(file,tmp,strlen(tmp));
        !           154:                                                linesquoted++; }
        !           155:                                        break; }
        !           156:                                if(quote[0]=='L') {
        !           157:                                        fseek(stream,l,SEEK_SET);
        !           158:                                        i=1;
        !           159:                                        CRLF;
        !           160:                                        attr(LIGHTGRAY);
        !           161:                                        while(!feof(stream) && !ferror(stream) && !msgabort()) {
        !           162:                                                if(!fgets(str,255,stream))
        !           163:                                                        break;
        !           164:                                                quotestr(str);
        !           165:                                                bprintf("%3d: %.74s\r\n",i,str);
        !           166:                                                i++; }
        !           167:                                        continue; }
        !           168: 
        !           169:                                if(!isdigit(quote[0]))
        !           170:                                        break;
        !           171:                                p=quote;
        !           172:                                while(p) {
        !           173:                                        if(*p==',' || *p==SP)
        !           174:                                                p++;
        !           175:                                        i=atoi(p);
        !           176:                                        if(!i)
        !           177:                                                break;
        !           178:                                        fseek(stream,l,SEEK_SET);
        !           179:                                        j=1;
        !           180:                                        while(!feof(stream) && !ferror(stream) && j<i) {
        !           181:                                                if(!fgets(tmp,255,stream))
        !           182:                                                        break;
        !           183:                                                j++; }          /* skip beginning */
        !           184:                                        tp=strchr(p,'-');   /* tp for temp pointer */
        !           185:                                        if(tp) {                 /* range */
        !           186:                                                i=atoi(tp+1);
        !           187:                                                while(!feof(stream) && !ferror(stream) && j<=i) {
        !           188:                                                        if(!fgets(str,255,stream))
        !           189:                                                                break;
        !           190:                                                        quotestr(str);
        !           191:                                                        sprintf(tmp,qstr,str);
        !           192:                                                        write(file,tmp,strlen(tmp));
        !           193:                                                        linesquoted++;
        !           194:                                                        j++; } }
        !           195:                                        else {                  /* one line */
        !           196:                                                if(fgets(str,255,stream)) {
        !           197:                                                        quotestr(str);
        !           198:                                                        sprintf(tmp,qstr,str);
        !           199:                                                        write(file,tmp,strlen(tmp));
        !           200:                                                        linesquoted++; } }
        !           201:                                        p=strchr(p,',');
        !           202:                                        // if(!p) p=strchr(p,SP);  02/05/96 huh?
        !           203:                                        } }
        !           204: 
        !           205:                        fclose(stream);
        !           206:                        close(file); } }
        !           207:        else {
        !           208:                sprintf(str,"%sQUOTES.TXT",cfg.node_dir);
        !           209:                remove(str); }
        !           210: 
        !           211:        if(!online || sys_status&SS_ABORT) {
        !           212:                LFREE(buf);
        !           213:                return(false); }
        !           214: 
        !           215:        if(!(mode&WM_EXTDESC)) {
        !           216:                if(mode&WM_FILE) {
        !           217:                        c=12;
        !           218:                        CRLF;
        !           219:                        bputs(text[Filename]); }
        !           220:                else {
        !           221:                        c=LEN_TITLE;
        !           222:                        bputs(text[TitlePrompt]); }
        !           223:                if(!(mode&(WM_EMAIL|WM_NETMAIL)) && !(mode&WM_FILE)
        !           224:                        && cfg.sub[subnum]->misc&(SUB_QNET /* |SUB_PNET */ ))
        !           225:                        c=25;
        !           226:                if(mode&WM_QWKNET)
        !           227:                        c=25;
        !           228:                if(!getstr(title,c,mode&WM_FILE ? K_LINE|K_UPPER : K_LINE|K_EDIT|K_AUTODEL)
        !           229:                        && useron_level && useron.logons) {
        !           230:                        LFREE(buf);
        !           231:                        return(false); }
        !           232:                if(!(mode&(WM_EMAIL|WM_NETMAIL)) && cfg.sub[subnum]->misc&SUB_QNET
        !           233:                        && !SYSOP
        !           234:                        && (!stricmp(title,"DROP") || !stricmp(title,"ADD")
        !           235:                        || !strnicmp(dest,"SBBS",4))) {
        !           236:                        LFREE(buf);   /* Users can't post DROP or ADD in QWK netted subs */
        !           237:                        return(false); } }      /* or messages to "SBBS" */
        !           238: 
        !           239:        if(!online || sys_status&SS_ABORT) {
        !           240:                LFREE(buf);
        !           241:                return(false); }
        !           242: 
        !           243:        /* Create WWIV compatible EDITOR.INF file */
        !           244: 
        !           245:        if(useron.xedit) {
        !           246:                editor_inf(useron.xedit,dest,title,mode,subnum);
        !           247:                if(cfg.xedit[useron.xedit-1]->type) {
        !           248:                        gettimeleft();
        !           249:                        xtrndat(useron.alias,cfg.node_dir,cfg.xedit[useron.xedit-1]->type
        !           250:                           ,timeleft,cfg.xedit[useron.xedit-1]->misc); }
        !           251:                }
        !           252: 
        !           253:        if(console&CON_RAW_IN) {
        !           254:                bprintf(text[EnterMsgNowRaw]
        !           255:                        ,(ulong)cfg.level_linespermsg[useron_level]*MAX_LINE_LEN);
        !           256:                if(top[0] && !(mode&WM_NOTOP)) {
        !           257:                        strcpy((char *)buf,top);
        !           258:                        strcat((char *)buf,crlf);
        !           259:                        l=strlen((char *)buf); }
        !           260:                else
        !           261:                        l=0;
        !           262:                while(l<(ulong)(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)) {
        !           263:                        c=getkey(0);
        !           264:                        if(sys_status&SS_ABORT) {  /* Ctrl-C */
        !           265:                                LFREE(buf);
        !           266:                                return(false); }
        !           267:                        if((c==ESC || c==1) && useron.rest&FLAG('A')) /* ANSI restriction */
        !           268:                                continue;
        !           269:                        if(c==BEL && useron.rest&FLAG('B'))   /* Beep restriction */
        !           270:                                continue;
        !           271:                        if(!(console&CON_RAW_IN))       /* Ctrl-Z was hit */
        !           272:                                break;
        !           273:                        outchar(c);
        !           274:                        buf[l++]=c; }
        !           275:                buf[l]=0;
        !           276:                if(l==(ulong)cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)
        !           277:                        bputs(text[OutOfBytes]); }
        !           278: 
        !           279: 
        !           280:        else if((online==ON_LOCAL && cfg.node_misc&NM_LCL_EDIT && cfg.node_editor[0])
        !           281:                || useron.xedit) {
        !           282: 
        !           283:                if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&IO_INTS) {
        !           284:                        ex_mode|=EX_OUTL;
        !           285:                        if(online==ON_REMOTE)
        !           286:                                ex_mode|=(EX_OUTR|EX_INR);
        !           287:                        if(cfg.xedit[useron.xedit-1]->misc&WWIVCOLOR)
        !           288:                                ex_mode|=EX_WWIV; }
        !           289: 
        !           290:                sprintf(str,"%s%s",cfg.node_dir,msgtmp);    /* temporary file for input */
        !           291:                if(!linesquoted && fexist(str))
        !           292:                        remove(str);
        !           293:                if(linesquoted) {
        !           294:                        qlen=flength(str);
        !           295:                        qtime=fdate(str); }
        !           296:                if(online==ON_LOCAL) {
        !           297:                        if(cfg.node_misc&NM_LCL_EDIT && cfg.node_editor[0])
        !           298:                                external(cmdstr(cfg.node_editor,str,nulstr,NULL)
        !           299:                                        ,0,cfg.node_dir); 
        !           300:                        else
        !           301:                                external(cmdstr(cfg.xedit[useron.xedit-1]->lcmd,str,nulstr,NULL)
        !           302:                                        ,ex_mode,cfg.node_dir); }
        !           303: 
        !           304:                else {
        !           305:                        rioctl(IOCM|PAUSE|ABORT);
        !           306:                        external(cmdstr(cfg.xedit[useron.xedit-1]->rcmd,str,nulstr,NULL),ex_mode,cfg.node_dir);
        !           307:                        rioctl(IOSM|PAUSE|ABORT); }
        !           308:                checkline();
        !           309:                if(!fexist(str) || !online
        !           310:                        || (linesquoted && qlen==flength(str) && qtime==fdate(str))) {
        !           311:                        LFREE(buf);
        !           312:                        return(false); }
        !           313:                buf[0]=0;
        !           314:                if(!(mode&WM_NOTOP))
        !           315:                        strcpy((char *)buf,top);
        !           316:                if((file=nopen(str,O_RDONLY))==-1) {
        !           317:                        errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
        !           318:                        LFREE(buf);
        !           319:                        return(false); }
        !           320:                length=filelength(file);
        !           321:                l=strlen((char *)buf);    /* reserve space for top and terminating null */
        !           322:                /* truncate if too big */
        !           323:                if(length>(long)((cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-(l+1))) {
        !           324:                        length=(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-(l+1);
        !           325:                        bputs(text[OutOfBytes]); }
        !           326:                lread(file,buf+l,length);
        !           327:                close(file);
        !           328:                // remove(str);            /* no need to save the temp input file */
        !           329:                buf[l+length]=0; }
        !           330:        else {
        !           331:                buf[0]=0;
        !           332:                if(linesquoted) {
        !           333:                        sprintf(str,"%s%s",cfg.node_dir,msgtmp);
        !           334:                        if((file=nopen(str,O_RDONLY))!=-1) {
        !           335:                                length=filelength(file);
        !           336:                                l=length>cfg.level_linespermsg[useron_level]*MAX_LINE_LEN
        !           337:                                        ? cfg.level_linespermsg[useron_level]*MAX_LINE_LEN : length;
        !           338:                                lread(file,buf,l);
        !           339:                                buf[l]=0;
        !           340:                                close(file);
        !           341:                                // remove(str);
        !           342:                                } }
        !           343:                if(!(msgeditor((char *)buf,mode&WM_NOTOP ? nulstr : top,title))) {
        !           344:                        LFREE(buf);
        !           345:                        return(false); } }
        !           346: 
        !           347:        now=time(NULL);
        !           348:        bputs(text[Saving]);
        !           349:        if((stream=fnopen(&file,fname,O_WRONLY|O_CREAT|O_TRUNC))==NULL) {
        !           350:                errormsg(WHERE,ERR_OPEN,fname,O_WRONLY|O_CREAT|O_TRUNC);
        !           351:                LFREE(buf);
        !           352:                return(false); }
        !           353:        for(l=i=0;buf[l] && i<cfg.level_linespermsg[useron_level];l++) {
        !           354:                if((uchar)buf[l]==141 && useron.xedit
        !           355:                && cfg.xedit[useron.xedit-1]->misc&QUICKBBS) {
        !           356:                        fwrite(crlf,2,1,stream);
        !           357:                        i++;
        !           358:                        continue; }
        !           359:                if(buf[l]==LF && (!l || buf[l-1]!=CR) && useron.xedit
        !           360:                        && cfg.xedit[useron.xedit-1]->misc&EXPANDLF) {
        !           361:                        fwrite(crlf,2,1,stream);
        !           362:                        i++;
        !           363:                        continue; }
        !           364:                if(!(mode&(WM_EMAIL|WM_NETMAIL))
        !           365:                        && (!l || buf[l-1]==LF)
        !           366:                        && buf[l]=='-' && buf[l+1]=='-' && buf[l+2]=='-'
        !           367:                        && (buf[l+3]==SP || buf[l+3]==TAB || buf[l+3]==CR))
        !           368:                        buf[l+1]='+';
        !           369:                if(buf[l]==LF)
        !           370:                        i++;
        !           371:                fputc(buf[l],stream); }
        !           372: 
        !           373:        if(buf[l])
        !           374:                bputs(text[NoMoreLines]);
        !           375:        fclose(stream);
        !           376:        LFREE((char *)buf);
        !           377:        bprintf(text[SavedNBytes],l,i);
        !           378:        return(true);
        !           379: }
        !           380: 
        !           381: void remove_re(char *str)
        !           382: {
        !           383:        while(!strnicmp(str,"RE:",3)) {
        !           384:                strcpy(str,str+3);
        !           385:                while(str[0]==SP)
        !           386:                        strcpy(str,str+1); }
        !           387: }
        !           388: 
        !           389: /****************************************************************************/
        !           390: /* Modify 'str' to for quoted format. Remove ^A codes, etc.                 */
        !           391: /****************************************************************************/
        !           392: void quotestr(char *str)
        !           393: {
        !           394:        int j;
        !           395: 
        !           396:        j=strlen(str);
        !           397:        while(j && (str[j-1]==SP || str[j-1]==LF || str[j-1]==CR)) j--;
        !           398:        str[j]=0;
        !           399:        remove_ctrl_a(str);
        !           400: }
        !           401: 
        !           402: void sbbs_t::editor_inf(int xeditnum,char *dest, char *title, long mode
        !           403:        ,uint subnum)
        !           404: {
        !           405:        char str[512];
        !           406:        int file;
        !           407: 
        !           408:        xeditnum--;
        !           409: 
        !           410:        if(cfg.xedit[xeditnum]->misc&QUICKBBS) {
        !           411:                sprintf(str,"%sMSGINF",cfg.node_dir);
        !           412:                if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !           413:                        errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
        !           414:                        return; }
        !           415:                sprintf(str,"%s\r\n%s\r\n%s\r\n%u\r\n%s\r\n%s\r\n"
        !           416:                        ,(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME) ? useron.name
        !           417:                                : useron.alias
        !           418:                                ,dest,title,1
        !           419:                                ,mode&WM_NETMAIL ? "NetMail"
        !           420:                                :mode&WM_EMAIL ? "Electronic Mail"
        !           421:                                :subnum==INVALID_SUB ? nulstr
        !           422:                                :cfg.sub[subnum]->sname
        !           423:                        ,mode&WM_PRIVATE ? "YES":"NO");
        !           424:                write(file,str,strlen(str));
        !           425:                close(file); }
        !           426:        else {
        !           427:                sprintf(str,"%sEDITOR.INF",cfg.node_dir);
        !           428:                if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !           429:                        errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
        !           430:                        return; }
        !           431:                sprintf(str,"%s\r\n%s\r\n%u\r\n%s\r\n%s\r\n%u\r\n"
        !           432:                        ,title,dest,useron.number
        !           433:                        ,(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME) ? useron.name
        !           434:                        : useron.alias
        !           435:                        ,useron.name,useron.level);
        !           436:                write(file,str,strlen(str));
        !           437:                close(file); }
        !           438: }
        !           439: 
        !           440: 
        !           441: 
        !           442: /****************************************************************************/
        !           443: /* Removes from file 'str' every LF terminated line that starts with 'str2' */
        !           444: /* That is divisable by num. Function skips first 'skip' number of lines    */
        !           445: /****************************************************************************/
        !           446: void sbbs_t::removeline(char *str, char *str2, char num, char skip)
        !           447: {
        !           448:        char    HUGE16 *buf;
        !           449:     char    slen;
        !           450:     int     i,file;
        !           451:        long    l=0,flen;
        !           452:     FILE    *stream;
        !           453: 
        !           454:        if((file=nopen(str,O_RDONLY))==-1) {
        !           455:                errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
        !           456:                return; }
        !           457:        flen=filelength(file);
        !           458:        slen=strlen(str2);
        !           459:        if((buf=(char *)MALLOC(flen))==NULL) {
        !           460:                close(file);
        !           461:                errormsg(WHERE,ERR_ALLOC,str,flen);
        !           462:                return; }
        !           463:        if(lread(file,buf,flen)!=flen) {
        !           464:                close(file);
        !           465:                errormsg(WHERE,ERR_READ,str,flen);
        !           466:                FREE(buf);
        !           467:                return; }
        !           468:        close(file);
        !           469:        if((stream=fnopen(&file,str,O_WRONLY|O_TRUNC))==NULL) {
        !           470:                close(file);
        !           471:                errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_TRUNC);
        !           472:                FREE(buf);
        !           473:                return; }
        !           474:        for(i=0;l<flen && i<skip;l++) {
        !           475:                fputc(buf[l],stream);
        !           476:                if(buf[l]==LF)
        !           477:                        i++; }
        !           478:        while(l<flen) {
        !           479:                if(!strncmp((char *)buf+l,str2,slen)) {
        !           480:                        for(i=0;i<num && l<flen;i++) {
        !           481:                                while(l<flen && buf[l]!=LF) l++;
        !           482:                                l++; } }
        !           483:                else {
        !           484:                        for(i=0;i<num && l<flen;i++) {
        !           485:                                while(l<flen && buf[l]!=LF) fputc(buf[l++],stream);
        !           486:                                fputc(buf[l++],stream); } } }
        !           487:        fclose(stream);
        !           488:        FREE((char *)buf);
        !           489: }
        !           490: 
        !           491: /*****************************************************************************/
        !           492: /* The Synchronet editor.                                                    */
        !           493: /* Returns the number of lines edited.                                       */
        !           494: /*****************************************************************************/
        !           495: ulong sbbs_t::msgeditor(char *buf, char *top, char *title)
        !           496: {
        !           497:        int             i,j,line,lines=0,maxlines;
        !           498:        char    strin[256],**str,done=0;
        !           499:        char    tmp[512];
        !           500:     ulong      l,m;
        !           501: 
        !           502:        if(online==ON_REMOTE) {
        !           503:                rioctl(IOCM|ABORT);
        !           504:                rioctl(IOCS|ABORT); }
        !           505: 
        !           506:        maxlines=cfg.level_linespermsg[useron.level];
        !           507: 
        !           508:        if((str=(char **)MALLOC(sizeof(char *)*(maxlines+1)))==NULL) {
        !           509:                errormsg(WHERE,ERR_ALLOC,"msgeditor",sizeof(char *)*(maxlines+1));
        !           510:                return(0); }
        !           511:        m=strlen(buf);
        !           512:        l=0;
        !           513:        while(l<m && lines<maxlines) {
        !           514:                msgabort(); /* to allow pausing */
        !           515:                if((str[lines]=(char *)MALLOC(MAX_LINE_LEN))==NULL) {
        !           516:                        errormsg(WHERE,ERR_ALLOC,nulstr,MAX_LINE_LEN);
        !           517:                        for(i=0;i<lines;i++)
        !           518:                                FREE(str[lines]);
        !           519:                        FREE(str);
        !           520:                        if(online==ON_REMOTE)
        !           521:                                rioctl(IOSM|ABORT);
        !           522:                        return(0); }
        !           523:                for(i=0;i<79 && l<m;i++,l++) {
        !           524:                        if(buf[l]==CR) {
        !           525:                                l+=2;
        !           526:                                break; }
        !           527:                        if(buf[l]==TAB) {
        !           528:                                if(!(i%8))                  /* hard-coded tabstop of 8 */
        !           529:                                        str[lines][i++]=SP;     /* for expansion */
        !           530:                                while(i%8 && i<79)
        !           531:                                        str[lines][i++]=SP;
        !           532:                                i--;
        !           533:                                /***
        !           534:                                bprintf("\r\nMessage editor: Expanded tab on line #%d",lines+1);
        !           535:                                ***/ }
        !           536:                        else str[lines][i]=buf[l]; }
        !           537:                if(i==79) {
        !           538:                        if(buf[l]==CR)
        !           539:                                l+=2;
        !           540:                        else
        !           541:                                bprintf("\r\nMessage editor: Split line #%d",lines+1); }
        !           542:                str[lines][i]=0;
        !           543:                lines++; }
        !           544:        if(lines)
        !           545:                bprintf("\r\nMessage editor: Read in %d lines\r\n",lines);
        !           546:        bprintf(text[EnterMsgNow],maxlines);
        !           547:        for(i=0;i<79;i++)
        !           548:                if(i%TABSIZE || !i)
        !           549:                        outchar('-');
        !           550:                else outchar('+');
        !           551:        CRLF;
        !           552:        putmsg(top,P_SAVEATR|P_NOATCODES);
        !           553:        for(line=0;line<lines && !msgabort();line++) { /* display lines in buf */
        !           554:                putmsg(str[line],P_SAVEATR|P_NOATCODES);
        !           555:                if(useron.misc&ANSI)
        !           556:                        bputs("\x1b[K");  /* delete to end of line */
        !           557:                CRLF; }
        !           558:        SYNC;
        !           559:        if(online==ON_REMOTE)
        !           560:                rioctl(IOSM|ABORT);
        !           561:        while(online && !done) {
        !           562:                checkline();
        !           563:                if(line==lines) {
        !           564:                        if((str[line]=(char *)MALLOC(MAX_LINE_LEN))==NULL) {
        !           565:                                errormsg(WHERE,ERR_ALLOC,nulstr,MAX_LINE_LEN);
        !           566:                                for(i=0;i<lines;i++)
        !           567:                                        FREE(str[i]);
        !           568:                                FREE(str);
        !           569:                                return(0); }
        !           570:                        str[line][0]=0; }
        !           571:                if(line>(maxlines-10)) {
        !           572:                        if(line==maxlines)
        !           573:                                bputs(text[NoMoreLines]);
        !           574:                        else
        !           575:                                bprintf(text[OnlyNLinesLeft],maxlines-line); }
        !           576:                strcpy(strin,str[line]);
        !           577:                do {
        !           578:                        if(!line)
        !           579:                                outchar(CR);
        !           580:                        getstr(strin,79,K_WRAP|K_MSG|K_EDIT);
        !           581:                        } while(console&CON_UPARROW && !line);
        !           582: 
        !           583:                if(sys_status&SS_ABORT) {
        !           584:                        if(line==lines)
        !           585:                                FREE(str[line]);
        !           586:                        continue; }
        !           587:                if(strin[0]=='/' && strlen(strin)<8) {
        !           588:                        if(!stricmp(strin,"/DEBUG") && SYSOP) {
        !           589:                                if(line==lines)
        !           590:                                        FREE(str[line]);
        !           591:                                bprintf("\r\nline=%d lines=%d rows=%d\r\n",line,lines,rows);
        !           592:                                continue; }
        !           593:                        else if(!stricmp(strin,"/ABT")) {
        !           594:                                if(line==lines)                 /* delete a line */
        !           595:                                        FREE(str[line]);
        !           596:                                for(i=0;i<lines;i++)
        !           597:                                        FREE(str[i]);
        !           598:                                FREE(str);
        !           599:                                return(0); }
        !           600:                        else if(toupper(strin[1])=='D') {
        !           601:                                if(line==lines)         /* delete a line */
        !           602:                                        FREE(str[line]);
        !           603:                                if(!lines)
        !           604:                                        continue;
        !           605:                                i=atoi(strin+2)-1;
        !           606:                                if(i==-1)   /* /D means delete last line */
        !           607:                                        i=lines-1;
        !           608:                                if(i>=lines || i<0)
        !           609:                                        bputs(text[InvalidLineNumber]);
        !           610:                                else {
        !           611:                                        FREE(str[i]);
        !           612:                                        lines--;
        !           613:                                        while(i<lines) {
        !           614:                                                str[i]=str[i+1];
        !           615:                                                i++; }
        !           616:                                        if(line>lines)
        !           617:                                                line=lines; }
        !           618:                                continue; }
        !           619:                        else if(toupper(strin[1])=='I') {
        !           620:                                if(line==lines)         /* insert a line before number x */
        !           621:                                        FREE(str[line]);
        !           622:                                if(line==maxlines || !lines)
        !           623:                                        continue;
        !           624:                                i=atoi(strin+2)-1;
        !           625:                                if(i==-1)
        !           626:                                        i=lines-1;
        !           627:                                if(i>=lines || i<0)
        !           628:                                        bputs(text[InvalidLineNumber]);
        !           629:                                else {
        !           630:                                        for(line=lines;line>i;line--)   /* move the pointers */
        !           631:                                                str[line]=str[line-1];
        !           632:                                        if((str[i]=(char *)MALLOC(MAX_LINE_LEN))==NULL) {
        !           633:                                                errormsg(WHERE,ERR_ALLOC,nulstr,MAX_LINE_LEN);
        !           634:                                                for(i=0;i<lines;i++)
        !           635:                                                        FREE(str[i]);
        !           636:                                                FREE(str);
        !           637:                                                return(0); }
        !           638:                                        str[i][0]=0;
        !           639:                                        line=++lines; }
        !           640:                                continue; }
        !           641:                        else if(toupper(strin[1])=='E') {
        !           642:                                if(line==lines)         /* edit a line */
        !           643:                                        FREE(str[line]);
        !           644:                                if(!lines)
        !           645:                                        continue;
        !           646:                                i=atoi(strin+2)-1;
        !           647:                                j=K_MSG|K_EDIT; /* use j for the getstr mode */
        !           648:                                if(i==-1) { /* /E means edit last line */
        !           649:                                        i=lines-1;
        !           650:                                        j|=K_WRAP; }    /* wrap when editing last line */
        !           651:                                if(i>=lines || i<0)
        !           652:                                        bputs(text[InvalidLineNumber]);
        !           653:                                else
        !           654:                                        getstr(str[i],79,j);
        !           655:                                continue; }
        !           656:                        else if(!stricmp(strin,"/CLR")) {
        !           657:                                bputs(text[MsgCleared]);
        !           658:                                if(line!=lines)
        !           659:                                        lines--;
        !           660:                                for(i=0;i<=lines;i++)
        !           661:                                        FREE(str[i]);
        !           662:                                line=0;
        !           663:                                lines=0;
        !           664:                                putmsg(top,P_SAVEATR|P_NOATCODES);
        !           665:                                continue; }
        !           666:                        else if(toupper(strin[1])=='L') {   /* list message */
        !           667:                                if(line==lines)
        !           668:                                        FREE(str[line]);
        !           669:                                if(lines)
        !           670:                                        i=!noyes(text[WithLineNumbersQ]);
        !           671:                                CRLF;
        !           672:                                attr(LIGHTGRAY);
        !           673:                                putmsg(top,P_SAVEATR|P_NOATCODES);
        !           674:                                if(!lines) {
        !           675:                                        continue; }
        !           676:                                j=atoi(strin+2);
        !           677:                                if(j) j--;  /* start from line j */
        !           678:                                while(j<lines && !msgabort()) {
        !           679:                                        if(i) { /* line numbers */
        !           680:                                                sprintf(tmp,"%3d: %-.74s",j+1,str[j]);
        !           681:                                                putmsg(tmp,P_SAVEATR|P_NOATCODES); }
        !           682:                                        else
        !           683:                                                putmsg(str[j],P_SAVEATR|P_NOATCODES);
        !           684:                                        if(useron.misc&ANSI)
        !           685:                                                bputs("\x1b[K");  /* delete to end of line */
        !           686:                                        CRLF;
        !           687:                                        j++; }
        !           688:                                SYNC;
        !           689:                                continue; }
        !           690:                        else if(!stricmp(strin,"/S")) { /* Save */
        !           691:                                if(line==lines)
        !           692:                                        FREE(str[line]);
        !           693:                                done=1;
        !           694:                                continue;}
        !           695:                        else if(!stricmp(strin,"/T")) { /* Edit title */
        !           696:                                if(line==lines)
        !           697:                                        FREE(str[line]);
        !           698:                                if(title[0]) {
        !           699:                                        bputs(text[TitlePrompt]);
        !           700:                                        getstr(title,LEN_TITLE,K_LINE|K_EDIT|K_AUTODEL);
        !           701:                                        SYNC;
        !           702:                                        CRLF; }
        !           703:                                continue; }
        !           704:                        else if(!stricmp(strin,"/?")) {
        !           705:                                if(line==lines)
        !           706:                                        FREE(str[line]);
        !           707:                                menu("editor"); /* User Editor Commands */
        !           708:                                SYNC;
        !           709:                                continue; }
        !           710:                        else if(!stricmp(strin,"/ATTR"))    {
        !           711:                                if(line==lines)
        !           712:                                        FREE(str[line]);
        !           713:                                menu("attr");   /* User ANSI Commands */
        !           714:                                SYNC;
        !           715:                                continue; } }
        !           716:                strcpy(str[line],strin);
        !           717:                if(line<maxlines)
        !           718:                        line++;
        !           719:                else
        !           720:                        FREE(str[line]);
        !           721:                if(line>lines)
        !           722:                        lines++;
        !           723:                if(console&CON_UPARROW) {
        !           724:                        outchar(CR);
        !           725:                        bprintf("\x1b[A\x1b[K");    /* up one line, clear to eol */
        !           726:                        line-=2; }
        !           727:                }
        !           728:        if(!online) {
        !           729:                for(i=0;i<lines;i++)
        !           730:                        FREE(str[i]);
        !           731:                FREE(str);
        !           732:                return(0); }
        !           733:        strcpy(buf,top);
        !           734:        for(i=0;i<lines;i++) {
        !           735:                strcat(buf,str[i]);
        !           736:                strcat(buf,crlf);
        !           737:                FREE(str[i]); }
        !           738:        FREE(str);
        !           739:        return(lines);
        !           740: }
        !           741: 
        !           742: 
        !           743: /****************************************************************************/
        !           744: /* Edits an existing file or creates a new one in MSG format                */
        !           745: /****************************************************************************/
        !           746: void sbbs_t::editfile(char *str)
        !           747: {
        !           748:        char *buf,str2[128],mode=0;   /* EX_CC */
        !           749:     int file;
        !           750:        long length,maxlines,lines,l;
        !           751: 
        !           752:        maxlines=cfg.level_linespermsg[useron.level];
        !           753:        sprintf(str2,"%sQUOTES.TXT",cfg.node_dir);
        !           754:        remove(str2);
        !           755:        if(cfg.node_editor[0] && online==ON_LOCAL) {
        !           756:                external(cmdstr(cfg.node_editor,str,nulstr,NULL),0,cfg.node_dir);
        !           757:                return; }
        !           758:        if(useron.xedit) {
        !           759:                editor_inf(useron.xedit,nulstr,nulstr,0,INVALID_SUB);
        !           760:                if(cfg.xedit[useron.xedit-1]->misc&IO_INTS) {
        !           761:                        mode|=EX_OUTL;
        !           762:                        if(online==ON_REMOTE)
        !           763:                                mode|=(EX_OUTR|EX_INR);
        !           764:                        if(cfg.xedit[useron.xedit-1]->misc&WWIVCOLOR)
        !           765:                                mode|=EX_WWIV; }
        !           766:                if(online==ON_LOCAL)
        !           767:                        external(cmdstr(cfg.xedit[useron.xedit-1]->lcmd,str,nulstr,NULL),mode,cfg.node_dir);
        !           768:                else {
        !           769:                        rioctl(IOCM|PAUSE|ABORT);
        !           770:                        external(cmdstr(cfg.xedit[useron.xedit-1]->rcmd,str,nulstr,NULL),mode,cfg.node_dir);
        !           771:                        rioctl(IOSM|PAUSE|ABORT); }
        !           772:                return; }
        !           773:        if((buf=(char *)MALLOC(maxlines*MAX_LINE_LEN))==NULL) {
        !           774:                errormsg(WHERE,ERR_ALLOC,nulstr,maxlines*MAX_LINE_LEN);
        !           775:                return; }
        !           776:        if((file=nopen(str,O_RDONLY))!=-1) {
        !           777:                length=filelength(file);
        !           778:                if(length>(long)maxlines*MAX_LINE_LEN) {
        !           779:                        attr(cfg.color[clr_err]);
        !           780:                        bprintf("\7\r\nFile size (%lu bytes) is larger than (%lu).\r\n"
        !           781:                                ,length,(ulong)maxlines*MAX_LINE_LEN);
        !           782:                        close(file);
        !           783:                        FREE(buf); }
        !           784:                if(read(file,buf,length)!=length) {
        !           785:                        close(file);
        !           786:                        FREE(buf);
        !           787:                        errormsg(WHERE,ERR_READ,str,length);
        !           788:                        return; }
        !           789:                buf[length]=0;
        !           790:                close(file); }
        !           791:        else {
        !           792:                buf[0]=0;
        !           793:                bputs(text[NewFile]); }
        !           794:        if(!msgeditor(buf,nulstr,nulstr)) {
        !           795:                FREE(buf);
        !           796:                return; }
        !           797:        bputs(text[Saving]);
        !           798:        if((file=nopen(str,O_CREAT|O_WRONLY|O_TRUNC))==-1) {
        !           799:                errormsg(WHERE,ERR_OPEN,str,O_CREAT|O_WRONLY|O_TRUNC);
        !           800:                FREE(buf);
        !           801:                return; }
        !           802:        if((size_t)write(file,buf,strlen(buf))!=strlen(buf)) {
        !           803:                close(file);
        !           804:                errormsg(WHERE,ERR_WRITE,str,strlen(buf));
        !           805:                FREE(buf);
        !           806:                return; }
        !           807:        for(l=lines=0;buf[l];l++)
        !           808:                if(buf[l]==LF)
        !           809:                        lines++;
        !           810:        bprintf(text[SavedNBytes],l,lines);
        !           811:        close(file);
        !           812:        FREE(buf);
        !           813:        return;
        !           814: }
        !           815: 
        !           816: /*************************/
        !           817: /* Copy file attachments */
        !           818: /*************************/
        !           819: void sbbs_t::copyfattach(uint to, uint from, char *title)
        !           820: {
        !           821:        char str[128],str2[128],str3[128],*tp,*sp,*p;
        !           822: 
        !           823:        strcpy(str,title);
        !           824:        tp=str;
        !           825:        while(1) {
        !           826:                p=strchr(tp,SP);
        !           827:                if(p) *p=0;
        !           828:                sp=strrchr(tp,'/');              /* sp is slash pointer */
        !           829:                if(!sp) sp=strrchr(tp,'\\');
        !           830:                if(sp) tp=sp+1;
        !           831:                sprintf(str2,"%sfile/%04u.in/%s"  /* str2 is path/fname */
        !           832:                        ,cfg.data_dir,to,tp);
        !           833:                sprintf(str3,"%sfile/%04u.in/%s"  /* str2 is path/fname */
        !           834:                        ,cfg.data_dir,from,tp);
        !           835:                if(strcmp(str2,str3))
        !           836:                        mv(str3,str2,1);
        !           837:                if(!p)
        !           838:                        break;
        !           839:                tp=p+1; }
        !           840: }
        !           841: 
        !           842: 
        !           843: /****************************************************************************/
        !           844: /* Forwards mail (fname) to usernumber                                      */
        !           845: /* Called from function readmail                                                                                       */
        !           846: /****************************************************************************/
        !           847: void sbbs_t::forwardmail(smbmsg_t *msg, int usernumber)
        !           848: {
        !           849:        char            str[256],touser[128];
        !           850:        char            tmp[512];
        !           851:        int                     i;
        !           852:        node_t          node;
        !           853:        msghdr_t        hdr=msg->hdr;
        !           854:        idxrec_t        idx=msg->idx;
        !           855: 
        !           856:        if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) {
        !           857:                bputs(text[TooManyEmailsToday]);
        !           858:                return; }
        !           859:        if(useron.rest&FLAG('F')) {
        !           860:                bputs(text[R_Forward]);
        !           861:                return; }
        !           862:        if(usernumber==1 && useron.rest&FLAG('S')) {
        !           863:                bprintf(text[R_Feedback],cfg.sys_op);
        !           864:                return; }
        !           865:        if(usernumber!=1 && useron.rest&FLAG('E')) {
        !           866:                bputs(text[R_Email]);
        !           867:                return; }
        !           868: 
        !           869:        msg->idx.attr&=~(MSG_READ|MSG_DELETE);
        !           870:        msg->hdr.attr=msg->idx.attr;
        !           871: 
        !           872: 
        !           873:        smb_hfield(msg,SENDER,strlen(useron.alias),useron.alias);
        !           874:        sprintf(str,"%u",useron.number);
        !           875:        smb_hfield(msg,SENDEREXT,strlen(str),str);
        !           876: 
        !           877:        username(&cfg,usernumber,touser);
        !           878:        smb_hfield(msg,RECIPIENT,strlen(touser),touser);
        !           879:        sprintf(str,"%u",usernumber);
        !           880:        smb_hfield(msg,RECIPIENTEXT,sizeof(str),str);
        !           881:        msg->idx.to=usernumber;
        !           882: 
        !           883:        now=time(NULL);
        !           884:        smb_hfield(msg,FORWARDED,sizeof(time_t),&now);
        !           885: 
        !           886: 
        !           887:        if((i=smb_open_da(&smb))!=0) {
        !           888:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
        !           889:                return; }
        !           890:        if((i=smb_incdat(&smb,msg->hdr.offset,smb_getmsgdatlen(msg),1))!=0) {
        !           891:                errormsg(WHERE,ERR_WRITE,smb.file,i);
        !           892:                return; }
        !           893:        smb_close_da(&smb);
        !           894: 
        !           895: 
        !           896:        if((i=smb_addmsghdr(&smb,msg,SMB_SELFPACK))!=0) {
        !           897:                errormsg(WHERE,ERR_WRITE,smb.file,i);
        !           898:                return; }
        !           899: 
        !           900:        if(msg->hdr.auxattr&MSG_FILEATTACH)
        !           901:                copyfattach(usernumber,useron.number,msg->subj);
        !           902: 
        !           903:        bprintf(text[Forwarded],username(&cfg,usernumber,str),usernumber);
        !           904:        sprintf(str,"Forwarded mail to %s #%d",username(&cfg,usernumber,tmp)
        !           905:                ,usernumber);
        !           906:        logline("E",str);
        !           907:        msg->idx=idx;
        !           908:        msg->hdr=hdr;
        !           909: 
        !           910: 
        !           911:        if(usernumber==1) {
        !           912:                useron.fbacks++;
        !           913:                logon_fbacks++;
        !           914:                putuserrec(&cfg,useron.number,U_FBACKS,5,ultoa(useron.fbacks,tmp,10)); }
        !           915:        else {
        !           916:                useron.emails++;
        !           917:                logon_emails++;
        !           918:                putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); }
        !           919:        useron.etoday++;
        !           920:        putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10));
        !           921: 
        !           922:        for(i=1;i<=cfg.sys_nodes;i++) { /* Tell user, if online */
        !           923:                getnodedat(i,&node,0);
        !           924:                if(node.useron==usernumber && !(node.misc&NODE_POFF)
        !           925:                        && (node.status==NODE_INUSE || node.status==NODE_QUIET)) {
        !           926:                        sprintf(str,text[EmailNodeMsg],cfg.node_num,useron.alias);
        !           927:                        putnmsg(i,str);
        !           928:                        break; } }
        !           929:        if(i>cfg.sys_nodes) {   /* User wasn't online, so leave short msg */
        !           930:                sprintf(str,text[UserSentYouMail],useron.alias);
        !           931:                putsmsg(&cfg,usernumber,str); }
        !           932: }
        !           933: 
        !           934: /****************************************************************************/
        !           935: /* Auto-Message Routine ('A' from the main menu)                            */
        !           936: /****************************************************************************/
        !           937: void sbbs_t::automsg()
        !           938: {
        !           939:     char       str[256],buf[300],anon=0;
        !           940:        char    tmp[512];
        !           941:        char    automsg[MAX_PATH];
        !           942:     int                file;
        !           943: 
        !           944:        sprintf(automsg,"%smsgs/auto.msg",cfg.data_dir);
        !           945:        while(online) {
        !           946:                SYNC;
        !           947:                mnemonics(text[AutoMsg]);
        !           948:                switch(getkeys("RWQ",0)) {
        !           949:                        case 'R':
        !           950:                                printfile(automsg,P_NOABORT|P_NOATCODES);
        !           951:                                break;
        !           952:                        case 'W':
        !           953:                                if(useron.rest&FLAG('W')) {
        !           954:                                        bputs(text[R_AutoMsg]);
        !           955:                                        break; }
        !           956:                                action=NODE_AMSG;
        !           957:                                SYNC;
        !           958:                                bputs("\r\n3 lines:\r\n");
        !           959:                                if(!getstr(str,68,K_WRAP|K_MSG))
        !           960:                                        break;
        !           961:                                strcpy(buf,str);
        !           962:                                strcat(buf,"\r\n          ");
        !           963:                                getstr(str,68,K_WRAP|K_MSG);
        !           964:                                strcat(buf,str);
        !           965:                                strcat(buf,"\r\n          ");
        !           966:                                getstr(str,68,K_MSG);
        !           967:                                strcat(str,crlf);
        !           968:                                strcat(buf,str);
        !           969:                                if(yesno(text[OK])) {
        !           970:                                        if(useron.exempt&FLAG('A')) {
        !           971:                                                if(!noyes(text[AnonymousQ]))
        !           972:                                                        anon=1; }
        !           973:                                        if((file=nopen(automsg,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !           974:                                                errormsg(WHERE,ERR_OPEN,automsg,O_WRONLY|O_CREAT|O_TRUNC);
        !           975:                                                return; }
        !           976:                                        if(anon)
        !           977:                                                sprintf(tmp,"%.80s",text[Anonymous]);
        !           978:                                        else
        !           979:                                                sprintf(tmp,"%s #%d",useron.alias,useron.number);
        !           980:                                        sprintf(str,text[AutoMsgBy],tmp);
        !           981:                                        strcat(str,"          ");
        !           982:                                        write(file,str,strlen(str));
        !           983:                                        write(file,buf,strlen(buf));
        !           984:                                        close(file); }
        !           985:                                break;
        !           986:                        case 'Q':
        !           987:                                return; } }
        !           988: }
        !           989: 
        !           990: /****************************************************************************/
        !           991: /* Edits messages                                                                                                                      */
        !           992: /****************************************************************************/
        !           993: void sbbs_t::editmsg(smbmsg_t *msg, uint subnum)
        !           994: {
        !           995:        char    str[256],buf[SDT_BLOCK_LEN];
        !           996:        ushort  xlat;
        !           997:        int     file,i,j,x;
        !           998:        ulong   length,offset;
        !           999:        FILE    *instream;
        !          1000: 
        !          1001:        if(!msg->hdr.total_dfields)
        !          1002:                return;
        !          1003:        sprintf(str,"%sINPUT.MSG",cfg.node_dir);
        !          1004:        remove(str);
        !          1005:        msgtotxt(msg,str,0,1);
        !          1006:        editfile(str);
        !          1007:        length=flength(str)+2;   /* +2 for translation string */
        !          1008:        if(length<1L)
        !          1009:                return;
        !          1010: 
        !          1011:        if((i=smb_locksmbhdr(&smb))!=0) {
        !          1012:                errormsg(WHERE,ERR_LOCK,smb.file,i);
        !          1013:                return; }
        !          1014: 
        !          1015:        if((i=smb_getstatus(&smb))!=0) {
        !          1016:                errormsg(WHERE,ERR_READ,smb.file,i);
        !          1017:                return; }
        !          1018: 
        !          1019:        if(!(smb.status.attr&SMB_HYPERALLOC)) {
        !          1020:                if((i=smb_open_da(&smb))!=0) {
        !          1021:                        errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
        !          1022:                        return; }
        !          1023:                for(x=0;x<msg->hdr.total_dfields;x++)
        !          1024:                        if((i=smb_freemsgdat(&smb,msg->hdr.offset+msg->dfield[x].offset
        !          1025:                                ,msg->dfield[x].length,1))!=0)
        !          1026:                                errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); }
        !          1027: 
        !          1028:        msg->dfield[0].type=TEXT_BODY;                          /* Make one single data field */
        !          1029:        msg->dfield[0].length=length;
        !          1030:        msg->dfield[0].offset=0;
        !          1031:        for(x=1;x<msg->hdr.total_dfields;x++) {         /* Clear the other data fields */
        !          1032:                msg->dfield[x].type=UNUSED;                     /* so we leave the header length */
        !          1033:                msg->dfield[x].length=0;                                /* unchanged */
        !          1034:                msg->dfield[x].offset=0; }
        !          1035: 
        !          1036: 
        !          1037:        if(smb.status.attr&SMB_HYPERALLOC) {
        !          1038:                offset=smb_hallocdat(&smb); }
        !          1039:        else {
        !          1040:                if((subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_FAST)
        !          1041:                        || (subnum==INVALID_SUB && cfg.sys_misc&SM_FASTMAIL))
        !          1042:                        offset=smb_fallocdat(&smb,length,1);
        !          1043:                else
        !          1044:                        offset=smb_allocdat(&smb,length,1);
        !          1045:                smb_close_da(&smb); }
        !          1046: 
        !          1047:        msg->hdr.offset=offset;
        !          1048:        if((file=open(str,O_RDONLY|O_BINARY))==-1
        !          1049:                || (instream=fdopen(file,"rb"))==NULL) {
        !          1050:                smb_unlocksmbhdr(&smb);
        !          1051:                smb_freemsgdat(&smb,offset,length,1);
        !          1052:                errormsg(WHERE,ERR_OPEN,str,O_RDONLY|O_BINARY);
        !          1053:                return; }
        !          1054: 
        !          1055:        setvbuf(instream,NULL,_IOFBF,2*1024);
        !          1056:        fseek(smb.sdt_fp,offset,SEEK_SET);
        !          1057:        xlat=XLAT_NONE;
        !          1058:        fwrite(&xlat,2,1,smb.sdt_fp);
        !          1059:        x=SDT_BLOCK_LEN-2;                              /* Don't read/write more than 255 */
        !          1060:        while(!feof(instream)) {
        !          1061:                memset(buf,0,x);
        !          1062:                j=fread(buf,1,x,instream);
        !          1063:                if((j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR)
        !          1064:                        buf[j-1]=buf[j-2]=0;    /* Convert to NULL */
        !          1065:                fwrite(buf,j,1,smb.sdt_fp);
        !          1066:                x=SDT_BLOCK_LEN; }
        !          1067:        fflush(smb.sdt_fp);
        !          1068:        fclose(instream);
        !          1069: 
        !          1070:        smb_unlocksmbhdr(&smb);
        !          1071:        msg->hdr.length=smb_getmsghdrlen(msg);
        !          1072:        if((i=smb_putmsghdr(&smb,msg))!=0)
        !          1073:                errormsg(WHERE,ERR_WRITE,smb.file,i);
        !          1074: }
        !          1075: 
        !          1076: /****************************************************************************/
        !          1077: /* Moves a message from one message base to another                                            */
        !          1078: /****************************************************************************/
        !          1079: bool sbbs_t::movemsg(smbmsg_t* msg, uint subnum)
        !          1080: {
        !          1081:        char str[256],*buf;
        !          1082:        uint i;
        !          1083:        int file,newgrp,newsub,storage;
        !          1084:        ulong offset,length;
        !          1085: 
        !          1086:        for(i=0;i<usrgrps;i++)           /* Select New Group */
        !          1087:                uselect(1,i,"Message Group",cfg.grp[usrgrp[i]]->lname,0);
        !          1088:        if((newgrp=uselect(0,0,0,0,0))<0)
        !          1089:                return(false);
        !          1090: 
        !          1091:        for(i=0;i<usrsubs[newgrp];i++)           /* Select New Sub-Board */
        !          1092:                uselect(1,i,"Sub-Board",cfg.sub[usrsub[newgrp][i]]->lname,0);
        !          1093:        if((newsub=uselect(0,0,0,0,0))<0)
        !          1094:                return(false);
        !          1095:        newsub=usrsub[newgrp][newsub];
        !          1096: 
        !          1097:        length=smb_getmsgdatlen(msg);
        !          1098:        if((buf=(char *)MALLOC(length))==NULL) {
        !          1099:                errormsg(WHERE,ERR_ALLOC,smb.file,length);
        !          1100:                return(false); }
        !          1101: 
        !          1102:        fseek(smb.sdt_fp,msg->hdr.offset,SEEK_SET);
        !          1103:        fread(buf,length,1,smb.sdt_fp);
        !          1104: 
        !          1105:        if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) {
        !          1106:                FREE(buf);
        !          1107:                errormsg(WHERE,ERR_OPEN,cfg.sub[newsub]->code,i);
        !          1108:                return(false); }
        !          1109: 
        !          1110:        sprintf(smb.file,"%s%s",cfg.sub[newsub]->data_dir,cfg.sub[newsub]->code);
        !          1111:        smb.retry_time=cfg.smb_retry_time;
        !          1112:        if((i=smb_open(&smb))!=0) {
        !          1113:                FREE(buf);
        !          1114:                smb_stack(&smb,SMB_STACK_POP);
        !          1115:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
        !          1116:                return(false); }
        !          1117: 
        !          1118:        if(filelength(fileno(smb.shd_fp))<1) {   /* Create it if it doesn't exist */
        !          1119:                smb.status.max_crcs=cfg.sub[newsub]->maxcrcs;
        !          1120:                smb.status.max_msgs=cfg.sub[newsub]->maxmsgs;
        !          1121:                smb.status.max_age=cfg.sub[newsub]->maxage;
        !          1122:                smb.status.attr=cfg.sub[newsub]->misc&SUB_HYPER ? SMB_HYPERALLOC :0;
        !          1123:                if((i=smb_create(&smb))!=0) {
        !          1124:                        FREE(buf);
        !          1125:                        smb_close(&smb);
        !          1126:                        smb_stack(&smb,SMB_STACK_POP);
        !          1127:                        errormsg(WHERE,ERR_CREATE,smb.file,i);
        !          1128:                        return(false); } }
        !          1129: 
        !          1130:        if((i=smb_locksmbhdr(&smb))!=0) {
        !          1131:                FREE(buf);
        !          1132:                smb_close(&smb);
        !          1133:                smb_stack(&smb,SMB_STACK_POP);
        !          1134:                errormsg(WHERE,ERR_LOCK,smb.file,i);
        !          1135:                return(false); }
        !          1136: 
        !          1137:        if((i=smb_getstatus(&smb))!=0) {
        !          1138:                FREE(buf);
        !          1139:                smb_close(&smb);
        !          1140:                smb_stack(&smb,SMB_STACK_POP);
        !          1141:                errormsg(WHERE,ERR_READ,smb.file,i);
        !          1142:                return(false); }
        !          1143: 
        !          1144:        if(smb.status.attr&SMB_HYPERALLOC) {
        !          1145:                offset=smb_hallocdat(&smb);
        !          1146:                storage=SMB_HYPERALLOC; }
        !          1147:        else {
        !          1148:                if((i=smb_open_da(&smb))!=0) {
        !          1149:                        FREE(buf);
        !          1150:                        smb_close(&smb);
        !          1151:                        smb_stack(&smb,SMB_STACK_POP);
        !          1152:                        errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
        !          1153:                        return(false); }
        !          1154:                if(cfg.sub[newsub]->misc&SUB_FAST) {
        !          1155:                        offset=smb_fallocdat(&smb,length,1);
        !          1156:                        storage=SMB_FASTALLOC; }
        !          1157:                else {
        !          1158:                        offset=smb_allocdat(&smb,length,1);
        !          1159:                        storage=SMB_SELFPACK; }
        !          1160:                smb_close_da(&smb); }
        !          1161: 
        !          1162:        msg->hdr.offset=offset;
        !          1163: 
        !          1164:        memcpy(msg->hdr.id,"SHD\x1a",4);
        !          1165:        msg->hdr.version=smb_ver();
        !          1166: 
        !          1167:        smb_unlocksmbhdr(&smb);
        !          1168: 
        !          1169:        fseek(smb.sdt_fp,offset,SEEK_SET);
        !          1170:        fwrite(buf,length,1,smb.sdt_fp);
        !          1171:        fflush(smb.sdt_fp);
        !          1172:        FREE(buf);
        !          1173: 
        !          1174:        i=smb_addmsghdr(&smb,msg,storage);
        !          1175:        smb_close(&smb);
        !          1176:        smb_stack(&smb,SMB_STACK_POP);
        !          1177: 
        !          1178:        if(i) {
        !          1179:                smb_freemsgdat(&smb,offset,length,1);
        !          1180:                errormsg(WHERE,ERR_WRITE,smb.file,i);
        !          1181:                return(false); }
        !          1182: 
        !          1183:        bprintf("\r\nMoved to %s %s\r\n\r\n"
        !          1184:                ,cfg.grp[usrgrp[newgrp]]->sname,cfg.sub[newsub]->lname);
        !          1185:        sprintf(str,"Moved message from %s %s to %s %s"
        !          1186:                ,cfg.grp[newgrp]->sname,cfg.sub[newsub]->sname
        !          1187:                ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->sname);
        !          1188:        logline("M+",str);
        !          1189:        if(cfg.sub[newsub]->misc&SUB_FIDO && cfg.sub[newsub]->echomail_sem[0])
        !          1190:                if((file=nopen(cmdstr(cfg.sub[newsub]->echomail_sem,nulstr,nulstr,NULL)
        !          1191:                        ,O_WRONLY|O_CREAT|O_TRUNC))!=-1)
        !          1192:                        close(file);
        !          1193:        return(true);
        !          1194: }
        !          1195: 
        !          1196: ushort sbbs_t::chmsgattr(ushort attr)
        !          1197: {
        !          1198:        int ch;
        !          1199: 
        !          1200:        while(online && !(sys_status&SS_ABORT)) {
        !          1201:                CRLF;
        !          1202:                show_msgattr(attr);
        !          1203:                menu("msgattr");
        !          1204:                ch=getkey(K_UPPER);
        !          1205:                if(ch)
        !          1206:                        bprintf("%c\r\n",ch);
        !          1207:                switch(ch) {
        !          1208:                        case 'P':
        !          1209:                                attr^=MSG_PRIVATE;
        !          1210:                                break;
        !          1211:                        case 'R':
        !          1212:                                attr^=MSG_READ;
        !          1213:                                break;
        !          1214:                        case 'K':
        !          1215:                                attr^=MSG_KILLREAD;
        !          1216:                                break;
        !          1217:                        case 'A':
        !          1218:                                attr^=MSG_ANONYMOUS;
        !          1219:                                break;
        !          1220:                        case 'N':   /* Non-purgeable */
        !          1221:                                attr^=MSG_PERMANENT;
        !          1222:                                break;
        !          1223:                        case 'M':
        !          1224:                                attr^=MSG_MODERATED;
        !          1225:                                break;
        !          1226:                        case 'V':
        !          1227:                                attr^=MSG_VALIDATED;
        !          1228:                                break;
        !          1229:                        case 'D':
        !          1230:                                attr^=MSG_DELETE;
        !          1231:                                break;
        !          1232:                        case 'L':
        !          1233:                                attr^=MSG_LOCKED;
        !          1234:                                break;
        !          1235:                        default:
        !          1236:                                return(attr); } }
        !          1237:        return(attr);
        !          1238: }

unix.superglobalmegacorp.com

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