Annotation of sbbs/src/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.68 2006/09/15 01:36:33 rswindell Exp $ */
        !             6: 
        !             7: /****************************************************************************
        !             8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
        !             9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
        !            10:  *                                                                                                                                                     *
        !            11:  * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html         *
        !            12:  *                                                                                                                                                     *
        !            13:  * This program is free software; you can redistribute it and/or                       *
        !            14:  * modify it under the terms of the GNU General Public License                         *
        !            15:  * as published by the Free Software Foundation; either version 2                      *
        !            16:  * of the License, or (at your option) any later version.                                      *
        !            17:  * See the GNU General Public License for more details: gpl.txt or                     *
        !            18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
        !            19:  *                                                                                                                                                     *
        !            20:  * Anonymous FTP access to the most recent released source is available at     *
        !            21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
        !            22:  *                                                                                                                                                     *
        !            23:  * Anonymous CVS access to the development source and modification history     *
        !            24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
        !            25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
        !            26:  *     (just hit return, no password is necessary)                                                     *
        !            27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
        !            28:  *                                                                                                                                                     *
        !            29:  * For Synchronet coding style and modification guidelines, see                                *
        !            30:  * http://www.synchro.net/source.html                                                                          *
        !            31:  *                                                                                                                                                     *
        !            32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
        !            33:  * format) via e-mail to [email protected]                                                                      *
        !            34:  *                                                                                                                                                     *
        !            35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
        !            36:  ****************************************************************************/
        !            37: 
        !            38: #include "sbbs.h"
        !            39: 
        !            40: #define MAX_LINE_LEN 82L
        !            41: 
        !            42: const char *qstr=" > %.76s\r\n";
        !            43: void quotestr(char *str);
        !            44: 
        !            45: /****************************************************************************/
        !            46: /* Returns temporary message text filename (for message/text editors)          */
        !            47: /****************************************************************************/
        !            48: char* sbbs_t::msg_tmp_fname(int xedit, char* fname, size_t len)
        !            49: {
        !            50:        safe_snprintf(fname, len, "%sINPUT.MSG", cfg.temp_dir);
        !            51: 
        !            52:        if(xedit) {
        !            53:                if(cfg.xedit[xedit-1]->misc&QUICKBBS)
        !            54:                        safe_snprintf(fname, len, "%sMSGTMP", cfg.node_dir);    /* QuickBBS editors are dumb */
        !            55:                if(cfg.xedit[xedit-1]->misc&XTRN_LWRCASE)
        !            56:                        strlwr(fname);
        !            57:        }
        !            58: 
        !            59:        return(fname);
        !            60: }
        !            61: 
        !            62: /****************************************************************************/
        !            63: /* Creates a message (post or mail) using standard line editor. 'fname' is  */
        !            64: /* is name of file to create, 'top' is a buffer to place at beginning of    */
        !            65: /* message and 'title' is the title (70chars max) for the message.          */
        !            66: /* 'dest' contains a text description of where the message is going.        */
        !            67: /****************************************************************************/
        !            68: bool sbbs_t::writemsg(char *fname, char *top, char *title, long mode, int subnum
        !            69:        ,char *dest)
        !            70: {
        !            71:        char    str[256],quote[128],c,*buf,*p,*tp
        !            72:                                ,useron_level;
        !            73:        char    msgtmp[MAX_PATH+1];
        !            74:        char    tmp[512];
        !            75:        int             i,j,file,linesquoted=0;
        !            76:        long    length,qlen=0,qtime=0,ex_mode=0;
        !            77:        int             max_title_len=LEN_TITLE;
        !            78:        ulong   l;
        !            79:        FILE*   stream;
        !            80:        FILE*   fp;
        !            81: 
        !            82:        useron_level=useron.level;
        !            83: 
        !            84:        if((buf=(char*)malloc(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN))
        !            85:                ==NULL) {
        !            86:                errormsg(WHERE,ERR_ALLOC,fname
        !            87:                        ,cfg.level_linespermsg[useron_level]*MAX_LINE_LEN);
        !            88:                return(false); 
        !            89:        }
        !            90: 
        !            91:        if(mode&WM_NETMAIL ||
        !            92:                (!(mode&(WM_EMAIL|WM_NETMAIL)) && cfg.sub[subnum]->misc&SUB_PNET))
        !            93:                mode|=WM_NOTOP;
        !            94: 
        !            95:        msg_tmp_fname(useron.xedit, msgtmp, sizeof(msgtmp));
        !            96: 
        !            97:        if(mode&WM_QUOTE && !(useron.rest&FLAG('J'))
        !            98:                && ((mode&(WM_EMAIL|WM_NETMAIL) && cfg.sys_misc&SM_QUOTE_EM)
        !            99:                || (!(mode&(WM_EMAIL|WM_NETMAIL)) && (uint)subnum!=INVALID_SUB
        !           100:                        && cfg.sub[subnum]->misc&SUB_QUOTE))) {
        !           101: 
        !           102:                /* Quote entire message to MSGTMP or INPUT.MSG */
        !           103: 
        !           104:                if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&QUOTEALL) {
        !           105:                        strcpy(tmp,"QUOTES.TXT");
        !           106:                        if(cfg.xedit[useron.xedit-1]->misc&XTRN_LWRCASE)
        !           107:                                strlwr(tmp);
        !           108:                        sprintf(str,"%s%s",cfg.node_dir,tmp);
        !           109:                        if((stream=fnopen(NULL,str,O_RDONLY))==NULL) {
        !           110:                                errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
        !           111:                                free(buf);
        !           112:                                return(false); 
        !           113:                        }
        !           114: 
        !           115:                        if((file=nopen(msgtmp,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !           116:                                errormsg(WHERE,ERR_OPEN,msgtmp,O_WRONLY|O_CREAT|O_TRUNC);
        !           117:                                free(buf);
        !           118:                                fclose(stream);
        !           119:                                return(false); 
        !           120:                        }
        !           121: 
        !           122:                        while(!feof(stream) && !ferror(stream)) {
        !           123:                                if(!fgets(str,255,stream))
        !           124:                                        break;
        !           125:                                quotestr(str);
        !           126:                                sprintf(tmp,qstr,str);
        !           127:                                write(file,tmp,strlen(tmp));
        !           128:                                linesquoted++; 
        !           129:                        }
        !           130:                        fclose(stream);
        !           131:                        close(file); 
        !           132:                }
        !           133: 
        !           134:                /* Quote nothing to MSGTMP or INPUT.MSG automatically */
        !           135: 
        !           136:                else if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&QUOTENONE)
        !           137:                        ;
        !           138: 
        !           139:                else if(yesno(text[QuoteMessageQ])) {
        !           140:                        strcpy(tmp,"QUOTES.TXT");
        !           141:                        if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&XTRN_LWRCASE)
        !           142:                                strlwr(tmp);
        !           143:                        sprintf(str,"%s%s",cfg.node_dir,tmp);
        !           144:                        if((stream=fnopen(&file,str,O_RDONLY))==NULL) {
        !           145:                                errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
        !           146:                                free(buf);
        !           147:                                return(false); 
        !           148:                        }
        !           149: 
        !           150:                        if((file=nopen(msgtmp,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !           151:                                errormsg(WHERE,ERR_OPEN,msgtmp,O_WRONLY|O_CREAT|O_TRUNC);
        !           152:                                free(buf);
        !           153:                                fclose(stream);
        !           154:                                return(false); 
        !           155:                        }
        !           156: 
        !           157:                        l=ftell(stream);                        /* l now points to start of message */
        !           158: 
        !           159:                        while(online) {
        !           160:                                sprintf(str,text[QuoteLinesPrompt],linesquoted ? "Done":"All");
        !           161:                                mnemonics(str);
        !           162:                                i=getstr(quote,10,K_UPPER);
        !           163:                                if(sys_status&SS_ABORT) {
        !           164:                                        fclose(stream);
        !           165:                                        close(file);
        !           166:                                        free(buf);
        !           167:                                        return(false); 
        !           168:                                }
        !           169:                                if(!i && linesquoted)
        !           170:                                        break;
        !           171:                                if(!i || quote[0]=='A') {                   /* Quote all */
        !           172:                                        fseek(stream,l,SEEK_SET);
        !           173:                                        while(!feof(stream) && !ferror(stream)) {
        !           174:                                                if(!fgets(str,255,stream))
        !           175:                                                        break;
        !           176:                                                quotestr(str);
        !           177:                                                sprintf(tmp,qstr,str);
        !           178:                                                write(file,tmp,strlen(tmp));
        !           179:                                                linesquoted++; 
        !           180:                                        }
        !           181:                                        break; 
        !           182:                                }
        !           183:                                if(quote[0]=='L') {
        !           184:                                        fseek(stream,l,SEEK_SET);
        !           185:                                        i=1;
        !           186:                                        CRLF;
        !           187:                                        attr(LIGHTGRAY);
        !           188:                                        while(!feof(stream) && !ferror(stream) && !msgabort()) {
        !           189:                                                if(!fgets(str,255,stream))
        !           190:                                                        break;
        !           191:                                                quotestr(str);
        !           192:                                                bprintf("%3d: %.74s\r\n",i,str);
        !           193:                                                i++; 
        !           194:                                        }
        !           195:                                        continue; 
        !           196:                                }
        !           197: 
        !           198:                                if(!isdigit(quote[0]))
        !           199:                                        break;
        !           200:                                p=quote;
        !           201:                                while(p) {
        !           202:                                        if(*p==',' || *p==' ')
        !           203:                                                p++;
        !           204:                                        i=atoi(p);
        !           205:                                        if(!i)
        !           206:                                                break;
        !           207:                                        fseek(stream,l,SEEK_SET);
        !           208:                                        j=1;
        !           209:                                        while(!feof(stream) && !ferror(stream) && j<i) {
        !           210:                                                if(!fgets(tmp,255,stream))
        !           211:                                                        break;
        !           212:                                                j++; /* skip beginning */
        !           213:                                        }               
        !           214:                                        tp=strchr(p,'-');   /* tp for temp pointer */
        !           215:                                        if(tp) {                 /* range */
        !           216:                                                i=atoi(tp+1);
        !           217:                                                while(!feof(stream) && !ferror(stream) && j<=i) {
        !           218:                                                        if(!fgets(str,255,stream))
        !           219:                                                                break;
        !           220:                                                        quotestr(str);
        !           221:                                                        sprintf(tmp,qstr,str);
        !           222:                                                        write(file,tmp,strlen(tmp));
        !           223:                                                        linesquoted++;
        !           224:                                                        j++; 
        !           225:                                                } 
        !           226:                                        }
        !           227:                                        else {                  /* one line */
        !           228:                                                if(fgets(str,255,stream)) {
        !           229:                                                        quotestr(str);
        !           230:                                                        sprintf(tmp,qstr,str);
        !           231:                                                        write(file,tmp,strlen(tmp));
        !           232:                                                        linesquoted++; 
        !           233:                                                } 
        !           234:                                        }
        !           235:                                        p=strchr(p,',');
        !           236:                                        // if(!p) p=strchr(p,' ');  02/05/96 huh?
        !           237:                                } 
        !           238:                        }
        !           239: 
        !           240:                        fclose(stream);
        !           241:                        close(file); 
        !           242:                } 
        !           243:        }
        !           244:        else {
        !           245:                strcpy(tmp,"QUOTES.TXT");
        !           246:                if(useron.xedit && cfg.xedit[useron.xedit-1]->misc&XTRN_LWRCASE)
        !           247:                        strlwr(tmp);
        !           248:                sprintf(str,"%s%s",cfg.node_dir,tmp);
        !           249:                removecase(str); 
        !           250:        }
        !           251: 
        !           252:        if(!online || sys_status&SS_ABORT) {
        !           253:                free(buf);
        !           254:                return(false); 
        !           255:        }
        !           256: 
        !           257:        if(!(mode&(WM_EXTDESC|WM_SUBJ_RO))) {
        !           258:                if(mode&WM_FILE) {
        !           259:                        max_title_len=12;       /* ToDo: implied 8.3 filename limit! */
        !           260:                        CRLF;
        !           261:                        bputs(text[Filename]); 
        !           262:                }
        !           263:                else {
        !           264:                        max_title_len=LEN_TITLE;
        !           265:                        if(mode&WM_QWKNET
        !           266:                                || (subnum!=INVALID_SUB 
        !           267:                                        && (cfg.sub[subnum]->misc&(SUB_QNET|SUB_INET|SUB_FIDO))==SUB_QNET))
        !           268:                                max_title_len=25;
        !           269:                        bputs(text[SubjectPrompt]); 
        !           270:                }
        !           271:                if(!getstr(title,max_title_len,mode&WM_FILE ? K_LINE : K_LINE|K_EDIT|K_AUTODEL)
        !           272:                        && useron_level && useron.logons) {
        !           273:                        free(buf);
        !           274:                        return(false); 
        !           275:                }
        !           276:                if(!(mode&(WM_EMAIL|WM_NETMAIL)) && cfg.sub[subnum]->misc&SUB_QNET
        !           277:                        && !SYSOP
        !           278:                        && (!stricmp(title,"DROP") || !stricmp(title,"ADD")
        !           279:                        || !strnicmp(dest,"SBBS",4))) {
        !           280:                        free(buf);   /* Users can't post DROP or ADD in QWK netted subs */
        !           281:                        return(false); /* or messages to "SBBS" */
        !           282:                }
        !           283:        }
        !           284: 
        !           285:        if(!online || sys_status&SS_ABORT) {
        !           286:                free(buf);
        !           287:                return(false); 
        !           288:        }
        !           289: 
        !           290:        if(console&CON_RAW_IN) {
        !           291:                bprintf(text[EnterMsgNowRaw]
        !           292:                        ,(ulong)cfg.level_linespermsg[useron_level]*MAX_LINE_LEN);
        !           293:                if(top[0] && !(mode&WM_NOTOP)) {
        !           294:                        strcpy((char *)buf,top);
        !           295:                        strcat((char *)buf,crlf);
        !           296:                        l=strlen((char *)buf); 
        !           297:                }
        !           298:                else
        !           299:                        l=0;
        !           300:                while(l<(ulong)(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)) {
        !           301:                        c=getkey(0);
        !           302:                        if(sys_status&SS_ABORT) {  /* Ctrl-C */
        !           303:                                free(buf);
        !           304:                                return(false); 
        !           305:                        }
        !           306:                        if((c==ESC || c==CTRL_A) && useron.rest&FLAG('A')) /* ANSI restriction */
        !           307:                                continue;
        !           308:                        if(c==BEL && useron.rest&FLAG('B'))   /* Beep restriction */
        !           309:                                continue;
        !           310:                        if(!(console&CON_RAW_IN))       /* Ctrl-Z was hit */
        !           311:                                break;
        !           312:                        outchar(c);
        !           313:                        buf[l++]=c; 
        !           314:                }
        !           315:                buf[l]=0;
        !           316:                if(l==(ulong)cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)
        !           317:                        bputs(text[OutOfBytes]); 
        !           318:        }
        !           319: 
        !           320: 
        !           321:        else if(useron.xedit) {
        !           322: 
        !           323:                editor_inf(useron.xedit,dest,title,mode,subnum);
        !           324:                if(cfg.xedit[useron.xedit-1]->type) {
        !           325:                        gettimeleft();
        !           326:                        xtrndat(useron.alias,cfg.node_dir,cfg.xedit[useron.xedit-1]->type
        !           327:                           ,timeleft,cfg.xedit[useron.xedit-1]->misc); 
        !           328:                }
        !           329: 
        !           330:                if(cfg.xedit[useron.xedit-1]->misc&IO_INTS) {
        !           331:                        ex_mode|=(EX_OUTR|EX_INR);
        !           332:                        if(cfg.xedit[useron.xedit-1]->misc&WWIVCOLOR)
        !           333:                                ex_mode|=EX_WWIV; 
        !           334:                }
        !           335:                if(cfg.xedit[useron.xedit-1]->misc&XTRN_NATIVE)
        !           336:                        ex_mode|=EX_NATIVE;
        !           337:                if(cfg.xedit[useron.xedit-1]->misc&XTRN_SH)
        !           338:                        ex_mode|=EX_SH;
        !           339: 
        !           340:                if(!linesquoted)
        !           341:                        removecase(msgtmp);
        !           342:                else {
        !           343:                        qlen=flength(msgtmp);
        !           344:                        qtime=fdate(msgtmp); 
        !           345:                }
        !           346: 
        !           347:                CLS;
        !           348:                rioctl(IOCM|PAUSE|ABORT);
        !           349:                external(cmdstr(cfg.xedit[useron.xedit-1]->rcmd,msgtmp,nulstr,NULL),ex_mode,cfg.node_dir);
        !           350:                rioctl(IOSM|PAUSE|ABORT); 
        !           351: 
        !           352:                checkline();
        !           353:                if(!fexistcase(msgtmp) || !online
        !           354:                        || (linesquoted && qlen==flength(msgtmp) && qtime==fdate(msgtmp))) {
        !           355:                        free(buf);
        !           356:                        return(false); 
        !           357:                }
        !           358:                SAFEPRINTF(str,"%sRESULT.ED",cfg.node_dir);
        !           359:                if(!(mode&(WM_EXTDESC|WM_FILE|WM_SUBJ_RO))
        !           360:                        && !(cfg.xedit[useron.xedit-1]->misc&QUICKBBS) 
        !           361:                        && fexistcase(str)) {
        !           362:                        if((fp=fopen(str,"r")) != NULL) {
        !           363:                                fgets(str,sizeof(str),fp);
        !           364:                                fgets(str,sizeof(str),fp);
        !           365:                                truncsp(str);
        !           366:                                sprintf(title,"%.*s",max_title_len,str);
        !           367:                                fclose(fp);
        !           368:                        }
        !           369:                }
        !           370: 
        !           371:                buf[0]=0;
        !           372:                if(!(mode&WM_NOTOP))
        !           373:                        strcpy((char *)buf,top);
        !           374:                if((file=nopen(msgtmp,O_RDONLY))==-1) {
        !           375:                        errormsg(WHERE,ERR_OPEN,msgtmp,O_RDONLY);
        !           376:                        free(buf);
        !           377:                        return(false); 
        !           378:                }
        !           379:                length=filelength(file);
        !           380:                l=strlen((char *)buf);    /* reserve space for top and terminating null */
        !           381:                /* truncate if too big */
        !           382:                if(length>(long)((cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-(l+1))) {
        !           383:                        length=(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-(l+1);
        !           384:                        bputs(text[OutOfBytes]); 
        !           385:                }
        !           386:                lread(file,buf+l,length);
        !           387:                close(file);
        !           388:                // remove(msgtmp);         /* no need to save the temp input file */
        !           389:                buf[l+length]=0; 
        !           390:        }
        !           391:        else {
        !           392:                buf[0]=0;
        !           393:                if(linesquoted) {
        !           394:                        if((file=nopen(msgtmp,O_RDONLY))!=-1) {
        !           395:                                length=filelength(file);
        !           396:                                l=length>(cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-1
        !           397:                                        ? (cfg.level_linespermsg[useron_level]*MAX_LINE_LEN)-1 : length;
        !           398:                                lread(file,buf,l);
        !           399:                                buf[l]=0;
        !           400:                                close(file);
        !           401:                                // remove(msgtmp);
        !           402:                        } 
        !           403:                }
        !           404:                if(!(msgeditor((char *)buf,mode&WM_NOTOP ? nulstr : top,title))) {
        !           405:                        free(buf);      /* Assertion here Dec-17-2003, think I fixed in block above (rev 1.52) */
        !           406:                        return(false); 
        !           407:                } 
        !           408:        }
        !           409: 
        !           410:        now=time(NULL);
        !           411:        bputs(text[Saving]);
        !           412:        if((stream=fnopen(&file,fname,O_WRONLY|O_CREAT|O_TRUNC))==NULL) {
        !           413:                errormsg(WHERE,ERR_OPEN,fname,O_WRONLY|O_CREAT|O_TRUNC);
        !           414:                free(buf);
        !           415:                return(false); 
        !           416:        }
        !           417:        for(l=i=0;buf[l] && i<cfg.level_linespermsg[useron_level];l++) {
        !           418:                if((uchar)buf[l]==141 && useron.xedit
        !           419:                && cfg.xedit[useron.xedit-1]->misc&QUICKBBS) {
        !           420:                        fwrite(crlf,2,1,stream);
        !           421:                        i++;
        !           422:                        continue; 
        !           423:                }
        !           424:                /* Expand LF to CRLF? */
        !           425:                if(buf[l]==LF && (!l || buf[l-1]!=CR) && useron.xedit
        !           426:                        && cfg.xedit[useron.xedit-1]->misc&EXPANDLF) {
        !           427:                        fwrite(crlf,2,1,stream);
        !           428:                        i++;
        !           429:                        continue; 
        !           430:                }
        !           431:                /* Strip FidoNet Kludge Lines? */
        !           432:                if(buf[l]==1 && useron.xedit
        !           433:                        && cfg.xedit[useron.xedit-1]->misc&STRIPKLUDGE) {
        !           434:                        while(buf[l] && buf[l]!=LF) 
        !           435:                                l++;
        !           436:                        if(buf[l]==0)
        !           437:                                break;
        !           438:                        continue;
        !           439:                }
        !           440:                if(!(mode&(WM_EMAIL|WM_NETMAIL))
        !           441:                        && (!l || buf[l-1]==LF)
        !           442:                        && buf[l]=='-' && buf[l+1]=='-' && buf[l+2]=='-'
        !           443:                        && (buf[l+3]==' ' || buf[l+3]==TAB || buf[l+3]==CR))
        !           444:                        buf[l+1]='+';
        !           445:                if(buf[l]==LF)
        !           446:                        i++;
        !           447:                fputc(buf[l],stream); 
        !           448:        }
        !           449: 
        !           450:        if(buf[l])
        !           451:                bputs(text[NoMoreLines]);
        !           452: 
        !           453:        /* Signature file */
        !           454:        if(subnum==INVALID_SUB || !(cfg.sub[subnum]->misc&SUB_NOUSERSIG)) {
        !           455:                sprintf(str,"%suser/%04u.sig",cfg.data_dir,useron.number);
        !           456:                FILE* sig;
        !           457:                if(fexist(str) && (sig=fopen(str,"rb"))!=NULL) {
        !           458:                        while(!feof(sig)) {
        !           459:                                if(!fgets(str,sizeof(str),sig))
        !           460:                                        break;
        !           461:                                fputs(str,stream);
        !           462:                                l+=strlen(str); /* byte counter */
        !           463:                                i++;                    /* line counter */
        !           464:                        }
        !           465:                        fclose(sig);
        !           466:                }
        !           467:        }
        !           468: 
        !           469:        fclose(stream);
        !           470:        free((char *)buf);
        !           471:        bprintf(text[SavedNBytes],l,i);
        !           472:        return(true);
        !           473: }
        !           474: 
        !           475: /****************************************************************************/
        !           476: /* Modify 'str' to for quoted format. Remove ^A codes, etc.                 */
        !           477: /****************************************************************************/
        !           478: void quotestr(char *str)
        !           479: {
        !           480:        int j;
        !           481: 
        !           482:        j=strlen(str);
        !           483:        while(j && (str[j-1]==' ' || str[j-1]==LF || str[j-1]==CR)) j--;
        !           484:        str[j]=0;
        !           485:        remove_ctrl_a(str,NULL);
        !           486: }
        !           487: 
        !           488: void sbbs_t::editor_inf(int xeditnum,char *dest, char *title, long mode
        !           489:        ,uint subnum)
        !           490: {
        !           491:        char str[MAX_PATH+1];
        !           492:        char tmp[32];
        !           493:        int file;
        !           494: 
        !           495:        xeditnum--;
        !           496: 
        !           497:        if(cfg.xedit[xeditnum]->misc&QUICKBBS) {
        !           498:                strcpy(tmp,"MSGINF");
        !           499:                if(cfg.xedit[xeditnum]->misc&XTRN_LWRCASE)
        !           500:                        strlwr(tmp);
        !           501:                sprintf(str,"%s%s",cfg.node_dir,tmp);
        !           502:                if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !           503:                        errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
        !           504:                        return; 
        !           505:                }
        !           506:                sprintf(str,"%s\r\n%s\r\n%s\r\n%u\r\n%s\r\n%s\r\n"
        !           507:                        ,(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME) ? useron.name
        !           508:                                : useron.alias
        !           509:                                ,dest,title,1
        !           510:                                ,mode&WM_NETMAIL ? "NetMail"
        !           511:                                :mode&WM_EMAIL ? "Electronic Mail"
        !           512:                                :subnum==INVALID_SUB ? nulstr
        !           513:                                :cfg.sub[subnum]->sname
        !           514:                        ,mode&WM_PRIVATE ? "YES":"NO");
        !           515:                write(file,str,strlen(str));
        !           516:                close(file); 
        !           517:        }
        !           518:        else {
        !           519:                SAFEPRINTF(str,"%sRESULT.ED",cfg.node_dir);
        !           520:                removecase(str);
        !           521:                strcpy(tmp,"EDITOR.INF");
        !           522:                if(cfg.xedit[xeditnum]->misc&XTRN_LWRCASE)
        !           523:                        strlwr(tmp);
        !           524:                sprintf(str,"%s%s",cfg.node_dir,tmp);
        !           525:                if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !           526:                        errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_TRUNC);
        !           527:                        return; 
        !           528:                }
        !           529:                sprintf(str,"%s\r\n%s\r\n%u\r\n%s\r\n%s\r\n%u\r\n"
        !           530:                        ,title,dest,useron.number
        !           531:                        ,(subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_NAME) ? useron.name
        !           532:                        : useron.alias
        !           533:                        ,useron.name,useron.level);
        !           534:                write(file,str,strlen(str));
        !           535:                close(file); 
        !           536:        }
        !           537: }
        !           538: 
        !           539: 
        !           540: 
        !           541: /****************************************************************************/
        !           542: /* Removes from file 'str' every LF terminated line that starts with 'str2' */
        !           543: /* That is divisable by num. Function skips first 'skip' number of lines    */
        !           544: /****************************************************************************/
        !           545: void sbbs_t::removeline(char *str, char *str2, char num, char skip)
        !           546: {
        !           547:        char*   buf;
        !           548:     char    slen;
        !           549:     int     i,file;
        !           550:        long    l=0,flen;
        !           551:     FILE    *stream;
        !           552: 
        !           553:        if((file=nopen(str,O_RDONLY))==-1) {
        !           554:                errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
        !           555:                return; 
        !           556:        }
        !           557:        flen=filelength(file);
        !           558:        slen=strlen(str2);
        !           559:        if((buf=(char *)malloc(flen))==NULL) {
        !           560:                close(file);
        !           561:                errormsg(WHERE,ERR_ALLOC,str,flen);
        !           562:                return; 
        !           563:        }
        !           564:        if(lread(file,buf,flen)!=flen) {
        !           565:                close(file);
        !           566:                errormsg(WHERE,ERR_READ,str,flen);
        !           567:                free(buf);
        !           568:                return; 
        !           569:        }
        !           570:        close(file);
        !           571:        if((stream=fnopen(&file,str,O_WRONLY|O_TRUNC))==NULL) {
        !           572:                close(file);
        !           573:                errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_TRUNC);
        !           574:                free(buf);
        !           575:                return; 
        !           576:        }
        !           577:        for(i=0;l<flen && i<skip;l++) {
        !           578:                fputc(buf[l],stream);
        !           579:                if(buf[l]==LF)
        !           580:                        i++; 
        !           581:        }
        !           582:        while(l<flen) {
        !           583:                if(!strncmp((char *)buf+l,str2,slen)) {
        !           584:                        for(i=0;i<num && l<flen;i++) {
        !           585:                                while(l<flen && buf[l]!=LF) l++;
        !           586:                                l++; 
        !           587:                        } 
        !           588:                }
        !           589:                else {
        !           590:                        for(i=0;i<num && l<flen;i++) {
        !           591:                                while(l<flen && buf[l]!=LF) fputc(buf[l++],stream);
        !           592:                                fputc(buf[l++],stream); 
        !           593:                        } 
        !           594:                } 
        !           595:        }
        !           596:        fclose(stream);
        !           597:        free((char *)buf);
        !           598: }
        !           599: 
        !           600: /*****************************************************************************/
        !           601: /* The Synchronet editor.                                                    */
        !           602: /* Returns the number of lines edited.                                       */
        !           603: /*****************************************************************************/
        !           604: ulong sbbs_t::msgeditor(char *buf, char *top, char *title)
        !           605: {
        !           606:        int             i,j,line,lines=0,maxlines;
        !           607:        char    strin[256],**str,done=0;
        !           608:        char    tmp[512];
        !           609:        char    path[MAX_PATH+1];
        !           610:     ulong      l,m;
        !           611: 
        !           612:        rioctl(IOCM|ABORT);
        !           613:        rioctl(IOCS|ABORT); 
        !           614: 
        !           615:        maxlines=cfg.level_linespermsg[useron.level];
        !           616: 
        !           617:        if((str=(char **)malloc(sizeof(char *)*(maxlines+1)))==NULL) {
        !           618:                errormsg(WHERE,ERR_ALLOC,"msgeditor",sizeof(char *)*(maxlines+1));
        !           619:                return(0)        !           620:        }
        !           621:        m=strlen(buf);
        !           622:        l=0;
        !           623:        while(l<m && lines<maxlines) {
        !           624:                msgabort(); /* to allow pausing */
        !           625:                if((str[lines]=(char *)malloc(MAX_LINE_LEN))==NULL) {
        !           626:                        errormsg(WHERE,ERR_ALLOC,nulstr,MAX_LINE_LEN);
        !           627:                        for(i=0;i<lines;i++)
        !           628:                                free(str[i]);
        !           629:                        free(str);
        !           630:                        rioctl(IOSM|ABORT);
        !           631:                        return(0)        !           632:                }
        !           633:                for(i=0;i<79 && l<m;i++,l++) {
        !           634:                        if(buf[l]==CR) {
        !           635:                                l+=2;
        !           636:                                break; 
        !           637:                        }
        !           638:                        if(buf[l]==TAB) {
        !           639:                                if(!(i%8))                  /* hard-coded tabstop of 8 */
        !           640:                                        str[lines][i++]=' ';     /* for expansion */
        !           641:                                while(i%8 && i<79)
        !           642:                                        str[lines][i++]=' ';
        !           643:                                i--;
        !           644:                                /***
        !           645:                                bprintf("\r\nMessage editor: Expanded tab on line #%d",lines+1);
        !           646:                                ***/ }
        !           647:                        else str[lines][i]=buf[l]; 
        !           648:                }
        !           649:                if(i==79) {
        !           650:                        if(buf[l]==CR)
        !           651:                                l+=2;
        !           652:                        else
        !           653:                                bprintf("\r\nMessage editor: Split line #%d",lines+1); 
        !           654:                }
        !           655:                str[lines][i]=0;
        !           656:                lines++; 
        !           657:        }
        !           658:        if(lines)
        !           659:                bprintf("\r\nMessage editor: Read in %d lines\r\n",lines);
        !           660:        bprintf(text[EnterMsgNow],maxlines);
        !           661: 
        !           662:        sprintf(path,"%smenu/msgtabs.*", cfg.text_dir);
        !           663:        if(fexist(path))
        !           664:                menu("msgtabs");
        !           665:        else {
        !           666:                for(i=0;i<79;i++) {
        !           667:                        if(i%EDIT_TABSIZE || !i)
        !           668:                                outchar('-');
        !           669:                        else 
        !           670:                                outchar('+');
        !           671:                }
        !           672:                CRLF;
        !           673:        }
        !           674:        putmsg(top,P_SAVEATR|P_NOATCODES);
        !           675:        for(line=0;line<lines && !msgabort();line++) { /* display lines in buf */
        !           676:                putmsg(str[line],P_SAVEATR|P_NOATCODES);
        !           677:                cleartoeol();  /* delete to end of line */
        !           678:                CRLF; 
        !           679:        }
        !           680:        SYNC;
        !           681:        rioctl(IOSM|ABORT);
        !           682:        while(online && !done) {
        !           683:                checkline();
        !           684:                if(line==lines) {
        !           685:                        if((str[line]=(char *)malloc(MAX_LINE_LEN))==NULL) {
        !           686:                                errormsg(WHERE,ERR_ALLOC,nulstr,MAX_LINE_LEN);
        !           687:                                for(i=0;i<lines;i++)
        !           688:                                        free(str[i]);
        !           689:                                free(str);
        !           690:                                return(0)        !           691:                        }
        !           692:                        str[line][0]=0; 
        !           693:                }
        !           694:                if(line>(maxlines-10)) {
        !           695:                        if(line==maxlines)
        !           696:                                bputs(text[NoMoreLines]);
        !           697:                        else
        !           698:                                bprintf(text[OnlyNLinesLeft],maxlines-line); 
        !           699:                }
        !           700:                strcpy(strin,str[line]);
        !           701:                do {
        !           702:                        if(!line)
        !           703:                                outchar(CR);
        !           704:                        getstr(strin,79,K_WRAP|K_MSG|K_EDIT);
        !           705:                        } while(console&CON_UPARROW && !line);
        !           706: 
        !           707:                if(sys_status&SS_ABORT) {
        !           708:                        if(line==lines)
        !           709:                                free(str[line]);
        !           710:                        continue; 
        !           711:                }
        !           712:                if(strin[0]=='/' && strlen(strin)<8) {
        !           713:                        if(!stricmp(strin,"/DEBUG") && SYSOP) {
        !           714:                                if(line==lines)
        !           715:                                        free(str[line]);
        !           716:                                bprintf("\r\nline=%d lines=%d rows=%d\r\n",line,lines,rows);
        !           717:                                continue; 
        !           718:                        }
        !           719:                        else if(!stricmp(strin,"/ABT")) {
        !           720:                                if(line==lines)                 /* delete a line */
        !           721:                                        free(str[line]);
        !           722:                                for(i=0;i<lines;i++)
        !           723:                                        free(str[i]);
        !           724:                                free(str);
        !           725:                                return(0)        !           726:                        }
        !           727:                        else if(toupper(strin[1])=='D') {
        !           728:                                if(line==lines)         /* delete a line */
        !           729:                                        free(str[line]);
        !           730:                                if(!lines)
        !           731:                                        continue;
        !           732:                                i=atoi(strin+2)-1;
        !           733:                                if(i==-1)   /* /D means delete last line */
        !           734:                                        i=lines-1;
        !           735:                                if(i>=lines || i<0)
        !           736:                                        bputs(text[InvalidLineNumber]);
        !           737:                                else {
        !           738:                                        free(str[i]);
        !           739:                                        lines--;
        !           740:                                        while(i<lines) {
        !           741:                                                str[i]=str[i+1];
        !           742:                                                i++; 
        !           743:                                        }
        !           744:                                        if(line>lines)
        !           745:                                                line=lines; 
        !           746:                                }
        !           747:                                continue; 
        !           748:                        }
        !           749:                        else if(toupper(strin[1])=='I') {
        !           750:                                if(line==lines)         /* insert a line before number x */
        !           751:                                        free(str[line]);
        !           752:                                if(line==maxlines || !lines)
        !           753:                                        continue;
        !           754:                                i=atoi(strin+2)-1;
        !           755:                                if(i==-1)
        !           756:                                        i=lines-1;
        !           757:                                if(i>=lines || i<0)
        !           758:                                        bputs(text[InvalidLineNumber]);
        !           759:                                else {
        !           760:                                        for(line=lines;line>i;line--)   /* move the pointers */
        !           761:                                                str[line]=str[line-1];
        !           762:                                        if((str[i]=(char *)malloc(MAX_LINE_LEN))==NULL) {
        !           763:                                                errormsg(WHERE,ERR_ALLOC,nulstr,MAX_LINE_LEN);
        !           764:                                                for(i=0;i<lines;i++)
        !           765:                                                        free(str[i]);
        !           766:                                                free(str);
        !           767:                                                return(0)        !           768:                                        }
        !           769:                                        str[i][0]=0;
        !           770:                                        line=++lines; 
        !           771:                                }
        !           772:                                continue; 
        !           773:                        }
        !           774:                        else if(toupper(strin[1])=='E') {
        !           775:                                if(line==lines)         /* edit a line */
        !           776:                                        free(str[line]);
        !           777:                                if(!lines)
        !           778:                                        continue;
        !           779:                                i=atoi(strin+2)-1;
        !           780:                                j=K_MSG|K_EDIT; /* use j for the getstr mode */
        !           781:                                if(i==-1) { /* /E means edit last line */
        !           782:                                        i=lines-1;
        !           783:                                        j|=K_WRAP;      /* wrap when editing last line */
        !           784:                                }    
        !           785:                                if(i>=lines || i<0)
        !           786:                                        bputs(text[InvalidLineNumber]);
        !           787:                                else
        !           788:                                        getstr(str[i],79,j);
        !           789:                                continue; 
        !           790:                        }
        !           791:                        else if(!stricmp(strin,"/CLR")) {
        !           792:                                bputs(text[MsgCleared]);
        !           793:                                if(line!=lines)
        !           794:                                        lines--;
        !           795:                                for(i=0;i<=lines;i++)
        !           796:                                        free(str[i]);
        !           797:                                line=0;
        !           798:                                lines=0;
        !           799:                                putmsg(top,P_SAVEATR|P_NOATCODES);
        !           800:                                continue; 
        !           801:                        }
        !           802:                        else if(toupper(strin[1])=='L') {   /* list message */
        !           803:                                if(line==lines)
        !           804:                                        free(str[line]);
        !           805:                                if(lines)
        !           806:                                        i=!noyes(text[WithLineNumbersQ]);
        !           807:                                else
        !           808:                                        i=0;
        !           809:                                CRLF;
        !           810:                                attr(LIGHTGRAY);
        !           811:                                putmsg(top,P_SAVEATR|P_NOATCODES);
        !           812:                                if(!lines) {
        !           813:                                        continue; 
        !           814:                                }
        !           815:                                j=atoi(strin+2);
        !           816:                                if(j) j--;  /* start from line j */
        !           817:                                while(j<lines && !msgabort()) {
        !           818:                                        if(i) { /* line numbers */
        !           819:                                                sprintf(tmp,"%3d: %-.74s",j+1,str[j]);
        !           820:                                                putmsg(tmp,P_SAVEATR|P_NOATCODES); 
        !           821:                                        }
        !           822:                                        else
        !           823:                                                putmsg(str[j],P_SAVEATR|P_NOATCODES);
        !           824:                                        cleartoeol();  /* delete to end of line */
        !           825:                                        CRLF;
        !           826:                                        j++; 
        !           827:                                }
        !           828:                                SYNC;
        !           829:                                continue; 
        !           830:                        }
        !           831:                        else if(!stricmp(strin,"/S")) { /* Save */
        !           832:                                if(line==lines)
        !           833:                                        free(str[line]);
        !           834:                                done=1;
        !           835:                                continue;}
        !           836:                        else if(!stricmp(strin,"/T")) { /* Edit title/subject */
        !           837:                                if(line==lines)
        !           838:                                        free(str[line]);
        !           839:                                if(title[0]) {
        !           840:                                        bputs(text[SubjectPrompt]);
        !           841:                                        getstr(title,LEN_TITLE,K_LINE|K_EDIT|K_AUTODEL);
        !           842:                                        SYNC;
        !           843:                                        CRLF; 
        !           844:                                }
        !           845:                                continue; 
        !           846:                        }
        !           847:                        else if(!stricmp(strin,"/?")) {
        !           848:                                if(line==lines)
        !           849:                                        free(str[line]);
        !           850:                                menu("editor"); /* User Editor Commands */
        !           851:                                SYNC;
        !           852:                                continue; 
        !           853:                        }
        !           854:                        else if(!stricmp(strin,"/ATTR"))    {
        !           855:                                if(line==lines)
        !           856:                                        free(str[line]);
        !           857:                                menu("attr");   /* User ANSI Commands */
        !           858:                                SYNC;
        !           859:                                continue; 
        !           860:                        } 
        !           861:                }
        !           862:                strcpy(str[line],strin);
        !           863:                if(line<maxlines)
        !           864:                        line++;
        !           865:                else
        !           866:                        free(str[line]);
        !           867:                if(line>lines)
        !           868:                        lines++;
        !           869:                if(console&CON_UPARROW) {
        !           870:                        outchar(CR);
        !           871:                        cursor_up();
        !           872:                        cleartoeol();
        !           873:                        line-=2; 
        !           874:                }
        !           875:                }
        !           876:        if(!online) {
        !           877:                for(i=0;i<lines;i++)
        !           878:                        free(str[i]);
        !           879:                free(str);
        !           880:                return(0)        !           881:        }
        !           882:        strcpy(buf,top);
        !           883:        for(i=0;i<lines;i++) {
        !           884:                strcat(buf,str[i]);
        !           885:                strcat(buf,crlf);
        !           886:                free(str[i]); 
        !           887:        }
        !           888:        free(str);
        !           889:        return(lines);
        !           890: }
        !           891: 
        !           892: 
        !           893: /****************************************************************************/
        !           894: /* Edits an existing file or creates a new one in MSG format                */
        !           895: /****************************************************************************/
        !           896: void sbbs_t::editfile(char *fname)
        !           897: {
        !           898:        char *buf,path[MAX_PATH+1];
        !           899:        char msgtmp[MAX_PATH+1];
        !           900:     int file;
        !           901:        long length,maxlines,lines,l,mode=0;
        !           902: 
        !           903:        maxlines=cfg.level_linespermsg[useron.level];
        !           904:        sprintf(path,"%sQUOTES.TXT",cfg.node_dir);
        !           905:        removecase(path);
        !           906: 
        !           907:        if(useron.xedit) {
        !           908: 
        !           909:                SAFECOPY(path,fname);
        !           910: 
        !           911:                msg_tmp_fname(useron.xedit, msgtmp, sizeof(msgtmp));
        !           912:                if(stricmp(msgtmp,path)) {
        !           913:                        removecase(msgtmp);
        !           914:                        if(fexistcase(path))
        !           915:                                fcopy(path, msgtmp);
        !           916:                }
        !           917: 
        !           918:                editor_inf(useron.xedit,fname,nulstr,0,INVALID_SUB);
        !           919:                if(cfg.xedit[useron.xedit-1]->misc&XTRN_NATIVE)
        !           920:                        mode|=EX_NATIVE;
        !           921:                if(cfg.xedit[useron.xedit-1]->misc&XTRN_SH)
        !           922:                        mode|=EX_SH;
        !           923:                if(cfg.xedit[useron.xedit-1]->misc&IO_INTS) {
        !           924:                        mode|=(EX_OUTR|EX_INR);
        !           925:                        if(cfg.xedit[useron.xedit-1]->misc&WWIVCOLOR)
        !           926:                                mode|=EX_WWIV; 
        !           927:                }
        !           928:                CLS;
        !           929:                rioctl(IOCM|PAUSE|ABORT);
        !           930:                external(cmdstr(cfg.xedit[useron.xedit-1]->rcmd,msgtmp,nulstr,NULL),mode,cfg.node_dir);
        !           931:                if(stricmp(msgtmp,path) && !fcompare(msgtmp, path))     /* file changed */
        !           932:                        fcopy(msgtmp, path);
        !           933:                rioctl(IOSM|PAUSE|ABORT); 
        !           934:                return; 
        !           935:        }
        !           936:        if((buf=(char *)malloc(maxlines*MAX_LINE_LEN))==NULL) {
        !           937:                errormsg(WHERE,ERR_ALLOC,nulstr,maxlines*MAX_LINE_LEN);
        !           938:                return; 
        !           939:        }
        !           940:        if((file=nopen(fname,O_RDONLY))!=-1) {
        !           941:                length=filelength(file);
        !           942:                if(length>(long)maxlines*MAX_LINE_LEN) {
        !           943:                        close(file);
        !           944:                        free(buf); 
        !           945:                        attr(cfg.color[clr_err]);
        !           946:                        bprintf("\7\r\nFile size (%lu bytes) is larger than %lu (maxlines: %lu).\r\n"
        !           947:                                ,length, (ulong)maxlines*MAX_LINE_LEN, maxlines);
        !           948:                        return;
        !           949:                }
        !           950:                if(read(file,buf,length)!=length) {
        !           951:                        close(file);
        !           952:                        free(buf);
        !           953:                        errormsg(WHERE,ERR_READ,fname,length);
        !           954:                        return; 
        !           955:                }
        !           956:                buf[length]=0;
        !           957:                close(file); 
        !           958:        }
        !           959:        else {
        !           960:                buf[0]=0;
        !           961:                bputs(text[NewFile]); 
        !           962:        }
        !           963:        if(!msgeditor(buf,nulstr,nulstr)) {
        !           964:                free(buf);
        !           965:                return; 
        !           966:        }
        !           967:        bputs(text[Saving]);
        !           968:        if((file=nopen(fname,O_CREAT|O_WRONLY|O_TRUNC))==-1) {
        !           969:                errormsg(WHERE,ERR_OPEN,fname,O_CREAT|O_WRONLY|O_TRUNC);
        !           970:                free(buf);
        !           971:                return; 
        !           972:        }
        !           973:        if((size_t)write(file,buf,strlen(buf))!=strlen(buf)) {
        !           974:                close(file);
        !           975:                errormsg(WHERE,ERR_WRITE,fname,strlen(buf));
        !           976:                free(buf);
        !           977:                return; 
        !           978:        }
        !           979:        for(l=lines=0;buf[l];l++)
        !           980:                if(buf[l]==LF)
        !           981:                        lines++;
        !           982:        bprintf(text[SavedNBytes],l,lines);
        !           983:        close(file);
        !           984:        free(buf);
        !           985:        return;
        !           986: }
        !           987: 
        !           988: /*************************/
        !           989: /* Copy file attachments */
        !           990: /*************************/
        !           991: void sbbs_t::copyfattach(uint to, uint from, char *title)
        !           992: {
        !           993:        char str[128],str2[128],str3[128],*tp,*sp,*p;
        !           994: 
        !           995:        strcpy(str,title);
        !           996:        tp=str;
        !           997:        while(1) {
        !           998:                p=strchr(tp,' ');
        !           999:                if(p) *p=0;
        !          1000:                sp=strrchr(tp,'/');              /* sp is slash pointer */
        !          1001:                if(!sp) sp=strrchr(tp,'\\');
        !          1002:                if(sp) tp=sp+1;
        !          1003:                sprintf(str2,"%sfile/%04u.in/%s"  /* str2 is path/fname */
        !          1004:                        ,cfg.data_dir,to,tp);
        !          1005:                sprintf(str3,"%sfile/%04u.in/%s"  /* str2 is path/fname */
        !          1006:                        ,cfg.data_dir,from,tp);
        !          1007:                if(strcmp(str2,str3))
        !          1008:                        mv(str3,str2,1);
        !          1009:                if(!p)
        !          1010:                        break;
        !          1011:                tp=p+1; 
        !          1012:        }
        !          1013: }
        !          1014: 
        !          1015: 
        !          1016: /****************************************************************************/
        !          1017: /* Forwards mail (fname) to usernumber                                      */
        !          1018: /* Called from function readmail                                                                                       */
        !          1019: /****************************************************************************/
        !          1020: void sbbs_t::forwardmail(smbmsg_t *msg, int usernumber)
        !          1021: {
        !          1022:        char            str[256],touser[128];
        !          1023:        char            tmp[512];
        !          1024:        int                     i;
        !          1025:        node_t          node;
        !          1026:        msghdr_t        hdr=msg->hdr;
        !          1027:        idxrec_t        idx=msg->idx;
        !          1028: 
        !          1029:        if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) {
        !          1030:                bputs(text[TooManyEmailsToday]);
        !          1031:                return; 
        !          1032:        }
        !          1033:        if(useron.rest&FLAG('F')) {
        !          1034:                bputs(text[R_Forward]);
        !          1035:                return; 
        !          1036:        }
        !          1037:        if(usernumber==1 && useron.rest&FLAG('S')) {
        !          1038:                bprintf(text[R_Feedback],cfg.sys_op);
        !          1039:                return; 
        !          1040:        }
        !          1041:        if(usernumber!=1 && useron.rest&FLAG('E')) {
        !          1042:                bputs(text[R_Email]);
        !          1043:                return; 
        !          1044:        }
        !          1045: 
        !          1046:        msg->idx.attr&=~(MSG_READ|MSG_DELETE);
        !          1047:        msg->hdr.attr=msg->idx.attr;
        !          1048: 
        !          1049: 
        !          1050:        smb_hfield_str(msg,SENDER,useron.alias);
        !          1051:        sprintf(str,"%u",useron.number);
        !          1052:        smb_hfield_str(msg,SENDEREXT,str);
        !          1053: 
        !          1054:        username(&cfg,usernumber,touser);
        !          1055:        smb_hfield_str(msg,RECIPIENT,touser);
        !          1056:        sprintf(str,"%u",usernumber);
        !          1057:        smb_hfield(msg,RECIPIENTEXT,sizeof(str),str);
        !          1058:        msg->idx.to=usernumber;
        !          1059: 
        !          1060:        now=time(NULL);
        !          1061:        smb_hfield(msg,FORWARDED,sizeof(time_t),&now);
        !          1062: 
        !          1063: 
        !          1064:        if((i=smb_open_da(&smb))!=SMB_SUCCESS) {
        !          1065:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
        !          1066:                return; 
        !          1067:        }
        !          1068:        if((i=smb_incmsg_dfields(&smb,msg,1))!=SMB_SUCCESS) {
        !          1069:                errormsg(WHERE,ERR_WRITE,smb.file,i);
        !          1070:                return; 
        !          1071:        }
        !          1072:        smb_close_da(&smb);
        !          1073: 
        !          1074: 
        !          1075:        if((i=smb_addmsghdr(&smb,msg,SMB_SELFPACK))!=SMB_SUCCESS) {
        !          1076:                errormsg(WHERE,ERR_WRITE,smb.file,i);
        !          1077:                smb_freemsg_dfields(&smb,msg,1);
        !          1078:                return; 
        !          1079:        }
        !          1080: 
        !          1081:        if(msg->hdr.auxattr&MSG_FILEATTACH)
        !          1082:                copyfattach(usernumber,useron.number,msg->subj);
        !          1083: 
        !          1084:        bprintf(text[Forwarded],username(&cfg,usernumber,str),usernumber);
        !          1085:        sprintf(str,"%s forwarded mail to %s #%d"
        !          1086:                ,useron.alias
        !          1087:                ,username(&cfg,usernumber,tmp)
        !          1088:                ,usernumber);
        !          1089:        logline("E",str);
        !          1090:        msg->idx=idx;
        !          1091:        msg->hdr=hdr;
        !          1092: 
        !          1093: 
        !          1094:        if(usernumber==1) {
        !          1095:                useron.fbacks++;
        !          1096:                logon_fbacks++;
        !          1097:                putuserrec(&cfg,useron.number,U_FBACKS,5,ultoa(useron.fbacks,tmp,10)); 
        !          1098:        }
        !          1099:        else {
        !          1100:                useron.emails++;
        !          1101:                logon_emails++;
        !          1102:                putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); 
        !          1103:        }
        !          1104:        useron.etoday++;
        !          1105:        putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10));
        !          1106: 
        !          1107:        for(i=1;i<=cfg.sys_nodes;i++) { /* Tell user, if online */
        !          1108:                getnodedat(i,&node,0);
        !          1109:                if(node.useron==usernumber && !(node.misc&NODE_POFF)
        !          1110:                        && (node.status==NODE_INUSE || node.status==NODE_QUIET)) {
        !          1111:                        sprintf(str,text[EmailNodeMsg],cfg.node_num,useron.alias);
        !          1112:                        putnmsg(&cfg,i,str);
        !          1113:                        break; 
        !          1114:                } 
        !          1115:        }
        !          1116:        if(i>cfg.sys_nodes) {   /* User wasn't online, so leave short msg */
        !          1117:                sprintf(str,text[UserSentYouMail],useron.alias);
        !          1118:                putsmsg(&cfg,usernumber,str); 
        !          1119:        }
        !          1120: }
        !          1121: 
        !          1122: /****************************************************************************/
        !          1123: /* Auto-Message Routine ('A' from the main menu)                            */
        !          1124: /****************************************************************************/
        !          1125: void sbbs_t::automsg()
        !          1126: {
        !          1127:     char       str[256],buf[300],anon=0;
        !          1128:        char    tmp[512];
        !          1129:        char    automsg[MAX_PATH+1];
        !          1130:     int                file;
        !          1131:        time_t  now=time(NULL);
        !          1132: 
        !          1133:        sprintf(automsg,"%smsgs/auto.msg",cfg.data_dir);
        !          1134:        while(online) {
        !          1135:                SYNC;
        !          1136:                mnemonics(text[AutoMsg]);
        !          1137:                switch(getkeys("RWQ",0)) {
        !          1138:                        case 'R':
        !          1139:                                printfile(automsg,P_NOABORT|P_NOATCODES);
        !          1140:                                break;
        !          1141:                        case 'W':
        !          1142:                                if(useron.rest&FLAG('W')) {
        !          1143:                                        bputs(text[R_AutoMsg]);
        !          1144:                                        break; 
        !          1145:                                }
        !          1146:                                action=NODE_AMSG;
        !          1147:                                SYNC;
        !          1148:                                bputs("\r\n3 lines:\r\n");
        !          1149:                                if(!getstr(str,68,K_WRAP|K_MSG))
        !          1150:                                        break;
        !          1151:                                strcpy(buf,str);
        !          1152:                                strcat(buf,"\r\n          ");
        !          1153:                                getstr(str,68,K_WRAP|K_MSG);
        !          1154:                                strcat(buf,str);
        !          1155:                                strcat(buf,"\r\n          ");
        !          1156:                                getstr(str,68,K_MSG);
        !          1157:                                strcat(str,crlf);
        !          1158:                                strcat(buf,str);
        !          1159:                                if(yesno(text[OK])) {
        !          1160:                                        if(useron.exempt&FLAG('A')) {
        !          1161:                                                if(!noyes(text[AnonymousQ]))
        !          1162:                                                        anon=1; 
        !          1163:                                        }
        !          1164:                                        if((file=nopen(automsg,O_WRONLY|O_CREAT|O_TRUNC))==-1) {
        !          1165:                                                errormsg(WHERE,ERR_OPEN,automsg,O_WRONLY|O_CREAT|O_TRUNC);
        !          1166:                                                return; 
        !          1167:                                        }
        !          1168:                                        if(anon)
        !          1169:                                                sprintf(tmp,"%.80s",text[Anonymous]);
        !          1170:                                        else
        !          1171:                                                sprintf(tmp,"%s #%d",useron.alias,useron.number);
        !          1172:                                        sprintf(str,text[AutoMsgBy],tmp,timestr(&now));
        !          1173:                                        strcat(str,"          ");
        !          1174:                                        write(file,str,strlen(str));
        !          1175:                                        write(file,buf,strlen(buf));
        !          1176:                                        close(file); 
        !          1177:                                }
        !          1178:                                break;
        !          1179:                        case 'Q':
        !          1180:                                return; 
        !          1181:                } 
        !          1182:        }
        !          1183: }
        !          1184: 
        !          1185: /****************************************************************************/
        !          1186: /* Edits messages                                                                                                                      */
        !          1187: /****************************************************************************/
        !          1188: void sbbs_t::editmsg(smbmsg_t *msg, uint subnum)
        !          1189: {
        !          1190:        char    buf[SDT_BLOCK_LEN];
        !          1191:        char    msgtmp[MAX_PATH+1];
        !          1192:        ushort  xlat;
        !          1193:        int     file,i,j,x;
        !          1194:        long    length,offset;
        !          1195:        FILE    *instream;
        !          1196: 
        !          1197:        if(!msg->hdr.total_dfields)
        !          1198:                return;
        !          1199: 
        !          1200:        msg_tmp_fname(useron.xedit, msgtmp, sizeof(msgtmp));
        !          1201:        removecase(msgtmp);
        !          1202:        msgtotxt(msg,msgtmp,0,1);
        !          1203:        editfile(msgtmp);
        !          1204:        length=flength(msgtmp);
        !          1205:        if(length<1L)
        !          1206:                return;
        !          1207: 
        !          1208:        length+=2;       /* +2 for translation string */
        !          1209: 
        !          1210:        if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) {
        !          1211:                errormsg(WHERE,ERR_LOCK,smb.file,i);
        !          1212:                return; 
        !          1213:        }
        !          1214: 
        !          1215:        if((i=smb_getstatus(&smb))!=SMB_SUCCESS) {
        !          1216:                errormsg(WHERE,ERR_READ,smb.file,i);
        !          1217:                return; 
        !          1218:        }
        !          1219: 
        !          1220:        if(!(smb.status.attr&SMB_HYPERALLOC)) {
        !          1221:                if((i=smb_open_da(&smb))!=SMB_SUCCESS) {
        !          1222:                        errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
        !          1223:                        return; 
        !          1224:                }
        !          1225:                if((i=smb_freemsg_dfields(&smb,msg,1))!=SMB_SUCCESS)
        !          1226:                        errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); 
        !          1227:        }
        !          1228: 
        !          1229:        msg->dfield[0].type=TEXT_BODY;                          /* Make one single data field */
        !          1230:        msg->dfield[0].length=length;
        !          1231:        msg->dfield[0].offset=0;
        !          1232:        for(x=1;x<msg->hdr.total_dfields;x++) {         /* Clear the other data fields */
        !          1233:                msg->dfield[x].type=UNUSED;                     /* so we leave the header length */
        !          1234:                msg->dfield[x].length=0;                                /* unchanged */
        !          1235:                msg->dfield[x].offset=0; 
        !          1236:        }
        !          1237: 
        !          1238: 
        !          1239:        if(smb.status.attr&SMB_HYPERALLOC)
        !          1240:                offset=smb_hallocdat(&smb); 
        !          1241:        else {
        !          1242:                if((subnum!=INVALID_SUB && cfg.sub[subnum]->misc&SUB_FAST)
        !          1243:                        || (subnum==INVALID_SUB && cfg.sys_misc&SM_FASTMAIL))
        !          1244:                        offset=smb_fallocdat(&smb,length,1);
        !          1245:                else
        !          1246:                        offset=smb_allocdat(&smb,length,1);
        !          1247:                smb_close_da(&smb); 
        !          1248:        }
        !          1249: 
        !          1250:        msg->hdr.offset=offset;
        !          1251:        if((file=open(msgtmp,O_RDONLY|O_BINARY))==-1
        !          1252:                || (instream=fdopen(file,"rb"))==NULL) {
        !          1253:                smb_unlocksmbhdr(&smb);
        !          1254:                smb_freemsgdat(&smb,offset,length,1);
        !          1255:                errormsg(WHERE,ERR_OPEN,msgtmp,O_RDONLY|O_BINARY);
        !          1256:                return; 
        !          1257:        }
        !          1258: 
        !          1259:        setvbuf(instream,NULL,_IOFBF,2*1024);
        !          1260:        fseek(smb.sdt_fp,offset,SEEK_SET);
        !          1261:        xlat=XLAT_NONE;
        !          1262:        fwrite(&xlat,2,1,smb.sdt_fp);
        !          1263:        x=SDT_BLOCK_LEN-2;                              /* Don't read/write more than 255 */
        !          1264:        while(!feof(instream)) {
        !          1265:                memset(buf,0,x);
        !          1266:                j=fread(buf,1,x,instream);
        !          1267:                if(j<1)
        !          1268:                        break;
        !          1269:                if(j>1 && (j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR)
        !          1270:                        buf[j-1]=buf[j-2]=0;    /* Convert to NULL */
        !          1271:                fwrite(buf,j,1,smb.sdt_fp);
        !          1272:                x=SDT_BLOCK_LEN; 
        !          1273:        }
        !          1274:        fflush(smb.sdt_fp);
        !          1275:        fclose(instream);
        !          1276: 
        !          1277:        smb_unlocksmbhdr(&smb);
        !          1278:        msg->hdr.length=(ushort)smb_getmsghdrlen(msg);
        !          1279:        if((i=smb_putmsghdr(&smb,msg))!=SMB_SUCCESS)
        !          1280:                errormsg(WHERE,ERR_WRITE,smb.file,i);
        !          1281: }
        !          1282: 
        !          1283: /****************************************************************************/
        !          1284: /* Moves a message from one message base to another                                            */
        !          1285: /****************************************************************************/
        !          1286: bool sbbs_t::movemsg(smbmsg_t* msg, uint subnum)
        !          1287: {
        !          1288:        char str[256],*buf;
        !          1289:        uint i;
        !          1290:        int newgrp,newsub,storage;
        !          1291:        ulong offset,length;
        !          1292:        smbmsg_t        newmsg=*msg;
        !          1293:        smb_t           newsmb;
        !          1294: 
        !          1295:        for(i=0;i<usrgrps;i++)           /* Select New Group */
        !          1296:                uselect(1,i,"Message Group",cfg.grp[usrgrp[i]]->lname,0);
        !          1297:        if((newgrp=uselect(0,0,0,0,0))<0)
        !          1298:                return(false);
        !          1299: 
        !          1300:        for(i=0;i<usrsubs[newgrp];i++)           /* Select New Sub-Board */
        !          1301:                uselect(1,i,"Sub-Board",cfg.sub[usrsub[newgrp][i]]->lname,0);
        !          1302:        if((newsub=uselect(0,0,0,0,0))<0)
        !          1303:                return(false);
        !          1304:        newsub=usrsub[newgrp][newsub];
        !          1305: 
        !          1306:        length=smb_getmsgdatlen(msg);
        !          1307:        if((buf=(char *)malloc(length))==NULL) {
        !          1308:                errormsg(WHERE,ERR_ALLOC,smb.file,length);
        !          1309:                return(false); 
        !          1310:        }
        !          1311: 
        !          1312:        fseek(smb.sdt_fp,msg->hdr.offset,SEEK_SET);
        !          1313:        fread(buf,length,1,smb.sdt_fp);
        !          1314: 
        !          1315:        sprintf(newsmb.file,"%s%s",cfg.sub[newsub]->data_dir,cfg.sub[newsub]->code);
        !          1316:        newsmb.retry_time=cfg.smb_retry_time;
        !          1317:        newsmb.subnum=newsub;
        !          1318:        if((i=smb_open(&newsmb))!=SMB_SUCCESS) {
        !          1319:                free(buf);
        !          1320:                errormsg(WHERE,ERR_OPEN,newsmb.file,i,newsmb.last_error);
        !          1321:                return(false); 
        !          1322:        }
        !          1323: 
        !          1324:        if(filelength(fileno(newsmb.shd_fp))<1) {        /* Create it if it doesn't exist */
        !          1325:                newsmb.status.max_crcs=cfg.sub[newsub]->maxcrcs;
        !          1326:                newsmb.status.max_msgs=cfg.sub[newsub]->maxmsgs;
        !          1327:                newsmb.status.max_age=cfg.sub[newsub]->maxage;
        !          1328:                newsmb.status.attr=cfg.sub[newsub]->misc&SUB_HYPER ? SMB_HYPERALLOC :0;
        !          1329:                if((i=smb_create(&newsmb))!=SMB_SUCCESS) {
        !          1330:                        free(buf);
        !          1331:                        smb_close(&newsmb);
        !          1332:                        errormsg(WHERE,ERR_CREATE,newsmb.file,i,newsmb.last_error);
        !          1333:                        return(false); 
        !          1334:                } 
        !          1335:        }
        !          1336: 
        !          1337:        if((i=smb_locksmbhdr(&newsmb))!=SMB_SUCCESS) {
        !          1338:                free(buf);
        !          1339:                smb_close(&newsmb);
        !          1340:                errormsg(WHERE,ERR_LOCK,newsmb.file,i,newsmb.last_error);
        !          1341:                return(false); 
        !          1342:        }
        !          1343: 
        !          1344:        if((i=smb_getstatus(&newsmb))!=SMB_SUCCESS) {
        !          1345:                free(buf);
        !          1346:                smb_close(&newsmb);
        !          1347:                errormsg(WHERE,ERR_READ,newsmb.file,i,newsmb.last_error);
        !          1348:                return(false); 
        !          1349:        }
        !          1350: 
        !          1351:        if(newsmb.status.attr&SMB_HYPERALLOC) {
        !          1352:                offset=smb_hallocdat(&newsmb);
        !          1353:                storage=SMB_HYPERALLOC; 
        !          1354:        }
        !          1355:        else {
        !          1356:                if((i=smb_open_da(&newsmb))!=SMB_SUCCESS) {
        !          1357:                        free(buf);
        !          1358:                        smb_close(&newsmb);
        !          1359:                        errormsg(WHERE,ERR_OPEN,newsmb.file,i,newsmb.last_error);
        !          1360:                        return(false); 
        !          1361:                }
        !          1362:                if(cfg.sub[newsub]->misc&SUB_FAST) {
        !          1363:                        offset=smb_fallocdat(&newsmb,length,1);
        !          1364:                        storage=SMB_FASTALLOC; 
        !          1365:                }
        !          1366:                else {
        !          1367:                        offset=smb_allocdat(&newsmb,length,1);
        !          1368:                        storage=SMB_SELFPACK; 
        !          1369:                }
        !          1370:                smb_close_da(&newsmb); 
        !          1371:        }
        !          1372: 
        !          1373:        newmsg.hdr.offset=offset;
        !          1374:        newmsg.hdr.version=smb_ver();
        !          1375: 
        !          1376:        fseek(newsmb.sdt_fp,offset,SEEK_SET);
        !          1377:        fwrite(buf,length,1,newsmb.sdt_fp);
        !          1378:        fflush(newsmb.sdt_fp);
        !          1379:        free(buf);
        !          1380: 
        !          1381:        i=smb_addmsghdr(&newsmb,&newmsg,storage);       // calls smb_unlocksmbhdr() 
        !          1382:        smb_close(&newsmb);
        !          1383: 
        !          1384:        if(i) {
        !          1385:                errormsg(WHERE,ERR_WRITE,newsmb.file,i,newsmb.last_error);
        !          1386:                smb_freemsg_dfields(&newsmb,&newmsg,1);
        !          1387:                return(false); 
        !          1388:        }
        !          1389: 
        !          1390:        bprintf("\r\nMoved to %s %s\r\n\r\n"
        !          1391:                ,cfg.grp[usrgrp[newgrp]]->sname,cfg.sub[newsub]->lname);
        !          1392:        sprintf(str,"%s moved message from %s %s to %s %s"
        !          1393:                ,useron.alias
        !          1394:                ,cfg.grp[newgrp]->sname,cfg.sub[newsub]->sname
        !          1395:                ,cfg.grp[cfg.sub[subnum]->grp]->sname,cfg.sub[subnum]->sname);
        !          1396:        logline("M+",str);
        !          1397:        signal_sub_sem(&cfg,newsub);
        !          1398: 
        !          1399:        return(true);
        !          1400: }
        !          1401: 
        !          1402: ushort sbbs_t::chmsgattr(ushort attr)
        !          1403: {
        !          1404:        int ch;
        !          1405: 
        !          1406:        while(online && !(sys_status&SS_ABORT)) {
        !          1407:                CRLF;
        !          1408:                show_msgattr(attr);
        !          1409:                menu("msgattr");
        !          1410:                ch=getkey(K_UPPER);
        !          1411:                if(ch)
        !          1412:                        bprintf("%c\r\n",ch);
        !          1413:                switch(ch) {
        !          1414:                        case 'P':
        !          1415:                                attr^=MSG_PRIVATE;
        !          1416:                                break;
        !          1417:                        case 'R':
        !          1418:                                attr^=MSG_READ;
        !          1419:                                break;
        !          1420:                        case 'K':
        !          1421:                                attr^=MSG_KILLREAD;
        !          1422:                                break;
        !          1423:                        case 'A':
        !          1424:                                attr^=MSG_ANONYMOUS;
        !          1425:                                break;
        !          1426:                        case 'N':   /* Non-purgeable */
        !          1427:                                attr^=MSG_PERMANENT;
        !          1428:                                break;
        !          1429:                        case 'M':
        !          1430:                                attr^=MSG_MODERATED;
        !          1431:                                break;
        !          1432:                        case 'V':
        !          1433:                                attr^=MSG_VALIDATED;
        !          1434:                                break;
        !          1435:                        case 'D':
        !          1436:                                attr^=MSG_DELETE;
        !          1437:                                break;
        !          1438:                        case 'L':
        !          1439:                                attr^=MSG_LOCKED;
        !          1440:                                break;
        !          1441:                        default:
        !          1442:                                return(attr); 
        !          1443:                } 
        !          1444:        }
        !          1445:        return(attr);
        !          1446: }

unix.superglobalmegacorp.com

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