Annotation of sbbs/sbbs2/msg2.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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