|
|
1.1 ! root 1: /* fido.cpp */ ! 2: ! 3: /* Synchronet FidoNet-related routines */ ! 4: ! 5: /* $Id: fido.cpp,v 1.39 2006/04/05 09:45:21 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "sbbs.h" ! 39: #include "qwk.h" ! 40: ! 41: faddr_t atofaddr(scfg_t* cfg, char *str); ! 42: ! 43: void pt_zone_kludge(fmsghdr_t hdr,int fido) ! 44: { ! 45: char str[256]; ! 46: ! 47: sprintf(str,"\1INTL %hu:%hu/%hu %hu:%hu/%hu\r" ! 48: ,hdr.destzone,hdr.destnet,hdr.destnode ! 49: ,hdr.origzone,hdr.orignet,hdr.orignode); ! 50: write(fido,str,strlen(str)); ! 51: ! 52: if(hdr.destpoint) { ! 53: sprintf(str,"\1TOPT %hu\r" ! 54: ,hdr.destpoint); ! 55: write(fido,str,strlen(str)); } ! 56: ! 57: if(hdr.origpoint) { ! 58: sprintf(str,"\1FMPT %hu\r" ! 59: ,hdr.origpoint); ! 60: write(fido,str,strlen(str)); } ! 61: } ! 62: ! 63: bool sbbs_t::lookup_netuser(char *into) ! 64: { ! 65: char to[128],name[26],str[256],q[128]; ! 66: int i; ! 67: FILE *stream; ! 68: ! 69: if(strchr(into,'@')) ! 70: return(false); ! 71: strcpy(to,into); ! 72: strupr(to); ! 73: sprintf(str,"%sqnet/users.dat", cfg.data_dir); ! 74: if((stream=fnopen(&i,str,O_RDONLY))==NULL) ! 75: return(false); ! 76: while(!feof(stream)) { ! 77: if(!fgets(str,sizeof(str),stream)) ! 78: break; ! 79: str[25]=0; ! 80: truncsp(str); ! 81: strcpy(name,str); ! 82: strupr(name); ! 83: str[35]=0; ! 84: truncsp(str+27); ! 85: sprintf(q,"Do you mean %s @%s",str,str+27); ! 86: if(strstr(name,to) && yesno(q)) { ! 87: fclose(stream); ! 88: sprintf(into,"%s@%s",str,str+27); ! 89: return(true); } ! 90: if(sys_status&SS_ABORT) ! 91: break; } ! 92: fclose(stream); ! 93: return(false); ! 94: } ! 95: ! 96: /****************************************************************************/ ! 97: /* Send FidoNet/QWK/Internet NetMail from BBS */ ! 98: /****************************************************************************/ ! 99: bool sbbs_t::netmail(char *into, char *title, long mode) ! 100: { ! 101: char str[256],subj[128],to[256],fname[128],*buf,*p,ch; ! 102: char tmp[512]; ! 103: int file,fido,x,cc_found,cc_sent; ! 104: uint i; ! 105: long length,l; ! 106: faddr_t addr; ! 107: fmsghdr_t hdr; ! 108: struct tm tm; ! 109: ! 110: if(useron.etoday>=cfg.level_emailperday[useron.level] && !SYSOP) { ! 111: bputs(text[TooManyEmailsToday]); ! 112: return(false); ! 113: } ! 114: ! 115: SAFECOPY(subj,title); ! 116: ! 117: strcpy(to,into); ! 118: ! 119: lookup_netuser(to); ! 120: ! 121: p=strrchr(to,'@'); /* Find '@' in name@addr */ ! 122: if(p && !isdigit(*(p+1)) && !strchr(p,'.') && !strchr(p,':')) { ! 123: mode&=~WM_FILE; ! 124: qnetmail(to,title,mode|WM_NETMAIL); ! 125: return(false); } ! 126: if(!cfg.total_faddrs || p==NULL || !strchr(p+1,'/')) { ! 127: if(!p && cfg.dflt_faddr.zone) ! 128: addr=cfg.dflt_faddr; ! 129: else if(cfg.inetmail_misc&NMAIL_ALLOW) { ! 130: if(mode&WM_FILE && !SYSOP && !(cfg.inetmail_misc&NMAIL_FILE)) ! 131: mode&=~WM_FILE; ! 132: return(inetmail(into,title,mode|WM_NETMAIL)); ! 133: } ! 134: else if(cfg.dflt_faddr.zone) ! 135: addr=cfg.dflt_faddr; ! 136: else { ! 137: bputs(text[InvalidNetMailAddr]); ! 138: return(false); ! 139: } ! 140: } else { ! 141: addr=atofaddr(&cfg,p+1); /* Get fido address */ ! 142: *p=0; /* Chop off address */ ! 143: } ! 144: ! 145: if(mode&WM_FILE && !SYSOP && !(cfg.netmail_misc&NMAIL_FILE)) ! 146: mode&=~WM_FILE; ! 147: ! 148: if((!SYSOP && !(cfg.netmail_misc&NMAIL_ALLOW)) || useron.rest&FLAG('M') ! 149: || !cfg.total_faddrs) { ! 150: bputs(text[NoNetMailAllowed]); ! 151: return(false); ! 152: } ! 153: ! 154: truncsp(to); /* Truncate off space */ ! 155: ! 156: memset(&hdr,0,sizeof(hdr)); /* Initialize header to null */ ! 157: strcpy(hdr.from,cfg.netmail_misc&NMAIL_ALIAS ? useron.alias : useron.name); ! 158: SAFECOPY(hdr.to,to); ! 159: ! 160: /* Look-up in nodelist? */ ! 161: ! 162: if(cfg.netmail_cost && !(useron.exempt&FLAG('S'))) { ! 163: if(useron.cdt+useron.freecdt<cfg.netmail_cost) { ! 164: bputs(text[NotEnoughCredits]); ! 165: return(false); ! 166: } ! 167: sprintf(str,text[NetMailCostContinueQ],cfg.netmail_cost); ! 168: if(noyes(str)) ! 169: return(false); ! 170: } ! 171: ! 172: now=time(NULL); ! 173: if(localtime_r(&now,&tm)!=NULL) ! 174: sprintf(hdr.time,"%02u %3.3s %02u %02u:%02u:%02u" ! 175: ,tm.tm_mday,mon[tm.tm_mon],TM_YEAR(tm.tm_year) ! 176: ,tm.tm_hour,tm.tm_min,tm.tm_sec); ! 177: ! 178: hdr.destzone =addr.zone; ! 179: hdr.destnet =addr.net; ! 180: hdr.destnode =addr.node; ! 181: hdr.destpoint =addr.point; ! 182: ! 183: for(i=0;i<cfg.total_faddrs;i++) ! 184: if(addr.zone==cfg.faddr[i].zone && addr.net==cfg.faddr[i].net) ! 185: break; ! 186: if(i==cfg.total_faddrs) { ! 187: for(i=0;i<cfg.total_faddrs;i++) ! 188: if(addr.zone==cfg.faddr[i].zone) ! 189: break; ! 190: } ! 191: if(i==cfg.total_faddrs) ! 192: i=0; ! 193: hdr.origzone =cfg.faddr[i].zone; ! 194: hdr.orignet =cfg.faddr[i].net; ! 195: hdr.orignode =cfg.faddr[i].node; ! 196: hdr.origpoint =cfg.faddr[i].point; ! 197: ! 198: smb_faddrtoa(&cfg.faddr[i],str); ! 199: bprintf(text[NetMailing],hdr.to,smb_faddrtoa(&addr,tmp),hdr.from,str); ! 200: ! 201: hdr.attr=(FIDO_LOCAL|FIDO_PRIVATE); ! 202: ! 203: if(cfg.netmail_misc&NMAIL_CRASH) hdr.attr|=FIDO_CRASH; ! 204: if(cfg.netmail_misc&NMAIL_HOLD) hdr.attr|=FIDO_HOLD; ! 205: if(cfg.netmail_misc&NMAIL_KILL) hdr.attr|=FIDO_KILLSENT; ! 206: if(mode&WM_FILE) hdr.attr|=FIDO_FILE; ! 207: ! 208: sprintf(str,"%sNETMAIL.MSG", cfg.node_dir); ! 209: remove(str); /* Just incase it's already there */ ! 210: // mode&=~WM_FILE; ! 211: if(!writemsg(str,nulstr,subj,WM_NETMAIL|mode,INVALID_SUB,into)) { ! 212: bputs(text[Aborted]); ! 213: return(false); ! 214: } ! 215: ! 216: if(mode&WM_FILE) { ! 217: strcpy(fname,subj); ! 218: sprintf(str,"%sfile/%04u.out", cfg.data_dir, useron.number); ! 219: MKDIR(str); ! 220: strcpy(tmp, cfg.data_dir); ! 221: if(tmp[0]=='.') /* Relative path */ ! 222: sprintf(tmp,"%s%s", cfg.node_dir, cfg.data_dir); ! 223: sprintf(str,"%sfile/%04u.out/%s",tmp,useron.number,fname); ! 224: strcpy(subj,str); ! 225: if(fexistcase(str)) { ! 226: bputs(text[FileAlreadyThere]); ! 227: return(false); } ! 228: #if 0 /* no such thing as local logon */ ! 229: if(online==ON_LOCAL) { /* Local upload */ ! 230: bputs(text[EnterPath]); ! 231: if(!getstr(str,60,K_LINE|K_UPPER)) { ! 232: bputs(text[Aborted]); ! 233: return(false); ! 234: } ! 235: backslash(str); ! 236: strcat(str,fname); ! 237: if(mv(str,subj,1)) ! 238: return(false); ! 239: } else ! 240: #endif ! 241: { /* Remote */ ! 242: xfer_prot_menu(XFER_UPLOAD); ! 243: mnemonics(text[ProtocolOrQuit]); ! 244: strcpy(str,"Q"); ! 245: for(x=0;x<cfg.total_prots;x++) ! 246: if(cfg.prot[x]->ulcmd[0] && chk_ar(cfg.prot[x]->ar,&useron)) { ! 247: sprintf(tmp,"%c",cfg.prot[x]->mnemonic); ! 248: strcat(str,tmp); } ! 249: ch=(char)getkeys(str,0); ! 250: if(ch=='Q' || sys_status&SS_ABORT) { ! 251: bputs(text[Aborted]); ! 252: return(false); } ! 253: for(x=0;x<cfg.total_prots;x++) ! 254: if(cfg.prot[x]->ulcmd[0] && cfg.prot[x]->mnemonic==ch ! 255: && chk_ar(cfg.prot[x]->ar,&useron)) ! 256: break; ! 257: if(x<cfg.total_prots) /* This should be always */ ! 258: protocol(cfg.prot[x],XFER_UPLOAD,subj,nulstr,true); ! 259: } ! 260: sprintf(tmp,"%s%s",cfg.temp_dir,title); ! 261: if(!fexistcase(subj) && fexistcase(tmp)) ! 262: mv(tmp,subj,0); ! 263: l=flength(subj); ! 264: if(l>0) ! 265: bprintf(text[FileNBytesReceived],fname,ultoac(l,tmp)); ! 266: else { ! 267: bprintf(text[FileNotReceived],fname); ! 268: return(false); ! 269: } ! 270: } ! 271: ! 272: p=subj; ! 273: if((SYSOP || useron.exempt&FLAG('F')) ! 274: && !strnicmp(p,"CR:",3)) { /* Crash over-ride by sysop */ ! 275: p+=3; /* skip CR: */ ! 276: if(*p==' ') p++; /* skip extra space if it exists */ ! 277: hdr.attr|=FIDO_CRASH; } ! 278: ! 279: if((SYSOP || useron.exempt&FLAG('F')) ! 280: && !strnicmp(p,"FR:",3)) { /* File request */ ! 281: p+=3; /* skip FR: */ ! 282: if(*p==' ') p++; ! 283: hdr.attr|=FIDO_FREQ; } ! 284: ! 285: if((SYSOP || useron.exempt&FLAG('F')) ! 286: && !strnicmp(p,"RR:",3)) { /* Return receipt request */ ! 287: p+=3; /* skip RR: */ ! 288: if(*p==' ') p++; ! 289: hdr.attr|=FIDO_RRREQ; } ! 290: ! 291: if((SYSOP || useron.exempt&FLAG('F')) ! 292: && !strnicmp(p,"FA:",3)) { /* File Attachment */ ! 293: p+=3; /* skip FA: */ ! 294: if(*p==' ') p++; ! 295: hdr.attr|=FIDO_FILE; } ! 296: ! 297: SAFECOPY(hdr.subj,p); ! 298: ! 299: sprintf(str,"%sNETMAIL.MSG", cfg.node_dir); ! 300: if((file=nopen(str,O_RDONLY))==-1) { ! 301: errormsg(WHERE,ERR_OPEN,str,O_RDONLY); ! 302: return(false); } ! 303: length=filelength(file); ! 304: if((buf=(char *)malloc(length))==NULL) { ! 305: close(file); ! 306: errormsg(WHERE,ERR_ALLOC,str,length); ! 307: return(false); } ! 308: read(file,buf,length); ! 309: close(file); ! 310: ! 311: cc_sent=0; ! 312: while(1) { ! 313: for(i=1;i;i++) { ! 314: sprintf(str,"%s%u.msg", cfg.netmail_dir,i); ! 315: if(!fexistcase(str)) ! 316: break; } ! 317: if(!i) { ! 318: bputs(text[TooManyEmailsToday]); ! 319: return(false); } ! 320: if((fido=nopen(str,O_WRONLY|O_CREAT|O_EXCL))==-1) { ! 321: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_EXCL); ! 322: return(false); } ! 323: write(fido,&hdr,sizeof(hdr)); ! 324: ! 325: pt_zone_kludge(hdr,fido); ! 326: ! 327: if(cfg.netmail_misc&NMAIL_DIRECT) { ! 328: sprintf(str,"\1FLAGS DIR\r\n"); ! 329: write(fido,str,strlen(str)); } ! 330: if(mode&WM_FILE) { ! 331: sprintf(str,"\1FLAGS KFS\r\n"); ! 332: write(fido,str,strlen(str)); } ! 333: ! 334: if(cc_sent) { ! 335: sprintf(str,"* Originally to: %s\r\n\r\n",into); ! 336: write(fido,str,strlen(str)); } ! 337: ! 338: l=0L; ! 339: while(l<length) { ! 340: if(buf[l]==CTRL_A) /* Ctrl-A, so skip it and the next char */ ! 341: l++; ! 342: else if(buf[l]!=LF) { ! 343: if((uchar)buf[l]==0x8d) /* r0dent i converted to normal i */ ! 344: buf[l]='i'; ! 345: write(fido,buf+l,1); } ! 346: l++; } ! 347: l=0; ! 348: write(fido,&l,1); /* Null terminator */ ! 349: close(fido); ! 350: ! 351: useron.emails++; ! 352: logon_emails++; ! 353: putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); ! 354: useron.etoday++; ! 355: putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10)); ! 356: ! 357: if(!(useron.exempt&FLAG('S'))) ! 358: subtract_cdt(&cfg,&useron,cfg.netmail_cost); ! 359: if(mode&WM_FILE) ! 360: sprintf(str,"%s sent NetMail file attachment to %s (%s)" ! 361: ,useron.alias ! 362: ,hdr.to,smb_faddrtoa(&addr,tmp)); ! 363: else ! 364: sprintf(str,"%s sent NetMail to %s (%s)" ! 365: ,useron.alias ! 366: ,hdr.to,smb_faddrtoa(&addr,tmp)); ! 367: logline("EN",str); ! 368: ! 369: cc_found=0; ! 370: for(l=0;l<length && cc_found<=cc_sent;l++) ! 371: if(l+3<length && !strnicmp(buf+l,"CC:",3)) { ! 372: cc_found++; ! 373: l+=2; } ! 374: else { ! 375: while(l<length && *(buf+l)!=LF) ! 376: l++; } ! 377: if(!cc_found) ! 378: break; ! 379: while(l<length && *(buf+l)==' ') l++; ! 380: for(i=0;l<length && *(buf+l)!=LF && i<128;i++,l++) ! 381: str[i]=buf[l]; ! 382: if(!i) ! 383: break; ! 384: str[i]=0; ! 385: p=strrchr(str,'@'); ! 386: if(p) { ! 387: addr=atofaddr(&cfg,p+1); ! 388: *p=0; ! 389: SAFECOPY(hdr.to,str); } ! 390: else { ! 391: atofaddr(&cfg,str); ! 392: strcpy(hdr.to,"Sysop"); } ! 393: hdr.destzone =addr.zone; ! 394: hdr.destnet =addr.net; ! 395: hdr.destnode =addr.node; ! 396: hdr.destpoint =addr.point; ! 397: cc_sent++; } ! 398: ! 399: if(cfg.netmail_sem[0]) /* update semaphore file */ ! 400: ftouch(cmdstr(cfg.netmail_sem,nulstr,nulstr,NULL)); ! 401: ! 402: free(buf); ! 403: return(true); ! 404: } ! 405: ! 406: /****************************************************************************/ ! 407: /* Send NetMail from QWK REP Packet */ ! 408: /****************************************************************************/ ! 409: void sbbs_t::qwktonetmail(FILE *rep, char *block, char *into, uchar fromhub) ! 410: { ! 411: char *qwkbuf,to[129],name[129],sender[129],senderaddr[129] ! 412: ,str[256],*p,*cp,*addr,fulladdr[129],ch; ! 413: char tmp[512]; ! 414: int i,fido,inet=0,qnet=0; ! 415: ushort net,xlat; ! 416: long l,offset,length,m,n; ! 417: faddr_t fidoaddr; ! 418: fmsghdr_t hdr; ! 419: smbmsg_t msg; ! 420: struct tm tm; ! 421: ! 422: if(useron.rest&FLAG('M')) { ! 423: bputs(text[NoNetMailAllowed]); ! 424: return; } ! 425: ! 426: sprintf(str,"%.6s",block+116); ! 427: n=atol(str); /* i = number of 128 byte records */ ! 428: ! 429: if(n<2L || n>999999L) { ! 430: errormsg(WHERE,ERR_CHK,"QWK blocks",n); ! 431: return; } ! 432: if((qwkbuf=(char *)malloc(n*QWK_BLOCK_LEN))==NULL) { ! 433: errormsg(WHERE,ERR_ALLOC,nulstr,n*QWK_BLOCK_LEN); ! 434: return; } ! 435: memcpy((char *)qwkbuf,block,QWK_BLOCK_LEN); ! 436: fread(qwkbuf+QWK_BLOCK_LEN,n-1,QWK_BLOCK_LEN,rep); ! 437: ! 438: if(into==NULL) ! 439: sprintf(to,"%-128.128s",(char *)qwkbuf+QWK_BLOCK_LEN); /* To user on first line */ ! 440: else ! 441: strcpy(to,into); ! 442: ! 443: p=strchr(to,QWK_NEWLINE); /* chop off at first CR */ ! 444: if(p) *p=0; ! 445: ! 446: strcpy(name,to); ! 447: p=strchr(name,'@'); ! 448: if(p) *p=0; ! 449: truncsp(name); ! 450: ! 451: ! 452: p=strrchr(to,'@'); /* Find '@' in name@addr */ ! 453: if(p && !isdigit(*(p+1)) && !strchr(p,'.') && !strchr(p,':')) { /* QWKnet */ ! 454: qnet=1; ! 455: *p=0; } ! 456: else if(p==NULL || !isdigit(*(p+1)) || !cfg.total_faddrs) { ! 457: if(p==NULL && cfg.dflt_faddr.zone) ! 458: fidoaddr=cfg.dflt_faddr; ! 459: else if(cfg.inetmail_misc&NMAIL_ALLOW) { /* Internet */ ! 460: inet=1; ! 461: } ! 462: else if(cfg.dflt_faddr.zone) ! 463: fidoaddr=cfg.dflt_faddr; ! 464: else { ! 465: bputs(text[InvalidNetMailAddr]); ! 466: free(qwkbuf); ! 467: return; } } ! 468: else { ! 469: fidoaddr=atofaddr(&cfg,p+1); /* Get fido address */ ! 470: *p=0; /* Chop off address */ ! 471: } ! 472: ! 473: ! 474: if(!inet && !qnet && /* FidoNet */ ! 475: ((!SYSOP && !(cfg.netmail_misc&NMAIL_ALLOW)) || !cfg.total_faddrs)) { ! 476: bputs(text[NoNetMailAllowed]); ! 477: free(qwkbuf); ! 478: return; } ! 479: ! 480: truncsp(to); /* Truncate off space */ ! 481: ! 482: if(!stricmp(to,"SBBS") && !SYSOP && qnet) { ! 483: free(qwkbuf); ! 484: return; } ! 485: ! 486: l=QWK_BLOCK_LEN; /* Start of message text */ ! 487: ! 488: if(qnet || inet) { ! 489: ! 490: if(into==NULL) { /* If name@addr on first line, skip first line */ ! 491: while(l<(n*QWK_BLOCK_LEN) && qwkbuf[l]!=QWK_NEWLINE) l++; ! 492: l++; } ! 493: ! 494: memset(&msg,0,sizeof(smbmsg_t)); ! 495: msg.hdr.version=smb_ver(); ! 496: msg.hdr.when_imported.time=time(NULL); ! 497: msg.hdr.when_imported.zone=sys_timezone(&cfg); ! 498: ! 499: if(fromhub || useron.rest&FLAG('Q')) { ! 500: net=NET_QWK; ! 501: smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net); ! 502: if(!strncmp(qwkbuf+l,"@VIA:",5)) { ! 503: sprintf(str,"%.128s",qwkbuf+l+5); ! 504: cp=strchr(str,QWK_NEWLINE); ! 505: if(cp) *cp=0; ! 506: l+=strlen(str)+1; ! 507: cp=str; ! 508: while(*cp && *cp<=' ') cp++; ! 509: sprintf(senderaddr,"%s/%s" ! 510: ,fromhub ? cfg.qhub[fromhub-1]->id : useron.alias,cp); ! 511: strupr(senderaddr); ! 512: smb_hfield(&msg,SENDERNETADDR,strlen(senderaddr),senderaddr); } ! 513: else { ! 514: if(fromhub) ! 515: strcpy(senderaddr, cfg.qhub[fromhub-1]->id); ! 516: else ! 517: strcpy(senderaddr, useron.alias); ! 518: strupr(senderaddr); ! 519: smb_hfield(&msg,SENDERNETADDR,strlen(senderaddr),senderaddr); } ! 520: sprintf(sender,"%.25s",block+46); } /* From name */ ! 521: else { /* Not Networked */ ! 522: msg.hdr.when_written.zone=sys_timezone(&cfg); ! 523: sprintf(str,"%u",useron.number); ! 524: smb_hfield(&msg,SENDEREXT,strlen(str),str); ! 525: strcpy(sender,(qnet || cfg.inetmail_misc&NMAIL_ALIAS) ! 526: ? useron.alias : useron.name); ! 527: } ! 528: truncsp(sender); ! 529: smb_hfield(&msg,SENDER,strlen(sender),sender); ! 530: if(fromhub) ! 531: msg.idx.from=0; ! 532: else ! 533: msg.idx.from=useron.number; ! 534: if(!strncmp(qwkbuf+l,"@TZ:",4)) { ! 535: sprintf(str,"%.128s",qwkbuf+l); ! 536: cp=strchr(str,QWK_NEWLINE); ! 537: if(cp) *cp=0; ! 538: l+=strlen(str)+1; ! 539: cp=str+4; ! 540: while(*cp && *cp<=' ') cp++; ! 541: msg.hdr.when_written.zone=(short)ahtoul(cp); } ! 542: else ! 543: msg.hdr.when_written.zone=sys_timezone(&cfg); ! 544: memset(&tm,0,sizeof(tm)); ! 545: tm.tm_mon=((qwkbuf[8]&0xf)*10)+(qwkbuf[9]&0xf); ! 546: if(tm.tm_mon) tm.tm_mon--; /* 0 based */ ! 547: tm.tm_mday=((qwkbuf[11]&0xf)*10)+(qwkbuf[12]&0xf); ! 548: tm.tm_year=((qwkbuf[14]&0xf)*10)+(qwkbuf[15]&0xf); ! 549: if(tm.tm_year<Y2K_2DIGIT_WINDOW) ! 550: tm.tm_year+=100; ! 551: tm.tm_hour=((qwkbuf[16]&0xf)*10)+(qwkbuf[17]&0xf); ! 552: tm.tm_min=((qwkbuf[19]&0xf)*10)+(qwkbuf[20]&0xf); /* From QWK time */ ! 553: tm.tm_sec=0; ! 554: ! 555: tm.tm_isdst=-1; /* Do not adjust for DST */ ! 556: msg.hdr.when_written.time=mktime(&tm); ! 557: ! 558: sprintf(str,"%.25s",block+71); /* Title */ ! 559: smb_hfield(&msg,SUBJECT,strlen(str),str); ! 560: } ! 561: ! 562: if(qnet) { ! 563: ! 564: p++; ! 565: addr=p; ! 566: msg.idx.to=qwk_route(addr,fulladdr); ! 567: if(!fulladdr[0]) { /* Invalid address, so BOUNCE it */ ! 568: /** ! 569: errormsg(WHERE,ERR_CHK,addr,0); ! 570: free(qwkbuf); ! 571: smb_freemsgmem(msg); ! 572: return; ! 573: **/ ! 574: smb_hfield(&msg,SENDER,strlen(cfg.sys_id),cfg.sys_id); ! 575: msg.idx.from=0; ! 576: msg.idx.to=useron.number; ! 577: strcpy(to,sender); ! 578: strcpy(fulladdr,senderaddr); ! 579: sprintf(str,"BADADDR: %s",addr); ! 580: smb_hfield(&msg,SUBJECT,strlen(str),str); ! 581: net=NET_NONE; ! 582: smb_hfield(&msg,SENDERNETTYPE,sizeof(net),&net); ! 583: } ! 584: /* This is required for fixsmb to be able to rebuild the index */ ! 585: sprintf(str,"%u",msg.idx.to); ! 586: smb_hfield_str(&msg,RECIPIENTEXT,str); ! 587: ! 588: smb_hfield(&msg,RECIPIENT,strlen(name),name); ! 589: net=NET_QWK; ! 590: smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net); ! 591: ! 592: truncsp(fulladdr); ! 593: smb_hfield(&msg,RECIPIENTNETADDR,strlen(fulladdr),fulladdr); ! 594: ! 595: bprintf(text[NetMailing],to,fulladdr,sender,cfg.sys_id); } ! 596: ! 597: if(inet) { /* Internet E-mail */ ! 598: ! 599: if(cfg.inetmail_cost && !(useron.exempt&FLAG('S'))) { ! 600: if(useron.cdt+useron.freecdt<cfg.inetmail_cost) { ! 601: bputs(text[NotEnoughCredits]); ! 602: free(qwkbuf); ! 603: smb_freemsgmem(&msg); ! 604: return; } ! 605: sprintf(str,text[NetMailCostContinueQ],cfg.inetmail_cost); ! 606: if(noyes(str)) { ! 607: free(qwkbuf); ! 608: smb_freemsgmem(&msg); ! 609: return; } } ! 610: ! 611: net=NET_INTERNET; ! 612: smb_hfield(&msg,RECIPIENT,strlen(name),name); ! 613: msg.idx.to=0; /* Out-bound NetMail set to 0 */ ! 614: smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(net),&net); ! 615: smb_hfield(&msg,RECIPIENTNETADDR,strlen(to),to); ! 616: ! 617: bprintf(text[NetMailing],name,to ! 618: ,cfg.inetmail_misc&NMAIL_ALIAS ? useron.alias : useron.name ! 619: ,cfg.sys_inetaddr); } ! 620: ! 621: if(qnet || inet) { ! 622: ! 623: bputs(text[WritingIndx]); ! 624: ! 625: if((i=smb_stack(&smb,SMB_STACK_PUSH))!=0) { ! 626: errormsg(WHERE,ERR_OPEN,"MAIL",i); ! 627: free(qwkbuf); ! 628: smb_freemsgmem(&msg); ! 629: return; } ! 630: sprintf(smb.file,"%smail", cfg.data_dir); ! 631: smb.retry_time=cfg.smb_retry_time; ! 632: smb.subnum=INVALID_SUB; ! 633: if((i=smb_open(&smb))!=0) { ! 634: smb_stack(&smb,SMB_STACK_POP); ! 635: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); ! 636: free(qwkbuf); ! 637: smb_freemsgmem(&msg); ! 638: return; } ! 639: ! 640: if(smb_fgetlength(smb.shd_fp)<1L) { /* Create it if it doesn't exist */ ! 641: smb.status.max_crcs=cfg.mail_maxcrcs; ! 642: smb.status.max_msgs=0; ! 643: smb.status.max_age=cfg.mail_maxage; ! 644: smb.status.attr=SMB_EMAIL; ! 645: if((i=smb_create(&smb))!=0) { ! 646: smb_close(&smb); ! 647: smb_stack(&smb,SMB_STACK_POP); ! 648: errormsg(WHERE,ERR_CREATE,smb.file,i,smb.last_error); ! 649: free(qwkbuf); ! 650: smb_freemsgmem(&msg); ! 651: return; } } ! 652: ! 653: length=n*256L; // Extra big for CRLF xlat, was (n-1L)*256L (03/16/96) ! 654: ! 655: ! 656: if(length&0xfff00000UL || !length) { ! 657: smb_close(&smb); ! 658: smb_stack(&smb,SMB_STACK_POP); ! 659: sprintf(str,"REP msg (%ld)",n); ! 660: errormsg(WHERE,ERR_LEN,str,length); ! 661: free(qwkbuf); ! 662: smb_freemsgmem(&msg); ! 663: return; } ! 664: ! 665: if((i=smb_open_da(&smb))!=0) { ! 666: smb_close(&smb); ! 667: smb_stack(&smb,SMB_STACK_POP); ! 668: errormsg(WHERE,ERR_OPEN,smb.file,i,smb.last_error); ! 669: free(qwkbuf); ! 670: smb_freemsgmem(&msg); ! 671: return; } ! 672: if(cfg.sys_misc&SM_FASTMAIL) ! 673: offset=smb_fallocdat(&smb,length,1); ! 674: else ! 675: offset=smb_allocdat(&smb,length,1); ! 676: smb_close_da(&smb); ! 677: ! 678: smb_fseek(smb.sdt_fp,offset,SEEK_SET); ! 679: xlat=XLAT_NONE; ! 680: smb_fwrite(&smb,&xlat,2,smb.sdt_fp); ! 681: m=2; ! 682: for(;l<n*QWK_BLOCK_LEN && m<length;l++) { ! 683: if(qwkbuf[l]==0 || qwkbuf[l]==LF) ! 684: continue; ! 685: if(qwkbuf[l]==QWK_NEWLINE) { ! 686: smb_fwrite(&smb,crlf,2,smb.sdt_fp); ! 687: m+=2; ! 688: continue; } ! 689: smb_fputc(qwkbuf[l],smb.sdt_fp); ! 690: m++; } ! 691: ! 692: for(ch=0;m<length;m++) /* Pad out with NULLs */ ! 693: smb_fputc(ch,smb.sdt_fp); ! 694: smb_fflush(smb.sdt_fp); ! 695: ! 696: msg.hdr.offset=offset; ! 697: ! 698: smb_dfield(&msg,TEXT_BODY,length); ! 699: ! 700: i=smb_addmsghdr(&smb,&msg,SMB_SELFPACK); ! 701: smb_close(&smb); ! 702: smb_stack(&smb,SMB_STACK_POP); ! 703: ! 704: smb_freemsgmem(&msg); ! 705: if(i!=SMB_SUCCESS) { ! 706: errormsg(WHERE,ERR_WRITE,smb.file,i,smb.last_error); ! 707: smb_freemsgdat(&smb,offset,length,1); ! 708: } ! 709: else { /* Successful */ ! 710: if(inet) { ! 711: if(cfg.inetmail_sem[0]) /* update semaphore file */ ! 712: ftouch(cmdstr(cfg.inetmail_sem,nulstr,nulstr,NULL)); ! 713: if(!(useron.exempt&FLAG('S'))) ! 714: subtract_cdt(&cfg,&useron,cfg.inetmail_cost); } ! 715: ! 716: useron.emails++; ! 717: logon_emails++; ! 718: putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); ! 719: useron.etoday++; ! 720: putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10)); ! 721: ! 722: sprintf(str,"%s sent %s NetMail to %s (%s) via QWK" ! 723: ,useron.alias ! 724: ,qnet ? "QWK":"Internet",name,qnet ? fulladdr : to); ! 725: logline("EN",str); } ! 726: ! 727: free((char *)qwkbuf); ! 728: return; } ! 729: ! 730: ! 731: /****************************** FidoNet **********************************/ ! 732: ! 733: if(!fidoaddr.zone || !cfg.netmail_dir[0]) { // No fido netmail allowed ! 734: bputs(text[InvalidNetMailAddr]); ! 735: free(qwkbuf); ! 736: return; ! 737: } ! 738: ! 739: memset(&hdr,0,sizeof(hdr)); /* Initialize header to null */ ! 740: ! 741: if(fromhub || useron.rest&FLAG('Q')) { ! 742: sprintf(str,"%.25s",block+46); /* From */ ! 743: truncsp(str); ! 744: sprintf(tmp,"@%s",fromhub ? cfg.qhub[fromhub-1]->id : useron.alias); ! 745: strupr(tmp); ! 746: strcat(str,tmp); } ! 747: else ! 748: strcpy(str,cfg.netmail_misc&NMAIL_ALIAS ? useron.alias : useron.name); ! 749: SAFECOPY(hdr.from,str); ! 750: ! 751: SAFECOPY(hdr.to,to); ! 752: ! 753: /* Look-up in nodelist? */ ! 754: ! 755: if(cfg.netmail_cost && !(useron.exempt&FLAG('S'))) { ! 756: if(useron.cdt+useron.freecdt<cfg.netmail_cost) { ! 757: bputs(text[NotEnoughCredits]); ! 758: free(qwkbuf); ! 759: return; } ! 760: sprintf(str,text[NetMailCostContinueQ],cfg.netmail_cost); ! 761: if(noyes(str)) { ! 762: free(qwkbuf); ! 763: return; } } ! 764: ! 765: hdr.destzone =fidoaddr.zone; ! 766: hdr.destnet =fidoaddr.net; ! 767: hdr.destnode =fidoaddr.node; ! 768: hdr.destpoint =fidoaddr.point; ! 769: ! 770: for(i=0;i<cfg.total_faddrs;i++) ! 771: if(fidoaddr.zone==cfg.faddr[i].zone && fidoaddr.net==cfg.faddr[i].net) ! 772: break; ! 773: if(i==cfg.total_faddrs) { ! 774: for(i=0;i<cfg.total_faddrs;i++) ! 775: if(fidoaddr.zone==cfg.faddr[i].zone) ! 776: break; } ! 777: if(i==cfg.total_faddrs) ! 778: i=0; ! 779: hdr.origzone =cfg.faddr[i].zone; ! 780: hdr.orignet =cfg.faddr[i].net; ! 781: hdr.orignode =cfg.faddr[i].node; ! 782: hdr.origpoint =cfg.faddr[i].point; ! 783: ! 784: smb_faddrtoa(&cfg.faddr[i],str); ! 785: bprintf(text[NetMailing],hdr.to,smb_faddrtoa(&fidoaddr,tmp),hdr.from,str); ! 786: tm.tm_mon=((qwkbuf[8]&0xf)*10)+(qwkbuf[9]&0xf); ! 787: if (tm.tm_mon) tm.tm_mon--; ! 788: tm.tm_mday=((qwkbuf[11]&0xf)*10)+(qwkbuf[12]&0xf); ! 789: tm.tm_year=((qwkbuf[14]&0xf)*10)+(qwkbuf[15]&0xf)+1900; ! 790: tm.tm_hour=((qwkbuf[16]&0xf)*10)+(qwkbuf[17]&0xf); ! 791: tm.tm_min=((qwkbuf[19]&0xf)*10)+(qwkbuf[20]&0xf); /* From QWK time */ ! 792: tm.tm_sec=0; ! 793: sprintf(hdr.time,"%02u %3.3s %02u %02u:%02u:%02u" /* To FidoNet */ ! 794: ,tm.tm_mday,mon[tm.tm_mon],TM_YEAR(tm.tm_year) ! 795: ,tm.tm_hour,tm.tm_min,tm.tm_sec); ! 796: hdr.attr=(FIDO_LOCAL|FIDO_PRIVATE); ! 797: ! 798: if(cfg.netmail_misc&NMAIL_CRASH) hdr.attr|=FIDO_CRASH; ! 799: if(cfg.netmail_misc&NMAIL_HOLD) hdr.attr|=FIDO_HOLD; ! 800: if(cfg.netmail_misc&NMAIL_KILL) hdr.attr|=FIDO_KILLSENT; ! 801: ! 802: sprintf(str,"%.25s",block+71); /* Title */ ! 803: truncsp(str); ! 804: p=str; ! 805: if((SYSOP || useron.exempt&FLAG('F')) ! 806: && !strnicmp(p,"CR:",3)) { /* Crash over-ride by sysop */ ! 807: p+=3; /* skip CR: */ ! 808: if(*p==' ') p++; /* skip extra space if it exists */ ! 809: hdr.attr|=FIDO_CRASH; } ! 810: ! 811: if((SYSOP || useron.exempt&FLAG('F')) ! 812: && !strnicmp(p,"FR:",3)) { /* File request */ ! 813: p+=3; /* skip FR: */ ! 814: if(*p==' ') p++; ! 815: hdr.attr|=FIDO_FREQ; } ! 816: ! 817: if((SYSOP || useron.exempt&FLAG('F')) ! 818: && !strnicmp(p,"RR:",3)) { /* Return receipt request */ ! 819: p+=3; /* skip RR: */ ! 820: if(*p==' ') p++; ! 821: hdr.attr|=FIDO_RRREQ; } ! 822: ! 823: if((SYSOP || useron.exempt&FLAG('F')) ! 824: && !strnicmp(p,"FA:",3)) { /* File attachment */ ! 825: p+=3; /* skip FA: */ ! 826: if(*p==' ') p++; ! 827: hdr.attr|=FIDO_FILE; } ! 828: ! 829: SAFECOPY(hdr.subj,p); ! 830: ! 831: for(i=1;i;i++) { ! 832: sprintf(str,"%s%u.msg", cfg.netmail_dir,i); ! 833: if(!fexistcase(str)) ! 834: break; } ! 835: if(!i) { ! 836: bputs(text[TooManyEmailsToday]); ! 837: return; } ! 838: if((fido=nopen(str,O_WRONLY|O_CREAT|O_EXCL))==-1) { ! 839: free(qwkbuf); ! 840: errormsg(WHERE,ERR_OPEN,str,O_WRONLY|O_CREAT|O_EXCL); ! 841: return; } ! 842: write(fido,&hdr,sizeof(hdr)); ! 843: ! 844: pt_zone_kludge(hdr,fido); ! 845: ! 846: if(cfg.netmail_misc&NMAIL_DIRECT) { ! 847: sprintf(str,"\1FLAGS DIR\r\n"); ! 848: write(fido,str,strlen(str)); } ! 849: ! 850: l=QWK_BLOCK_LEN; ! 851: ! 852: if(into==NULL) { /* If name@addr on first line, skip first line */ ! 853: while(l<n*QWK_BLOCK_LEN && qwkbuf[l]!=QWK_NEWLINE) l++; ! 854: l++; } ! 855: ! 856: while(l<n*QWK_BLOCK_LEN) { ! 857: if(qwkbuf[l]==CTRL_A) /* Ctrl-A, so skip it and the next char */ ! 858: l++; ! 859: else if(qwkbuf[l]!=LF) { ! 860: if(qwkbuf[l]==QWK_NEWLINE) /* QWK cr/lf char converted to hard CR */ ! 861: qwkbuf[l]=CR; ! 862: write(fido,(char *)qwkbuf+l,1); } ! 863: l++; } ! 864: l=0; ! 865: write(fido,&l,1); /* Null terminator */ ! 866: close(fido); ! 867: free((char *)qwkbuf); ! 868: if(cfg.netmail_sem[0]) /* update semaphore file */ ! 869: ftouch(cmdstr(cfg.netmail_sem,nulstr,nulstr,NULL)); ! 870: if(!(useron.exempt&FLAG('S'))) ! 871: subtract_cdt(&cfg,&useron,cfg.netmail_cost); ! 872: ! 873: useron.emails++; ! 874: logon_emails++; ! 875: putuserrec(&cfg,useron.number,U_EMAILS,5,ultoa(useron.emails,tmp,10)); ! 876: useron.etoday++; ! 877: putuserrec(&cfg,useron.number,U_ETODAY,5,ultoa(useron.etoday,tmp,10)); ! 878: ! 879: sprintf(str,"%s sent NetMail to %s @%s via QWK" ! 880: ,useron.alias ! 881: ,hdr.to,smb_faddrtoa(&fidoaddr,tmp)); ! 882: logline("EN",str); ! 883: } ! 884: ! 885: /****************************************************************************/ ! 886: /* Returns the FidoNet address kept in str as ASCII. */ ! 887: /****************************************************************************/ ! 888: faddr_t atofaddr(scfg_t* cfg, char *str) ! 889: { ! 890: char *p; ! 891: faddr_t addr; ! 892: ! 893: addr.zone=addr.net=addr.node=addr.point=0; ! 894: if((p=strchr(str,':'))!=NULL) { ! 895: addr.zone=atoi(str); ! 896: addr.net=atoi(p+1); } ! 897: else { ! 898: if(cfg->total_faddrs) ! 899: addr.zone=cfg->faddr[0].zone; ! 900: else ! 901: addr.zone=1; ! 902: addr.net=atoi(str); } ! 903: if(!addr.zone) /* no such thing as zone 0 */ ! 904: addr.zone=1; ! 905: if((p=strchr(str,'/'))!=NULL) ! 906: addr.node=atoi(p+1); ! 907: else { ! 908: if(cfg->total_faddrs) ! 909: addr.net=cfg->faddr[0].net; ! 910: else ! 911: addr.net=1; ! 912: addr.node=atoi(str); } ! 913: if((p=strchr(str,'.'))!=NULL) ! 914: addr.point=atoi(p+1); ! 915: return(addr); ! 916: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.