|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.