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