Annotation of sbbs/src/sbbs3/netmail.cpp, revision 1.1.1.1

1.1       root        1: /* netmail.cpp */
                      2: 
                      3: /* Synchronet network mail-related functions */
                      4: 
                      5: /* $Id: netmail.cpp,v 1.34 2005/10/02 23:33:45 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 2005 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: #include "qwk.h"
                     40: 
                     41: /****************************************************************************/
                     42: /****************************************************************************/
                     43: bool sbbs_t::inetmail(char *into, char *subj, long mode)
                     44: {
                     45:        char    str[256],str2[256],msgpath[256],title[256],name[256],ch
                     46:                        ,buf[SDT_BLOCK_LEN],*p,addr[256];
                     47:        char    tmp[512];
                     48:        char    your_addr[128];
                     49:        ushort  xlat=XLAT_NONE,net=NET_INTERNET;
                     50:        int     i,j,x,file;
                     51:        long    l;
                     52:        ulong   length,offset;
                     53:        FILE    *instream;
                     54:        smbmsg_t msg;
                     55: 
                     56:        if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) {
                     57:                bputs(text[TooManyEmailsToday]);
                     58:                return(false); 
                     59:        }
                     60: 
                     61:        strcpy(name,into);
                     62:        strcpy(addr,into);
                     63:        strcpy(title,subj);
                     64: 
                     65:        if((!SYSOP && !(cfg.inetmail_misc&NMAIL_ALLOW)) || useron.rest&FLAG('M')) {
                     66:                bputs(text[NoNetMailAllowed]);
                     67:                return(false); }
                     68: 
                     69:        if(cfg.inetmail_cost && !(useron.exempt&FLAG('S'))) {
                     70:                if(useron.cdt+useron.freecdt<cfg.inetmail_cost) {
                     71:                        bputs(text[NotEnoughCredits]);
                     72:                        return(false); }
                     73:                sprintf(str,text[NetMailCostContinueQ],cfg.inetmail_cost);
                     74:                if(noyes(str))
                     75:                        return(false); }
                     76: 
                     77:        /* Get destination user name */
                     78:        p=strrchr(name,'@');
                     79:        if(!p)
                     80:                p=strrchr(name,'!');
                     81:        if(p) {
                     82:                *p=0;
                     83:                truncsp(name); }
                     84: 
                     85:        /* Get this user's internet mailing address */
                     86:        usermailaddr(&cfg,your_addr
                     87:                ,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name);
                     88: 
                     89:        bprintf(text[InternetMailing],addr,your_addr);
                     90:        action=NODE_SMAL;
                     91:        nodesync();
                     92: 
                     93:        sprintf(msgpath,"%snetmail.msg",cfg.node_dir);
                     94:        if(!writemsg(msgpath,nulstr,title,mode,INVALID_SUB,into)) {
                     95:                bputs(text[Aborted]);
                     96:                return(false); }
                     97: 
                     98:        if(mode&WM_FILE) {
                     99:                sprintf(str2,"%sfile/%04u.out",cfg.data_dir,useron.number);
                    100:                MKDIR(str2);
                    101:                sprintf(str2,"%sfile/%04u.out/%s",cfg.data_dir,useron.number,title);
                    102:                if(fexistcase(str2)) {
                    103:                        bputs(text[FileAlreadyThere]);
                    104:                        remove(msgpath);
                    105:                        return(false); }
                    106: #if 0  /* no such thing as local logon */
                    107:                if(online==ON_LOCAL) {          /* Local upload */
                    108:                        bputs(text[EnterPath]);
                    109:                        if(!getstr(str,60,K_LINE|K_UPPER)) {
                    110:                                bputs(text[Aborted]);
                    111:                                remove(msgpath);
                    112:                                return(false); }
                    113:                        backslash(str);
                    114:                        strcat(str,title);
                    115:                        mv(str,str2,1); }
                    116:                else 
                    117: #endif
                    118:                { /* Remote */
                    119:                        xfer_prot_menu(XFER_UPLOAD);
                    120:                        mnemonics(text[ProtocolOrQuit]);
                    121:                        strcpy(str,"Q");
                    122:                        for(x=0;x<cfg.total_prots;x++)
                    123:                                if(cfg.prot[x]->ulcmd[0] && chk_ar(cfg.prot[x]->ar,&useron)) {
                    124:                                        sprintf(tmp,"%c",cfg.prot[x]->mnemonic);
                    125:                                        strcat(str,tmp); }
                    126:                        ch=(char)getkeys(str,0);
                    127:                        if(ch=='Q' || sys_status&SS_ABORT) {
                    128:                                bputs(text[Aborted]);
                    129:                                remove(msgpath);
                    130:                                return(false); }
                    131:                        for(x=0;x<cfg.total_prots;x++)
                    132:                                if(cfg.prot[x]->ulcmd[0] && cfg.prot[x]->mnemonic==ch
                    133:                                        && chk_ar(cfg.prot[x]->ar,&useron))
                    134:                                        break;
                    135:                        if(x<cfg.total_prots)   /* This should be always */
                    136:                                protocol(cfg.prot[x],XFER_UPLOAD,str2,nulstr,true); 
                    137:                }
                    138:                sprintf(tmp,"%s%s",cfg.temp_dir,title);
                    139:                if(!fexistcase(str2) && fexistcase(tmp))
                    140:                        mv(tmp,str2,0);
                    141:                l=flength(str2);
                    142:                if(l>0)
                    143:                        bprintf(text[FileNBytesReceived],title,ultoac(l,tmp));
                    144:                else {
                    145:                        bprintf(text[FileNotReceived],title);
                    146:                        remove(msgpath);
                    147:                        return(false); } }
                    148: 
                    149:        if((i=smb_stack(&smb,SMB_STACK_PUSH))!=SMB_SUCCESS) {
                    150:                errormsg(WHERE,ERR_OPEN,"MAIL",i);
                    151:                return(false); }
                    152:        sprintf(smb.file,"%smail",cfg.data_dir);
                    153:        smb.retry_time=cfg.smb_retry_time;
                    154:        smb.subnum=INVALID_SUB;
                    155:        if((i=smb_open(&smb))!=SMB_SUCCESS) {
                    156:                smb_stack(&smb,SMB_STACK_POP);
                    157:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
                    158:                return(false); }
                    159: 
                    160:        if(filelength(fileno(smb.shd_fp))<1) {   /* Create it if it doesn't exist */
                    161:                smb.status.max_crcs=cfg.mail_maxcrcs;
                    162:                smb.status.max_age=cfg.mail_maxage;
                    163:                smb.status.max_msgs=0;
                    164:                smb.status.attr=SMB_EMAIL;
                    165:                if((i=smb_create(&smb))!=SMB_SUCCESS) {
                    166:                        smb_close(&smb);
                    167:                        smb_stack(&smb,SMB_STACK_POP);
                    168:                        errormsg(WHERE,ERR_CREATE,smb.file,i);
                    169:                        return(false); } }
                    170: 
                    171:        if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) {
                    172:                smb_close(&smb);
                    173:                smb_stack(&smb,SMB_STACK_POP);
                    174:                errormsg(WHERE,ERR_LOCK,smb.file,i);
                    175:                return(false); }
                    176: 
                    177:        length=flength(msgpath)+2;       /* +2 for translation string */
                    178: 
                    179:        if(length&0xfff00000UL) {
                    180:                smb_unlocksmbhdr(&smb);
                    181:                smb_close(&smb);
                    182:                smb_stack(&smb,SMB_STACK_POP);
                    183:                errormsg(WHERE,ERR_LEN,msgpath,length);
                    184:                return(false); }
                    185: 
                    186:        if((i=smb_open_da(&smb))!=SMB_SUCCESS) {
                    187:                smb_unlocksmbhdr(&smb);
                    188:                smb_close(&smb);
                    189:                smb_stack(&smb,SMB_STACK_POP);
                    190:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
                    191:                return(false); }
                    192:        if(cfg.sys_misc&SM_FASTMAIL)
                    193:                offset=smb_fallocdat(&smb,length,1);
                    194:        else
                    195:                offset=smb_allocdat(&smb,length,1);
                    196:        smb_close_da(&smb);
                    197: 
                    198:        if((file=open(msgpath,O_RDONLY|O_BINARY))==-1
                    199:                || (instream=fdopen(file,"rb"))==NULL) {
                    200:                smb_freemsgdat(&smb,offset,length,1);
                    201:                smb_unlocksmbhdr(&smb);
                    202:                smb_close(&smb);
                    203:                smb_stack(&smb,SMB_STACK_POP);
                    204:                errormsg(WHERE,ERR_OPEN,msgpath,O_RDONLY|O_BINARY);
                    205:                return(false); }
                    206: 
                    207:        setvbuf(instream,NULL,_IOFBF,2*1024);
                    208:        fseek(smb.sdt_fp,offset,SEEK_SET);
                    209:        xlat=XLAT_NONE;
                    210:        fwrite(&xlat,2,1,smb.sdt_fp);
                    211:        x=SDT_BLOCK_LEN-2;                              /* Don't read/write more than 255 */
                    212:        while(!feof(instream)) {
                    213:                memset(buf,0,x);
                    214:                j=fread(buf,1,x,instream);
                    215:                if(j<1)
                    216:                        break;
                    217:                if(j>1 && (j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR)
                    218:                        buf[j-1]=buf[j-2]=0;
                    219:                fwrite(buf,j,1,smb.sdt_fp);
                    220:                x=SDT_BLOCK_LEN; }
                    221:        fflush(smb.sdt_fp);
                    222:        fclose(instream);
                    223: 
                    224:        memset(&msg,0,sizeof(smbmsg_t));
                    225:        msg.hdr.version=smb_ver();
                    226:        if(mode&WM_FILE)
                    227:                msg.hdr.auxattr|=MSG_FILEATTACH;
                    228:        msg.hdr.when_written.time=msg.hdr.when_imported.time=time(NULL);
                    229:        msg.hdr.when_written.zone=msg.hdr.when_imported.zone=sys_timezone(&cfg);
                    230: 
                    231:        msg.hdr.offset=offset;
                    232: 
                    233:        net=NET_INTERNET;
                    234:        smb_hfield_str(&msg,RECIPIENT,name);
                    235:        smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net);
                    236:        smb_hfield_str(&msg,RECIPIENTNETADDR,addr);
                    237: 
                    238:        strcpy(str,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name);
                    239:        smb_hfield_str(&msg,SENDER,str);
                    240: 
                    241:        sprintf(str,"%u",useron.number);
                    242:        smb_hfield_str(&msg,SENDEREXT,str);
                    243: 
                    244:        /*
                    245:        smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net);
                    246:        smb_hfield(&msg,SENDERNETADDR,strlen(sys_inetaddr),sys_inetaddr);
                    247:        */
                    248: 
                    249:        /* Security logging */
                    250:        msg_client_hfields(&msg,&client);
                    251: 
                    252:        smb_hfield_str(&msg,SUBJECT,title);
                    253:        strcpy(str,title);
                    254: 
                    255:        smb_dfield(&msg,TEXT_BODY,length);
                    256: 
                    257:        i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK);        // calls smb_unlocksmbhdr() 
                    258:        smb_close(&smb);
                    259:        smb_stack(&smb,SMB_STACK_POP);
                    260: 
                    261:        smb_freemsgmem(&msg);
                    262:        if(i!=SMB_SUCCESS) {
                    263:                errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
                    264:                smb_freemsgdat(&smb,offset,length,1);
                    265:                return(false); 
                    266:        }
                    267: 
                    268:        if(mode&WM_FILE && online==ON_REMOTE)
                    269:                autohangup();
                    270: 
                    271:        if(cfg.inetmail_sem[0])          /* update semaphore file */
                    272:                ftouch(cmdstr(cfg.inetmail_sem,nulstr,nulstr,NULL));
                    273:        if(!(useron.exempt&FLAG('S')))
                    274:                subtract_cdt(&cfg,&useron,cfg.inetmail_cost);
                    275: 
                    276:        useron.emails++;
                    277:        logon_emails++;
                    278:        putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); 
                    279:        useron.etoday++;
                    280:        putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10));
                    281: 
                    282:        sprintf(str,"%s sent Internet Mail to %s (%s)"
                    283:                ,useron.alias
                    284:                ,name,addr);
                    285:        logline("EN",str);
                    286:        return(true);
                    287: }
                    288: 
                    289: bool sbbs_t::qnetmail(char *into, char *subj, long mode)
                    290: {
                    291:        char    str[256],msgpath[128],title[128],to[128],fulladdr[128]
                    292:                        ,buf[SDT_BLOCK_LEN],*addr;
                    293:        char    tmp[512];
                    294:        ushort  xlat=XLAT_NONE,net=NET_QWK,touser;
                    295:        int     i,j,x,file;
                    296:        ulong   length,offset;
                    297:        FILE    *instream;
                    298:        smbmsg_t msg;
                    299: 
                    300:        if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) {
                    301:                bputs(text[TooManyEmailsToday]);
                    302:                return(false); 
                    303:        }
                    304: 
                    305:        strcpy(to,into);
                    306:        strcpy(title,subj);
                    307: 
                    308:        if(useron.rest&FLAG('M')) {
                    309:                bputs(text[NoNetMailAllowed]);
                    310:                return(false); }
                    311: 
                    312:        addr=strrchr(to,'@');
                    313:        if(!addr) {
                    314:                bputs(text[InvalidNetMailAddr]);
                    315:                return(false); 
                    316:        }
                    317:        *addr=0;
                    318:        addr++;
                    319:        strupr(addr);
                    320:        truncsp(addr);
                    321:        touser=qwk_route(addr,fulladdr);
                    322:        if(!fulladdr[0]) {
                    323:                bputs(text[InvalidNetMailAddr]);
                    324:                return(false); 
                    325:        }
                    326: 
                    327:        truncsp(to);
                    328:        if(!stricmp(to,"SBBS") && !SYSOP) {
                    329:                bputs(text[InvalidNetMailAddr]);
                    330:                return(false); 
                    331:        }
                    332:        bprintf(text[NetMailing],to,fulladdr
                    333:                ,useron.alias,cfg.sys_id);
                    334:        action=NODE_SMAL;
                    335:        nodesync();
                    336: 
                    337:        sprintf(msgpath,"%snetmail.msg",cfg.node_dir);
                    338:        if(!writemsg(msgpath,nulstr,title,mode|WM_QWKNET,INVALID_SUB,to)) {
                    339:                bputs(text[Aborted]);
                    340:                return(false); }
                    341: 
                    342:        if((i=smb_stack(&smb,SMB_STACK_PUSH))!=SMB_SUCCESS) {
                    343:                errormsg(WHERE,ERR_OPEN,"MAIL",i);
                    344:                return(false); }
                    345:        sprintf(smb.file,"%smail",cfg.data_dir);
                    346:        smb.retry_time=cfg.smb_retry_time;
                    347:        smb.subnum=INVALID_SUB;
                    348:        if((i=smb_open(&smb))!=SMB_SUCCESS) {
                    349:                smb_stack(&smb,SMB_STACK_POP);
                    350:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
                    351:                return(false); }
                    352: 
                    353:        if(filelength(fileno(smb.shd_fp))<1) {   /* Create it if it doesn't exist */
                    354:                smb.status.max_crcs=cfg.mail_maxcrcs;
                    355:                smb.status.max_msgs=0;
                    356:                smb.status.max_age=cfg.mail_maxage;
                    357:                smb.status.attr=SMB_EMAIL;
                    358:                if((i=smb_create(&smb))!=SMB_SUCCESS) {
                    359:                        smb_close(&smb);
                    360:                        smb_stack(&smb,SMB_STACK_POP);
                    361:                        errormsg(WHERE,ERR_CREATE,smb.file,i,smb.last_error);
                    362:                        return(false); } }
                    363: 
                    364:        if((i=smb_locksmbhdr(&smb))!=SMB_SUCCESS) {
                    365:                smb_close(&smb);
                    366:                smb_stack(&smb,SMB_STACK_POP);
                    367:                errormsg(WHERE,ERR_LOCK,smb.file,i,smb.last_error);
                    368:                return(false); }
                    369: 
                    370:        length=flength(msgpath)+2;       /* +2 for translation string */
                    371: 
                    372:        if(length&0xfff00000UL) {
                    373:                smb_unlocksmbhdr(&smb);
                    374:                smb_close(&smb);
                    375:                smb_stack(&smb,SMB_STACK_POP);
                    376:                errormsg(WHERE,ERR_LEN,msgpath,length);
                    377:                return(false); }
                    378: 
                    379:        if((i=smb_open_da(&smb))!=SMB_SUCCESS) {
                    380:                smb_unlocksmbhdr(&smb);
                    381:                smb_close(&smb);
                    382:                smb_stack(&smb,SMB_STACK_POP);
                    383:                errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error);
                    384:                return(false); }
                    385:        if(cfg.sys_misc&SM_FASTMAIL)
                    386:                offset=smb_fallocdat(&smb,length,1);
                    387:        else
                    388:                offset=smb_allocdat(&smb,length,1);
                    389:        smb_close_da(&smb);
                    390: 
                    391:        if((file=open(msgpath,O_RDONLY|O_BINARY))==-1
                    392:                || (instream=fdopen(file,"rb"))==NULL) {
                    393:                smb_freemsgdat(&smb,offset,length,1);
                    394:                smb_unlocksmbhdr(&smb);
                    395:                smb_close(&smb);
                    396:                smb_stack(&smb,SMB_STACK_POP);
                    397:                errormsg(WHERE,ERR_OPEN,msgpath,O_RDONLY|O_BINARY);
                    398:                return(false); }
                    399: 
                    400:        setvbuf(instream,NULL,_IOFBF,2*1024);
                    401:        fseek(smb.sdt_fp,offset,SEEK_SET);
                    402:        xlat=XLAT_NONE;
                    403:        fwrite(&xlat,2,1,smb.sdt_fp);
                    404:        x=SDT_BLOCK_LEN-2;                              /* Don't read/write more than 255 */
                    405:        while(!feof(instream)) {
                    406:                memset(buf,0,x);
                    407:                j=fread(buf,1,x,instream);
                    408:                if(j<1)
                    409:                        break;
                    410:                if(j>1 && (j!=x || feof(instream)) && buf[j-1]==LF && buf[j-2]==CR)
                    411:                        buf[j-1]=buf[j-2]=0;
                    412:                fwrite(buf,j,1,smb.sdt_fp);
                    413:                x=SDT_BLOCK_LEN; }
                    414:        fflush(smb.sdt_fp);
                    415:        fclose(instream);
                    416: 
                    417:        memset(&msg,0,sizeof(smbmsg_t));
                    418:        msg.hdr.version=smb_ver();
                    419:        if(mode&WM_FILE)
                    420:                msg.hdr.auxattr|=MSG_FILEATTACH;
                    421:        msg.hdr.when_written.time=msg.hdr.when_imported.time=time(NULL);
                    422:        msg.hdr.when_written.zone=msg.hdr.when_imported.zone=sys_timezone(&cfg);
                    423: 
                    424:        msg.hdr.offset=offset;
                    425: 
                    426:        net=NET_QWK;
                    427:        smb_hfield_str(&msg,RECIPIENT,to);
                    428:        sprintf(str,"%u",touser);
                    429:        smb_hfield_str(&msg,RECIPIENTEXT,str);
                    430:        smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net);
                    431:        smb_hfield_str(&msg,RECIPIENTNETADDR,fulladdr);
                    432: 
                    433:        smb_hfield_str(&msg,SENDER,useron.alias);
                    434: 
                    435:        sprintf(str,"%u",useron.number);
                    436:        smb_hfield_str(&msg,SENDEREXT,str);
                    437: 
                    438:        /* Security logging */
                    439:        msg_client_hfields(&msg,&client);
                    440: 
                    441:        smb_hfield_str(&msg,SUBJECT,title);
                    442: 
                    443:        smb_dfield(&msg,TEXT_BODY,length);
                    444: 
                    445:        i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK); // calls smb_unlocksmbhdr() 
                    446:        smb_close(&smb);
                    447:        smb_stack(&smb,SMB_STACK_POP);
                    448: 
                    449:        smb_freemsgmem(&msg);
                    450:        if(i!=SMB_SUCCESS) {
                    451:                errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error);
                    452:                smb_freemsgdat(&smb,offset,length,1);
                    453:                return(false); 
                    454:        }
                    455: 
                    456:        useron.emails++;
                    457:        logon_emails++;
                    458:        putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); 
                    459:        useron.etoday++;
                    460:        putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10));
                    461: 
                    462:        sprintf(str,"%s sent QWK NetMail to %s (%s)"
                    463:                ,useron.alias
                    464:                ,to,fulladdr);
                    465:        logline("EN",str);
                    466:        return(true);
                    467: }

unix.superglobalmegacorp.com

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