|
|
1.1 ! root 1: /* sbbsecho.c */ ! 2: ! 3: /* Synchronet FidoNet EchoMail Scanning/Tossing and NetMail Tossing Utility */ ! 4: ! 5: /* $Id: sbbsecho.c,v 1.182 2006/06/27 22:26:15 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: /* Portions written by Allen Christiansen 1994-1996 */ ! 39: ! 40: #ifdef _WIN32 ! 41: #include <windows.h> ! 42: #endif ! 43: ! 44: #include <time.h> ! 45: #include <errno.h> ! 46: #include <stdio.h> ! 47: #include <ctype.h> ! 48: #include <fcntl.h> ! 49: #include <stdarg.h> ! 50: #include <stdlib.h> ! 51: #include <string.h> ! 52: #include <sys/stat.h> ! 53: ! 54: #ifdef __WATCOMC__ ! 55: #include <mem.h> ! 56: #endif ! 57: ! 58: #ifndef __unix__ ! 59: #include <malloc.h> ! 60: #endif ! 61: ! 62: #include "conwrap.h" /* getch() */ ! 63: #include "sbbs.h" /* load_cfg() */ ! 64: #include "sbbsdefs.h" ! 65: #include "smblib.h" ! 66: #include "scfglib.h" ! 67: #include "lzh.h" ! 68: #include "sbbsecho.h" ! 69: #include "genwrap.h" /* PLATFORM_DESC */ ! 70: ! 71: smb_t *smb,*email; ! 72: long misc=(IMPORT_PACKETS|IMPORT_NETMAIL|IMPORT_ECHOMAIL|EXPORT_ECHOMAIL ! 73: |DELETE_NETMAIL|DELETE_PACKETS); ! 74: ulong netmail=0; ! 75: int log_level=LOG_NOTICE; ! 76: char tmp[256],pkt_type=0; ! 77: int secure,cur_smb=0; ! 78: FILE *fidologfile=NULL; ! 79: two_two_t two_two; ! 80: two_plus_t two_plus; ! 81: BOOL twit_list; ! 82: ! 83: faddr_t sys_faddr = {1,1,1,0}; /* Default system address: 1:1/1.0 */ ! 84: config_t cfg; ! 85: scfg_t scfg; ! 86: char revision[16]; ! 87: char compiler[32]; ! 88: ! 89: BOOL pause_on_exit=FALSE; ! 90: ! 91: #ifndef __NT__ ! 92: #define delfile(x) remove(x) ! 93: #else ! 94: int delfile(char *filename) ! 95: { ! 96: int i=0; ! 97: ! 98: while(remove(filename) && i++<120) /* Wait up to 60 seconds to delete file */ ! 99: delay(500); /* for Win95 bug fix */ ! 100: return(i); ! 101: } ! 102: #endif ! 103: ! 104: #if defined(__unix__) /* borrowed from MSVC */ ! 105: unsigned _rotr ( ! 106: unsigned val, ! 107: int shift ! 108: ) ! 109: { ! 110: register unsigned lobit; /* non-zero means lo bit set */ ! 111: register unsigned num = val; /* number to rotate */ ! 112: ! 113: shift &= 0x1f; /* modulo 32 -- this will also make ! 114: negative shifts work */ ! 115: while (shift--) { ! 116: lobit = num & 1; /* get high bit */ ! 117: num >>= 1; /* shift right one bit */ ! 118: if (lobit) ! 119: num |= 0x80000000; /* set hi bit if lo bit was set */ ! 120: } ! 121: ! 122: return num; ! 123: } ! 124: #endif ! 125: ! 126: void logprintf(char *str, ...); ! 127: ! 128: /****************************************************************************/ ! 129: /* This is needed by load_cfg.c */ ! 130: /****************************************************************************/ ! 131: int lprintf(int level, char *fmat, ...) ! 132: { ! 133: va_list argptr; ! 134: char sbuf[256]; ! 135: int chcount; ! 136: ! 137: va_start(argptr,fmat); ! 138: chcount=vsnprintf(sbuf,sizeof(sbuf),fmat,argptr); ! 139: sbuf[sizeof(sbuf)-1]=0; ! 140: va_end(argptr); ! 141: truncsp(sbuf); ! 142: printf("%s\n",sbuf); ! 143: ! 144: if(level<=log_level) ! 145: logprintf("%s",sbuf); ! 146: return(chcount); ! 147: } ! 148: ! 149: /**********************/ ! 150: /* Log print function */ ! 151: /**********************/ ! 152: void logprintf(char *str, ...) ! 153: { ! 154: va_list argptr; ! 155: char buf[256]; ! 156: time_t now; ! 157: struct tm *gm; ! 158: ! 159: if(!(misc&LOGFILE) || fidologfile==NULL) ! 160: return; ! 161: va_start(argptr,str); ! 162: vsnprintf(buf,sizeof(buf),str,argptr); ! 163: buf[sizeof(buf)-1]=0; ! 164: va_end(argptr); ! 165: now=time(NULL); ! 166: gm=localtime(&now); ! 167: fprintf(fidologfile,"%02u/%02u/%02u %02u:%02u:%02u %s\n" ! 168: ,gm->tm_mon+1,gm->tm_mday,TM_YEAR(gm->tm_year),gm->tm_hour,gm->tm_min,gm->tm_sec ! 169: ,buf); ! 170: } ! 171: ! 172: /*****************************************************************************/ ! 173: /* Returns command line generated from instr with %c replacments */ ! 174: /*****************************************************************************/ ! 175: char *mycmdstr(scfg_t* cfg, char *instr, char *fpath, char *fspec) ! 176: { ! 177: static char cmd[MAX_PATH+1]; ! 178: char str[256],str2[128]; ! 179: int i,j,len; ! 180: ! 181: len=strlen(instr); ! 182: for(i=j=0;i<len && j<128;i++) { ! 183: if(instr[i]=='%') { ! 184: i++; ! 185: cmd[j]=0; ! 186: switch(toupper(instr[i])) { ! 187: case 'F': /* File path */ ! 188: strcat(cmd,fpath); ! 189: break; ! 190: case 'G': /* Temp directory */ ! 191: if(cfg->temp_dir[0]!='\\' ! 192: && cfg->temp_dir[0]!='/' ! 193: && cfg->temp_dir[1]!=':') { ! 194: strcpy(str,cfg->node_dir); ! 195: strcat(str,cfg->temp_dir); ! 196: if(FULLPATH(str2,str,40)) ! 197: strcpy(str,str2); ! 198: backslash(str); ! 199: strcat(cmd,str);} ! 200: else ! 201: strcat(cmd,cfg->temp_dir); ! 202: break; ! 203: case 'J': ! 204: if(cfg->data_dir[0]!='\\' ! 205: && cfg->data_dir[0]!='/' ! 206: && cfg->data_dir[1]!=':') { ! 207: strcpy(str,cfg->node_dir); ! 208: strcat(str,cfg->data_dir); ! 209: if(FULLPATH(str2,str,40)) ! 210: strcpy(str,str2); ! 211: backslash(str); ! 212: strcat(cmd,str); } ! 213: else ! 214: strcat(cmd,cfg->data_dir); ! 215: break; ! 216: case 'K': ! 217: if(cfg->ctrl_dir[0]!='\\' ! 218: && cfg->ctrl_dir[0]!='/' ! 219: && cfg->ctrl_dir[1]!=':') { ! 220: strcpy(str,cfg->node_dir); ! 221: strcat(str,cfg->ctrl_dir); ! 222: if(FULLPATH(str2,str,40)) ! 223: strcpy(str,str2); ! 224: backslash(str); ! 225: strcat(cmd,str); } ! 226: else ! 227: strcat(cmd,cfg->ctrl_dir); ! 228: break; ! 229: case 'N': /* Node Directory (same as SBBSNODE environment var) */ ! 230: strcat(cmd,cfg->node_dir); ! 231: break; ! 232: case 'O': /* SysOp */ ! 233: strcat(cmd,cfg->sys_op); ! 234: break; ! 235: case 'Q': /* QWK ID */ ! 236: strcat(cmd,cfg->sys_id); ! 237: break; ! 238: case 'S': /* File Spec */ ! 239: strcat(cmd,fspec); ! 240: break; ! 241: case '!': /* EXEC Directory */ ! 242: strcat(cmd,cfg->exec_dir); ! 243: break; ! 244: case '@': /* EXEC Directory for DOS/OS2/Win32, blank for Unix */ ! 245: #ifndef __unix__ ! 246: strcat(cmd,cfg->exec_dir); ! 247: #endif ! 248: break; ! 249: case '#': /* Node number (same as SBBSNNUM environment var) */ ! 250: sprintf(str,"%d",cfg->node_num); ! 251: strcat(cmd,str); ! 252: break; ! 253: case '*': ! 254: sprintf(str,"%03d",cfg->node_num); ! 255: strcat(cmd,str); ! 256: break; ! 257: case '%': /* %% for percent sign */ ! 258: strcat(cmd,"%"); ! 259: break; ! 260: case '.': /* .exe for DOS/OS2/Win32, blank for Unix */ ! 261: #ifndef __unix__ ! 262: strcat(cmd,".exe"); ! 263: #endif ! 264: break; ! 265: case '?': /* Platform */ ! 266: #ifdef __OS2__ ! 267: strcpy(str,"OS2"); ! 268: #else ! 269: strcpy(str,PLATFORM_DESC); ! 270: #endif ! 271: strlwr(str); ! 272: strcat(cmd,str); ! 273: break; ! 274: default: /* unknown specification */ ! 275: lprintf(LOG_ERR,"ERROR Checking Command Line '%s'",instr); ! 276: bail(1); ! 277: break; } ! 278: j=strlen(cmd); } ! 279: else ! 280: cmd[j++]=instr[i]; } ! 281: cmd[j]=0; ! 282: ! 283: return(cmd); ! 284: } ! 285: ! 286: /****************************************************************************/ ! 287: /* Runs an external program directly using spawnvp */ ! 288: /****************************************************************************/ ! 289: int execute(char *cmdline) ! 290: { ! 291: #if 1 ! 292: return system(cmdline); ! 293: #else ! 294: char c,d,e,cmdlen,*arg[30],str[256]; ! 295: int i; ! 296: ! 297: strcpy(str,cmdline); ! 298: arg[0]=str; /* point to the beginning of the string */ ! 299: cmdlen=strlen(str); ! 300: for(c=0,d=1,e=0;c<cmdlen;c++,e++) /* Break up command line */ ! 301: if(str[c]==' ') { ! 302: str[c]=0; /* insert nulls */ ! 303: arg[d++]=str+c+1; /* point to the beginning of the next arg */ ! 304: e=0; } ! 305: arg[d]=0; ! 306: i=spawnvp(P_WAIT,arg[0],arg); ! 307: return(i); ! 308: #endif ! 309: } ! 310: ! 311: /****************************************************************************** ! 312: Returns the system address with the same zone as the address passed ! 313: ******************************************************************************/ ! 314: faddr_t getsysfaddr(short zone) ! 315: { ! 316: int i; ! 317: ! 318: for(i=0;i<scfg.total_faddrs;i++) ! 319: if(scfg.faddr[i].zone==zone) ! 320: return(scfg.faddr[i]); ! 321: return(sys_faddr); ! 322: } ! 323: ! 324: /****************************************************************************** ! 325: This function creates or appends on existing Binkley compatible .?LO file ! 326: attach file. ! 327: Returns 0 on success. ! 328: ******************************************************************************/ ! 329: int write_flofile(char *attachment, faddr_t dest, BOOL bundle) ! 330: { ! 331: char fname[MAX_PATH+1]; ! 332: char outbound[MAX_PATH+1]; ! 333: char str[MAX_PATH+1]; ! 334: char ch; ! 335: char searchstr[MAX_PATH+1]; ! 336: ushort attr=0; ! 337: int i,file; ! 338: FILE *stream; ! 339: ! 340: i=matchnode(dest,0); ! 341: if(i<(int)cfg.nodecfgs) ! 342: attr=cfg.nodecfg[i].attr; ! 343: ! 344: if(attr&ATTR_CRASH) ch='c'; ! 345: else if(attr&ATTR_HOLD) ch='h'; ! 346: else if(attr&ATTR_DIRECT) ch='d'; ! 347: else ch='f'; ! 348: if(dest.zone==sys_faddr.zone) /* Default zone, use default outbound */ ! 349: strcpy(outbound,cfg.outbound); ! 350: else { /* Inter-zone outbound is OUTBOUND.XXX */ ! 351: sprintf(outbound,"%.*s.%03x" ! 352: ,(int)strlen(cfg.outbound)-1,cfg.outbound,dest.zone); ! 353: MKDIR(outbound); ! 354: backslash(outbound); ! 355: } ! 356: if(dest.point) { /* Point destination is OUTBOUND\*.PNT */ ! 357: sprintf(str,"%04x%04x.pnt" ! 358: ,dest.net,dest.node); ! 359: strcat(outbound,str); } ! 360: if(outbound[strlen(outbound)-1]=='\\' ! 361: || outbound[strlen(outbound)-1]=='/') ! 362: outbound[strlen(outbound)-1]=0; ! 363: MKDIR(outbound); ! 364: backslash(outbound); ! 365: if(dest.point) ! 366: sprintf(fname,"%s%08x.%clo",outbound,dest.point,ch); ! 367: else ! 368: sprintf(fname,"%s%04x%04x.%clo",outbound,dest.net,dest.node,ch); ! 369: if(bundle && misc&TRUNC_BUNDLES) ! 370: ch='#'; ! 371: else ! 372: ch='^'; ! 373: if(*attachment == '^') /* work-around for BRE/FE inter-BBS attachment bug */ ! 374: attachment++; ! 375: fexistcase(attachment); /* just in-case it's the wrong case for a Unix file system */ ! 376: sprintf(searchstr,"%c%s",ch,attachment); ! 377: if(findstr(searchstr,fname)) /* file already in FLO file */ ! 378: return(0); ! 379: if((stream=fopen(fname,"a"))==NULL) { ! 380: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,fname,strerror(errno)); ! 381: return(-1); ! 382: } ! 383: fprintf(stream,"%s\n",searchstr); ! 384: fclose(stream); ! 385: return(0); ! 386: } ! 387: ! 388: /* Writes text buffer to file, expanding sole LFs to CRLFs */ ! 389: size_t fwrite_crlf(char* buf, size_t len, FILE* fp) ! 390: { ! 391: char ch,last_ch=0; ! 392: size_t i; ! 393: size_t wr=0; /* total chars written (may be > len) */ ! 394: ! 395: for(i=0;i<len;i++) { ! 396: ch=*buf++; ! 397: if(ch=='\n' && last_ch!='\r') { ! 398: if(fputc('\r',fp)==EOF) ! 399: return(wr); ! 400: wr++; ! 401: } ! 402: if(fputc(ch,fp)==EOF) ! 403: return(wr); ! 404: wr++; ! 405: last_ch=ch; ! 406: } ! 407: ! 408: return(wr); ! 409: } ! 410: ! 411: /****************************************************************************** ! 412: This function will create a netmail message (.MSG format). ! 413: If file is non-zero, will set file attachment bit (for bundles). ! 414: Returns 0 on success. ! 415: ******************************************************************************/ ! 416: int create_netmail(char *to, char *subject, char *body, faddr_t dest, BOOL file_attached) ! 417: { ! 418: FILE *fstream; ! 419: char str[256],fname[MAX_PATH+1]; ! 420: ushort attr=0; ! 421: int fmsg; ! 422: uint i; ! 423: static uint startmsg; ! 424: time_t t; ! 425: faddr_t faddr; ! 426: fmsghdr_t hdr; ! 427: struct tm *tm; ! 428: ! 429: if(!startmsg) startmsg=1; ! 430: i=matchnode(dest,0); ! 431: if(i<cfg.nodecfgs) { ! 432: attr=cfg.nodecfg[i].attr; ! 433: if(!attr) { ! 434: i=matchnode(dest,2); ! 435: if(i<cfg.nodecfgs) ! 436: attr=cfg.nodecfg[i].attr; } } ! 437: ! 438: do { ! 439: for(i=startmsg;i;i++) { ! 440: sprintf(fname,"%s%u.msg",scfg.netmail_dir,i); ! 441: if(!fexistcase(fname)) ! 442: break; ! 443: } ! 444: if(!i) { ! 445: lprintf(LOG_WARNING,"Directory full: %s",scfg.netmail_dir); ! 446: return(-1); } ! 447: startmsg=i+1; ! 448: if((fstream=fnopen(&fmsg,fname,O_RDWR|O_CREAT))==NULL) { ! 449: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,fname,strerror(errno)); ! 450: return(-1); } ! 451: ! 452: faddr=getsysfaddr(dest.zone); ! 453: memset(&hdr,0,sizeof(fmsghdr_t)); ! 454: hdr.origzone=faddr.zone; ! 455: hdr.orignet=faddr.net; ! 456: hdr.orignode=faddr.node; ! 457: hdr.origpoint=faddr.point; ! 458: hdr.destzone=dest.zone; ! 459: hdr.destnet=dest.net; ! 460: hdr.destnode=dest.node; ! 461: hdr.destpoint=dest.point; ! 462: ! 463: hdr.attr=(FIDO_PRIVATE|FIDO_KILLSENT|FIDO_LOCAL); ! 464: if(file_attached) ! 465: hdr.attr|=FIDO_FILE; ! 466: ! 467: if(attr&ATTR_HOLD) ! 468: hdr.attr|=FIDO_HOLD; ! 469: if(attr&ATTR_CRASH) ! 470: hdr.attr|=FIDO_CRASH; ! 471: ! 472: sprintf(hdr.from,"SBBSecho"); ! 473: ! 474: t=time(NULL); ! 475: tm=localtime(&t); ! 476: sprintf(hdr.time,"%02u %3.3s %02u %02u:%02u:%02u" ! 477: ,tm->tm_mday,mon[tm->tm_mon],TM_YEAR(tm->tm_year) ! 478: ,tm->tm_hour,tm->tm_min,tm->tm_sec); ! 479: ! 480: if(to) ! 481: SAFECOPY(hdr.to,to); ! 482: else ! 483: SAFECOPY(hdr.to,"SYSOP"); ! 484: ! 485: SAFECOPY(hdr.subj,subject); ! 486: ! 487: fwrite(&hdr,sizeof(fmsghdr_t),1,fstream); ! 488: sprintf(str,"\1INTL %hu:%hu/%hu %hu:%hu/%hu\r" ! 489: ,hdr.destzone,hdr.destnet,hdr.destnode ! 490: ,hdr.origzone,hdr.orignet,hdr.orignode); ! 491: fwrite(str,strlen(str),1,fstream); ! 492: ! 493: /* Add FSC-53 FLAGS kludge */ ! 494: fprintf(fstream,"\1FLAGS"); ! 495: if(attr&ATTR_DIRECT) ! 496: fprintf(fstream," DIR"); ! 497: if(file_attached) { ! 498: if(misc&TRUNC_BUNDLES) ! 499: fprintf(fstream," TFS"); ! 500: else ! 501: fprintf(fstream," KFS"); ! 502: } ! 503: fprintf(fstream,"\r"); ! 504: ! 505: if(hdr.destpoint) { ! 506: sprintf(str,"\1TOPT %hu\r",hdr.destpoint); ! 507: fwrite(str,strlen(str),1,fstream); } ! 508: if(hdr.origpoint) { ! 509: sprintf(str,"\1FMPT %hu\r",hdr.origpoint); ! 510: fwrite(str,strlen(str),1,fstream); } ! 511: if(!file_attached || (!(attr&ATTR_DIRECT) && file_attached)) ! 512: fwrite_crlf(body,strlen(body)+1,fstream); /* Write additional NULL */ ! 513: else ! 514: fwrite("\0",1,1,fstream); /* Write NULL */ ! 515: fclose(fstream); ! 516: } while(!fexistcase(fname)); ! 517: return(0); ! 518: } ! 519: ! 520: /****************************************************************************** ! 521: This function takes the contents of 'infile' and puts it into a netmail ! 522: message bound for addr. ! 523: ******************************************************************************/ ! 524: void file_to_netmail(FILE *infile,char *title,faddr_t addr,char *to) ! 525: { ! 526: char *buf,*p; ! 527: long l,m,len; ! 528: ! 529: l=len=ftell(infile); ! 530: if(len>8192L) ! 531: len=8192L; ! 532: rewind(infile); ! 533: if((buf=(char *)malloc(len+1))==NULL) { ! 534: lprintf(LOG_ERR,"ERROR line %d allocating %lu for file to netmail buf",__LINE__,len); ! 535: return; } ! 536: while((m=fread(buf,1,(len>8064L) ? 8064L:len,infile))>0) { ! 537: buf[m]=0; ! 538: if(l>8064L && (p=strrchr(buf,'\n'))!=NULL) { ! 539: p++; ! 540: if(*p) { ! 541: *p=0; ! 542: p++; ! 543: fseek(infile,-1L,SEEK_CUR); ! 544: while(*p) { /* Seek back to end of last line */ ! 545: p++; ! 546: fseek(infile,-1L,SEEK_CUR); } } } ! 547: if(ftell(infile)<l) ! 548: strcat(buf,"\r\nContinued in next message...\r\n"); ! 549: create_netmail(to,title,buf,addr,FALSE); ! 550: } ! 551: free(buf); ! 552: } ! 553: /****************************************************************************** ! 554: This function sends a notify list to applicable nodes, this list includes the ! 555: settings configured for the node, as well as a list of areas the node is ! 556: connected to. ! 557: ******************************************************************************/ ! 558: void notify_list(void) ! 559: { ! 560: FILE * tmpf; ! 561: char str[256]; ! 562: uint i,j,k; ! 563: ! 564: for(k=0;k<cfg.nodecfgs;k++) { ! 565: ! 566: if(!(cfg.nodecfg[k].attr&SEND_NOTIFY)) ! 567: continue; ! 568: ! 569: if((tmpf=tmpfile())==NULL) { ! 570: lprintf(LOG_ERR,"ERROR line %d couldn't open tmpfile",__LINE__); ! 571: return; } ! 572: ! 573: fprintf(tmpf,"Following are the options set for your system and a list " ! 574: "of areas\r\nyou are connected to. Please make sure everything " ! 575: "is correct.\r\n\r\n"); ! 576: fprintf(tmpf,"Packet Type %s\r\n" ! 577: ,cfg.nodecfg[k].pkt_type==PKT_TWO ? "2" ! 578: :cfg.nodecfg[k].pkt_type==PKT_TWO_TWO ? "2.2":"2+"); ! 579: fprintf(tmpf,"Archive Type %s\r\n" ! 580: ,(cfg.nodecfg[k].arctype>cfg.arcdefs) ? ! 581: "None":cfg.arcdef[cfg.nodecfg[k].arctype].name); ! 582: fprintf(tmpf,"Mail Status %s\r\n" ! 583: ,cfg.nodecfg[k].attr&ATTR_CRASH ? "Crash" ! 584: :cfg.nodecfg[k].attr&ATTR_HOLD ? "Hold" : "None"); ! 585: fprintf(tmpf,"Direct %s\r\n" ! 586: ,cfg.nodecfg[k].attr&ATTR_DIRECT ? "Yes":"No"); ! 587: fprintf(tmpf,"Passive %s\r\n" ! 588: ,cfg.nodecfg[k].attr&ATTR_PASSIVE ? "Yes":"No"); ! 589: fprintf(tmpf,"Remote AreaMgr %s\r\n\r\n" ! 590: ,cfg.nodecfg[k].password[0] ? "Yes" : "No"); ! 591: ! 592: fprintf(tmpf,"Connected Areas\r\n---------------\r\n"); ! 593: for(i=0;i<cfg.areas;i++) { ! 594: sprintf(str,"%s\r\n",cfg.area[i].name); ! 595: if(str[0]=='*') ! 596: continue; ! 597: for(j=0;j<cfg.area[i].uplinks;j++) ! 598: if(!memcmp(&cfg.nodecfg[k].faddr,&cfg.area[i].uplink[j] ! 599: ,sizeof(faddr_t))) ! 600: break; ! 601: if(j<cfg.area[i].uplinks) ! 602: fprintf(tmpf,"%s",str); } ! 603: ! 604: if(ftell(tmpf)) ! 605: file_to_netmail(tmpf,"SBBSecho Notify List",cfg.nodecfg[k].faddr, /* To: */NULL); ! 606: fclose(tmpf); } ! 607: } ! 608: /****************************************************************************** ! 609: This function creates a netmail to addr showing a list of available areas (0), ! 610: a list of connected areas (1), or a list of removed areas (2). ! 611: ******************************************************************************/ ! 612: void netmail_arealist(int type, faddr_t addr, char* to) ! 613: { ! 614: FILE *stream,*tmpf; ! 615: char str[256],temp[256],title[128],match,*p,*tp; ! 616: int file,i,j,k,x,y; ! 617: ! 618: if(!type) ! 619: strcpy(title,"List of Available Areas"); ! 620: else if(type==1) ! 621: strcpy(title,"List of Connected Areas"); ! 622: else ! 623: strcpy(title,"List of Unlinked Areas"); ! 624: ! 625: if((tmpf=tmpfile())==NULL) { ! 626: lprintf(LOG_ERR,"ERROR line %d couldn't open tmpfile",__LINE__); ! 627: return; } ! 628: ! 629: if(type==1 || !(misc&ELIST_ONLY)) { ! 630: for(i=0;i<cfg.areas;i++) { ! 631: if(type) { ! 632: for(j=0;j<cfg.area[i].uplinks;j++) ! 633: if(!memcmp(&addr,&cfg.area[i].uplink[j],sizeof(faddr_t))) ! 634: break; ! 635: if((type==1 && j<cfg.area[i].uplinks) || ! 636: (type==2 && j==cfg.area[i].uplinks)) ! 637: fprintf(tmpf,"%s\r\n",cfg.area[i].name); } ! 638: else ! 639: fprintf(tmpf,"%s\r\n",cfg.area[i].name); } } ! 640: ! 641: if(!type) { ! 642: i=matchnode(addr,0); ! 643: if(i<cfg.nodecfgs) { ! 644: for(j=0;j<cfg.listcfgs;j++) { ! 645: match=0; ! 646: for(k=0;k<cfg.listcfg[j].numflags;k++) { ! 647: if(match) break; ! 648: for(x=0;x<cfg.nodecfg[i].numflags;x++) ! 649: if(!stricmp(cfg.listcfg[j].flag[k].flag ! 650: ,cfg.nodecfg[i].flag[x].flag)) { ! 651: if((stream=fopen(cfg.listcfg[j].listpath,"r"))==NULL) { ! 652: lprintf(LOG_ERR,"ERROR line %d couldn't open %s %s" ! 653: ,__LINE__,cfg.listcfg[j].listpath ! 654: ,strerror(errno)); ! 655: match=1; ! 656: break; } ! 657: while(!feof(stream)) { ! 658: if(!fgets(str,sizeof(str),stream)) ! 659: break; ! 660: p=str; ! 661: SKIP_WHITESPACE(p); ! 662: if(*p==';') /* Ignore Comment Lines */ ! 663: continue; ! 664: tp=p; ! 665: FIND_WHITESPACE(tp); ! 666: *tp=0; ! 667: if(!(misc&ELIST_ONLY)) { ! 668: for(y=0;y<cfg.areas;y++) ! 669: if(!stricmp(cfg.area[y].name,p)) ! 670: break; ! 671: if(y==cfg.areas) ! 672: fprintf(tmpf,"%s\r\n",p); } ! 673: else ! 674: fprintf(tmpf,"%s\r\n",p); } ! 675: fclose(stream); ! 676: match=1; ! 677: break; } } } } } ! 678: ! 679: if(!ftell(tmpf)) ! 680: create_netmail(to,title,"None.",addr,FALSE); ! 681: else ! 682: file_to_netmail(tmpf,title,addr,to); ! 683: fclose(tmpf); ! 684: } ! 685: /****************************************************************************** ! 686: Imitation of Borland's tempnam function because Watcom doesn't have it ! 687: ******************************************************************************/ ! 688: char *tempname(char *dir, char *prefix) ! 689: { ! 690: char str[MAX_PATH+1],*p; ! 691: int i; ! 692: ! 693: for(i=0;i<1000;i++) { ! 694: sprintf(str,"%s%s%03u.$$$",dir,prefix,i); ! 695: if(!fexist(str)) ! 696: break; } ! 697: if(i>=1000) { ! 698: lprintf(LOG_ERR,"tempnam: too many files"); ! 699: return(NULL); } ! 700: p=malloc(strlen(str)+1); ! 701: if(!p) { ! 702: lprintf(LOG_CRIT,"tempnam: couldn't malloc %u",strlen(str)+1); ! 703: return(NULL); } ! 704: strcpy(p,str); ! 705: return(p); ! 706: } ! 707: ! 708: int check_elists(char *areatag,faddr_t addr) ! 709: { ! 710: FILE *stream; ! 711: char str[1025],quit=0,*p,*tp; ! 712: int i,j,k,x,file,match=0; ! 713: ! 714: i=matchnode(addr,0); ! 715: if(i<cfg.nodecfgs) { ! 716: for(j=0;j<cfg.listcfgs;j++) { ! 717: quit=0; ! 718: for(k=0;k<cfg.listcfg[j].numflags;k++) { ! 719: if(quit) break; ! 720: for(x=0;x<cfg.nodecfg[i].numflags;x++) ! 721: if(!stricmp(cfg.listcfg[j].flag[k].flag ! 722: ,cfg.nodecfg[i].flag[x].flag)) { ! 723: if((stream=fopen(cfg.listcfg[j].listpath,"r"))==NULL) { ! 724: lprintf(LOG_ERR,"ERROR line %d opening %s" ! 725: ,__LINE__,cfg.listcfg[j].listpath); ! 726: quit=1; ! 727: break; } ! 728: while(!feof(stream)) { ! 729: if(!fgets(str,sizeof(str),stream)) ! 730: break; ! 731: p=str; ! 732: SKIP_WHITESPACE(p); ! 733: if(*p==';') /* Ignore Comment Lines */ ! 734: continue; ! 735: tp=p; ! 736: FIND_WHITESPACE(tp); ! 737: *tp=0; ! 738: if(!stricmp(areatag,p)) { ! 739: match=1; ! 740: break; } } ! 741: fclose(stream); ! 742: quit=1; ! 743: if(match) ! 744: return(match); ! 745: break; } } } } ! 746: return(match); ! 747: } ! 748: /****************************************************************************** ! 749: Used by AREAFIX to add/remove/change areas in the areas file ! 750: ******************************************************************************/ ! 751: void alter_areas(area_t* add_area, area_t* del_area, faddr_t addr, char* to) ! 752: { ! 753: FILE *nmfile,*afilein,*afileout,*fwdfile; ! 754: char str[1024],fields[1024],field1[256],field2[256],field3[256] ! 755: ,outpath[MAX_PATH+1] ! 756: ,*outname,*p,*tp,nomatch=0,match=0; ! 757: int i,j,k,x,y; ! 758: ulong tagcrc; ! 759: ! 760: SAFECOPY(outpath,cfg.areafile); ! 761: *getfname(outpath)=0; ! 762: if((outname=tempname(outpath,"AREAS"))==NULL) { ! 763: lprintf(LOG_ERR,"ERROR tempnam(%s,AREAS)",outpath); ! 764: return; } ! 765: if((nmfile=tmpfile())==NULL) { ! 766: lprintf(LOG_ERR,"ERROR in tmpfile()"); ! 767: free(outname); ! 768: return; } ! 769: if((afileout=fopen(outname,"w+"))==NULL) { ! 770: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,outname ! 771: ,strerror(errno)); ! 772: fclose(nmfile); ! 773: free(outname); ! 774: return; } ! 775: if((afilein=fopen(cfg.areafile,"r"))==NULL) { ! 776: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,cfg.areafile ! 777: ,strerror(errno)); ! 778: fclose(afileout); ! 779: fclose(nmfile); ! 780: free(outname); ! 781: return; } ! 782: while(!feof(afilein)) { ! 783: if(!fgets(fields,sizeof(fields),afilein)) ! 784: break; ! 785: truncsp(fields); ! 786: p=fields; ! 787: SKIP_WHITESPACE(p); ! 788: if(*p==';') { /* Skip Comment Lines */ ! 789: fprintf(afileout,"%s\n",fields); ! 790: continue; } ! 791: SAFECOPY(field1,p); /* Internal Code Field */ ! 792: truncstr(field1," \t\r\n"); ! 793: FIND_WHITESPACE(p); ! 794: SKIP_WHITESPACE(p); ! 795: SAFECOPY(field2,p); /* Areatag Field */ ! 796: truncstr(field2," \t\r\n"); ! 797: FIND_WHITESPACE(p); ! 798: SKIP_WHITESPACE(p); ! 799: if((tp=strchr(p,';'))!=NULL) { ! 800: SAFECOPY(field3,p); /* Comment Field (if any) */ ! 801: FIND_WHITESPACE(tp); ! 802: *tp=0; } ! 803: else ! 804: field3[0]=0; ! 805: if(del_area->tags) { /* Check for areas to remove */ ! 806: for(i=0;i<del_area->tags;i++) { ! 807: if(!stricmp(del_area->tag[i],field2) || ! 808: !stricmp(del_area->tag[0],"-ALL")) /* Match Found */ ! 809: break; } ! 810: if(i<del_area->tags) { ! 811: for(i=0;i<cfg.areas;i++) { ! 812: if(!stricmp(field2,cfg.area[i].name)) { ! 813: for(j=0;j<cfg.area[i].uplinks;j++) ! 814: if(!memcmp(&cfg.area[i].uplink[j],&addr ! 815: ,sizeof(faddr_t))) ! 816: break; ! 817: if(j==cfg.area[i].uplinks) { ! 818: fprintf(afileout,"%s\n",fields); ! 819: /* bugfix here Mar-25-2004 (wasn't breaking for "-ALL") */ ! 820: if(stricmp(del_area->tag[0],"-ALL")) ! 821: fprintf(nmfile,"%s not connected.\r\n",field2); ! 822: break; ! 823: } ! 824: ! 825: /* Added 12/4/95 to remove uplink from connected uplinks */ ! 826: ! 827: for(k=j;k<cfg.area[i].uplinks-1;k++) ! 828: memcpy(&cfg.area[i].uplink[k],&cfg.area[i].uplink[k+1] ! 829: ,sizeof(faddr_t)); ! 830: --cfg.area[i].uplinks; ! 831: if(cfg.area[i].uplinks==0) { ! 832: FREE_AND_NULL(cfg.area[i].uplink); ! 833: } else ! 834: if((cfg.area[i].uplink=(faddr_t *) ! 835: realloc(cfg.area[i].uplink,sizeof(faddr_t) ! 836: *(cfg.area[i].uplinks)))==NULL) { ! 837: lprintf(LOG_ERR,"ERROR line %d allocating memory for area " ! 838: "#%u uplinks.",__LINE__,i+1); ! 839: bail(1); ! 840: } ! 841: ! 842: fprintf(afileout,"%-16s%-23s ",field1,field2); ! 843: for(j=0;j<cfg.area[i].uplinks;j++) { ! 844: if(!memcmp(&cfg.area[i].uplink[j],&addr ! 845: ,sizeof(faddr_t))) ! 846: continue; ! 847: fprintf(afileout,"%s " ! 848: ,smb_faddrtoa(&cfg.area[i].uplink[j],NULL)); } ! 849: if(field3[0]) ! 850: fprintf(afileout,"%s",field3); ! 851: fprintf(afileout,"\n"); ! 852: fprintf(nmfile,"%s removed.\r\n",field2); ! 853: break; ! 854: } ! 855: } ! 856: if(i==cfg.areas) /* Something screwy going on */ ! 857: fprintf(afileout,"%s\n",fields); ! 858: continue; } } /* Area match so continue on */ ! 859: if(add_area->tags) { /* Check for areas to add */ ! 860: for(i=0;i<add_area->tags;i++) ! 861: if(!stricmp(add_area->tag[i],field2) || ! 862: !stricmp(add_area->tag[0],"+ALL")) /* Match Found */ ! 863: break; ! 864: if(i<add_area->tags) { ! 865: if(stricmp(add_area->tag[i],"+ALL")) ! 866: add_area->tag[i][0]=0; /* So we can check other lists */ ! 867: for(i=0;i<cfg.areas;i++) { ! 868: if(!stricmp(field2,cfg.area[i].name)) { ! 869: for(j=0;j<cfg.area[i].uplinks;j++) ! 870: if(!memcmp(&cfg.area[i].uplink[j],&addr ! 871: ,sizeof(faddr_t))) ! 872: break; ! 873: if(j<cfg.area[i].uplinks) { ! 874: fprintf(afileout,"%s\n",fields); ! 875: fprintf(nmfile,"%s already connected.\r\n",field2); ! 876: break; } ! 877: if(misc&ELIST_ONLY && !check_elists(field2,addr)) { ! 878: fprintf(afileout,"%s\n",fields); ! 879: break; } ! 880: ! 881: /* Added 12/4/95 to add uplink to connected uplinks */ ! 882: ! 883: ++cfg.area[i].uplinks; ! 884: if((cfg.area[i].uplink=(faddr_t *) ! 885: realloc(cfg.area[i].uplink,sizeof(faddr_t) ! 886: *(cfg.area[i].uplinks)))==NULL) { ! 887: lprintf(LOG_ERR,"ERROR line %d allocating memory for area " ! 888: "#%u uplinks.",__LINE__,i+1); ! 889: bail(1); } ! 890: memcpy(&cfg.area[i].uplink[j],&addr,sizeof(faddr_t)); ! 891: ! 892: fprintf(afileout,"%-16s%-23s ",field1,field2); ! 893: for(j=0;j<cfg.area[i].uplinks;j++) ! 894: fprintf(afileout,"%s " ! 895: ,smb_faddrtoa(&cfg.area[i].uplink[j],NULL)); ! 896: if(field3[0]) ! 897: fprintf(afileout,"%s",field3); ! 898: fprintf(afileout,"\n"); ! 899: fprintf(nmfile,"%s added.\r\n",field2); ! 900: break; } } ! 901: if(i==cfg.areas) /* Something screwy going on */ ! 902: fprintf(afileout,"%s\n",fields); ! 903: continue; } /* Area match so continue on */ ! 904: nomatch=1; } /* This area wasn't in there */ ! 905: fprintf(afileout,"%s\n",fields); } /* No match so write back line */ ! 906: fclose(afilein); ! 907: if(nomatch || (add_area->tags && !stricmp(add_area->tag[0],"+ALL"))) { ! 908: i=matchnode(addr,0); ! 909: if(i<cfg.nodecfgs) { ! 910: for(j=0;j<cfg.listcfgs;j++) { ! 911: match=0; ! 912: for(k=0;k<cfg.listcfg[j].numflags;k++) { ! 913: if(match) break; ! 914: for(x=0;x<cfg.nodecfg[i].numflags;x++) ! 915: if(!stricmp(cfg.listcfg[j].flag[k].flag ! 916: ,cfg.nodecfg[i].flag[x].flag)) { ! 917: if((fwdfile=tmpfile())==NULL) { ! 918: lprintf(LOG_ERR,"ERROR line %d opening forward temp " ! 919: "file",__LINE__); ! 920: match=1; ! 921: break; } ! 922: if((afilein=fopen(cfg.listcfg[j].listpath,"r"))==NULL) { ! 923: lprintf(LOG_ERR,"ERROR line %d opening %s" ! 924: ,__LINE__,cfg.listcfg[j].listpath); ! 925: fclose(fwdfile); ! 926: match=1; ! 927: break; } ! 928: while(!feof(afilein)) { ! 929: if(!fgets(str,sizeof(str),afilein)) ! 930: break; ! 931: p=str; ! 932: SKIP_WHITESPACE(p); ! 933: if(*p==';') /* Ignore Comment Lines */ ! 934: continue; ! 935: tp=p; ! 936: FIND_WHITESPACE(tp); ! 937: *tp=0; ! 938: if(!stricmp(add_area->tag[0],"+ALL")) { ! 939: SAFECOPY(tmp,p); ! 940: tagcrc=crc32(strupr(tmp),0); ! 941: for(y=0;y<cfg.areas;y++) ! 942: if(tagcrc==cfg.area[y].tag) ! 943: break; ! 944: if(y<cfg.areas) ! 945: continue; } ! 946: for(y=0;y<add_area->tags;y++) ! 947: if((!stricmp(add_area->tag[y],str) && ! 948: add_area->tag[y][0]) || ! 949: !stricmp(add_area->tag[0],"+ALL")) ! 950: break; ! 951: if(y<add_area->tags) { ! 952: fprintf(afileout,"%-16s%-23s","P",str); ! 953: if(cfg.listcfg[j].forward.zone) ! 954: fprintf(afileout," %s" ! 955: ,smb_faddrtoa(&cfg.listcfg[j].forward,NULL)); ! 956: fprintf(afileout," %s\n",smb_faddrtoa(&addr,NULL)); ! 957: fprintf(nmfile,"%s added.\r\n",str); ! 958: if(stricmp(add_area->tag[0],"+ALL")) ! 959: add_area->tag[y][0]=0; ! 960: if(!(cfg.listcfg[j].misc&NOFWD) ! 961: && cfg.listcfg[j].forward.zone) ! 962: fprintf(fwdfile,"%s\r\n",str); } } ! 963: fclose(afilein); ! 964: if(!(cfg.listcfg[j].misc&NOFWD) && ftell(fwdfile)>0) ! 965: file_to_netmail(fwdfile,cfg.listcfg[j].password ! 966: ,cfg.listcfg[j].forward,/* To: */"Areafix"); ! 967: fclose(fwdfile); ! 968: match=1; ! 969: break; } } } } } ! 970: if(add_area->tags && stricmp(add_area->tag[0],"+ALL")) { ! 971: for(i=0;i<add_area->tags;i++) ! 972: if(add_area->tag[i][0]) ! 973: fprintf(nmfile,"%s not found.\r\n",add_area->tag[i]); } ! 974: if(!ftell(nmfile)) ! 975: create_netmail(to,"Area Change Request","No changes made.",addr,FALSE); ! 976: else ! 977: file_to_netmail(nmfile,"Area Change Request",addr,to); ! 978: fclose(nmfile); ! 979: fclose(afileout); ! 980: if(delfile(cfg.areafile)) /* Delete AREAS.BBS */ ! 981: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,cfg.areafile ! 982: ,strerror(errno)); ! 983: if(rename(outname,cfg.areafile)) /* Rename new AREAS.BBS file */ ! 984: lprintf(LOG_ERR,"ERROR line %d renaming %s to %s",__LINE__,outname,cfg.areafile); ! 985: free(outname); ! 986: } ! 987: /****************************************************************************** ! 988: Used by AREAFIX to add/remove/change uplink info in the configuration file ! 989: old = the old setting for this option, new = what the setting is changing to ! 990: option = 0 for compression type change ! 991: 1 for areafix password change ! 992: 2 to set this node to passive ! 993: 3 to set this node to active (remove passive) ! 994: ******************************************************************************/ ! 995: void alter_config(faddr_t addr, char *old, char *new, int option) ! 996: { ! 997: FILE *outfile,*cfgfile; ! 998: char str[257],outpath[MAX_PATH+1],tmp[257],tmp2[257],*outname,*p,*tp ! 999: ,match=0; ! 1000: int i,j,k,file; ! 1001: faddr_t taddr; ! 1002: ! 1003: i=matchnode(addr,0); /* i = config number from here on */ ! 1004: SAFECOPY(outpath,cfg.cfgfile); ! 1005: *getfname(outpath)=0; ! 1006: if((outname=tempname(outpath,"CFG"))==NULL) { ! 1007: lprintf(LOG_ERR,"ERROR tempnam(%s,CFG)",outpath); ! 1008: return; } ! 1009: if((outfile=fopen(outname,"w+"))==NULL) { ! 1010: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,outname ! 1011: ,strerror(errno)); ! 1012: free(outname); ! 1013: return; } ! 1014: if((cfgfile=fopen(cfg.cfgfile,"r"))==NULL) { ! 1015: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,cfg.cfgfile ! 1016: ,strerror(errno)); ! 1017: fclose(outfile); ! 1018: free(outname); ! 1019: return; } ! 1020: ! 1021: while(!feof(cfgfile)) { ! 1022: if(!fgets(str,sizeof(str),cfgfile)) ! 1023: break; ! 1024: truncsp(str); ! 1025: p=str; ! 1026: SKIP_WHITESPACE(p); ! 1027: if(*p==';') { ! 1028: fprintf(outfile,"%s\n",str); ! 1029: continue; } ! 1030: sprintf(tmp,"%-.25s",p); ! 1031: tp=strchr(tmp,' '); ! 1032: if(tp) ! 1033: *tp=0; /* Chop off at space */ ! 1034: strupr(tmp); /* Convert code to uppercase */ ! 1035: FIND_WHITESPACE(p); /* Skip code */ ! 1036: SKIP_WHITESPACE(p); /* Skip white space */ ! 1037: ! 1038: if(option==0 && !strcmp(tmp,"USEPACKER")) { /* Change Compression */ ! 1039: if(!*p) ! 1040: continue; ! 1041: strcpy(tmp2,p); ! 1042: p=tmp2; ! 1043: FIND_WHITESPACE(p); ! 1044: *p=0; ! 1045: p++; ! 1046: if(!stricmp(new,tmp2)) { /* Add to new definition */ ! 1047: fprintf(outfile,"%-10s %s %s %s\n",tmp,tmp2 ! 1048: ,smb_faddrtoa(&cfg.nodecfg[i].faddr,NULL) ! 1049: ,(*p) ? p : ""); ! 1050: match=1; ! 1051: continue; } ! 1052: else if(!stricmp(old,tmp2)) { /* Remove from old def */ ! 1053: for(j=k=0;j<cfg.nodecfgs;j++) { ! 1054: if(j==i) ! 1055: continue; ! 1056: if(!stricmp(cfg.arcdef[cfg.nodecfg[j].arctype].name,tmp2)) { ! 1057: if(!k) { ! 1058: fprintf(outfile,"%-10s %s",tmp,tmp2); ! 1059: k++; } ! 1060: fprintf(outfile," %s" ! 1061: ,smb_faddrtoa(&cfg.nodecfg[j].faddr,NULL)); } } ! 1062: fprintf(outfile,"\n"); ! 1063: continue; } } ! 1064: ! 1065: if(option==1 && !strcmp(tmp,"AREAFIX")) { /* Change Password */ ! 1066: if(!*p) ! 1067: continue; ! 1068: taddr=smb_atofaddr(&sys_faddr,p); ! 1069: if(!memcmp(&cfg.nodecfg[i].faddr,&taddr,sizeof(faddr_t))) { ! 1070: FIND_WHITESPACE(p); /* Skip over address */ ! 1071: SKIP_WHITESPACE(p); /* Skip over whitespace */ ! 1072: FIND_WHITESPACE(p); /* Skip over password */ ! 1073: SKIP_WHITESPACE(p); /* Skip over whitespace */ ! 1074: fprintf(outfile,"%-10s %s %s %s\n",tmp ! 1075: ,smb_faddrtoa(&cfg.nodecfg[i].faddr,NULL),new,p); ! 1076: continue; } } ! 1077: ! 1078: if(option>1 && !strcmp(tmp,"PASSIVE")) { /* Toggle Passive Areas */ ! 1079: match=1; ! 1080: for(j=k=0;j<cfg.nodecfgs;j++) { ! 1081: if(option==2 && j==i) { ! 1082: if(!k) fprintf(outfile,"%-10s",tmp); ! 1083: fprintf(outfile," %s",smb_faddrtoa(&cfg.nodecfg[j].faddr,NULL)); ! 1084: k++; ! 1085: continue; } ! 1086: if(option==3 && j==i) ! 1087: continue; ! 1088: if(cfg.nodecfg[j].attr&ATTR_PASSIVE) { ! 1089: if(!k) fprintf(outfile,"%-10s",tmp); ! 1090: fprintf(outfile," %s",smb_faddrtoa(&cfg.nodecfg[j].faddr,NULL)); ! 1091: k++; } } ! 1092: if(k) fprintf(outfile,"\n"); ! 1093: continue; } ! 1094: fprintf(outfile,"%s\n",str); } ! 1095: ! 1096: if(!match) { ! 1097: if(option==0) ! 1098: fprintf(outfile,"%-10s %s %s\n","USEPACKER",new ! 1099: ,smb_faddrtoa(&cfg.nodecfg[i].faddr,NULL)); ! 1100: if(option==2) ! 1101: fprintf(outfile,"%-10s %s\n","PASSIVE" ! 1102: ,smb_faddrtoa(&cfg.nodecfg[i].faddr,NULL)); } ! 1103: ! 1104: fclose(cfgfile); ! 1105: fclose(outfile); ! 1106: if(delfile(cfg.cfgfile)) ! 1107: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,cfg.cfgfile ! 1108: ,strerror(errno)); ! 1109: if(rename(outname,cfg.cfgfile)) ! 1110: lprintf(LOG_ERR,"ERROR line %d renaming %s to %s",__LINE__,outname,cfg.cfgfile); ! 1111: free(outname); ! 1112: } ! 1113: /****************************************************************************** ! 1114: Used by AREAFIX to process any '%' commands that come in via netmail ! 1115: ******************************************************************************/ ! 1116: void command(char* instr, faddr_t addr, char* to) ! 1117: { ! 1118: FILE *stream,*tmpf; ! 1119: char str[MAX_PATH+1],temp[256],*buf,*p; ! 1120: int file,i,node; ! 1121: long l; ! 1122: area_t add_area,del_area; ! 1123: ! 1124: node=matchnode(addr,0); ! 1125: if(node>=cfg.nodecfgs) ! 1126: return; ! 1127: memset(&add_area,0,sizeof(area_t)); ! 1128: memset(&del_area,0,sizeof(area_t)); ! 1129: strupr(instr); ! 1130: if((p=strstr(instr,"HELP"))!=NULL) { ! 1131: sprintf(str,"%sAREAMGR.HLP",scfg.exec_dir); ! 1132: if(!fexistcase(str)) ! 1133: return; ! 1134: if((stream=fnopen(&file,str,O_RDONLY))==NULL) { ! 1135: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,str ! 1136: ,strerror(errno)); ! 1137: return; ! 1138: } ! 1139: l=filelength(file); ! 1140: if((buf=(char *)malloc(l+1L))==NULL) { ! 1141: lprintf(LOG_CRIT,"ERROR line %d allocating %lu bytes for %s",__LINE__,l,str); ! 1142: return; ! 1143: } ! 1144: fread(buf,l,1,stream); ! 1145: fclose(stream); ! 1146: buf[l]=0; ! 1147: create_netmail(to,"Area Manager Help",buf,addr,FALSE); ! 1148: free(buf); ! 1149: return; ! 1150: } ! 1151: ! 1152: if((p=strstr(instr,"LIST"))!=NULL) { ! 1153: netmail_arealist(0,addr,to); ! 1154: return; ! 1155: } ! 1156: ! 1157: if((p=strstr(instr,"QUERY"))!=NULL) { ! 1158: netmail_arealist(1,addr,to); ! 1159: return; ! 1160: } ! 1161: ! 1162: if((p=strstr(instr,"UNLINKED"))!=NULL) { ! 1163: netmail_arealist(2,addr,to); ! 1164: return; ! 1165: } ! 1166: ! 1167: if((p=strstr(instr,"COMPRESSION"))!=NULL) { ! 1168: FIND_WHITESPACE(p); ! 1169: SKIP_WHITESPACE(p); ! 1170: for(i=0;i<cfg.arcdefs;i++) ! 1171: if(!stricmp(p,cfg.arcdef[i].name)) ! 1172: break; ! 1173: if(!stricmp(p,"NONE")) ! 1174: i=0xffff; ! 1175: if(i==cfg.arcdefs) { ! 1176: if((tmpf=tmpfile())==NULL) { ! 1177: lprintf(LOG_ERR,"ERROR line %d opening tmpfile()",__LINE__); ! 1178: return; } ! 1179: fprintf(tmpf,"Compression type unavailable.\r\n\r\n" ! 1180: "Available types are:\r\n"); ! 1181: for(i=0;i<cfg.arcdefs;i++) ! 1182: fprintf(tmpf," %s\r\n",cfg.arcdef[i].name); ! 1183: file_to_netmail(tmpf,"Compression Type Change",addr,to); ! 1184: fclose(tmpf); ! 1185: return; ! 1186: } ! 1187: alter_config(addr,cfg.arcdef[cfg.nodecfg[node].arctype].name ! 1188: ,cfg.arcdef[i].name,0); ! 1189: cfg.nodecfg[node].arctype=i; ! 1190: sprintf(str,"Compression type changed to %s.",cfg.arcdef[i].name); ! 1191: create_netmail(to,"Compression Type Change",str,addr,FALSE); ! 1192: return; ! 1193: } ! 1194: ! 1195: if((p=strstr(instr,"PASSWORD"))!=NULL) { ! 1196: FIND_WHITESPACE(p); ! 1197: SKIP_WHITESPACE(p); ! 1198: sprintf(temp,"%-.25s",p); ! 1199: p=temp; ! 1200: FIND_WHITESPACE(p); ! 1201: *p=0; ! 1202: if(node>=cfg.nodecfgs) /* Should never happen */ ! 1203: return; ! 1204: if(!stricmp(temp,cfg.nodecfg[node].password)) { ! 1205: sprintf(str,"Your password was already set to %s." ! 1206: ,cfg.nodecfg[node].password); ! 1207: create_netmail(to,"Password Change Request",str,addr,FALSE); ! 1208: return; } ! 1209: alter_config(addr,cfg.nodecfg[node].password,temp,1); ! 1210: sprintf(str,"Your password has been changed from %s to %.25s." ! 1211: ,cfg.nodecfg[node].password,temp); ! 1212: sprintf(cfg.nodecfg[node].password,"%.25s",temp); ! 1213: create_netmail(to,"Password Change Request",str,addr,FALSE); ! 1214: return; ! 1215: } ! 1216: ! 1217: if((p=strstr(instr,"RESCAN"))!=NULL) { ! 1218: export_echomail("",addr); ! 1219: create_netmail(to,"Rescan Areas" ! 1220: ,"All connected areas carried by your hub have been rescanned." ! 1221: ,addr,FALSE); ! 1222: return; ! 1223: } ! 1224: ! 1225: if((p=strstr(instr,"ACTIVE"))!=NULL) { ! 1226: if(!(cfg.nodecfg[node].attr&ATTR_PASSIVE)) { ! 1227: create_netmail(to,"Reconnect Disconnected Areas" ! 1228: ,"Your areas are already connected.",addr,FALSE); ! 1229: return; } ! 1230: alter_config(addr,0,0,3); ! 1231: create_netmail(to,"Reconnect Disconnected Areas" ! 1232: ,"Temporarily disconnected areas have been reconnected.",addr,FALSE); ! 1233: return; ! 1234: } ! 1235: ! 1236: if((p=strstr(instr,"PASSIVE"))!=NULL) { ! 1237: if(cfg.nodecfg[node].attr&ATTR_PASSIVE) { ! 1238: create_netmail(to,"Temporarily Disconnect Areas" ! 1239: ,"Your areas are already temporarily disconnected.",addr,FALSE); ! 1240: return; ! 1241: } ! 1242: alter_config(addr,0,0,2); ! 1243: create_netmail(to,"Temporarily Disconnect Areas" ! 1244: ,"Your areas have been temporarily disconnected.",addr,FALSE); ! 1245: return; ! 1246: } ! 1247: ! 1248: if((p=strstr(instr,"FROM"))!=NULL); ! 1249: ! 1250: if((p=strstr(instr,"+ALL"))!=NULL) { ! 1251: if((add_area.tag=(char **)realloc(add_area.tag ! 1252: ,sizeof(char *)*add_area.tags+1))==NULL) { ! 1253: lprintf(LOG_ERR,"ERROR line %d allocating memory for add area tag #%u" ! 1254: ,__LINE__,add_area.tags+1); ! 1255: bail(1); } ! 1256: if((add_area.tag[add_area.tags]=(char *)malloc(strlen(instr)+1))==NULL) { ! 1257: lprintf(LOG_ERR,"ERROR line %d allocating memory for add area tag #%u" ! 1258: ,__LINE__,add_area.tags+1); ! 1259: bail(1); } ! 1260: strcpy(add_area.tag[add_area.tags],instr); ! 1261: add_area.tags++; ! 1262: alter_areas(&add_area,&del_area,addr,to); ! 1263: for(i=0;i<add_area.tags;i++) ! 1264: free(add_area.tag[i]); ! 1265: FREE_AND_NULL(add_area.tag); ! 1266: return; ! 1267: } ! 1268: ! 1269: if((p=strstr(instr,"-ALL"))!=NULL) { ! 1270: if((del_area.tag=(char **)realloc(del_area.tag ! 1271: ,sizeof(char *)*del_area.tags+1))==NULL) { ! 1272: lprintf(LOG_ERR,"ERROR line %d allocating memory for del area tag #%u" ! 1273: ,__LINE__,del_area.tags+1); ! 1274: bail(1); } ! 1275: if((del_area.tag[del_area.tags]=(char *)malloc(strlen(instr)+1))==NULL) { ! 1276: lprintf(LOG_ERR,"ERROR line %d allocating memory for del area tag #%u" ! 1277: ,__LINE__,del_area.tags+1); ! 1278: bail(1); } ! 1279: strcpy(del_area.tag[del_area.tags],instr); ! 1280: del_area.tags++; ! 1281: alter_areas(&add_area,&del_area,addr,to); ! 1282: for(i=0;i<del_area.tags;i++) ! 1283: free(del_area.tag[i]); ! 1284: FREE_AND_NULL(del_area.tag); ! 1285: return; ! 1286: } ! 1287: } ! 1288: /****************************************************************************** ! 1289: This is where we're gonna process any netmail that comes in for areafix. ! 1290: Returns text for message body for the local sysop if necessary. ! 1291: ******************************************************************************/ ! 1292: char* process_areafix(faddr_t addr, char* inbuf, char* password, char* to) ! 1293: { ! 1294: static char body[512]; ! 1295: char str[128]; ! 1296: char *p,*tp,action,percent=0; ! 1297: int i; ! 1298: ulong l,m; ! 1299: area_t add_area,del_area; ! 1300: ! 1301: p=(char *)inbuf; ! 1302: ! 1303: while(*p==1) { /* Skip kludge lines 11/05/95 */ ! 1304: FIND_CHAR(p,'\r'); ! 1305: if(*p) { ! 1306: p++; /* Skip CR (required) */ ! 1307: if(*p=='\n') ! 1308: p++; /* Skip LF (optional) */ ! 1309: } ! 1310: } ! 1311: ! 1312: if(((tp=strstr(p,"---\r"))!=NULL || (tp=strstr(p,"--- "))!=NULL) && ! 1313: (*(tp-1)=='\r' || *(tp-1)=='\n')) ! 1314: *tp=0; ! 1315: ! 1316: if(!strnicmp(p,"%FROM",5)) { /* Remote Remote Maintenance (must be first) */ ! 1317: SAFECOPY(str,p+6); ! 1318: truncstr(str,"\r\n"); ! 1319: lprintf(LOG_NOTICE,"Remote maintenance for %s requested via %s",str ! 1320: ,smb_faddrtoa(&addr,NULL)); ! 1321: addr=atofaddr(str); } ! 1322: ! 1323: i=matchnode(addr,0); ! 1324: if(i>=cfg.nodecfgs) { ! 1325: create_netmail(to,"Areafix Request" ! 1326: ,"Your node is not configured for Areafix, please contact your hub.\r\n",addr,FALSE); ! 1327: sprintf(body,"An areafix request was made by node %s.\r\nThis node " ! 1328: "is not currently configured for areafix.\r\n" ! 1329: ,smb_faddrtoa(&addr,NULL)); ! 1330: return(body); } ! 1331: ! 1332: if(stricmp(cfg.nodecfg[i].password,password)) { ! 1333: create_netmail(to,"Areafix Request","Invalid Password.",addr,FALSE); ! 1334: sprintf(body,"Node %s attempted an areafix request using an invalid " ! 1335: "password.\r\nThe password attempted was %s.\r\nThe correct password " ! 1336: "for this node is %s.\r\n",smb_faddrtoa(&addr,NULL),password ! 1337: ,(cfg.nodecfg[i].password[0]) ? cfg.nodecfg[i].password ! 1338: : "[None Defined]"); ! 1339: return(body); } ! 1340: ! 1341: m=strlen(p); ! 1342: add_area.tags=0; ! 1343: add_area.tag=NULL; ! 1344: del_area.tags=0; ! 1345: del_area.tag=NULL; ! 1346: for(l=0;l<m;l++) { ! 1347: while(*(p+l) && isspace(*(p+l))) l++; ! 1348: while(*(p+l)==1) { /* Ignore kludge lines June-13-2004 */ ! 1349: while(*(p+l) && *(p+l)!='\r') l++; ! 1350: continue; ! 1351: } ! 1352: if(!(*(p+l))) break; ! 1353: if(*(p+l)=='+' || *(p+l)=='-' || *(p+l)=='%') { ! 1354: action=*(p+l); ! 1355: l++; } ! 1356: else ! 1357: action='+'; ! 1358: SAFECOPY(str,p+l); ! 1359: truncstr(str,"\r\n"); ! 1360: switch(action) { ! 1361: case '+': /* Add Area */ ! 1362: if((add_area.tag=(char **)realloc(add_area.tag ! 1363: ,sizeof(char *)*add_area.tags+1))==NULL) { ! 1364: lprintf(LOG_ERR,"ERROR line %d allocating memory for add area " ! 1365: "tag #%u",__LINE__,add_area.tags+1); ! 1366: bail(1); } ! 1367: if((add_area.tag[add_area.tags]=(char *)malloc(strlen(str)+1)) ! 1368: ==NULL) { ! 1369: lprintf(LOG_ERR,"ERROR line %d allocating memory for add area " ! 1370: "tag #%u",__LINE__,add_area.tags+1); ! 1371: bail(1); } ! 1372: strcpy(add_area.tag[add_area.tags],str); ! 1373: add_area.tags++; ! 1374: break; ! 1375: case '-': /* Remove Area */ ! 1376: if((del_area.tag=(char **)realloc(del_area.tag ! 1377: ,sizeof(char *)*del_area.tags+1))==NULL) { ! 1378: lprintf(LOG_ERR,"ERROR line %d allocating memory for del area " ! 1379: "tag #%u",__LINE__,del_area.tags+1); ! 1380: bail(1); } ! 1381: if((del_area.tag[del_area.tags]=(char *)malloc(strlen(str)+1)) ! 1382: ==NULL) { ! 1383: lprintf(LOG_ERR,"ERROR line %d allocating memory for del area " ! 1384: "tag #%u",__LINE__,del_area.tags+1); ! 1385: bail(1); } ! 1386: strcpy(del_area.tag[del_area.tags],str); ! 1387: del_area.tags++; ! 1388: break; ! 1389: case '%': /* Process Command */ ! 1390: command(str,addr,to); ! 1391: percent++; ! 1392: break; } ! 1393: ! 1394: while(*(p+l) && *(p+l)!='\r') l++; } ! 1395: ! 1396: if(!percent && !add_area.tags && !del_area.tags) { ! 1397: create_netmail(to,"Areafix Request","No commands to process.",addr,FALSE); ! 1398: sprintf(body,"Node %s attempted an areafix request with an empty message " ! 1399: "body or with no valid commands.\r\n",smb_faddrtoa(&addr,NULL)); ! 1400: return(body); } ! 1401: if(add_area.tags || del_area.tags) ! 1402: alter_areas(&add_area,&del_area,addr,to); ! 1403: if(add_area.tags) { ! 1404: for(i=0;i<add_area.tags;i++) ! 1405: free(add_area.tag[i]); ! 1406: FREE_AND_NULL(add_area.tag); } ! 1407: if(del_area.tags) { ! 1408: for(i=0;i<del_area.tags;i++) ! 1409: free(del_area.tag[i]); ! 1410: FREE_AND_NULL(del_area.tag); } ! 1411: return(0); ! 1412: } ! 1413: /****************************************************************************** ! 1414: This function will compare the archive signatures defined in the CFG file and ! 1415: extract 'infile' using the appropriate de-archiver. ! 1416: ******************************************************************************/ ! 1417: int unpack(char *infile) ! 1418: { ! 1419: FILE *stream; ! 1420: char str[256],tmp[128]; ! 1421: int i,j,ch,file; ! 1422: ! 1423: if((stream=fnopen(&file,infile,O_RDONLY))==NULL) { ! 1424: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,infile ! 1425: ,strerror(errno)); ! 1426: bail(1); } ! 1427: for(i=0;i<cfg.arcdefs;i++) { ! 1428: str[0]=0; ! 1429: fseek(stream,cfg.arcdef[i].byteloc,SEEK_SET); ! 1430: for(j=0;j<strlen(cfg.arcdef[i].hexid)/2;j++) { ! 1431: ch=fgetc(stream); ! 1432: if(ch==EOF) { ! 1433: i=cfg.arcdefs; ! 1434: break; } ! 1435: sprintf(tmp,"%02X",ch); ! 1436: strcat(str,tmp); ! 1437: } ! 1438: if(!stricmp(str,cfg.arcdef[i].hexid)) ! 1439: break; ! 1440: } ! 1441: fclose(stream); ! 1442: ! 1443: if(i==cfg.arcdefs) { ! 1444: lprintf(LOG_ERR,"ERROR line %d determining filetype of %s",__LINE__,infile); ! 1445: return(1); } ! 1446: ! 1447: j=execute(mycmdstr(&scfg,cfg.arcdef[i].unpack,infile ! 1448: ,secure ? cfg.secure : cfg.inbound)); ! 1449: if(j) { ! 1450: lprintf(LOG_ERR,"ERROR %d (%d) line %d executing %s" ! 1451: ,j,errno,__LINE__,mycmdstr(&scfg,cfg.arcdef[i].unpack,infile ! 1452: ,secure ? cfg.secure : cfg.inbound)); ! 1453: return(j); } ! 1454: return(0); ! 1455: } ! 1456: /****************************************************************************** ! 1457: This function will check the 'dest' for the type of archiver to use (as ! 1458: defined in the CFG file) and compress 'srcfile' into 'destfile' using the ! 1459: appropriate archive program. ! 1460: ******************************************************************************/ ! 1461: void pack(char *srcfile,char *destfile,faddr_t dest) ! 1462: { ! 1463: int i,j; ! 1464: uint use=0; ! 1465: ! 1466: i=matchnode(dest,0); ! 1467: if(i<cfg.nodecfgs) ! 1468: use=cfg.nodecfg[i].arctype; ! 1469: ! 1470: j=execute(mycmdstr(&scfg,cfg.arcdef[use].pack,destfile,srcfile)); ! 1471: if(j) { ! 1472: lprintf(LOG_ERR,"ERROR %d (%d) line %d executing %s" ! 1473: ,j,errno,__LINE__,mycmdstr(&scfg,cfg.arcdef[use].pack,destfile,srcfile)); } ! 1474: } ! 1475: ! 1476: enum { ! 1477: ATTACHMENT_ADD ! 1478: ,ATTACHMENT_NETMAIL ! 1479: ,ATTACHMENT_CHECK ! 1480: }; ! 1481: ! 1482: int attachment(char *bundlename,faddr_t dest, int mode) ! 1483: { ! 1484: FILE *fidomsg,*stream; ! 1485: char str[1025],*path,fname[129],*p; ! 1486: int fmsg,file,error=0L; ! 1487: long fncrc,*mfncrc=0L,num_mfncrc=0L,crcidx; ! 1488: attach_t attach; ! 1489: fmsghdr_t hdr; ! 1490: size_t f; ! 1491: glob_t g; ! 1492: ! 1493: if(bundlename==NULL && mode!=ATTACHMENT_NETMAIL) { ! 1494: lprintf(LOG_ERR,"ERROR line %d NULL bundlename",__LINE__); ! 1495: return(1); ! 1496: } ! 1497: sprintf(fname,"%sBUNDLES.SBE",cfg.outbound); ! 1498: if((stream=fnopen(&file,fname,O_RDWR|O_CREAT))==NULL) { ! 1499: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,fname,strerror(errno)); ! 1500: return(1); ! 1501: } ! 1502: ! 1503: if(mode==ATTACHMENT_CHECK) { /* Check for existance in BUNDLES.SBE */ ! 1504: while(!feof(stream)) { ! 1505: if(!fread(&attach,1,sizeof(attach_t),stream)) ! 1506: break; ! 1507: if(!stricmp(attach.fname,bundlename)) { ! 1508: fclose(stream); ! 1509: return(1); ! 1510: } ! 1511: } ! 1512: fclose(stream); ! 1513: if(!flength(fname)) ! 1514: remove(fname); ! 1515: return(0); ! 1516: } ! 1517: ! 1518: if(mode==ATTACHMENT_NETMAIL) { /* Create netmail attaches */ ! 1519: ! 1520: if(!filelength(file)) { ! 1521: fclose(stream); ! 1522: return(0); ! 1523: } ! 1524: /* Get attach names from existing MSGs */ ! 1525: #ifdef __unix__ ! 1526: sprintf(str,"%s*.[Mm][Ss][Gg]",scfg.netmail_dir); ! 1527: #else ! 1528: sprintf(str,"%s*.msg",scfg.netmail_dir); ! 1529: #endif ! 1530: glob(str,0,NULL,&g); ! 1531: for(f=0;f<g.gl_pathc;f++) { ! 1532: ! 1533: path=g.gl_pathv[f]; ! 1534: ! 1535: if((fidomsg=fnopen(&fmsg,path,O_RDWR))==NULL) { ! 1536: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,path ! 1537: ,strerror(errno)); ! 1538: continue; ! 1539: } ! 1540: if(filelength(fmsg)<sizeof(fmsghdr_t)) { ! 1541: lprintf(LOG_ERR,"ERROR line %d %s has invalid length of %lu bytes" ! 1542: ,__LINE__ ! 1543: ,path ! 1544: ,filelength(fmsg)); ! 1545: fclose(fidomsg); ! 1546: continue; ! 1547: } ! 1548: if(fread(&hdr,sizeof(fmsghdr_t),1,fidomsg)!=1) { ! 1549: fclose(fidomsg); ! 1550: lprintf(LOG_ERR,"ERROR line %d reading %u bytes from %s" ! 1551: ,__LINE__,sizeof(fmsghdr_t),path); ! 1552: continue; ! 1553: } ! 1554: fclose(fidomsg); ! 1555: if(!(hdr.attr&FIDO_FILE)) /* Not a file attach */ ! 1556: continue; ! 1557: num_mfncrc++; ! 1558: p=getfname(hdr.subj); ! 1559: if((mfncrc=(long *)realloc(mfncrc,num_mfncrc*sizeof(long)))==NULL) { ! 1560: lprintf(LOG_ERR,"ERROR line %d allocating %lu for bundle name crc" ! 1561: ,__LINE__,num_mfncrc*sizeof(long)); ! 1562: continue; ! 1563: } ! 1564: mfncrc[num_mfncrc-1]=crc32(strupr(p),0); ! 1565: } ! 1566: globfree(&g); ! 1567: ! 1568: while(!feof(stream)) { ! 1569: if(!fread(&attach,1,sizeof(attach_t),stream)) ! 1570: break; ! 1571: sprintf(str,"%s%s",cfg.outbound,attach.fname); ! 1572: if(!fexistcase(str)) ! 1573: continue; ! 1574: fncrc=crc32(strupr(attach.fname),0); ! 1575: for(crcidx=0;crcidx<num_mfncrc;crcidx++) ! 1576: if(mfncrc[crcidx]==fncrc) ! 1577: break; ! 1578: if(crcidx==num_mfncrc) ! 1579: if(create_netmail(/* To: */NULL,str ! 1580: ,misc&TRUNC_BUNDLES ? "\1FLAGS TFS\r" : "\1FLAGS KFS\r" ! 1581: ,attach.dest,TRUE)) ! 1582: error=1; ! 1583: } ! 1584: fclose(stream); ! 1585: if(!error) /* remove bundles.sbe if no error occurred */ ! 1586: remove(fname); /* used to truncate here, August-20-2002 */ ! 1587: if(num_mfncrc) ! 1588: free(mfncrc); ! 1589: return(0); ! 1590: } ! 1591: ! 1592: while(!feof(stream)) { ! 1593: if(!fread(&attach,1,sizeof(attach_t),stream)) ! 1594: break; ! 1595: if(!stricmp(attach.fname,bundlename)) { ! 1596: fclose(stream); ! 1597: return(0); ! 1598: } ! 1599: } ! 1600: ! 1601: memcpy(&attach.dest,&dest,sizeof(faddr_t)); ! 1602: strcpy(attach.fname,bundlename); ! 1603: fwrite(&attach,sizeof(attach_t),1,stream); ! 1604: fclose(stream); ! 1605: return(0); ! 1606: } ! 1607: ! 1608: /****************************************************************************** ! 1609: This function is called when a message packet has reached it's maximum size. ! 1610: It places packets into a bundle until that bundle is full, at which time the ! 1611: last character of the extension increments (1 thru 0 and then A thru Z). If ! 1612: all bundles have reached their maximum size remaining packets are placed into ! 1613: the Z bundle. ! 1614: ******************************************************************************/ ! 1615: void pack_bundle(char *infile,faddr_t dest) ! 1616: { ! 1617: char str[256],fname[256],outbound[128],day[3],*p; ! 1618: int i,j,file,node; ! 1619: time_t now; ! 1620: ! 1621: if(infile==NULL || infile[0]==0) { ! 1622: lprintf(LOG_ERR,"ERROR line %d invalid filename",__LINE__); ! 1623: bail(1); ! 1624: } ! 1625: ! 1626: node=matchnode(dest,0); ! 1627: strcpy(str,infile); ! 1628: str[strlen(str)-1]='t'; ! 1629: if(rename(infile,str)) /* Change .PK_ file to .PKT file */ ! 1630: lprintf(LOG_ERR,"ERROR line %d renaming %s to %s",__LINE__,infile,str); ! 1631: infile[strlen(infile)-1]='t'; ! 1632: time(&now); ! 1633: sprintf(day,"%-.2s",ctime(&now)); ! 1634: strupr(day); ! 1635: if(misc&FLO_MAILER) { ! 1636: if(node<cfg.nodecfgs && cfg.nodecfg[node].route.zone) { ! 1637: dest=cfg.nodecfg[node].route; ! 1638: if(cfg.log&LOG_ROUTING) ! 1639: lprintf(LOG_NOTICE,"Routing %s to %s",infile,smb_faddrtoa(&dest,NULL)); ! 1640: } ! 1641: ! 1642: if(dest.zone==sys_faddr.zone) /* Default zone, use default outbound */ ! 1643: strcpy(outbound,cfg.outbound); ! 1644: else { /* Inter-zone outbound is OUTBOUND.XXX */ ! 1645: sprintf(outbound,"%.*s.%03x" ! 1646: ,(int)strlen(cfg.outbound)-1,cfg.outbound,dest.zone); ! 1647: MKDIR(outbound); ! 1648: backslash(outbound); ! 1649: } ! 1650: if(dest.point) { /* Point destination is OUTBOUND\*.PNT */ ! 1651: sprintf(str,"%04x%04x.pnt" ! 1652: ,dest.net,dest.node); ! 1653: strcat(outbound,str); } ! 1654: } ! 1655: else ! 1656: strcpy(outbound,cfg.outbound); ! 1657: if(outbound[strlen(outbound)-1]=='\\' ! 1658: || outbound[strlen(outbound)-1]=='/') ! 1659: outbound[strlen(outbound)-1]=0; ! 1660: MKDIR(outbound); ! 1661: backslash(outbound); ! 1662: ! 1663: if(node<cfg.nodecfgs) ! 1664: if(cfg.nodecfg[node].arctype==0xffff) { /* Uncompressed! */ ! 1665: if(misc&FLO_MAILER) ! 1666: i=write_flofile(infile,dest,TRUE /* bundle */); ! 1667: else ! 1668: i=create_netmail(/* To: */NULL,infile ! 1669: ,misc&TRUNC_BUNDLES ? "\1FLAGS TFS\r" : "\1FLAGS KFS\r" ! 1670: ,dest,TRUE); ! 1671: if(i) bail(1); ! 1672: return; } ! 1673: ! 1674: if(dest.point && !(misc&FLO_MAILER)) ! 1675: sprintf(fname,"%s%04hxp%03hx.%s",outbound,0,(short)dest.point,day); ! 1676: else ! 1677: sprintf(fname,"%s%04hx%04hx.%s",outbound,(short)(sys_faddr.net-dest.net) ! 1678: ,(short)(sys_faddr.node-dest.node),day); ! 1679: for(i='0';i<='Z';i++) { ! 1680: if(i==':') ! 1681: i='A'; ! 1682: sprintf(str,"%s%c",fname,i); ! 1683: if(flength(str)==0) { ! 1684: /* Feb-10-2003: Don't overwrite or delete 0-byte file less than 24hrs old */ ! 1685: if((time(NULL)-fdate(str))<24L*60L*60L) ! 1686: continue; ! 1687: if(delfile(str)) ! 1688: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,str ! 1689: ,strerror(errno)); ! 1690: } ! 1691: if(fexistcase(str)) { ! 1692: if(flength(str)>=cfg.maxbdlsize) ! 1693: continue; ! 1694: file=sopen(str,O_WRONLY,SH_DENYRW); ! 1695: if(file==-1) /* Can't open?!? Probably being sent */ ! 1696: continue; ! 1697: close(file); ! 1698: p=getfname(str); ! 1699: if(!attachment(p,dest,ATTACHMENT_CHECK)) ! 1700: attachment(p,dest,ATTACHMENT_ADD); ! 1701: pack(infile,str,dest); ! 1702: if(delfile(infile)) ! 1703: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,infile ! 1704: ,strerror(errno)); ! 1705: return; } ! 1706: else { ! 1707: if(misc&FLO_MAILER) ! 1708: j=write_flofile(str,dest,TRUE /* bundle */); ! 1709: else { ! 1710: p=getfname(str); ! 1711: j=attachment(p,dest,ATTACHMENT_ADD); } ! 1712: if(j) ! 1713: bail(1); ! 1714: pack(infile,str,dest); ! 1715: if(delfile(infile)) ! 1716: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,infile ! 1717: ,strerror(errno)); ! 1718: return; } } ! 1719: ! 1720: pack(infile,str,dest); /* Won't get here unless all bundles are full */ ! 1721: } ! 1722: /****************************************************************************** ! 1723: This function checks the inbound directory for the first bundle it finds, it ! 1724: will then unpack and delete the bundle. If no bundles exist this function ! 1725: returns a FALSE, otherwise a TRUE is returned. ! 1726: ******************************************************************************/ ! 1727: BOOL unpack_bundle(void) ! 1728: { ! 1729: char* p; ! 1730: char str[MAX_PATH+1]; ! 1731: char fname[MAX_PATH+1]; ! 1732: int i; ! 1733: static glob_t g; ! 1734: static int gi; ! 1735: ! 1736: for(i=0;i<7;i++) { ! 1737: #if defined(__unix__) /* support upper or lower case */ ! 1738: switch(i) { ! 1739: case 0: ! 1740: p="[Ss][Uu]"; ! 1741: break; ! 1742: case 1: ! 1743: p="[Mm][Oo]"; ! 1744: break; ! 1745: case 2: ! 1746: p="[Tt][Uu]"; ! 1747: break; ! 1748: case 3: ! 1749: p="[Ww][Ee]"; ! 1750: break; ! 1751: case 4: ! 1752: p="[Tt][Hh]"; ! 1753: break; ! 1754: case 5: ! 1755: p="[Ff][Rr]"; ! 1756: break; ! 1757: default: ! 1758: p="[Ss][Aa]"; ! 1759: break; ! 1760: } ! 1761: #else ! 1762: switch(i) { ! 1763: case 0: ! 1764: p="su"; ! 1765: break; ! 1766: case 1: ! 1767: p="mo"; ! 1768: break; ! 1769: case 2: ! 1770: p="tu"; ! 1771: break; ! 1772: case 3: ! 1773: p="we"; ! 1774: break; ! 1775: case 4: ! 1776: p="th"; ! 1777: break; ! 1778: case 5: ! 1779: p="fr"; ! 1780: break; ! 1781: default: ! 1782: p="sa"; ! 1783: break; ! 1784: } ! 1785: #endif ! 1786: sprintf(str,"%s*.%s?",secure ? cfg.secure : cfg.inbound,p); ! 1787: if(gi>=g.gl_pathc) { ! 1788: gi=0; ! 1789: globfree(&g); ! 1790: glob(str,0,NULL,&g); ! 1791: } ! 1792: if(gi<g.gl_pathc) { ! 1793: SAFECOPY(fname,g.gl_pathv[gi]); ! 1794: lprintf(LOG_DEBUG,"Unpacking bundle: %s",fname); ! 1795: if(unpack(fname)) { /* failure */ ! 1796: lprintf(LOG_ERR,"!Unpack failure"); ! 1797: if(fdate(fname)+(48L*60L*60L)>time(NULL)) { ! 1798: SAFECOPY(str,fname); ! 1799: str[strlen(str)-2]='_'; ! 1800: if(fexistcase(str)) ! 1801: str[strlen(str)-2]='-'; ! 1802: if(fexistcase(str)) ! 1803: delfile(str); ! 1804: if(rename(fname,str)) ! 1805: lprintf(LOG_ERR,"ERROR line %d renaming %s to %s" ! 1806: ,__LINE__,fname,str); ! 1807: } ! 1808: } ! 1809: else { ! 1810: lprintf(LOG_DEBUG,"Deleting bundle: %s", fname); ! 1811: if(delfile(fname)) /* successful, so delete bundle */ ! 1812: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,fname ! 1813: ,strerror(errno)); ! 1814: } ! 1815: gi++; ! 1816: return(TRUE); ! 1817: } ! 1818: } ! 1819: ! 1820: return(FALSE); ! 1821: } ! 1822: ! 1823: /****************************************************************************/ ! 1824: /* Moves or copies a file from one dir to another */ ! 1825: /* both 'src' and 'dest' must contain full path and filename */ ! 1826: /* returns 0 if successful, -1 if error */ ! 1827: /****************************************************************************/ ! 1828: int mv(char *src, char *dest, BOOL copy) ! 1829: { ! 1830: char buf[4096],str[256]; ! 1831: int ind,outd; ! 1832: long length,chunk=4096,l; ! 1833: FILE *inp,*outp; ! 1834: ! 1835: if(!strcmp(src,dest)) /* source and destination are the same! */ ! 1836: return(0); ! 1837: if(!fexistcase(src)) { ! 1838: lprintf(LOG_WARNING,"MV ERROR: Source doesn't exist '%s",src); ! 1839: return(-1); ! 1840: } ! 1841: if(!copy && fexistcase(dest)) { ! 1842: lprintf(LOG_WARNING,"MV ERROR: Destination already exists '%s'",dest); ! 1843: return(-1); ! 1844: } ! 1845: if(!copy ! 1846: #ifndef __unix__ ! 1847: && ((src[1]!=':' && dest[1]!=':') ! 1848: || (src[1]==':' && dest[1]==':' && toupper(src[0])==toupper(dest[0]))) ! 1849: #endif ! 1850: ) { ! 1851: if(rename(src,dest)==0) /* same drive, so move */ ! 1852: return(0); ! 1853: /* rename failed, so attempt copy */ ! 1854: } ! 1855: if((ind=nopen(src,O_RDONLY))==-1) { ! 1856: lprintf(LOG_ERR,"MV ERROR: ERR_OPEN %s",src); ! 1857: return(-1); ! 1858: } ! 1859: if((inp=fdopen(ind,"rb"))==NULL) { ! 1860: close(ind); ! 1861: lprintf(LOG_ERR,"MV ERROR: ERR_FDOPEN %s",str); ! 1862: return(-1); ! 1863: } ! 1864: setvbuf(inp,NULL,_IOFBF,8*1024); ! 1865: if((outd=nopen(dest,O_WRONLY|O_CREAT|O_TRUNC))==-1) { ! 1866: fclose(inp); ! 1867: lprintf(LOG_ERR,"MV ERROR: ERR_OPEN %s",dest); ! 1868: return(-1); ! 1869: } ! 1870: if((outp=fdopen(outd,"wb"))==NULL) { ! 1871: close(outd); ! 1872: fclose(inp); ! 1873: lprintf(LOG_ERR,"MV ERROR: ERR_FDOPEN %s",str); ! 1874: return(-1); ! 1875: } ! 1876: setvbuf(outp,NULL,_IOFBF,8*1024); ! 1877: length=filelength(ind); ! 1878: l=0L; ! 1879: while(l<length) { ! 1880: if(l+chunk>length) ! 1881: chunk=length-l; ! 1882: fread(buf,chunk,1,inp); ! 1883: fwrite(buf,chunk,1,outp); ! 1884: l+=chunk; ! 1885: } ! 1886: fclose(inp); ! 1887: fclose(outp); ! 1888: if(!copy && delfile(src)) { ! 1889: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,src,strerror(errno)); ! 1890: return(-1); ! 1891: } ! 1892: return(0); ! 1893: } ! 1894: ! 1895: /****************************************************************************/ ! 1896: /* Returns the total number of msgs in the sub-board and sets 'ptr' to the */ ! 1897: /* date of the last message in the sub (0) if no messages. */ ! 1898: /****************************************************************************/ ! 1899: ulong getlastmsg(uint subnum, ulong *ptr, time_t *t) ! 1900: { ! 1901: int i; ! 1902: smb_t smbfile; ! 1903: ! 1904: ZERO_VAR(smbfile); ! 1905: if(subnum>=scfg.total_subs) { ! 1906: lprintf(LOG_ERR,"ERROR line %d getlastmsg %d",__LINE__,subnum); ! 1907: bail(1); } ! 1908: sprintf(smbfile.file,"%s%s",scfg.sub[subnum]->data_dir,scfg.sub[subnum]->code); ! 1909: smbfile.retry_time=scfg.smb_retry_time; ! 1910: if((i=smb_open(&smbfile))!=SMB_SUCCESS) { ! 1911: lprintf(LOG_ERR,"ERROR %d line %d opening %s",i,__LINE__,smbfile.file); ! 1912: return(0); } ! 1913: ! 1914: if(!filelength(fileno(smbfile.shd_fp))) { /* Empty base */ ! 1915: if(ptr) (*ptr)=0; ! 1916: smb_close(&smbfile); ! 1917: return(0); } ! 1918: smb_close(&smbfile); ! 1919: if(ptr) (*ptr)=smbfile.status.last_msg; ! 1920: return(smbfile.status.total_msgs); ! 1921: } ! 1922: ! 1923: ! 1924: ulong loadmsgs(post_t** post, ulong ptr) ! 1925: { ! 1926: int i; ! 1927: long l,total; ! 1928: idxrec_t idx; ! 1929: ! 1930: ! 1931: if((i=smb_locksmbhdr(&smb[cur_smb]))!=SMB_SUCCESS) { ! 1932: lprintf(LOG_ERR,"ERROR %d line %d locking %s",i,__LINE__,smb[cur_smb].file); ! 1933: return(0); ! 1934: } ! 1935: ! 1936: /* total msgs in sub */ ! 1937: total=filelength(fileno(smb[cur_smb].sid_fp))/sizeof(idxrec_t); ! 1938: ! 1939: if(!total) { /* empty */ ! 1940: smb_unlocksmbhdr(&smb[cur_smb]); ! 1941: return(0); ! 1942: } ! 1943: ! 1944: if(((*post)=(post_t*)malloc(sizeof(post_t)*total)) /* alloc for max */ ! 1945: ==NULL) { ! 1946: smb_unlocksmbhdr(&smb[cur_smb]); ! 1947: lprintf(LOG_ERR,"ERROR line %d allocating %lu bytes for %s",__LINE__ ! 1948: ,sizeof(post_t *)*total,smb[cur_smb].file); ! 1949: return(0); ! 1950: } ! 1951: ! 1952: fseek(smb[cur_smb].sid_fp,0L,SEEK_SET); ! 1953: for(l=0;l<total && !feof(smb[cur_smb].sid_fp); ) { ! 1954: if(smb_fread(&smb[cur_smb], &idx,sizeof(idx),smb[cur_smb].sid_fp) != sizeof(idx)) ! 1955: break; ! 1956: ! 1957: if(idx.number==0) /* invalid message number, ignore */ ! 1958: continue; ! 1959: ! 1960: if(idx.number<=ptr || idx.attr&MSG_DELETE) ! 1961: continue; ! 1962: ! 1963: if(idx.attr&MSG_MODERATED && !(idx.attr&MSG_VALIDATED)) ! 1964: break; ! 1965: ! 1966: (*post)[l++]=idx; ! 1967: } ! 1968: smb_unlocksmbhdr(&smb[cur_smb]); ! 1969: if(!l) ! 1970: FREE_AND_NULL(*post); ! 1971: return(l); ! 1972: } ! 1973: ! 1974: void bail(int code) ! 1975: { ! 1976: if(code || pause_on_exit) { ! 1977: fprintf(stderr,"\nHit any key..."); ! 1978: getch(); ! 1979: fprintf(stderr,"\n"); ! 1980: } ! 1981: exit(code); ! 1982: } ! 1983: ! 1984: typedef struct { ! 1985: ulong alias, ! 1986: real; ! 1987: } username_t; ! 1988: ! 1989: /****************************************************************************/ ! 1990: /* Note: Wrote another version of this function that read all userdata into */ ! 1991: /****************************************************************************/ ! 1992: /* Looks for a perfect match amoung all usernames (not deleted users) */ ! 1993: /* Returns the number of the perfect matched username or 0 if no match */ ! 1994: /* Called from functions waitforcall and newuser */ ! 1995: /* memory then scanned it from memory... took longer - always. */ ! 1996: /****************************************************************************/ ! 1997: ulong matchname(char *inname) ! 1998: { ! 1999: static ulong total_users; ! 2000: static username_t *username; ! 2001: ulong last_user; ! 2002: int userdat,i; ! 2003: char str[256],name[LEN_NAME+1],alias[LEN_ALIAS+1]; ! 2004: ulong l,crc; ! 2005: ! 2006: if(!total_users) { /* Load CRCs */ ! 2007: fprintf(stderr,"\n%-25s","Loading user names..."); ! 2008: sprintf(str,"%suser/user.dat",scfg.data_dir); ! 2009: if((userdat=nopen(str,O_RDONLY|O_DENYNONE))==-1) ! 2010: return(0); ! 2011: last_user=filelength(userdat)/U_LEN; ! 2012: for(total_users=0;total_users<last_user;total_users++) { ! 2013: printf("%5ld\b\b\b\b\b",total_users); ! 2014: if((username=(username_t *)realloc(username ! 2015: ,(total_users+1L)*sizeof(username_t)))==NULL) ! 2016: break; ! 2017: username[total_users].alias=0; ! 2018: username[total_users].real=0; ! 2019: i=0; ! 2020: while(i<LOOP_NODEDAB ! 2021: && lock(userdat,(long)((long)(total_users)*U_LEN)+U_ALIAS ! 2022: ,LEN_ALIAS+LEN_NAME)==-1) ! 2023: i++; ! 2024: if(i>=LOOP_NODEDAB) { /* Couldn't lock USER.DAT record */ ! 2025: lprintf(LOG_ERR,"ERROR locking USER.DAT record #%ld",total_users); ! 2026: continue; } ! 2027: lseek(userdat,(long)((long)(total_users)*U_LEN)+U_ALIAS,SEEK_SET); ! 2028: read(userdat,alias,LEN_ALIAS); ! 2029: read(userdat,name,LEN_NAME); ! 2030: lseek(userdat,(long)(((long)total_users)*U_LEN)+U_MISC,SEEK_SET); ! 2031: read(userdat,tmp,8); ! 2032: for(i=0;i<8;i++) ! 2033: if(tmp[i]==ETX || tmp[i]=='\r') break; ! 2034: tmp[i]=0; ! 2035: unlock(userdat,(long)((long)(total_users)*U_LEN)+U_ALIAS ! 2036: ,LEN_ALIAS+LEN_NAME); ! 2037: if(ahtoul(tmp)&DELETED) ! 2038: continue; ! 2039: for(i=0;i<LEN_ALIAS;i++) ! 2040: if(alias[i]==ETX || alias[i]=='\r') break; ! 2041: alias[i]=0; ! 2042: strupr(alias); ! 2043: for(i=0;i<LEN_NAME;i++) ! 2044: if(name[i]==ETX || name[i]=='\r') break; ! 2045: name[i]=0; ! 2046: strupr(name); ! 2047: username[total_users].alias=crc32(alias,0); ! 2048: username[total_users].real=crc32(name,0); } ! 2049: close(userdat); ! 2050: fprintf(stderr," \b\b\b\b\b"); /* Clear counter */ ! 2051: fprintf(stderr, ! 2052: "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" ! 2053: "%25s" ! 2054: "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" ! 2055: ,""); } ! 2056: ! 2057: strcpy(str,inname); ! 2058: strupr(str); ! 2059: crc=crc32(str,0); ! 2060: for(l=0;l<total_users;l++) ! 2061: if((crc==username[l].alias || crc==username[l].real)) ! 2062: return(l+1); ! 2063: return(0); ! 2064: } ! 2065: ! 2066: /****************************************************************************/ ! 2067: /* Converts goofy FidoNet time format into Unix format */ ! 2068: /****************************************************************************/ ! 2069: time_t fmsgtime(char *str) ! 2070: { ! 2071: char month[4]; ! 2072: struct tm tm; ! 2073: ! 2074: memset(&tm,0,sizeof(tm)); ! 2075: tm.tm_isdst=-1; /* Do not adjust for DST */ ! 2076: ! 2077: if(isdigit(str[1])) { /* Regular format: "01 Jan 86 02:34:56" */ ! 2078: tm.tm_mday=atoi(str); ! 2079: sprintf(month,"%3.3s",str+3); ! 2080: if(!stricmp(month,"jan")) ! 2081: tm.tm_mon=0; ! 2082: else if(!stricmp(month,"feb")) ! 2083: tm.tm_mon=1; ! 2084: else if(!stricmp(month,"mar")) ! 2085: tm.tm_mon=2; ! 2086: else if(!stricmp(month,"apr")) ! 2087: tm.tm_mon=3; ! 2088: else if(!stricmp(month,"may")) ! 2089: tm.tm_mon=4; ! 2090: else if(!stricmp(month,"jun")) ! 2091: tm.tm_mon=5; ! 2092: else if(!stricmp(month,"jul")) ! 2093: tm.tm_mon=6; ! 2094: else if(!stricmp(month,"aug")) ! 2095: tm.tm_mon=7; ! 2096: else if(!stricmp(month,"sep")) ! 2097: tm.tm_mon=8; ! 2098: else if(!stricmp(month,"oct")) ! 2099: tm.tm_mon=9; ! 2100: else if(!stricmp(month,"nov")) ! 2101: tm.tm_mon=10; ! 2102: else ! 2103: tm.tm_mon=11; ! 2104: tm.tm_year=atoi(str+7); ! 2105: if(tm.tm_year<Y2K_2DIGIT_WINDOW) ! 2106: tm.tm_year+=100; ! 2107: tm.tm_hour=atoi(str+11); ! 2108: tm.tm_min=atoi(str+14); ! 2109: tm.tm_sec=atoi(str+17); } ! 2110: ! 2111: else { /* SEAdog format: "Mon 1 Jan 86 02:34" */ ! 2112: tm.tm_mday=atoi(str+4); ! 2113: sprintf(month,"%3.3s",str+7); ! 2114: if(!stricmp(month,"jan")) ! 2115: tm.tm_mon=0; ! 2116: else if(!stricmp(month,"feb")) ! 2117: tm.tm_mon=1; ! 2118: else if(!stricmp(month,"mar")) ! 2119: tm.tm_mon=2; ! 2120: else if(!stricmp(month,"apr")) ! 2121: tm.tm_mon=3; ! 2122: else if(!stricmp(month,"may")) ! 2123: tm.tm_mon=4; ! 2124: else if(!stricmp(month,"jun")) ! 2125: tm.tm_mon=5; ! 2126: else if(!stricmp(month,"jul")) ! 2127: tm.tm_mon=6; ! 2128: else if(!stricmp(month,"aug")) ! 2129: tm.tm_mon=7; ! 2130: else if(!stricmp(month,"sep")) ! 2131: tm.tm_mon=8; ! 2132: else if(!stricmp(month,"oct")) ! 2133: tm.tm_mon=9; ! 2134: else if(!stricmp(month,"nov")) ! 2135: tm.tm_mon=10; ! 2136: else ! 2137: tm.tm_mon=11; ! 2138: tm.tm_year=atoi(str+11); ! 2139: if(tm.tm_year<Y2K_2DIGIT_WINDOW) ! 2140: tm.tm_year+=100; ! 2141: tm.tm_hour=atoi(str+14); ! 2142: tm.tm_min=atoi(str+17); ! 2143: tm.tm_sec=0; } ! 2144: return(mktime(&tm)); ! 2145: } ! 2146: ! 2147: static short fmsgzone(char* p) ! 2148: { ! 2149: char hr[4]=""; ! 2150: char min[4]=""; ! 2151: short val; ! 2152: BOOL west=TRUE; ! 2153: ! 2154: if(*p=='-') ! 2155: p++; ! 2156: else ! 2157: west=FALSE; ! 2158: ! 2159: if(strlen(p)>=2) ! 2160: sprintf(hr,"%.2s",p); ! 2161: if(strlen(p+2)>=2) ! 2162: sprintf(min,"%.2s",p+2); ! 2163: ! 2164: val=atoi(hr)*60; ! 2165: val+=atoi(min); ! 2166: ! 2167: if(west) ! 2168: switch(val|US_ZONE) { ! 2169: case AST: ! 2170: case EST: ! 2171: case CST: ! 2172: case MST: ! 2173: case PST: ! 2174: case YST: ! 2175: case HST: ! 2176: case BST: ! 2177: /* standard US timezone */ ! 2178: return(val|US_ZONE); ! 2179: default: ! 2180: /* non-standard timezone */ ! 2181: return(-val); ! 2182: } ! 2183: return(val); ! 2184: } ! 2185: ! 2186: char* getfmsg(FILE *stream, ulong *outlen) ! 2187: { ! 2188: uchar* fbuf; ! 2189: int ch; ! 2190: ulong l,length,start; ! 2191: ! 2192: length=0L; ! 2193: start=ftell(stream); /* Beginning of Message */ ! 2194: while(1) { ! 2195: ch=fgetc(stream); /* Look for Terminating NULL */ ! 2196: if(ch==0 || ch==EOF) /* Found end of message */ ! 2197: break; ! 2198: length++; /* Increment the Length */ ! 2199: } ! 2200: ! 2201: if((fbuf=(char *)malloc(length+1))==NULL) { ! 2202: lprintf(LOG_ERR,"ERROR line %d allocating %lu bytes of memory",__LINE__,length+1); ! 2203: bail(1); ! 2204: } ! 2205: ! 2206: fseek(stream,start,SEEK_SET); ! 2207: for(l=0;l<length;l++) ! 2208: fbuf[l]=fgetc(stream); ! 2209: if(ch==0) ! 2210: fgetc(stream); /* Read NULL */ ! 2211: ! 2212: while(length && fbuf[length-1]<=' ') /* truncate white-space */ ! 2213: length--; ! 2214: fbuf[length]=0; ! 2215: ! 2216: if(outlen) ! 2217: *outlen=length; ! 2218: return((char*)fbuf); ! 2219: } ! 2220: ! 2221: #define MAX_TAILLEN 1024 ! 2222: ! 2223: /****************************************************************************/ ! 2224: /* Coverts a FidoNet message into a Synchronet message */ ! 2225: /* Returns 0 on success, 1 dupe, 2 filtered, 3 empty, or other SMB error */ ! 2226: /****************************************************************************/ ! 2227: int fmsgtosmsg(uchar* fbuf, fmsghdr_t fmsghdr, uint user, uint subnum) ! 2228: { ! 2229: uchar ch,*sbody,stail[MAX_TAILLEN+1],*outbuf ! 2230: ,*p,str[128]; ! 2231: char msg_id[256]; ! 2232: BOOL done,esc,cr; ! 2233: int i,storage=SMB_SELFPACK; ! 2234: uint col; ! 2235: ushort xlat=XLAT_NONE,net; ! 2236: ulong l,m,length,bodylen,taillen,crc; ! 2237: ulong save; ! 2238: long dupechk_hashes=SMB_HASH_SOURCE_ALL; ! 2239: faddr_t faddr,origaddr,destaddr; ! 2240: smb_t* smbfile; ! 2241: char fname[MAX_PATH+1]; ! 2242: smbmsg_t msg; ! 2243: ! 2244: if(twit_list) { ! 2245: sprintf(fname,"%stwitlist.cfg",scfg.ctrl_dir); ! 2246: if(findstr(fmsghdr.from,fname) || findstr(fmsghdr.to,fname)) { ! 2247: lprintf(LOG_INFO,"Filtering message from %s to %s",fmsghdr.from,fmsghdr.to); ! 2248: return(2); ! 2249: } ! 2250: } ! 2251: ! 2252: memset(&msg,0,sizeof(smbmsg_t)); ! 2253: if(fmsghdr.attr&FIDO_PRIVATE) ! 2254: msg.idx.attr|=MSG_PRIVATE; ! 2255: msg.hdr.attr=msg.idx.attr; ! 2256: ! 2257: if(fmsghdr.attr&FIDO_FILE) ! 2258: msg.hdr.auxattr|=MSG_FILEATTACH; ! 2259: ! 2260: msg.hdr.when_imported.time=time(NULL); ! 2261: msg.hdr.when_imported.zone=sys_timezone(&scfg); ! 2262: msg.hdr.when_written.time=fmsgtime(fmsghdr.time); ! 2263: ! 2264: origaddr.zone=fmsghdr.origzone; /* only valid if NetMail */ ! 2265: origaddr.net=fmsghdr.orignet; ! 2266: origaddr.node=fmsghdr.orignode; ! 2267: origaddr.point=fmsghdr.origpoint; ! 2268: ! 2269: destaddr.zone=fmsghdr.destzone; /* only valid if NetMail */ ! 2270: destaddr.net=fmsghdr.destnet; ! 2271: destaddr.node=fmsghdr.destnode; ! 2272: destaddr.point=fmsghdr.destpoint; ! 2273: ! 2274: smb_hfield_str(&msg,SENDER,fmsghdr.from); ! 2275: smb_hfield_str(&msg,RECIPIENT,fmsghdr.to); ! 2276: ! 2277: if(user) { ! 2278: sprintf(str,"%u",user); ! 2279: smb_hfield_str(&msg,RECIPIENTEXT,str); ! 2280: } ! 2281: ! 2282: smb_hfield_str(&msg,SUBJECT,fmsghdr.subj); ! 2283: ! 2284: if(fbuf==NULL) { ! 2285: lprintf(LOG_ERR,"ERROR line %d allocating fbuf",__LINE__); ! 2286: smb_freemsgmem(&msg); ! 2287: return(-1); ! 2288: } ! 2289: length=strlen((char *)fbuf); ! 2290: if((sbody=(char*)malloc((length+1)*2))==NULL) { ! 2291: lprintf(LOG_ERR,"ERROR line %d allocating %lu bytes for body",__LINE__ ! 2292: ,(length+1)*2L); ! 2293: smb_freemsgmem(&msg); ! 2294: return(-1); ! 2295: } ! 2296: ! 2297: for(col=l=esc=done=bodylen=taillen=0,cr=1;l<length;l++) { ! 2298: ! 2299: if(!l && !strncmp((char *)fbuf,"AREA:",5)) { ! 2300: save=l; ! 2301: l+=5; ! 2302: while(l<length && fbuf[l]<=' ') l++; ! 2303: m=l; ! 2304: while(m<length && fbuf[m]!='\r') m++; ! 2305: while(m && fbuf[m-1]<=' ') m--; ! 2306: if(m>l) ! 2307: smb_hfield(&msg,FIDOAREA,(ushort)(m-l),fbuf+l); ! 2308: while(l<length && fbuf[l]!='\r') l++; ! 2309: /* If unknown echo, keep AREA: line in message body */ ! 2310: if(cfg.badecho>=0 && subnum==cfg.area[cfg.badecho].sub) ! 2311: l=save; ! 2312: else ! 2313: continue; ! 2314: } ! 2315: ! 2316: ch=fbuf[l]; ! 2317: if(ch==1 && cr) { /* kludge line */ ! 2318: ! 2319: if(!strncmp((char *)fbuf+l+1,"TOPT ",5)) ! 2320: destaddr.point=atoi((char *)fbuf+l+6); ! 2321: ! 2322: else if(!strncmp((char *)fbuf+l+1,"FMPT ",5)) ! 2323: origaddr.point=atoi((char *)fbuf+l+6); ! 2324: ! 2325: else if(!strncmp((char *)fbuf+l+1,"INTL ",5)) { ! 2326: faddr=atofaddr((char *)fbuf+l+6); ! 2327: destaddr.zone=faddr.zone; ! 2328: destaddr.net=faddr.net; ! 2329: destaddr.node=faddr.node; ! 2330: l+=6; ! 2331: while(l<length && fbuf[l]!=' ') l++; ! 2332: faddr=atofaddr((char *)fbuf+l+1); ! 2333: origaddr.zone=faddr.zone; ! 2334: origaddr.net=faddr.net; ! 2335: origaddr.node=faddr.node; } ! 2336: ! 2337: else if(!strncmp((char *)fbuf+l+1,"MSGID:",6)) { ! 2338: l+=7; ! 2339: while(l<length && fbuf[l]<=' ') l++; ! 2340: m=l; ! 2341: while(m<length && fbuf[m]!='\r') m++; ! 2342: while(m && fbuf[m-1]<=' ') m--; ! 2343: if(m>l) ! 2344: smb_hfield(&msg,FIDOMSGID,(ushort)(m-l),fbuf+l); } ! 2345: ! 2346: else if(!strncmp((char *)fbuf+l+1,"REPLY:",6)) { ! 2347: l+=7; ! 2348: while(l<length && fbuf[l]<=' ') l++; ! 2349: m=l; ! 2350: while(m<length && fbuf[m]!='\r') m++; ! 2351: while(m && fbuf[m-1]<=' ') m--; ! 2352: if(m>l) ! 2353: smb_hfield(&msg,FIDOREPLYID,(ushort)(m-l),fbuf+l); } ! 2354: ! 2355: else if(!strncmp((char *)fbuf+l+1,"FLAGS ",6) /* correct */ ! 2356: || !strncmp((char *)fbuf+l+1,"FLAGS:",6)) { /* incorrect */ ! 2357: l+=7; ! 2358: while(l<length && fbuf[l]<=' ') l++; ! 2359: m=l; ! 2360: while(m<length && fbuf[m]!='\r') m++; ! 2361: while(m && fbuf[m-1]<=' ') m--; ! 2362: if(m>l) ! 2363: smb_hfield(&msg,FIDOFLAGS,(ushort)(m-l),fbuf+l); } ! 2364: ! 2365: else if(!strncmp((char *)fbuf+l+1,"PATH:",5)) { ! 2366: l+=6; ! 2367: while(l<length && fbuf[l]<=' ') l++; ! 2368: m=l; ! 2369: while(m<length && fbuf[m]!='\r') m++; ! 2370: while(m && fbuf[m-1]<=' ') m--; ! 2371: if(m>l && misc&STORE_PATH) ! 2372: smb_hfield(&msg,FIDOPATH,(ushort)(m-l),fbuf+l); } ! 2373: ! 2374: else if(!strncmp((char *)fbuf+l+1,"PID:",4)) { ! 2375: l+=5; ! 2376: while(l<length && fbuf[l]<=' ') l++; ! 2377: m=l; ! 2378: while(m<length && fbuf[m]!='\r') m++; ! 2379: while(m && fbuf[m-1]<=' ') m--; ! 2380: if(m>l) ! 2381: smb_hfield(&msg,FIDOPID,(ushort)(m-l),fbuf+l); } ! 2382: ! 2383: else if(!strncmp((char *)fbuf+l+1,"TID:",4)) { ! 2384: l+=5; ! 2385: while(l<length && fbuf[l]<=' ') l++; ! 2386: m=l; ! 2387: while(m<length && fbuf[m]!='\r') m++; ! 2388: while(m && fbuf[m-1]<=' ') m--; ! 2389: if(m>l) ! 2390: smb_hfield(&msg,FIDOTID,(ushort)(m-l),fbuf+l); } ! 2391: ! 2392: else if(!strncmp((char *)fbuf+l+1,"TZUTC:",6)) { /* FSP-1001 */ ! 2393: l+=7; ! 2394: while(l<length && fbuf[l]<=' ') l++; ! 2395: msg.hdr.when_written.zone = fmsgzone(fbuf+l); ! 2396: } ! 2397: ! 2398: else if(!strncmp((char *)fbuf+l+1,"TZUTCINFO:",10)) { /* non-standard */ ! 2399: l+=11; ! 2400: while(l<length && fbuf[l]<=' ') l++; ! 2401: msg.hdr.when_written.zone = fmsgzone(fbuf+l); ! 2402: } ! 2403: ! 2404: else { /* Unknown kludge line */ ! 2405: while(l<length && fbuf[l]<=' ') l++; ! 2406: m=l; ! 2407: while(m<length && fbuf[m]!='\r') m++; ! 2408: while(m && fbuf[m-1]<=' ') m--; ! 2409: if(m>l && misc&STORE_KLUDGE) ! 2410: smb_hfield(&msg,FIDOCTRL,(ushort)(m-l),fbuf+l); } ! 2411: ! 2412: while(l<length && fbuf[l]!='\r') l++; ! 2413: continue; } ! 2414: ! 2415: if(ch!='\n' && ch!=0x8d) { /* ignore LF and soft CRs */ ! 2416: if(cr && (!strncmp((char *)fbuf+l,"--- ",4) ! 2417: || !strncmp((char *)fbuf+l,"---\r",4))) ! 2418: done=1; /* tear line and down go into tail */ ! 2419: if(done && cr && !strncmp((char *)fbuf+l,"SEEN-BY:",8)) { ! 2420: l+=8; ! 2421: while(l<length && fbuf[l]<=' ') l++; ! 2422: m=l; ! 2423: while(m<length && fbuf[m]!='\r') m++; ! 2424: while(m && fbuf[m-1]<=' ') m--; ! 2425: if(m>l && misc&STORE_SEENBY) ! 2426: smb_hfield(&msg,FIDOSEENBY,(ushort)(m-l),fbuf+l); ! 2427: while(l<length && fbuf[l]!='\r') l++; ! 2428: continue; } ! 2429: if(done) { ! 2430: if(taillen<MAX_TAILLEN) ! 2431: stail[taillen++]=ch; } ! 2432: else ! 2433: sbody[bodylen++]=ch; ! 2434: col++; ! 2435: if(ch=='\r') { ! 2436: cr=1; ! 2437: col=0; ! 2438: if(done) { ! 2439: if(taillen<MAX_TAILLEN) ! 2440: stail[taillen++]='\n'; } ! 2441: else ! 2442: sbody[bodylen++]='\n'; } ! 2443: else { ! 2444: cr=0; ! 2445: if(col==1 && !strncmp((char *)fbuf+l," * Origin: ",11)) { ! 2446: p=(char *)fbuf+l+11; ! 2447: while(*p && *p!='\r') p++; /* Find CR */ ! 2448: while(p && *p!='(') p--; /* rewind to '(' */ ! 2449: if(p) ! 2450: origaddr=atofaddr(p+1); /* get orig address */ ! 2451: done=1; } ! 2452: if(done) ! 2453: continue; ! 2454: ! 2455: if(ch==ESC) esc=1; /* ANSI codes */ ! 2456: if(ch==' ' && col>40 && !esc) { /* word wrap */ ! 2457: for(m=l+1;m<length;m++) /* find next space */ ! 2458: if(fbuf[m]<=' ') ! 2459: break; ! 2460: if(m<length && m-l>80-col) { /* if it's beyond the eol */ ! 2461: sbody[bodylen++]='\r'; ! 2462: sbody[bodylen++]='\n'; ! 2463: col=0; } } ! 2464: } } } ! 2465: ! 2466: if(bodylen>=2 && sbody[bodylen-2]=='\r' && sbody[bodylen-1]=='\n') ! 2467: bodylen-=2; /* remove last CRLF if present */ ! 2468: sbody[bodylen]=0; ! 2469: ! 2470: while(taillen && stail[taillen-1]<=' ') /* trim all garbage off the tail */ ! 2471: taillen--; ! 2472: stail[taillen]=0; ! 2473: ! 2474: if(subnum==INVALID_SUB && !bodylen && !taillen && misc&KILL_EMPTY_MAIL) { ! 2475: lprintf(LOG_INFO,"Empty NetMail - Ignored "); ! 2476: smb_freemsgmem(&msg); ! 2477: free(sbody); ! 2478: return(3); ! 2479: } ! 2480: ! 2481: if(!origaddr.zone && subnum==INVALID_SUB) ! 2482: net=NET_NONE; /* Message from SBBSecho */ ! 2483: else ! 2484: net=NET_FIDO; /* Record origin address */ ! 2485: ! 2486: if(net) { ! 2487: smb_hfield(&msg,SENDERNETTYPE,sizeof(ushort),&net); ! 2488: smb_hfield(&msg,SENDERNETADDR,sizeof(fidoaddr_t),&origaddr); } ! 2489: ! 2490: if(subnum==INVALID_SUB) { ! 2491: smbfile=email; ! 2492: if(net) { ! 2493: smb_hfield(&msg,RECIPIENTNETTYPE,sizeof(ushort),&net); ! 2494: smb_hfield(&msg,RECIPIENTNETADDR,sizeof(fidoaddr_t),&destaddr); ! 2495: } ! 2496: smbfile->status.attr = SMB_EMAIL; ! 2497: smbfile->status.max_age = scfg.mail_maxage; ! 2498: smbfile->status.max_crcs = scfg.mail_maxcrcs; ! 2499: if(scfg.sys_misc&SM_FASTMAIL) ! 2500: storage= SMB_FASTALLOC; ! 2501: } else { ! 2502: smbfile=&smb[cur_smb]; ! 2503: smbfile->status.max_age = scfg.sub[subnum]->maxage; ! 2504: smbfile->status.max_crcs = scfg.sub[subnum]->maxcrcs; ! 2505: smbfile->status.max_msgs = scfg.sub[subnum]->maxmsgs; ! 2506: if(scfg.sub[subnum]->misc&SUB_HYPER) ! 2507: storage = smbfile->status.attr = SMB_HYPERALLOC; ! 2508: else if(scfg.sub[subnum]->misc&SUB_FAST) ! 2509: storage = SMB_FASTALLOC; ! 2510: if(scfg.sub[subnum]->misc&SUB_LZH) ! 2511: xlat=XLAT_LZH; ! 2512: ! 2513: msg.idx.time=msg.hdr.when_imported.time; /* needed for MSG-ID generation */ ! 2514: msg.idx.number=smbfile->status.last_msg+1; /* needed for MSG-ID generation */ ! 2515: ! 2516: /* Generate default (RFC822) message-id (always) */ ! 2517: SAFECOPY(msg_id,get_msgid(&scfg,subnum,&msg)); ! 2518: smb_hfield_str(&msg,RFC822MSGID,msg_id); ! 2519: } ! 2520: if(smbfile->status.max_crcs==0) ! 2521: dupechk_hashes&=~(1<<SMB_HASH_SOURCE_BODY); ! 2522: ! 2523: i=smb_addmsg(smbfile, &msg, storage, dupechk_hashes, xlat, sbody, stail); ! 2524: ! 2525: if(i!=SMB_SUCCESS) { ! 2526: lprintf(LOG_ERR,"ERROR smb_addmsg returned %d: %s" ! 2527: ,i,smbfile->last_error); ! 2528: } ! 2529: smb_freemsgmem(&msg); ! 2530: ! 2531: return(i); ! 2532: } ! 2533: ! 2534: /***********************************************************************/ ! 2535: /* Get zone and point from kludge lines from the stream if they exist */ ! 2536: /***********************************************************************/ ! 2537: void getzpt(FILE *stream, fmsghdr_t *hdr) ! 2538: { ! 2539: char buf[0x1000]; ! 2540: int i,len,cr=0; ! 2541: long pos; ! 2542: faddr_t faddr; ! 2543: ! 2544: pos=ftell(stream); ! 2545: len=fread(buf,1,0x1000,stream); ! 2546: for(i=0;i<len;i++) { ! 2547: if(buf[i]=='\n') /* ignore line-feeds */ ! 2548: continue; ! 2549: if((!i || cr) && buf[i]==1) { /* kludge */ ! 2550: if(!strncmp(buf+i+1,"TOPT ",5)) ! 2551: hdr->destpoint=atoi(buf+i+6); ! 2552: else if(!strncmp(buf+i+1,"FMPT ",5)) ! 2553: hdr->origpoint=atoi(buf+i+6); ! 2554: else if(!strncmp(buf+i+1,"INTL ",5)) { ! 2555: faddr=atofaddr(buf+i+6); ! 2556: hdr->destzone=faddr.zone; ! 2557: hdr->destnet=faddr.net; ! 2558: hdr->destnode=faddr.node; ! 2559: i+=6; ! 2560: while(buf[i] && buf[i]!=' ') i++; ! 2561: faddr=atofaddr(buf+i+1); ! 2562: hdr->origzone=faddr.zone; ! 2563: hdr->orignet=faddr.net; ! 2564: hdr->orignode=faddr.node; } ! 2565: while(i<len && buf[i]!='\r') i++; ! 2566: cr=1; ! 2567: continue; } ! 2568: if(buf[i]=='\r') ! 2569: cr=1; ! 2570: else ! 2571: cr=0; } ! 2572: fseek(stream,pos,SEEK_SET); ! 2573: } ! 2574: /****************************************************************************** ! 2575: This function will seek to the next NULL found in stream ! 2576: ******************************************************************************/ ! 2577: void seektonull(FILE *stream) ! 2578: { ! 2579: char ch; ! 2580: ! 2581: while(!feof(stream)) { ! 2582: if(!fread(&ch,1,1,stream)) ! 2583: break; ! 2584: if(!ch) ! 2585: break; ! 2586: } ! 2587: } ! 2588: ! 2589: /****************************************************************************** ! 2590: This function returns a packet name - used for outgoing packets ! 2591: ******************************************************************************/ ! 2592: char *pktname(BOOL temp) ! 2593: { ! 2594: static char str[128]; ! 2595: int i; ! 2596: time_t now; ! 2597: struct tm *tm; ! 2598: ! 2599: now=time(NULL); ! 2600: for(i=0;i<MAX_TOTAL_PKTS*2;i++) { ! 2601: now++; ! 2602: tm=localtime(&now); ! 2603: sprintf(str,"%s%02u%02u%02u%02u.%s",cfg.outbound,tm->tm_mday,tm->tm_hour ! 2604: ,tm->tm_min,tm->tm_sec,temp ? "pk_" : "pkt"); ! 2605: if(!fexist(str)) /* Add 1 second if name exists */ ! 2606: break; ! 2607: } ! 2608: return(str); ! 2609: } ! 2610: /****************************************************************************** ! 2611: This function puts a message into a Fido packet, writing both the header ! 2612: information and the message body ! 2613: ******************************************************************************/ ! 2614: void putfmsg(FILE *stream,uchar *fbuf,fmsghdr_t fmsghdr,areasbbs_t area ! 2615: ,addrlist_t seenbys,addrlist_t paths) ! 2616: { ! 2617: char str[256],seenby[256]; ! 2618: short i,j,lastlen=0,net_exists=0; ! 2619: faddr_t addr,sysaddr; ! 2620: fpkdmsg_t pkdmsg; ! 2621: time_t t; ! 2622: size_t len; ! 2623: struct tm* tm; ! 2624: ! 2625: addr=getsysfaddr(fmsghdr.destzone); ! 2626: ! 2627: /* Write fixed-length header fields */ ! 2628: memset(&pkdmsg,0,sizeof(pkdmsg)); ! 2629: pkdmsg.type = 2; ! 2630: pkdmsg.orignet = addr.net; ! 2631: pkdmsg.orignode = addr.node; ! 2632: pkdmsg.destnet = fmsghdr.destnet; ! 2633: pkdmsg.destnode = fmsghdr.destnode; ! 2634: pkdmsg.attr = fmsghdr.attr; ! 2635: pkdmsg.cost = fmsghdr.cost; ! 2636: SAFECOPY(pkdmsg.time,fmsghdr.time); ! 2637: fwrite(&pkdmsg ,sizeof(pkdmsg) ,1,stream); ! 2638: ! 2639: /* Write variable-length (ASCIIZ) header fields */ ! 2640: fwrite(fmsghdr.to ,strlen(fmsghdr.to)+1 ,1,stream); ! 2641: fwrite(fmsghdr.from ,strlen(fmsghdr.from)+1 ,1,stream); ! 2642: fwrite(fmsghdr.subj ,strlen(fmsghdr.subj)+1 ,1,stream); ! 2643: ! 2644: len = strlen((char *)fbuf); ! 2645: ! 2646: /* Write message body */ ! 2647: if(area.name) ! 2648: if(strncmp((char *)fbuf,"AREA:",5)) /* No AREA: Line */ ! 2649: fprintf(stream,"AREA:%s\r",area.name); /* So add one */ ! 2650: fwrite(fbuf,len,1,stream); ! 2651: lastlen=9; ! 2652: if(len && fbuf[len-1]!='\r') ! 2653: fputc('\r',stream); ! 2654: ! 2655: if(area.name==NULL) { /* NetMail, so add FSP-1010 Via kludge line */ ! 2656: t=time(NULL); ! 2657: tm=gmtime(&t); ! 2658: fprintf(stream,"\1Via %s @%04u%02u%02u.%02u%02u%02u.UTC " ! 2659: "SBBSecho %s-%s r%s\r" ! 2660: ,smb_faddrtoa(&addr,NULL) ! 2661: ,tm->tm_year+1900 ! 2662: ,tm->tm_mon+1 ! 2663: ,tm->tm_mday ! 2664: ,tm->tm_hour ! 2665: ,tm->tm_min ! 2666: ,tm->tm_sec ! 2667: ,SBBSECHO_VER,PLATFORM_DESC,revision); ! 2668: } ! 2669: ! 2670: ! 2671: if(area.name && addr.zone!=fmsghdr.destzone) /* Zone Gate */ ! 2672: fprintf(stream,"SEEN-BY: %d/%d\r",fmsghdr.destnet,fmsghdr.destnode); ! 2673: ! 2674: if(area.name && addr.zone==fmsghdr.destzone) { /* Not NetMail */ ! 2675: fprintf(stream,"SEEN-BY:"); ! 2676: for(i=0;i<seenbys.addrs;i++) { /* Put back original SEEN-BYs */ ! 2677: strcpy(seenby," "); ! 2678: if(seenbys.addr[i].zone!=addr.zone) ! 2679: continue; ! 2680: if(seenbys.addr[i].net!=addr.net || !net_exists) { ! 2681: net_exists=1; ! 2682: addr.net=seenbys.addr[i].net; ! 2683: sprintf(str,"%d/",addr.net); ! 2684: strcat(seenby,str); } ! 2685: sprintf(str,"%d",seenbys.addr[i].node); ! 2686: strcat(seenby,str); ! 2687: if(lastlen+strlen(seenby)<80) { ! 2688: fwrite(seenby,strlen(seenby),1,stream); ! 2689: lastlen+=strlen(seenby); } ! 2690: else { ! 2691: --i; ! 2692: lastlen=9; /* +strlen(seenby); */ ! 2693: net_exists=0; ! 2694: fprintf(stream,"\rSEEN-BY:"); } } ! 2695: ! 2696: for(i=0;i<area.uplinks;i++) { /* Add all uplinks to SEEN-BYs */ ! 2697: strcpy(seenby," "); ! 2698: if(area.uplink[i].zone!=addr.zone || area.uplink[i].point) ! 2699: continue; ! 2700: for(j=0;j<seenbys.addrs;j++) ! 2701: if(!memcmp(&area.uplink[i],&seenbys.addr[j],sizeof(faddr_t))) ! 2702: break; ! 2703: if(j==seenbys.addrs) { ! 2704: if(area.uplink[i].net!=addr.net || !net_exists) { ! 2705: net_exists=1; ! 2706: addr.net=area.uplink[i].net; ! 2707: sprintf(str,"%d/",addr.net); ! 2708: strcat(seenby,str); } ! 2709: sprintf(str,"%d",area.uplink[i].node); ! 2710: strcat(seenby,str); ! 2711: if(lastlen+strlen(seenby)<80) { ! 2712: fwrite(seenby,strlen(seenby),1,stream); ! 2713: lastlen+=strlen(seenby); } ! 2714: else { ! 2715: --i; ! 2716: lastlen=9; /* +strlen(seenby); */ ! 2717: net_exists=0; ! 2718: fprintf(stream,"\rSEEN-BY:"); } } } ! 2719: ! 2720: for(i=0;i<scfg.total_faddrs;i++) { /* Add AKAs to SEEN-BYs */ ! 2721: strcpy(seenby," "); ! 2722: if(scfg.faddr[i].zone!=addr.zone || scfg.faddr[i].point) ! 2723: continue; ! 2724: for(j=0;j<seenbys.addrs;j++) ! 2725: if(!memcmp(&scfg.faddr[i],&seenbys.addr[j],sizeof(faddr_t))) ! 2726: break; ! 2727: if(j==seenbys.addrs) { ! 2728: if(scfg.faddr[i].net!=addr.net || !net_exists) { ! 2729: net_exists=1; ! 2730: addr.net=scfg.faddr[i].net; ! 2731: sprintf(str,"%d/",addr.net); ! 2732: strcat(seenby,str); } ! 2733: sprintf(str,"%d",scfg.faddr[i].node); ! 2734: strcat(seenby,str); ! 2735: if(lastlen+strlen(seenby)<80) { ! 2736: fwrite(seenby,strlen(seenby),1,stream); ! 2737: lastlen+=strlen(seenby); } ! 2738: else { ! 2739: --i; ! 2740: lastlen=9; /* +strlen(seenby); */ ! 2741: net_exists=0; ! 2742: fprintf(stream,"\rSEEN-BY:"); } } } ! 2743: ! 2744: lastlen=7; ! 2745: net_exists=0; ! 2746: fprintf(stream,"\r\1PATH:"); ! 2747: addr=getsysfaddr(fmsghdr.destzone); ! 2748: for(i=0;i<paths.addrs;i++) { /* Put back the original PATH */ ! 2749: strcpy(seenby," "); ! 2750: if(paths.addr[i].zone!=addr.zone || paths.addr[i].point) ! 2751: continue; ! 2752: if(paths.addr[i].net!=addr.net || !net_exists) { ! 2753: net_exists=1; ! 2754: addr.net=paths.addr[i].net; ! 2755: sprintf(str,"%d/",addr.net); ! 2756: strcat(seenby,str); } ! 2757: sprintf(str,"%d",paths.addr[i].node); ! 2758: strcat(seenby,str); ! 2759: if(lastlen+strlen(seenby)<80) { ! 2760: fwrite(seenby,strlen(seenby),1,stream); ! 2761: lastlen+=strlen(seenby); } ! 2762: else { ! 2763: --i; ! 2764: lastlen=7; /* +strlen(seenby); */ ! 2765: net_exists=0; ! 2766: fprintf(stream,"\r\1PATH:"); } } ! 2767: ! 2768: strcpy(seenby," "); /* Add first address with same zone to PATH */ ! 2769: sysaddr=getsysfaddr(fmsghdr.destzone); ! 2770: if(!sysaddr.point) { ! 2771: if(sysaddr.net!=addr.net || !net_exists) { ! 2772: net_exists=1; ! 2773: addr.net=sysaddr.net; ! 2774: sprintf(str,"%d/",addr.net); ! 2775: strcat(seenby,str); } ! 2776: sprintf(str,"%d",sysaddr.node); ! 2777: strcat(seenby,str); ! 2778: if(lastlen+strlen(seenby)<80) ! 2779: fwrite(seenby,strlen(seenby),1,stream); ! 2780: else { ! 2781: fprintf(stream,"\r\1PATH:"); ! 2782: fwrite(seenby,strlen(seenby),1,stream); } } ! 2783: ! 2784: fputc('\r',stream); } ! 2785: ! 2786: fputc(FIDO_PACKED_MSG_TERMINATOR, stream); ! 2787: } ! 2788: ! 2789: size_t terminate_packet(FILE* stream) ! 2790: { ! 2791: WORD terminator=FIDO_PACKET_TERMINATOR; ! 2792: ! 2793: return fwrite(&terminator, sizeof(terminator), 1, stream); ! 2794: } ! 2795: ! 2796: long find_packet_terminator(FILE* stream) ! 2797: { ! 2798: WORD terminator; ! 2799: long offset; ! 2800: ! 2801: fseek(stream, 0, SEEK_END); ! 2802: offset = ftell(stream); ! 2803: if(offset >= sizeof(fpkthdr_t)+sizeof(terminator)) { ! 2804: fseek(stream, offset-sizeof(terminator), SEEK_SET); ! 2805: if(fread(&terminator, sizeof(terminator), 1, stream) ! 2806: && terminator==FIDO_PACKET_TERMINATOR) ! 2807: offset -= sizeof(terminator); ! 2808: } ! 2809: return(offset); ! 2810: } ! 2811: ! 2812: /****************************************************************************** ! 2813: This function creates a binary list of the message seen-bys and path from ! 2814: inbuf. ! 2815: ******************************************************************************/ ! 2816: void gen_psb(addrlist_t *seenbys,addrlist_t *paths,char *inbuf ! 2817: ,ushort zone) ! 2818: { ! 2819: char str[128],seenby[256],*p,*p1,*p2,*fbuf; ! 2820: int i,j,len; ! 2821: faddr_t addr; ! 2822: ! 2823: if(!inbuf) ! 2824: return; ! 2825: fbuf=strstr((char *)inbuf,"\r * Origin: "); ! 2826: if(!fbuf) ! 2827: fbuf=strstr((char *)inbuf,"\n * Origin: "); ! 2828: if(!fbuf) ! 2829: fbuf=inbuf; ! 2830: if(seenbys->addr) { ! 2831: free(seenbys->addr); ! 2832: seenbys->addr=0; ! 2833: seenbys->addrs=0; } ! 2834: addr.zone=addr.net=addr.node=addr.point=seenbys->addrs=0; ! 2835: p=strstr((char *)fbuf,"\rSEEN-BY:"); ! 2836: if(!p) p=strstr((char *)fbuf,"\nSEEN-BY:"); ! 2837: if(p) { ! 2838: while(1) { ! 2839: sprintf(str,"%-.100s",p+10); ! 2840: if((p1=strchr(str,'\r'))!=NULL) ! 2841: *p1=0; ! 2842: p1=str; ! 2843: i=j=0; ! 2844: len=strlen(str); ! 2845: while(i<len) { ! 2846: j=i; ! 2847: while(i<len && *(p1+i)!=' ') ! 2848: ++i; ! 2849: if(j>len) ! 2850: break; ! 2851: sprintf(seenby,"%-.*s",(i-j),p1+j); ! 2852: if((p2=strchr(seenby,':'))!=NULL) { ! 2853: addr.zone=atoi(seenby); ! 2854: addr.net=atoi(p2+1); } ! 2855: else if((p2=strchr(seenby,'/'))!=NULL) ! 2856: addr.net=atoi(seenby); ! 2857: if((p2=strchr(seenby,'/'))!=NULL) ! 2858: addr.node=atoi(p2+1); ! 2859: else ! 2860: addr.node=atoi(seenby); ! 2861: if((p2=strchr(seenby,'.'))!=NULL) ! 2862: addr.point=atoi(p2+1); ! 2863: if(!addr.zone) ! 2864: addr.zone=zone; /* Was 1 */ ! 2865: if((seenbys->addr=(faddr_t *)realloc(seenbys->addr ! 2866: ,sizeof(faddr_t)*(seenbys->addrs+1)))==NULL) { ! 2867: lprintf(LOG_ERR,"ERROR line %d allocating memory for message " ! 2868: "seenbys.",__LINE__); ! 2869: bail(1); } ! 2870: memcpy(&seenbys->addr[seenbys->addrs],&addr,sizeof(faddr_t)); ! 2871: seenbys->addrs++; ! 2872: ++i; } ! 2873: p1=strstr(p+10,"\rSEEN-BY:"); ! 2874: if(!p1) ! 2875: p1=strstr(p+10,"\nSEEN-BY:"); ! 2876: if(!p1) ! 2877: break; ! 2878: p=p1; } } ! 2879: else { ! 2880: if((seenbys->addr=(faddr_t *)realloc(seenbys->addr ! 2881: ,sizeof(faddr_t)))==NULL) { ! 2882: lprintf(LOG_ERR,"ERROR line %d allocating memory for message seenbys." ! 2883: ,__LINE__); ! 2884: bail(1); } ! 2885: memset(&seenbys->addr[0],0,sizeof(faddr_t)); } ! 2886: ! 2887: if(paths->addr) { ! 2888: free(paths->addr); ! 2889: paths->addr=0; ! 2890: paths->addrs=0; } ! 2891: addr.zone=addr.net=addr.node=addr.point=paths->addrs=0; ! 2892: if((p=strstr((char *)fbuf,"\1PATH:"))!=NULL) { ! 2893: while(1) { ! 2894: sprintf(str,"%-.100s",p+7); ! 2895: if((p1=strchr(str,'\r'))!=NULL) ! 2896: *p1=0; ! 2897: p1=str; ! 2898: i=j=0; ! 2899: len=strlen(str); ! 2900: while(i<len) { ! 2901: j=i; ! 2902: while(i<len && *(p1+i)!=' ') ! 2903: ++i; ! 2904: if(j>len) ! 2905: break; ! 2906: sprintf(seenby,"%-.*s",(i-j),p1+j); ! 2907: if((p2=strchr(seenby,':'))!=NULL) { ! 2908: addr.zone=atoi(seenby); ! 2909: addr.net=atoi(p2+1); } ! 2910: else if((p2=strchr(seenby,'/'))!=NULL) ! 2911: addr.net=atoi(seenby); ! 2912: if((p2=strchr(seenby,'/'))!=NULL) ! 2913: addr.node=atoi(p2+1); ! 2914: else ! 2915: addr.node=atoi(seenby); ! 2916: if((p2=strchr(seenby,'.'))!=NULL) ! 2917: addr.point=atoi(p2+1); ! 2918: if(!addr.zone) ! 2919: addr.zone=zone; /* Was 1 */ ! 2920: if((paths->addr=(faddr_t *)realloc(paths->addr ! 2921: ,sizeof(faddr_t)*(paths->addrs+1)))==NULL) { ! 2922: lprintf(LOG_ERR,"ERROR line %d allocating memory for message " ! 2923: "paths.",__LINE__); ! 2924: bail(1); } ! 2925: memcpy(&paths->addr[paths->addrs],&addr,sizeof(faddr_t)); ! 2926: paths->addrs++; ! 2927: ++i; } ! 2928: if((p1=strstr(p+7,"\1PATH:"))==NULL) ! 2929: break; ! 2930: p=p1; } } ! 2931: else { ! 2932: if((paths->addr=(faddr_t *)realloc(paths->addr ! 2933: ,sizeof(faddr_t)))==NULL) { ! 2934: lprintf(LOG_ERR,"ERROR line %d allocating memory for message paths." ! 2935: ,__LINE__); ! 2936: bail(1); } ! 2937: memset(&paths->addr[0],0,sizeof(faddr_t)); } ! 2938: } ! 2939: ! 2940: /****************************************************************************** ! 2941: This function takes the addrs passed to it and compares them to the address ! 2942: passed in inaddr. 1 is returned if inaddr matches any of the addrs ! 2943: otherwise a 0 is returned. ! 2944: ******************************************************************************/ ! 2945: int check_psb(addrlist_t* addrlist,faddr_t inaddr) ! 2946: { ! 2947: int i; ! 2948: ! 2949: for(i=0;i<addrlist->addrs;i++) { ! 2950: if(!memcmp(&addrlist->addr[i],&inaddr,sizeof(faddr_t))) ! 2951: return(1); ! 2952: } ! 2953: return(0); ! 2954: } ! 2955: /****************************************************************************** ! 2956: This function strips the message seen-bys and path from inbuf. ! 2957: ******************************************************************************/ ! 2958: void strip_psb(char *inbuf) ! 2959: { ! 2960: char *p,*fbuf; ! 2961: ! 2962: if(!inbuf) ! 2963: return; ! 2964: fbuf=strstr((char *)inbuf,"\r * Origin: "); ! 2965: if(!fbuf) ! 2966: fbuf=inbuf; ! 2967: if((p=strstr((char *)fbuf,"\rSEEN-BY:"))!=NULL) ! 2968: *(p)=0; ! 2969: if((p=strstr((char *)fbuf,"\r\1PATH:"))!=NULL) ! 2970: *(p)=0; ! 2971: } ! 2972: void attach_bundles(void) ! 2973: { ! 2974: FILE *fidomsg; ! 2975: char str[1025],path[MAX_PATH+1],*packet; ! 2976: int fmsg; ! 2977: faddr_t pkt_faddr; ! 2978: pkthdr_t pkthdr; ! 2979: size_t f; ! 2980: glob_t g; ! 2981: ! 2982: sprintf(path,"%s*.pk_",cfg.outbound); ! 2983: glob(path,0,NULL,&g); ! 2984: for(f=0;f<g.gl_pathc && !kbhit();f++) { ! 2985: ! 2986: packet=g.gl_pathv[f]; ! 2987: ! 2988: printf("%21s: %s ","Outbound Packet",packet); ! 2989: if((fmsg=sopen(packet,O_RDWR|O_BINARY,SH_DENYRW))==-1) { ! 2990: lprintf(LOG_ERR,"ERROR %d line %d opening %s",errno,__LINE__,packet); ! 2991: continue; } ! 2992: if((fidomsg=fdopen(fmsg,"r+b"))==NULL) { ! 2993: close(fmsg); ! 2994: lprintf(LOG_ERR,"ERROR line %d fdopening %s",__LINE__,packet); ! 2995: continue; } ! 2996: if(filelength(fmsg)<sizeof(pkthdr_t)) { ! 2997: lprintf(LOG_ERR,"ERROR line %d invalid length of %lu bytes for %s" ! 2998: ,__LINE__,filelength(fmsg),packet); ! 2999: fclose(fidomsg); ! 3000: if(delfile(packet)) ! 3001: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,packet ! 3002: ,strerror(errno)); ! 3003: continue; } ! 3004: if(fread(&pkthdr,sizeof(pkthdr_t),1,fidomsg)!=1) { ! 3005: fclose(fidomsg); ! 3006: lprintf(LOG_ERR,"ERROR line %d reading %u bytes from %s",__LINE__ ! 3007: ,sizeof(pkthdr_t),packet); ! 3008: continue; } ! 3009: fseek(fidomsg,-2L,SEEK_END); ! 3010: fread(str,2,1,fidomsg); ! 3011: fclose(fidomsg); ! 3012: if(!str[0] && !str[1]) { /* Check for two nulls at end of packet */ ! 3013: pkt_faddr.zone=pkthdr.destzone; ! 3014: pkt_faddr.net=pkthdr.destnet; ! 3015: pkt_faddr.node=pkthdr.destnode; ! 3016: pkt_faddr.point=0; /* No point info in the 2.0 hdr! */ ! 3017: memcpy(&two_plus,&pkthdr.empty,sizeof(pkthdr.empty)); ! 3018: if(two_plus.cword==_rotr(two_plus.cwcopy,8) /* 2+ Packet Header */ ! 3019: && two_plus.cword && two_plus.cword&1) ! 3020: pkt_faddr.point=two_plus.destpoint; ! 3021: else if(pkthdr.baud==2) { /* Type 2.2 Packet Header */ ! 3022: memcpy(&two_two,&pkthdr.empty,sizeof(pkthdr.empty)); ! 3023: pkt_faddr.point=pkthdr.month; } ! 3024: lprintf(LOG_INFO,"Sending to %s",smb_faddrtoa(&pkt_faddr,NULL)); ! 3025: pack_bundle(packet,pkt_faddr); ! 3026: } else ! 3027: lprintf(LOG_WARNING,"Outbound Packet (%s) possibly still in use (invalid terminator: %02X%02X)" ! 3028: ,packet,(BYTE)str[0],(BYTE)str[1]); ! 3029: } ! 3030: globfree(&g); ! 3031: } ! 3032: /****************************************************************************** ! 3033: This is where we put outgoing messages into packets. Set the 'cleanup' ! 3034: parameter to 1 to force all the remaining packets closed and stuff them into ! 3035: a bundle. ! 3036: ******************************************************************************/ ! 3037: void pkt_to_pkt(uchar *fbuf,areasbbs_t area,faddr_t faddr ! 3038: ,fmsghdr_t fmsghdr,addrlist_t seenbys,addrlist_t paths, int cleanup) ! 3039: { ! 3040: int i,j,k,file; ! 3041: short node; ! 3042: time_t now; ! 3043: struct tm *tm; ! 3044: pkthdr_t pkthdr; ! 3045: static ushort openpkts,totalpkts; ! 3046: static outpkt_t outpkt[MAX_TOTAL_PKTS]; ! 3047: faddr_t sysaddr; ! 3048: two_two_t two; ! 3049: two_plus_t two_p; ! 3050: ! 3051: ! 3052: if(cleanup==1) { ! 3053: for(i=0;i<totalpkts;i++) { ! 3054: if(i>=MAX_TOTAL_PKTS) { ! 3055: lprintf(LOG_ERR,"MAX_TOTAL_PKTS (%d) REACHED!",MAX_TOTAL_PKTS); ! 3056: break; ! 3057: } ! 3058: if(outpkt[i].curopen) { ! 3059: terminate_packet(outpkt[i].stream); ! 3060: fclose(outpkt[i].stream); } ! 3061: else { ! 3062: if((outpkt[i].stream=fnopen(&file,outpkt[i].filename ! 3063: ,O_WRONLY|O_APPEND))==NULL) { ! 3064: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__ ! 3065: ,outpkt[i].filename,strerror(errno)); ! 3066: continue; } ! 3067: terminate_packet(outpkt[i].stream); ! 3068: fclose(outpkt[i].stream); } ! 3069: /* pack_nundle() disabled. Why? ToDo */ ! 3070: /* pack_bundle(outpkt[i].filename,outpkt[i].uplink); */ ! 3071: memset(&outpkt[i],0,sizeof(outpkt_t)); } ! 3072: totalpkts=openpkts=0; ! 3073: attach_bundles(); ! 3074: if(!(misc&FLO_MAILER)) ! 3075: attachment(0,faddr,ATTACHMENT_NETMAIL); ! 3076: return; } ! 3077: ! 3078: if(fbuf==NULL) { ! 3079: lprintf(LOG_ERR,"ERROR line %d allocating fbuf",__LINE__); ! 3080: return; } ! 3081: /* We want to see if there's already a packet open for this area. */ ! 3082: /* If not, we'll open a new one. Once we have a packet, we'll add */ ! 3083: /* messages to it as they come in. If necessary, we'll close an */ ! 3084: /* open packet to open a new one. */ ! 3085: ! 3086: for(j=0;j<area.uplinks;j++) { ! 3087: if((cleanup==2 && memcmp(&faddr,&area.uplink[j],sizeof(faddr_t))) || ! 3088: (!cleanup && (!memcmp(&faddr,&area.uplink[j],sizeof(faddr_t)) || ! 3089: check_psb(&seenbys,area.uplink[j])))) ! 3090: continue; ! 3091: node=matchnode(area.uplink[j],0); ! 3092: if(node<cfg.nodecfgs && cfg.nodecfg[node].attr&ATTR_PASSIVE) ! 3093: continue; ! 3094: sysaddr=getsysfaddr(area.uplink[j].zone); ! 3095: printf("%s ",smb_faddrtoa(&area.uplink[j],NULL)); ! 3096: for(i=0;i<totalpkts;i++) { ! 3097: if(i>=MAX_TOTAL_PKTS) { ! 3098: lprintf(LOG_ERR,"MAX_TOTAL_PKTS (%d) REACHED!",MAX_TOTAL_PKTS); ! 3099: break; ! 3100: } ! 3101: if(!memcmp(&area.uplink[j],&outpkt[i].uplink,sizeof(faddr_t))) { ! 3102: if(!outpkt[i].curopen) { ! 3103: if(openpkts==DFLT_OPEN_PKTS) ! 3104: for(k=0;k<totalpkts;k++) { ! 3105: if(outpkt[k].curopen) { ! 3106: fclose(outpkt[k].stream); ! 3107: outpkt[k].curopen=0; ! 3108: break; } } ! 3109: if((outpkt[i].stream=fnopen(&file,outpkt[i].filename ! 3110: ,O_WRONLY|O_APPEND))==NULL) { ! 3111: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__ ! 3112: ,outpkt[i].filename,strerror(errno)); ! 3113: bail(1); } ! 3114: outpkt[i].curopen=1; } ! 3115: if((strlen((char *)fbuf)+1+ftell(outpkt[i].stream)) ! 3116: <=cfg.maxpktsize) { ! 3117: fmsghdr.destnode=area.uplink[j].node; ! 3118: fmsghdr.destnet=area.uplink[j].net; ! 3119: fmsghdr.destzone=area.uplink[j].zone; ! 3120: putfmsg(outpkt[i].stream,fbuf,fmsghdr,area,seenbys,paths); } ! 3121: else { ! 3122: terminate_packet(outpkt[i].stream); ! 3123: fclose(outpkt[i].stream); ! 3124: /* pack_bundle() disabled. Why? ToDo */ ! 3125: /* pack_bundle(outpkt[i].filename,outpkt[i].uplink); */ ! 3126: outpkt[i].stream=outpkt[totalpkts-1].stream; ! 3127: memcpy(&outpkt[i],&outpkt[totalpkts-1],sizeof(outpkt_t)); ! 3128: memset(&outpkt[totalpkts-1],0,sizeof(outpkt_t)); ! 3129: --totalpkts; ! 3130: --openpkts; ! 3131: i=totalpkts; ! 3132: } ! 3133: break; ! 3134: } ! 3135: } ! 3136: if(i==totalpkts) { ! 3137: if(openpkts==DFLT_OPEN_PKTS) ! 3138: for(k=0;k<totalpkts;k++) { ! 3139: if(outpkt[k].curopen) { ! 3140: fclose(outpkt[k].stream); ! 3141: outpkt[k].curopen=0; ! 3142: --openpkts; ! 3143: break; } } ! 3144: strcpy(outpkt[i].filename,pktname(/* temp? */ TRUE)); ! 3145: now=time(NULL); ! 3146: tm=localtime(&now); ! 3147: if((outpkt[i].stream=fnopen(&file,outpkt[i].filename ! 3148: ,O_WRONLY|O_CREAT))==NULL) { ! 3149: lprintf(LOG_ERR,"ERROR line %d opening %s %s" ! 3150: ,__LINE__,outpkt[i].filename,strerror(errno)); ! 3151: bail(1); } ! 3152: pkthdr.orignode=sysaddr.node; ! 3153: fmsghdr.destnode=pkthdr.destnode=area.uplink[j].node; ! 3154: if(node<cfg.nodecfgs && cfg.nodecfg[node].pkt_type==PKT_TWO_TWO) { ! 3155: pkthdr.year=sysaddr.point; ! 3156: pkthdr.month=area.uplink[j].point; ! 3157: pkthdr.day=0; ! 3158: pkthdr.hour=0; ! 3159: pkthdr.min=0; ! 3160: pkthdr.sec=0; ! 3161: pkthdr.baud=0x0002; } ! 3162: else { ! 3163: pkthdr.year=tm->tm_year+1900; ! 3164: pkthdr.month=tm->tm_mon; ! 3165: pkthdr.day=tm->tm_mday; ! 3166: pkthdr.hour=tm->tm_hour; ! 3167: pkthdr.min=tm->tm_min; ! 3168: pkthdr.sec=tm->tm_sec; ! 3169: pkthdr.baud=0; } ! 3170: pkthdr.pkttype=0x0002; ! 3171: pkthdr.orignet=sysaddr.net; ! 3172: fmsghdr.destnet=pkthdr.destnet=area.uplink[j].net; ! 3173: pkthdr.prodcode=0; ! 3174: pkthdr.sernum=0; ! 3175: if(node<cfg.nodecfgs) ! 3176: memcpy(pkthdr.password,cfg.nodecfg[node].pktpwd,sizeof(pkthdr.password)); ! 3177: else ! 3178: memset(pkthdr.password,0,sizeof(pkthdr.password)); ! 3179: pkthdr.origzone=sysaddr.zone; ! 3180: fmsghdr.destzone=pkthdr.destzone=area.uplink[j].zone; ! 3181: memset(pkthdr.empty,0,sizeof(two_two_t)); ! 3182: ! 3183: if(node<cfg.nodecfgs) { ! 3184: if(cfg.nodecfg[node].pkt_type==PKT_TWO_TWO) { ! 3185: memset(&two,0,sizeof(two)); ! 3186: strcpy(two.origdomn,"fidonet"); ! 3187: strcpy(two.destdomn,"fidonet"); ! 3188: memcpy(&pkthdr.empty,&two,sizeof(pkthdr.empty)); } ! 3189: else if(cfg.nodecfg[node].pkt_type==PKT_TWO_PLUS) { ! 3190: memset(&two_p,0,sizeof(two_p)); ! 3191: if(sysaddr.point) { ! 3192: pkthdr.orignet=-1; ! 3193: two_p.auxnet=sysaddr.net; } ! 3194: two_p.cwcopy=0x0100; ! 3195: two_p.prodcode=pkthdr.prodcode; ! 3196: two_p.revision=pkthdr.sernum; ! 3197: two_p.cword=0x0001; ! 3198: two_p.origzone=pkthdr.origzone; ! 3199: two_p.destzone=pkthdr.destzone; ! 3200: two_p.origpoint=sysaddr.point; ! 3201: two_p.destpoint=area.uplink[j].point; ! 3202: memcpy(&pkthdr.empty,&two_p,sizeof(pkthdr.empty)); } ! 3203: } ! 3204: fwrite(&pkthdr,sizeof(pkthdr_t),1,outpkt[totalpkts].stream); ! 3205: putfmsg(outpkt[totalpkts].stream,fbuf,fmsghdr,area,seenbys,paths); ! 3206: outpkt[totalpkts].curopen=1; ! 3207: memcpy(&outpkt[totalpkts].uplink,&area.uplink[j] ! 3208: ,sizeof(faddr_t)); ! 3209: ++openpkts; ! 3210: ++totalpkts; ! 3211: if(totalpkts>=MAX_TOTAL_PKTS) { ! 3212: fclose(outpkt[totalpkts-1].stream); ! 3213: /* pack_bundle() disabled. Why? ToDo */ ! 3214: /* pack_bundle(outpkt[totalpkts-1].filename ! 3215: ,outpkt[totalpkts-1].uplink); */ ! 3216: --totalpkts; ! 3217: --openpkts; ! 3218: } ! 3219: } ! 3220: } ! 3221: } ! 3222: ! 3223: int pkt_to_msg(FILE* fidomsg, fmsghdr_t* hdr, char* info) ! 3224: { ! 3225: char path[MAX_PATH+1]; ! 3226: uchar* fmsgbuf; ! 3227: int i,file; ! 3228: ulong l; ! 3229: ! 3230: if((fmsgbuf=getfmsg(fidomsg,&l))==NULL) { ! 3231: lprintf(LOG_ERR,"ERROR line %d netmail allocation",__LINE__); ! 3232: return(-1); ! 3233: } ! 3234: ! 3235: if(!l && misc&KILL_EMPTY_MAIL) ! 3236: printf("Empty NetMail"); ! 3237: else { ! 3238: printf("Exporting: "); ! 3239: for(i=1;i;i++) { ! 3240: sprintf(path,"%s%u.msg",scfg.netmail_dir,i); ! 3241: if(!fexistcase(path)) ! 3242: break; ! 3243: } ! 3244: if(!i) { ! 3245: lprintf(LOG_WARNING,"Too many netmail messages"); ! 3246: return(-1); ! 3247: } ! 3248: if((file=nopen(path,O_WRONLY|O_CREAT))==-1) { ! 3249: lprintf(LOG_ERR,"ERROR %u line %d creating %s",errno,__LINE__,path); ! 3250: return(-1); ! 3251: } ! 3252: write(file,hdr,sizeof(fmsghdr_t)); ! 3253: write(file,fmsgbuf,l+1); /* Write the '\0' terminator too */ ! 3254: close(file); ! 3255: printf("%s", path); ! 3256: lprintf(LOG_INFO,"%s Exported to %s",info,path); ! 3257: } ! 3258: free(fmsgbuf); ! 3259: ! 3260: return(0); ! 3261: } ! 3262: ! 3263: ! 3264: /**************************************/ ! 3265: /* Send netmail, returns 0 on success */ ! 3266: /**************************************/ ! 3267: int import_netmail(char *path,fmsghdr_t hdr, FILE *fidomsg) ! 3268: { ! 3269: uchar info[512],str[256],tmp[256],subj[256] ! 3270: ,*fmsgbuf=NULL,*p,*tp,*sp; ! 3271: int i,match,usernumber; ! 3272: ulong length; ! 3273: faddr_t addr; ! 3274: ! 3275: hdr.destzone=hdr.origzone=sys_faddr.zone; ! 3276: hdr.destpoint=hdr.origpoint=0; ! 3277: getzpt(fidomsg,&hdr); /* use kludge if found */ ! 3278: for(match=0;match<scfg.total_faddrs;match++) ! 3279: if((hdr.destzone==scfg.faddr[match].zone || misc&FUZZY_ZONE) ! 3280: && hdr.destnet==scfg.faddr[match].net ! 3281: && hdr.destnode==scfg.faddr[match].node ! 3282: && hdr.destpoint==scfg.faddr[match].point) ! 3283: break; ! 3284: if(match<scfg.total_faddrs && misc&FUZZY_ZONE) ! 3285: hdr.origzone=hdr.destzone=scfg.faddr[match].zone; ! 3286: if(hdr.origpoint) ! 3287: sprintf(tmp,".%hu",hdr.origpoint); ! 3288: else ! 3289: tmp[0]=0; ! 3290: if(hdr.destpoint) ! 3291: sprintf(str,".%hu",hdr.destpoint); ! 3292: else ! 3293: str[0]=0; ! 3294: sprintf(info,"%s%s%s (%hu:%hu/%hu%s) To: %s (%hu:%hu/%hu%s)" ! 3295: ,path,path[0] ? " ":"" ! 3296: ,hdr.from,hdr.origzone,hdr.orignet,hdr.orignode,tmp ! 3297: ,hdr.to,hdr.destzone,hdr.destnet,hdr.destnode,str); ! 3298: printf("%s ",info); ! 3299: ! 3300: if(!(misc&IMPORT_NETMAIL)) { ! 3301: printf("Ignored"); ! 3302: if(!path[0]) { ! 3303: printf(" - "); ! 3304: pkt_to_msg(fidomsg,&hdr,info); ! 3305: } else if(cfg.log&LOG_IGNORED) ! 3306: lprintf(LOG_INFO,"%s Ignored",info); ! 3307: ! 3308: return(-1); ! 3309: } ! 3310: ! 3311: if(match>=scfg.total_faddrs && !(misc&IGNORE_ADDRESS)) { ! 3312: printf("Wrong address"); ! 3313: if(!path[0]) { ! 3314: printf(" - "); ! 3315: pkt_to_msg(fidomsg,&hdr,info); ! 3316: } ! 3317: return(2); ! 3318: } ! 3319: ! 3320: if(path[0]) { /* .msg file, not .pkt */ ! 3321: if(hdr.attr&FIDO_ORPHAN) { ! 3322: printf("Orphaned"); ! 3323: return(1); ! 3324: } ! 3325: if(hdr.attr&FIDO_RECV && !(misc&IGNORE_RECV)) { ! 3326: printf("Already received"); ! 3327: return(3); ! 3328: } ! 3329: if(hdr.attr&FIDO_LOCAL && !(misc&LOCAL_NETMAIL)) { ! 3330: printf("Created locally"); ! 3331: return(4); ! 3332: } ! 3333: if(hdr.attr&FIDO_INTRANS) { ! 3334: printf("In-transit"); ! 3335: return(5); ! 3336: } ! 3337: } ! 3338: ! 3339: if(email->shd_fp==NULL) { ! 3340: sprintf(email->file,"%smail",scfg.data_dir); ! 3341: email->retry_time=scfg.smb_retry_time; ! 3342: if((i=smb_open(email))!=SMB_SUCCESS) { ! 3343: lprintf(LOG_ERR,"ERROR %d line %d opening %s",i,__LINE__,email->file); ! 3344: bail(1); } } ! 3345: ! 3346: if(!filelength(fileno(email->shd_fp))) { ! 3347: email->status.max_crcs=scfg.mail_maxcrcs; ! 3348: email->status.max_msgs=0; ! 3349: email->status.max_age=scfg.mail_maxage; ! 3350: email->status.attr=SMB_EMAIL; ! 3351: if((i=smb_create(email))!=SMB_SUCCESS) { ! 3352: lprintf(LOG_ERR,"ERROR %d creating %s",i,email->file); ! 3353: bail(1); } } ! 3354: ! 3355: if(!stricmp(hdr.to,"AREAFIX") || !stricmp(hdr.to,"SBBSECHO")) { ! 3356: fmsgbuf=getfmsg(fidomsg,NULL); ! 3357: if(path[0]) { ! 3358: if(misc&DELETE_NETMAIL) { ! 3359: fclose(fidomsg); ! 3360: if(delfile(path)) ! 3361: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,path ! 3362: ,strerror(errno)); } ! 3363: else { ! 3364: hdr.attr|=FIDO_RECV; ! 3365: fseek(fidomsg,0L,SEEK_SET); ! 3366: fwrite(&hdr,sizeof(fmsghdr_t),1,fidomsg); ! 3367: fclose(fidomsg); } } /* Gotta close it here for areafix stuff */ ! 3368: addr.zone=hdr.origzone; ! 3369: addr.net=hdr.orignet; ! 3370: addr.node=hdr.orignode; ! 3371: addr.point=hdr.origpoint; ! 3372: p=process_areafix(addr,fmsgbuf,/* Password: */hdr.subj, /* To: */hdr.from); ! 3373: if(p && cfg.notify) { ! 3374: SAFECOPY(hdr.to,scfg.sys_op); ! 3375: SAFECOPY(hdr.from,"SBBSecho"); ! 3376: SAFECOPY(hdr.subj,"Areafix Request"); ! 3377: hdr.origzone=hdr.orignet=hdr.orignode=hdr.origpoint=0; ! 3378: if(fmsgtosmsg(p,hdr,cfg.notify,INVALID_SUB)==0) { ! 3379: sprintf(str,"\7\1n\1hSBBSecho \1n\1msent you mail\r\n"); ! 3380: putsmsg(&scfg,cfg.notify,str); ! 3381: } ! 3382: } ! 3383: if(fmsgbuf) ! 3384: free(fmsgbuf); ! 3385: if(cfg.log&LOG_AREAFIX) ! 3386: logprintf(info); ! 3387: return(-2); ! 3388: } ! 3389: ! 3390: usernumber=atoi(hdr.to); ! 3391: if(!stricmp(hdr.to,"SYSOP")) /* NetMail to "sysop" goes to #1 */ ! 3392: usernumber=1; ! 3393: if(!usernumber && match<scfg.total_faddrs) ! 3394: usernumber=matchname(hdr.to); ! 3395: if(!usernumber) { ! 3396: if(misc&UNKNOWN_NETMAIL && match<scfg.total_faddrs) /* receive unknown user */ ! 3397: usernumber=1; /* mail to 1 */ ! 3398: else { ! 3399: if(match<scfg.total_faddrs) { ! 3400: printf("Unknown user"); ! 3401: if(cfg.log&LOG_UNKNOWN) ! 3402: lprintf(LOG_WARNING,"%s Unknown user",info); ! 3403: } ! 3404: ! 3405: if(!path[0]) { ! 3406: printf(" - "); ! 3407: pkt_to_msg(fidomsg,&hdr,info); ! 3408: } ! 3409: return(2); ! 3410: } ! 3411: } ! 3412: ! 3413: /*********************/ ! 3414: /* Importing NetMail */ ! 3415: /*********************/ ! 3416: ! 3417: fmsgbuf=getfmsg(fidomsg,&length); ! 3418: ! 3419: switch(i=fmsgtosmsg(fmsgbuf,hdr,usernumber,INVALID_SUB)) { ! 3420: case 0: /* success */ ! 3421: break; ! 3422: case 2: /* filtered */ ! 3423: if(cfg.log&LOG_IGNORED) ! 3424: lprintf(LOG_WARNING,"%s Filtered - Ignored",info); ! 3425: break; ! 3426: case 3: /* empty */ ! 3427: if(cfg.log&LOG_IGNORED) ! 3428: lprintf(LOG_WARNING,"%s Empty - Ignored",info); ! 3429: break; ! 3430: default: ! 3431: lprintf(LOG_ERR,"ERROR (%d) Importing %s",i,info); ! 3432: break; ! 3433: } ! 3434: if(i) { ! 3435: if(fmsgbuf) ! 3436: free(fmsgbuf); ! 3437: return(0); ! 3438: } ! 3439: ! 3440: addr.zone=hdr.origzone; ! 3441: addr.net=hdr.orignet; ! 3442: addr.node=hdr.orignode; ! 3443: addr.point=hdr.origpoint; ! 3444: sprintf(str,"\7\1n\1hSBBSecho: \1m%.*s \1n\1msent you NetMail from \1h%s\1n\r\n" ! 3445: ,FIDO_NAME_LEN-1 ! 3446: ,hdr.from ! 3447: ,smb_faddrtoa(&addr,NULL)); ! 3448: putsmsg(&scfg,usernumber,str); ! 3449: ! 3450: if(hdr.attr&FIDO_FILE) { /* File attachment */ ! 3451: strcpy(subj,hdr.subj); ! 3452: tp=subj; ! 3453: while(1) { ! 3454: p=strchr(tp,' '); ! 3455: if(p) *p=0; ! 3456: sp=strrchr(tp,'/'); /* sp is slash pointer */ ! 3457: if(!sp) sp=strrchr(tp,'\\'); ! 3458: if(sp) tp=sp+1; ! 3459: sprintf(str,"%s%s",secure ? cfg.secure : cfg.inbound,tp); ! 3460: sprintf(tmp,"%sfile/%04u.in",scfg.data_dir,usernumber); ! 3461: MKDIR(tmp); ! 3462: backslash(tmp); ! 3463: strcat(tmp,tp); ! 3464: mv(str,tmp,0); ! 3465: if(!p) ! 3466: break; ! 3467: tp=p+1; } } ! 3468: netmail++; ! 3469: ! 3470: if(fmsgbuf) ! 3471: free(fmsgbuf); ! 3472: ! 3473: /***************************/ ! 3474: /* Updating message header */ ! 3475: /***************************/ ! 3476: /*** NOT packet compatible ! 3477: if(!(misc&DONT_SET_RECV)) { ! 3478: hdr.attr|=FIDO_RECV; ! 3479: fseek(fidomsg,0L,SEEK_SET); ! 3480: fwrite(&hdr,sizeof(fmsghdr_t),1,fidomsg); } ! 3481: ***/ ! 3482: if(cfg.log&LOG_IMPORTED) ! 3483: lprintf(LOG_INFO,"%s Imported",info); ! 3484: return(0); ! 3485: } ! 3486: ! 3487: /****************************************************************************** ! 3488: This is where we export echomail. This was separated from function main so ! 3489: it could be used for the remote rescan function. Passing anything but an ! 3490: empty address as 'addr' designates that a rescan should be done for that ! 3491: address. ! 3492: ******************************************************************************/ ! 3493: void export_echomail(char *sub_code,faddr_t addr) ! 3494: { ! 3495: char str[1025],tear,cr; ! 3496: char* buf=NULL; ! 3497: char* minus; ! 3498: uchar* fmsgbuf=NULL; ! 3499: ulong fmsgbuflen; ! 3500: int tzone; ! 3501: int g,i,j,k=0,file; ! 3502: ulong f,l,m,exp,ptr,msgs,lastmsg,posts,exported=0; ! 3503: float export_time; ! 3504: smbmsg_t msg; ! 3505: smbmsg_t orig_msg; ! 3506: fmsghdr_t hdr; ! 3507: struct tm *tm; ! 3508: faddr_t pkt_faddr; ! 3509: post_t *post; ! 3510: areasbbs_t fakearea; ! 3511: addrlist_t msg_seen,msg_path; ! 3512: clock_t start_tick=0,export_ticks=0; ! 3513: ! 3514: memset(&msg_seen,0,sizeof(addrlist_t)); ! 3515: memset(&msg_path,0,sizeof(addrlist_t)); ! 3516: memset(&fakearea,0,sizeof(areasbbs_t)); ! 3517: memset(&pkt_faddr,0,sizeof(faddr_t)); ! 3518: memset(&hdr,0,sizeof(hdr)); ! 3519: start_tick=0; ! 3520: ! 3521: lprintf(LOG_DEBUG,"\nScanning for Outbound EchoMail..."); ! 3522: ! 3523: for(g=0;g<scfg.total_grps;g++) ! 3524: for(i=0;i<scfg.total_subs;i++) ! 3525: if(scfg.sub[i]->misc&SUB_FIDO && scfg.sub[i]->grp==g) { ! 3526: for(j=0;j<cfg.areas;j++) /* Skip areas with no uplinks */ ! 3527: if(cfg.area[j].sub==i) ! 3528: break; ! 3529: if(j==cfg.areas || (j<cfg.areas && !cfg.area[j].uplinks)) ! 3530: continue; ! 3531: if(addr.zone) { /* Skip areas not meant for this address */ ! 3532: if(j<cfg.areas) ! 3533: for(k=0;k<cfg.area[j].uplinks;k++) ! 3534: if(!memcmp(&cfg.area[j].uplink[k],&addr,sizeof(faddr_t))) ! 3535: break; ! 3536: if(k==cfg.area[j].uplinks) ! 3537: continue; } ! 3538: if(sub_code[0] && stricmp(sub_code,scfg.sub[i]->code)) ! 3539: continue; ! 3540: lprintf(LOG_DEBUG,"\nScanning %-15.15s %s" ! 3541: ,scfg.grp[scfg.sub[i]->grp]->sname,scfg.sub[i]->lname); ! 3542: ptr=0; ! 3543: if(!addr.zone && !(misc&IGNORE_MSGPTRS)) { ! 3544: sprintf(str,"%s%s.sfp",scfg.sub[i]->data_dir,scfg.sub[i]->code); ! 3545: if((file=nopen(str,O_RDONLY))!=-1) { ! 3546: read(file,&ptr,sizeof(time_t)); ! 3547: close(file); } } ! 3548: ! 3549: msgs=getlastmsg(i,&lastmsg,0); ! 3550: if(!msgs || (!addr.zone && !(misc&IGNORE_MSGPTRS) && ptr>=lastmsg)) { ! 3551: lprintf(LOG_INFO,"No new messages."); ! 3552: if(ptr>lastmsg && !addr.zone && !(misc&LEAVE_MSGPTRS)) { ! 3553: lprintf(LOG_DEBUG,"Fixing new-scan pointer."); ! 3554: sprintf(str,"%s%s.sfp",scfg.sub[i]->data_dir,scfg.sub[i]->code); ! 3555: if((file=nopen(str,O_WRONLY|O_CREAT))==-1) { ! 3556: lprintf(LOG_ERR,"ERROR %d line %d opening/creating %s" ! 3557: ,errno,__LINE__,str); } ! 3558: else { ! 3559: write(file,&lastmsg,4); ! 3560: close(file); } } ! 3561: continue; } ! 3562: ! 3563: sprintf(smb[cur_smb].file,"%s%s" ! 3564: ,scfg.sub[i]->data_dir,scfg.sub[i]->code); ! 3565: smb[cur_smb].retry_time=scfg.smb_retry_time; ! 3566: if((j=smb_open(&smb[cur_smb]))!=SMB_SUCCESS) { ! 3567: lprintf(LOG_ERR,"ERROR %d line %d opening %s",j,__LINE__ ! 3568: ,smb[cur_smb].file); ! 3569: continue; } ! 3570: ! 3571: post=NULL; ! 3572: posts=loadmsgs(&post,ptr); ! 3573: ! 3574: if(!posts) { /* no new messages */ ! 3575: smb_close(&smb[cur_smb]); ! 3576: FREE_AND_NULL(post); ! 3577: continue; ! 3578: } ! 3579: ! 3580: if(start_tick) ! 3581: export_ticks+=msclock()-start_tick; ! 3582: start_tick=msclock(); ! 3583: ! 3584: for(m=exp=0;m<posts;m++) { ! 3585: printf("\r%8s %5lu of %-5lu " ! 3586: ,scfg.sub[i]->code,m+1,posts); ! 3587: memset(&msg,0,sizeof(msg)); ! 3588: msg.idx=post[m]; ! 3589: if((k=smb_lockmsghdr(&smb[cur_smb],&msg))!=SMB_SUCCESS) { ! 3590: lprintf(LOG_ERR,"ERROR %d line %d locking %s msghdr" ! 3591: ,k,__LINE__,smb[cur_smb].file); ! 3592: continue; ! 3593: } ! 3594: k=smb_getmsghdr(&smb[cur_smb],&msg); ! 3595: if(k || msg.hdr.number!=post[m].number) { ! 3596: smb_unlockmsghdr(&smb[cur_smb],&msg); ! 3597: smb_freemsgmem(&msg); ! 3598: ! 3599: msg.hdr.number=post[m].number; ! 3600: if((k=smb_getmsgidx(&smb[cur_smb],&msg))!=SMB_SUCCESS) { ! 3601: lprintf(LOG_ERR,"ERROR %d line %d reading %s index",k,__LINE__ ! 3602: ,smb[cur_smb].file); ! 3603: continue; } ! 3604: if((k=smb_lockmsghdr(&smb[cur_smb],&msg))!=SMB_SUCCESS) { ! 3605: lprintf(LOG_ERR,"ERROR %d line %d locking %s msghdr",k,__LINE__ ! 3606: ,smb[cur_smb].file); ! 3607: continue; } ! 3608: if((k=smb_getmsghdr(&smb[cur_smb],&msg))!=SMB_SUCCESS) { ! 3609: smb_unlockmsghdr(&smb[cur_smb],&msg); ! 3610: lprintf(LOG_ERR,"ERROR %d line %d reading %s msghdr",k,__LINE__ ! 3611: ,smb[cur_smb].file); ! 3612: continue; } } ! 3613: ! 3614: if((!addr.zone && !(misc&EXPORT_ALL) ! 3615: && (msg.from_net.type==NET_FIDO || msg.from_net.type==NET_FIDO_ASCII)) ! 3616: || !strnicmp(msg.subj,"NE:",3)) { /* no echo */ ! 3617: smb_unlockmsghdr(&smb[cur_smb],&msg); ! 3618: smb_freemsgmem(&msg); ! 3619: continue; } /* From a Fido node, ignore it */ ! 3620: ! 3621: if(msg.from_net.type!=NET_NONE ! 3622: && msg.from_net.type!=NET_FIDO ! 3623: && msg.from_net.type!=NET_FIDO_ASCII ! 3624: && !(scfg.sub[i]->misc&SUB_GATE)) { ! 3625: smb_unlockmsghdr(&smb[cur_smb],&msg); ! 3626: smb_freemsgmem(&msg); ! 3627: continue; } ! 3628: ! 3629: memset(&hdr,0,sizeof(fmsghdr_t)); /* Zero the header */ ! 3630: hdr.origzone=scfg.sub[i]->faddr.zone; ! 3631: hdr.orignet=scfg.sub[i]->faddr.net; ! 3632: hdr.orignode=scfg.sub[i]->faddr.node; ! 3633: hdr.origpoint=scfg.sub[i]->faddr.point; ! 3634: ! 3635: hdr.attr=FIDO_LOCAL; ! 3636: if(msg.hdr.attr&MSG_PRIVATE) ! 3637: hdr.attr|=FIDO_PRIVATE; ! 3638: ! 3639: SAFECOPY(hdr.from,msg.from); ! 3640: ! 3641: tm=localtime((time_t *)&msg.hdr.when_written.time); ! 3642: sprintf(hdr.time,"%02u %3.3s %02u %02u:%02u:%02u" ! 3643: ,tm->tm_mday,mon[tm->tm_mon],TM_YEAR(tm->tm_year) ! 3644: ,tm->tm_hour,tm->tm_min,tm->tm_sec); ! 3645: ! 3646: SAFECOPY(hdr.to,msg.to); ! 3647: ! 3648: SAFECOPY(hdr.subj,msg.subj); ! 3649: ! 3650: buf=smb_getmsgtxt(&smb[cur_smb],&msg,GETMSGTXT_ALL); ! 3651: if(!buf) { ! 3652: smb_unlockmsghdr(&smb[cur_smb],&msg); ! 3653: smb_freemsgmem(&msg); ! 3654: continue; ! 3655: } ! 3656: fmsgbuflen=strlen((char *)buf)+4096; /* over alloc for kludge lines */ ! 3657: fmsgbuf=malloc(fmsgbuflen); ! 3658: if(!fmsgbuf) { ! 3659: lprintf(LOG_ERR,"ERROR line %d allocating %lu bytes for fmsgbuf" ! 3660: ,__LINE__,fmsgbuflen); ! 3661: smb_unlockmsghdr(&smb[cur_smb],&msg); ! 3662: smb_freemsgmem(&msg); ! 3663: continue; ! 3664: } ! 3665: fmsgbuflen-=1024; /* give us a bit of a guard band here */ ! 3666: ! 3667: tear=0; ! 3668: f=0; ! 3669: ! 3670: tzone=smb_tzutc(msg.hdr.when_written.zone); ! 3671: if(tzone<0) { ! 3672: minus="-"; ! 3673: tzone=-tzone; ! 3674: } else ! 3675: minus=""; ! 3676: f+=sprintf(fmsgbuf+f,"\1TZUTC: %s%02d%02u\r" /* TZUTC (FSP-1001) */ ! 3677: ,minus,tzone/60,tzone%60); ! 3678: ! 3679: if(msg.ftn_flags!=NULL) ! 3680: f+=sprintf(fmsgbuf+f,"\1FLAGS %.256s\r", msg.ftn_flags); ! 3681: ! 3682: f+=sprintf(fmsgbuf+f,"\1MSGID: %.256s\r" ! 3683: ,ftn_msgid(scfg.sub[i],&msg)); ! 3684: ! 3685: if(msg.ftn_reply!=NULL) /* use original REPLYID */ ! 3686: f+=sprintf(fmsgbuf+f,"\1REPLY: %.256s\r", msg.ftn_reply); ! 3687: else if(msg.hdr.thread_back) { /* generate REPLYID */ ! 3688: memset(&orig_msg,0,sizeof(orig_msg)); ! 3689: orig_msg.hdr.number=msg.hdr.thread_back; ! 3690: if(smb_getmsgidx(&smb[cur_smb], &orig_msg)) ! 3691: f+=sprintf(fmsgbuf+f,"\1REPLY: <%s>\r",smb[cur_smb].last_error); ! 3692: else { ! 3693: smb_lockmsghdr(&smb[cur_smb],&orig_msg); ! 3694: smb_getmsghdr(&smb[cur_smb],&orig_msg); ! 3695: smb_unlockmsghdr(&smb[cur_smb],&orig_msg); ! 3696: f+=sprintf(fmsgbuf+f,"\1REPLY: %.256s\r" ! 3697: ,ftn_msgid(scfg.sub[i],&orig_msg)); ! 3698: } ! 3699: } ! 3700: if(msg.ftn_pid!=NULL) /* use original PID */ ! 3701: f+=sprintf(fmsgbuf+f,"\1PID: %.256s\r", msg.ftn_pid); ! 3702: if(msg.ftn_tid!=NULL) /* use original TID */ ! 3703: f+=sprintf(fmsgbuf+f,"\1TID: %.256s\r", msg.ftn_tid); ! 3704: else /* generate TID */ ! 3705: f+=sprintf(fmsgbuf+f,"\1TID: SBBSecho %s-%s r%s %s %s\r" ! 3706: ,SBBSECHO_VER,PLATFORM_DESC,revision,__DATE__,compiler); ! 3707: ! 3708: /* Unknown kludge lines are added here */ ! 3709: for(l=0;l<msg.total_hfields && f<fmsgbuflen;l++) ! 3710: if(msg.hfield[l].type == FIDOCTRL) ! 3711: f+=sprintf(fmsgbuf+f,"\1%.512s\r",(char*)msg.hfield_dat[l]); ! 3712: ! 3713: for(l=0,cr=1;buf[l] && f<fmsgbuflen;l++) { ! 3714: if(buf[l]==1) { /* Ctrl-A, so skip it and the next char */ ! 3715: l++; ! 3716: if(!buf[l]) ! 3717: break; ! 3718: continue; } ! 3719: ! 3720: if(misc&STRIP_LF && buf[l]=='\n') /* Ignore line feeds */ ! 3721: continue; ! 3722: ! 3723: if(cr) { ! 3724: if(buf[l]=='-' && buf[l+1]=='-' ! 3725: && buf[l+2]=='-' ! 3726: && (buf[l+3]==' ' || buf[l+3]=='\r')) { ! 3727: if(misc&CONVERT_TEAR) /* Convert to === */ ! 3728: buf[l]=buf[l+1]=buf[l+2]='='; ! 3729: else ! 3730: tear=1; } ! 3731: else if(!strncmp((char *)buf+l," * Origin: ",11)) ! 3732: buf[l+1]='#'; } /* Convert * Origin into # Origin */ ! 3733: ! 3734: if(buf[l]=='\r') ! 3735: cr=1; ! 3736: else ! 3737: cr=0; ! 3738: if(scfg.sub[i]->misc&SUB_ASCII || misc&ASCII_ONLY) { ! 3739: if(buf[l]<' ' && buf[l]!='\r' ! 3740: && buf[l]!='\n') /* Ctrl ascii */ ! 3741: buf[l]='.'; /* converted to '.' */ ! 3742: if((uchar)buf[l]>0x7f) /* extended ASCII */ ! 3743: buf[l]='*'; } /* converted to '*' */ ! 3744: ! 3745: fmsgbuf[f++]=buf[l]; } ! 3746: ! 3747: FREE_AND_NULL(buf); ! 3748: fmsgbuf[f]=0; ! 3749: ! 3750: if(!(scfg.sub[i]->misc&SUB_NOTAG)) { ! 3751: if(!tear) { /* No previous tear line */ ! 3752: sprintf(str,"--- SBBSecho %s-%s\r" ! 3753: ,SBBSECHO_VER,PLATFORM_DESC); ! 3754: strcat((char *)fmsgbuf,str); } ! 3755: ! 3756: sprintf(str," * Origin: %s (%s)\r" ! 3757: ,scfg.sub[i]->origline[0] ? scfg.sub[i]->origline : scfg.origline ! 3758: ,smb_faddrtoa(&scfg.sub[i]->faddr,NULL)); ! 3759: strcat((char *)fmsgbuf,str); } ! 3760: ! 3761: for(k=0;k<cfg.areas;k++) ! 3762: if(cfg.area[k].sub==i) { ! 3763: cfg.area[k].exported++; ! 3764: pkt_to_pkt(fmsgbuf,cfg.area[k] ! 3765: ,(addr.zone) ? addr:pkt_faddr,hdr,msg_seen ! 3766: ,msg_path,(addr.zone) ? 2:0); ! 3767: break; } ! 3768: FREE_AND_NULL(fmsgbuf); ! 3769: exported++; ! 3770: exp++; ! 3771: printf("Exp: %lu ",exp); ! 3772: smb_unlockmsghdr(&smb[cur_smb],&msg); ! 3773: smb_freemsgmem(&msg); } ! 3774: ! 3775: smb_close(&smb[cur_smb]); ! 3776: FREE_AND_NULL(post); ! 3777: ! 3778: /***********************/ ! 3779: /* Update FIDO_PTR.DAB */ ! 3780: /***********************/ ! 3781: if(!addr.zone && !(misc&LEAVE_MSGPTRS) && lastmsg>ptr) { ! 3782: sprintf(str,"%s%s.sfp",scfg.sub[i]->data_dir,scfg.sub[i]->code); ! 3783: if((file=nopen(str,O_WRONLY|O_CREAT))==-1) { ! 3784: lprintf(LOG_ERR,"ERROR %d line %d opening/creating %s" ! 3785: ,errno,__LINE__,str); } ! 3786: else { ! 3787: write(file,&lastmsg,4); ! 3788: close(file); } } } ! 3789: ! 3790: printf("\n"); ! 3791: if(start_tick) /* Last possible increment of export_ticks */ ! 3792: export_ticks+=msclock()-start_tick; ! 3793: ! 3794: pkt_to_pkt(buf,fakearea,pkt_faddr,hdr,msg_seen,msg_path,1); ! 3795: ! 3796: if(!addr.zone && cfg.log&LOG_AREA_TOTALS && exported) ! 3797: for(i=0;i<cfg.areas;i++) ! 3798: if(cfg.area[i].exported) ! 3799: lprintf(LOG_INFO,"Exported: %5u msgs %8s -> %s" ! 3800: ,cfg.area[i].exported,scfg.sub[cfg.area[i].sub]->code ! 3801: ,cfg.area[i].name); ! 3802: ! 3803: export_time=((float)export_ticks)/(float)MSCLOCKS_PER_SEC; ! 3804: if(cfg.log&LOG_TOTALS && exported && export_time) { ! 3805: lprintf(LOG_INFO,"Exported: %5lu msgs in %.1f sec (%.1f/min %.1f/sec)" ! 3806: ,exported,export_time ! 3807: ,export_time/60.0 ? (float)exported/(export_time/60.0) :(float)exported ! 3808: ,(float)exported/export_time); ! 3809: } ! 3810: } ! 3811: ! 3812: char* freadstr(FILE* fp, char* str, size_t maxlen) ! 3813: { ! 3814: int ch; ! 3815: size_t rd=0; ! 3816: size_t len=0; ! 3817: ! 3818: memset(str,0,maxlen); /* pre-terminate */ ! 3819: ! 3820: while(rd<maxlen && (ch=fgetc(fp))!=EOF) { ! 3821: if(ch==0) ! 3822: break; ! 3823: if((uchar)ch>=' ') /* not a ctrl char (garbage?) */ ! 3824: str[len++]=ch; ! 3825: rd++; ! 3826: } ! 3827: ! 3828: str[maxlen-1]=0; /* Force terminator */ ! 3829: ! 3830: return(str); ! 3831: } ! 3832: ! 3833: /***********************************/ ! 3834: /* Synchronet/FidoNet Message util */ ! 3835: /***********************************/ ! 3836: int main(int argc, char **argv) ! 3837: { ! 3838: FILE* fidomsg; ! 3839: char packet[MAX_PATH+1]; ! 3840: char ch,str[1025],fname[MAX_PATH+1],path[MAX_PATH+1] ! 3841: ,sub_code[LEN_EXTCODE+1] ! 3842: ,*p,*tp ! 3843: ,areatagstr[128],outbound[128] ! 3844: ,password[16]; ! 3845: uchar *fmsgbuf=NULL; ! 3846: ushort attr; ! 3847: int i,j,k,file,fmsg,grp,node; ! 3848: BOOL grunged; ! 3849: uint subnum[MAX_OPEN_SMBS]={INVALID_SUB}; ! 3850: ulong echomail=0,l,m/* f, */,areatag; ! 3851: time_t now; ! 3852: time_t ftime; ! 3853: float import_time; ! 3854: clock_t start_tick=0,import_ticks=0; ! 3855: struct tm *tm; ! 3856: size_t f; ! 3857: glob_t g; ! 3858: size_t offset; ! 3859: fmsghdr_t hdr; ! 3860: fpkdmsg_t pkdmsg; ! 3861: faddr_t addr,pkt_faddr; ! 3862: FILE *stream; ! 3863: pkthdr_t pkthdr; ! 3864: addrlist_t msg_seen,msg_path; ! 3865: areasbbs_t fakearea,curarea; ! 3866: char *usage="\n" ! 3867: "usage: sbbsecho [cfg_file] [-switches] [sub_code]\n" ! 3868: "\n" ! 3869: "where: cfg_file is the filename of config file (default is ctrl/sbbsecho.cfg)\n" ! 3870: " sub_code is the internal code for a sub-board (default is ALL subs)\n" ! 3871: "\n" ! 3872: "valid switches:\n" ! 3873: "\n" ! 3874: "p: do not import packets x: do not delete packets after import\n" ! 3875: "n: do not import netmail d: do not delete netmail after import\n" ! 3876: "i: do not import echomail e: do not export echomail\n" ! 3877: "m: ignore echomail ptrs (export all) u: update echomail ptrs (export none)\n" ! 3878: "j: ignore recieved bit on netmail t: do not update echomail ptrs\n" ! 3879: "l: create log file (data/sbbsecho.log) r: create report of import totals\n" ! 3880: "h: export all echomail (hub rescan) b: import locally created netmail too\n" ! 3881: "a: export ASCII characters only f: create packets for outbound netmail\n" ! 3882: "g: generate notify lists =: change existing tear lines to ===\n" ! 3883: "y: import netmail for unknown users to sysop\n" ! 3884: "o: import all netmail regardless of destination address\n" ! 3885: "s: import private echomail override (strip private status)\n" ! 3886: "!: notify users of received echomail @: prompt for key upon exiting (debug)\n"; ! 3887: ! 3888: if((email=(smb_t *)malloc(sizeof(smb_t)))==NULL) { ! 3889: printf("ERROR allocating memory for email.\n"); ! 3890: bail(1); } ! 3891: memset(email,0,sizeof(smb_t)); ! 3892: if((smb=(smb_t *)malloc(MAX_OPEN_SMBS*sizeof(smb_t)))==NULL) { ! 3893: printf("ERROR allocating memory for smbs.\n"); ! 3894: bail(1); } ! 3895: for(i=0;i<MAX_OPEN_SMBS;i++) ! 3896: memset(&smb[i],0,sizeof(smb_t)); ! 3897: memset(&cfg,0,sizeof(config_t)); ! 3898: memset(&hdr,0,sizeof(hdr)); ! 3899: memset(&pkt_faddr,0,sizeof(pkt_faddr)); ! 3900: memset(&msg_seen,0,sizeof(addrlist_t)); ! 3901: memset(&msg_path,0,sizeof(addrlist_t)); ! 3902: memset(&fakearea,0,sizeof(areasbbs_t)); ! 3903: ! 3904: sscanf("$Revision: 1.182 $", "%*s %s", revision); ! 3905: ! 3906: DESCRIBE_COMPILER(compiler); ! 3907: ! 3908: printf("\nSBBSecho v%s-%s (rev %s) - Synchronet FidoNet Packet " ! 3909: "Tosser\n" ! 3910: ,SBBSECHO_VER ! 3911: ,PLATFORM_DESC ! 3912: ,revision ! 3913: ); ! 3914: ! 3915: putenv("TMP="); ! 3916: setvbuf(stdout,NULL,_IONBF,0); ! 3917: ! 3918: sub_code[0]=0; ! 3919: ! 3920: for(i=1;i<argc;i++) { ! 3921: if(argv[i][0]=='-' ! 3922: #if !defined(__unix__) ! 3923: || argv[i][0]=='/' ! 3924: #endif ! 3925: ) { ! 3926: j=1; ! 3927: while(argv[i][j]) { ! 3928: switch(toupper(argv[i][j])) { ! 3929: case 'A': ! 3930: misc|=ASCII_ONLY; ! 3931: break; ! 3932: case 'B': ! 3933: misc|=LOCAL_NETMAIL; ! 3934: break; ! 3935: case 'D': ! 3936: misc&=~DELETE_NETMAIL; ! 3937: break; ! 3938: case 'E': ! 3939: misc&=~EXPORT_ECHOMAIL; ! 3940: break; ! 3941: case 'F': ! 3942: misc|=PACK_NETMAIL; ! 3943: break; ! 3944: case 'G': ! 3945: misc|=GEN_NOTIFY_LIST; ! 3946: break; ! 3947: case 'H': ! 3948: misc|=EXPORT_ALL; ! 3949: break; ! 3950: case 'I': ! 3951: misc&=~IMPORT_ECHOMAIL; ! 3952: break; ! 3953: case 'J': ! 3954: misc|=IGNORE_RECV; ! 3955: break; ! 3956: case 'L': ! 3957: misc|=LOGFILE; ! 3958: break; ! 3959: case 'M': ! 3960: misc|=IGNORE_MSGPTRS; ! 3961: break; ! 3962: case 'N': ! 3963: misc&=~IMPORT_NETMAIL; ! 3964: break; ! 3965: case 'O': ! 3966: misc|=IGNORE_ADDRESS; ! 3967: break; ! 3968: case 'P': ! 3969: misc&=~IMPORT_PACKETS; ! 3970: break; ! 3971: case 'R': ! 3972: misc|=REPORT; ! 3973: break; ! 3974: case 'S': ! 3975: misc|=IMPORT_PRIVATE; ! 3976: break; ! 3977: case 'T': ! 3978: misc|=LEAVE_MSGPTRS; ! 3979: break; ! 3980: case 'U': ! 3981: misc|=UPDATE_MSGPTRS; ! 3982: misc&=~EXPORT_ECHOMAIL; ! 3983: break; ! 3984: case 'X': ! 3985: misc&=~DELETE_PACKETS; ! 3986: break; ! 3987: case 'Y': ! 3988: misc|=UNKNOWN_NETMAIL; ! 3989: break; ! 3990: case '=': ! 3991: misc|=CONVERT_TEAR; ! 3992: break; ! 3993: case '!': ! 3994: misc|=NOTIFY_RECEIPT; ! 3995: break; ! 3996: case '@': ! 3997: pause_on_exit=TRUE; ! 3998: break; ! 3999: case 'Q': ! 4000: bail(0); ! 4001: default: ! 4002: printf(usage); ! 4003: bail(0); } ! 4004: j++; } } ! 4005: else { ! 4006: if(strchr(argv[i],'\\') || strchr(argv[i],'/') ! 4007: || argv[i][1]==':' || strchr(argv[i],'.')) ! 4008: SAFECOPY(cfg.cfgfile,argv[i]); ! 4009: else ! 4010: SAFECOPY(sub_code,argv[i]); } } ! 4011: ! 4012: if(!(misc&(IMPORT_NETMAIL|IMPORT_ECHOMAIL))) ! 4013: misc&=~IMPORT_PACKETS; ! 4014: ! 4015: p=getenv("SBBSCTRL"); ! 4016: if(p==NULL) { ! 4017: printf("\7\nSBBSCTRL environment variable not set.\n"); ! 4018: bail(1); } ! 4019: SAFECOPY(scfg.ctrl_dir,p); ! 4020: ! 4021: if(chdir(scfg.ctrl_dir)!=0) ! 4022: printf("!ERROR changing directory to: %s", scfg.ctrl_dir); ! 4023: ! 4024: printf("\nLoading configuration files from %s\n", scfg.ctrl_dir); ! 4025: scfg.size=sizeof(scfg); ! 4026: SAFECOPY(str,UNKNOWN_LOAD_ERROR); ! 4027: if(!load_cfg(&scfg, NULL, TRUE, str)) { ! 4028: fprintf(stderr,"!ERROR %s\n",str); ! 4029: fprintf(stderr,"!Failed to load configuration files\n"); ! 4030: bail(1); ! 4031: } ! 4032: ! 4033: sprintf(str,"%stwitlist.cfg",scfg.ctrl_dir); ! 4034: twit_list=fexist(str); ! 4035: ! 4036: if(scfg.total_faddrs) ! 4037: sys_faddr=scfg.faddr[0]; ! 4038: ! 4039: if(!cfg.cfgfile[0]) ! 4040: sprintf(cfg.cfgfile,"%ssbbsecho.cfg",scfg.ctrl_dir); ! 4041: strcpy(cfg.inbound,scfg.fidofile_dir); ! 4042: sprintf(cfg.areafile,"%sareas.bbs",scfg.data_dir); ! 4043: sprintf(cfg.logfile,"%ssbbsecho.log",scfg.logs_dir); ! 4044: ! 4045: read_echo_cfg(); ! 4046: ! 4047: if(misc&LOGFILE) ! 4048: if((fidologfile=fopen(cfg.logfile,"a"))==NULL) { ! 4049: fprintf(stderr,"\7ERROR line %d opening %s\n",__LINE__,cfg.logfile); ! 4050: bail(1); ! 4051: } ! 4052: ! 4053: /******* READ IN AREAS.BBS FILE *********/ ! 4054: ! 4055: printf("Reading %s",cfg.areafile); ! 4056: if((stream=fopen(cfg.areafile,"r"))==NULL) { ! 4057: fprintf(stderr,"\nError opening %s for read: %s\n" ! 4058: ,cfg.areafile,strerror(errno)); ! 4059: bail(1); } ! 4060: cfg.areas=0; /* Total number of areas in AREAS.BBS */ ! 4061: cfg.area=NULL; ! 4062: while(1) { ! 4063: if(!fgets(str,sizeof(str),stream)) ! 4064: break; ! 4065: truncsp(str); ! 4066: p=str; ! 4067: SKIP_WHITESPACE(p); /* Find first printable char */ ! 4068: if(*p==';' || !*p) /* Ignore blank lines or start with ; */ ! 4069: continue; ! 4070: if((cfg.area=(areasbbs_t *)realloc(cfg.area,sizeof(areasbbs_t)* ! 4071: (cfg.areas+1)))==NULL) { ! 4072: fprintf(stderr,"ERROR allocating memory for area #%u.\n",cfg.areas+1); ! 4073: bail(1); } ! 4074: memset(&cfg.area[cfg.areas],0,sizeof(areasbbs_t)); ! 4075: ! 4076: cfg.area[cfg.areas].sub=INVALID_SUB; /* Default to passthru */ ! 4077: ! 4078: sprintf(tmp,"%-.*s",LEN_EXTCODE,p); ! 4079: tp=tmp; ! 4080: FIND_WHITESPACE(tp); ! 4081: *tp=0; ! 4082: for(i=0;i<scfg.total_subs;i++) ! 4083: if(!stricmp(tmp,scfg.sub[i]->code)) ! 4084: break; ! 4085: if(i<scfg.total_subs) ! 4086: cfg.area[cfg.areas].sub=i; ! 4087: else if(stricmp(tmp,"P")) { ! 4088: lprintf(LOG_WARNING,"%s: Unrecognized internal code, assumed passthru",tmp); ! 4089: } ! 4090: ! 4091: FIND_WHITESPACE(p); /* Skip code */ ! 4092: SKIP_WHITESPACE(p); /* Skip white space */ ! 4093: sprintf(tmp,"%-.50s",p); /* Area tag */ ! 4094: truncstr(tmp,"\t "); ! 4095: strupr(tmp); ! 4096: if(tmp[0]=='*') /* UNKNOWN-ECHO area */ ! 4097: cfg.badecho=cfg.areas; ! 4098: if((cfg.area[cfg.areas].name=(char *)malloc(strlen(tmp)+1))==NULL) { ! 4099: fprintf(stderr,"ERROR allocating memory for area #%u tag name.\n" ! 4100: ,cfg.areas+1); ! 4101: bail(1); } ! 4102: strcpy(cfg.area[cfg.areas].name,tmp); ! 4103: strupr(tmp); ! 4104: cfg.area[cfg.areas].tag=crc32(tmp,0); ! 4105: ! 4106: FIND_WHITESPACE(p); /* Skip tag */ ! 4107: SKIP_WHITESPACE(p); /* Skip white space */ ! 4108: ! 4109: while(*p && *p!=';') { ! 4110: if((cfg.area[cfg.areas].uplink=(faddr_t *) ! 4111: realloc(cfg.area[cfg.areas].uplink ! 4112: ,sizeof(faddr_t)*(cfg.area[cfg.areas].uplinks+1)))==NULL) { ! 4113: fprintf(stderr,"ERROR allocating memory for area #%u uplinks.\n" ! 4114: ,cfg.areas+1); ! 4115: bail(1); } ! 4116: cfg.area[cfg.areas].uplink[cfg.area[cfg.areas].uplinks]=atofaddr(p); ! 4117: FIND_WHITESPACE(p); /* Skip address */ ! 4118: SKIP_WHITESPACE(p); /* Skip white space */ ! 4119: cfg.area[cfg.areas].uplinks++; } ! 4120: ! 4121: if(cfg.area[cfg.areas].sub!=INVALID_SUB || cfg.area[cfg.areas].uplinks) ! 4122: cfg.areas++; /* Don't allocate if no tossing */ ! 4123: } ! 4124: fclose(stream); ! 4125: ! 4126: printf("\n"); ! 4127: ! 4128: if(!cfg.areas) { ! 4129: lprintf(LOG_WARNING,"No areas defined!"); ! 4130: bail(1); ! 4131: } ! 4132: ! 4133: #if 0 /* AREAS.BBS DEBUG */ ! 4134: for(i=0;i<cfg.areas;i++) { ! 4135: printf("%4u: %-8s" ! 4136: ,i+1 ! 4137: ,cfg.area[i].sub==INVALID_SUB ? "Passthru" : ! 4138: scfg.sub[cfg.area[i].sub]->code); ! 4139: for(j=0;j<cfg.area[i].uplinks;j++) ! 4140: printf(" %s",smb_faddrtoa(&cfg.area[i].uplink[j],NULL)); ! 4141: printf("\n"); } ! 4142: #endif ! 4143: ! 4144: if(misc&GEN_NOTIFY_LIST) { ! 4145: lprintf(LOG_DEBUG,"\nGenerating Notify Lists..."); ! 4146: notify_list(); ! 4147: } ! 4148: ! 4149: /* Find any packets that have been left behind in the OUTBOUND directory */ ! 4150: now=time(NULL); ! 4151: lprintf(LOG_DEBUG,"\nScanning for Stray Outbound Packets..."); ! 4152: sprintf(path,"%s*.pk_",cfg.outbound); ! 4153: glob(path,0,NULL,&g); ! 4154: for(f=0;f<g.gl_pathc && !kbhit();f++) { ! 4155: ! 4156: strcpy(packet,(char*)g.gl_pathv[f]); ! 4157: ! 4158: lprintf(LOG_DEBUG,"%21s: %s ","Outbound Packet",packet); ! 4159: if((fmsg=sopen(packet,O_RDWR|O_BINARY,SH_DENYRW))==-1) { ! 4160: lprintf(LOG_ERR,"ERROR line %d opening %s",__LINE__,packet); ! 4161: continue; } ! 4162: if((fidomsg=fdopen(fmsg,"r+b"))==NULL) { ! 4163: close(fmsg); ! 4164: lprintf(LOG_ERR,"ERROR line %d fdopening %s",__LINE__,packet); ! 4165: continue; } ! 4166: if(filelength(fmsg)<sizeof(pkthdr_t)) { ! 4167: lprintf(LOG_ERR,"ERROR line %d invalid length of %lu bytes for %s" ! 4168: ,__LINE__,filelength(fmsg),packet); ! 4169: fclose(fidomsg); ! 4170: if(delfile(packet)) ! 4171: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,packet ! 4172: ,strerror(errno)); ! 4173: continue; } ! 4174: if(fread(&pkthdr,sizeof(pkthdr_t),1,fidomsg)!=1) { ! 4175: fclose(fidomsg); ! 4176: lprintf(LOG_ERR,"ERROR line %d reading %u bytes from %s",__LINE__ ! 4177: ,sizeof(pkthdr_t),packet); ! 4178: continue; } ! 4179: ftime=fdate(packet); ! 4180: if((ftime+(60L*60L))<=now) { ! 4181: fseek(fidomsg,-3L,SEEK_END); ! 4182: fread(str,3,1,fidomsg); ! 4183: if(str[2]) /* No ending NULL, probably junk */ ! 4184: fputc(FIDO_PACKED_MSG_TERMINATOR,fidomsg); ! 4185: if(str[1]) ! 4186: fputc(FIDO_PACKED_MSG_TERMINATOR,fidomsg); ! 4187: if(str[0]) ! 4188: fputc(FIDO_PACKED_MSG_TERMINATOR,fidomsg); ! 4189: fclose(fidomsg); ! 4190: pkt_faddr.zone=pkthdr.destzone; ! 4191: pkt_faddr.net=pkthdr.destnet; ! 4192: pkt_faddr.node=pkthdr.destnode; ! 4193: pkt_faddr.point=0; /* No point info in the 2.0 hdr! */ ! 4194: memcpy(&two_plus,&pkthdr.empty,sizeof(two_plus)); ! 4195: if(two_plus.cword==_rotr(two_plus.cwcopy,8) /* 2+ Packet Header */ ! 4196: && two_plus.cword && two_plus.cword&1) ! 4197: pkt_faddr.point=two_plus.destpoint; ! 4198: else if(pkthdr.baud==2) { /* Type 2.2 Packet Header */ ! 4199: memcpy(&two_two,&pkthdr.empty,sizeof(two_two)); ! 4200: pkt_faddr.point=pkthdr.month; } ! 4201: lprintf(LOG_DEBUG,"Sending to %s",smb_faddrtoa(&pkt_faddr,NULL)); ! 4202: pack_bundle(packet,pkt_faddr); } ! 4203: else { ! 4204: fclose(fidomsg); ! 4205: lprintf(LOG_WARNING,"Stray Outbound Packet (%s) possibly still in use (ftime: %.24s)" ! 4206: ,packet,ctime(&ftime)); ! 4207: } ! 4208: } ! 4209: globfree(&g); ! 4210: ! 4211: if(misc&IMPORT_PACKETS) { ! 4212: ! 4213: lprintf(LOG_DEBUG,"\nScanning for Inbound Packets..."); ! 4214: ! 4215: /* We want to loop while there are bundles waiting for us, but first we want */ ! 4216: /* to take care of any packets that may already be hanging around for some */ ! 4217: /* reason or another (thus the do/while loop) */ ! 4218: ! 4219: echomail=0; ! 4220: for(secure=0;secure<2;secure++) { ! 4221: if(secure && !cfg.secure[0]) ! 4222: break; ! 4223: do { ! 4224: /****** START OF IMPORT PKT ROUTINE ******/ ! 4225: ! 4226: offset=strlen(secure ? cfg.secure : cfg.inbound); ! 4227: #ifdef __unix__ ! 4228: sprintf(path,"%s*.[Pp][Kk][Tt]",secure ? cfg.secure : cfg.inbound); ! 4229: #else ! 4230: sprintf(path,"%s*.pkt",secure ? cfg.secure : cfg.inbound); ! 4231: #endif ! 4232: glob(path,0,NULL,&g); ! 4233: for(f=0;f<g.gl_pathc && !kbhit();f++) { ! 4234: ! 4235: strcpy(packet,g.gl_pathv[f]); ! 4236: ! 4237: if((fidomsg=fnopen(&fmsg,packet,O_RDWR))==NULL) { ! 4238: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,packet ! 4239: ,strerror(errno)); ! 4240: continue; ! 4241: } ! 4242: if(filelength(fmsg)<sizeof(pkthdr_t)) { ! 4243: lprintf(LOG_WARNING,"Invalid length of %s: %lu bytes" ! 4244: ,fmsg,filelength(fmsg)); ! 4245: fclose(fidomsg); ! 4246: continue; ! 4247: } ! 4248: ! 4249: fseek(fidomsg,-2L,SEEK_END); ! 4250: fread(str,2,1,fidomsg); ! 4251: if((str[0] || str[1]) && ! 4252: (fdate(packet)+(48L*60L*60L))<=time(NULL)) { ! 4253: fclose(fidomsg); ! 4254: lprintf(LOG_WARNING,"WARNING line %d packet %s not terminated correctly",__LINE__ ! 4255: ,packet); ! 4256: continue; ! 4257: } ! 4258: fseek(fidomsg,0L,SEEK_SET); ! 4259: if(fread(&pkthdr,sizeof(pkthdr_t),1,fidomsg)!=1) { ! 4260: fclose(fidomsg); ! 4261: lprintf(LOG_ERR,"ERROR line %d reading %u bytes from %s",__LINE__ ! 4262: ,sizeof(pkthdr_t),packet); ! 4263: continue; ! 4264: } ! 4265: ! 4266: pkt_faddr.zone=pkthdr.origzone ? pkthdr.origzone:sys_faddr.zone; ! 4267: pkt_faddr.net=pkthdr.orignet; ! 4268: pkt_faddr.node=pkthdr.orignode; ! 4269: pkt_faddr.point=0; ! 4270: ! 4271: printf("%21s: %s " ! 4272: ,secure ? "Importing Secure Pkt" : "Importing Packet",packet+offset); ! 4273: memcpy(&two_plus,&pkthdr.empty,sizeof(two_plus)); ! 4274: if(two_plus.cword==_rotr(two_plus.cwcopy,8) /* 2+ Packet Header */ ! 4275: && two_plus.cword && two_plus.cword&1) { ! 4276: pkt_type=PKT_TWO_PLUS; ! 4277: pkt_faddr.point=two_plus.origpoint ? two_plus.origpoint:0; ! 4278: if(pkt_faddr.point && pkthdr.orignet==-1) ! 4279: pkt_faddr.net=two_plus.auxnet ? two_plus.auxnet:sys_faddr.zone; ! 4280: printf("(Type 2+)"); ! 4281: if(cfg.log&LOG_PACKETS) ! 4282: logprintf("Importing %s%s (Type 2+) from %s" ! 4283: ,secure ? "(secure) ":"",packet+offset,smb_faddrtoa(&pkt_faddr,NULL)); ! 4284: } ! 4285: else if(pkthdr.baud==2) { /* Type 2.2 Packet Header */ ! 4286: pkt_type=PKT_TWO_TWO; ! 4287: memcpy(&two_two,&pkthdr.empty,sizeof(two_two)); ! 4288: pkt_faddr.point=pkthdr.year ? pkthdr.year:0; ! 4289: printf("(Type 2.2)"); ! 4290: if(cfg.log&LOG_PACKETS) ! 4291: logprintf("Importing %s%s (Type 2.2) from %s" ! 4292: ,secure ? "(secure) ":"",packet+offset,smb_faddrtoa(&pkt_faddr,NULL)); ! 4293: } ! 4294: else { ! 4295: pkt_type=PKT_TWO; ! 4296: printf("(Type 2)"); ! 4297: if(cfg.log&LOG_PACKETS) ! 4298: logprintf("Importing %s%s (Type 2) from %s" ! 4299: ,secure ? "(secure) ":"",packet+offset,smb_faddrtoa(&pkt_faddr,NULL)); ! 4300: } ! 4301: ! 4302: printf(" from %s\n",smb_faddrtoa(&pkt_faddr,NULL)); ! 4303: ! 4304: if(misc&SECURE) { ! 4305: k=matchnode(pkt_faddr,1); ! 4306: sprintf(password,"%.*s",FIDO_PASS_LEN,pkthdr.password); ! 4307: if(k<cfg.nodecfgs && cfg.nodecfg[k].pktpwd[0] && ! 4308: stricmp(password,cfg.nodecfg[k].pktpwd)) { ! 4309: sprintf(str,"Packet %s from %s - " ! 4310: "Incorrect password ('%s' instead of '%s')" ! 4311: ,packet+offset,smb_faddrtoa(&pkt_faddr,NULL) ! 4312: ,password,cfg.nodecfg[k].pktpwd); ! 4313: printf("Security Violation (Incorrect Password)\n"); ! 4314: if(cfg.log&LOG_SECURE) ! 4315: logprintf(str); ! 4316: fclose(fidomsg); ! 4317: continue; ! 4318: } ! 4319: } ! 4320: ! 4321: while(!feof(fidomsg)) { ! 4322: ! 4323: memset(&hdr,0,sizeof(fmsghdr_t)); ! 4324: ! 4325: if(start_tick) ! 4326: import_ticks+=msclock()-start_tick; ! 4327: start_tick=msclock(); ! 4328: ! 4329: if(fmsgbuf) { ! 4330: free(fmsgbuf); ! 4331: fmsgbuf=0; ! 4332: } ! 4333: ! 4334: grunged=FALSE; ! 4335: ! 4336: #if 0 /* Old way */ ! 4337: ! 4338: if(!fread(&ch,1,1,fidomsg)) /* Message type (0200h) */ ! 4339: break; ! 4340: if(ch!=02) ! 4341: continue; ! 4342: if(!fread(&ch,1,1,fidomsg)) ! 4343: break; ! 4344: if(ch!=00) ! 4345: continue; ! 4346: fread(&hdr.orignode,2,1,fidomsg); ! 4347: fread(&hdr.destnode,2,1,fidomsg); ! 4348: fread(&hdr.orignet,2,1,fidomsg); ! 4349: fread(&hdr.destnet,2,1,fidomsg); ! 4350: fread(&hdr.attr,2,1,fidomsg); ! 4351: fread(&hdr.cost,2,1,fidomsg); ! 4352: ! 4353: for(i=0;i<sizeof(hdr.time);i++) /* Read in the Date/Time */ ! 4354: if(!fread(hdr.time+i,1,1,fidomsg) || !hdr.time[i]) ! 4355: break; ! 4356: if(i==sizeof(hdr.time)) grunged=1; ! 4357: ! 4358: for(i=0;!grunged && i<sizeof(hdr.to);i++) /* Read in the 'To' Field */ ! 4359: if(!fread(hdr.to+i,1,1,fidomsg) || !hdr.to[i]) ! 4360: break; ! 4361: if(i==sizeof(hdr.to)) grunged=1; ! 4362: ! 4363: for(i=0;!grunged && i<sizeof(hdr.from);i++) /* Read in 'From' Field */ ! 4364: if(!fread(hdr.from+i,1,1,fidomsg) || !hdr.from[i]) ! 4365: break; ! 4366: if(i==sizeof(hdr.from)) grunged=1; ! 4367: ! 4368: for(i=0;!grunged && i<sizeof(hdr.subj);i++) /* Read in 'Subj' Field */ ! 4369: if(!fread(hdr.subj+i,1,1,fidomsg) || !hdr.subj[i]) ! 4370: break; ! 4371: if(i==sizeof(hdr.subj)) grunged=1; ! 4372: ! 4373: #else /* New way */ ! 4374: ! 4375: /* Read fixed-length header fields */ ! 4376: if(fread(&pkdmsg,sizeof(BYTE),sizeof(pkdmsg),fidomsg)!=sizeof(pkdmsg)) ! 4377: continue; ! 4378: ! 4379: if(pkdmsg.type==2) { /* Recognized type, copy fields */ ! 4380: hdr.orignode = pkdmsg.orignode; ! 4381: hdr.destnode = pkdmsg.destnode; ! 4382: hdr.orignet = pkdmsg.orignet; ! 4383: hdr.destnet = pkdmsg.destnet; ! 4384: hdr.attr = pkdmsg.attr; ! 4385: hdr.cost = pkdmsg.cost; ! 4386: SAFECOPY(hdr.time,pkdmsg.time); ! 4387: } else ! 4388: grunged=TRUE; ! 4389: ! 4390: /* Read variable-length header fields */ ! 4391: if(!grunged) { ! 4392: freadstr(fidomsg,hdr.to,sizeof(hdr.to)); ! 4393: freadstr(fidomsg,hdr.from,sizeof(hdr.from)); ! 4394: freadstr(fidomsg,hdr.subj,sizeof(hdr.subj)); ! 4395: } ! 4396: #endif ! 4397: hdr.attr&=~FIDO_LOCAL; /* Strip local bit, obviously not created locally */ ! 4398: ! 4399: str[0]=0; ! 4400: for(i=0;!grunged && i<sizeof(str);i++) /* Read in the 'AREA' Field */ ! 4401: if(!fread(str+i,1,1,fidomsg) || str[i]=='\r') ! 4402: break; ! 4403: if(i<sizeof(str)) ! 4404: str[i]=0; ! 4405: else ! 4406: grunged=1; ! 4407: ! 4408: if(grunged) { ! 4409: start_tick=0; ! 4410: if(cfg.log&LOG_GRUNGED) ! 4411: logprintf("Grunged message"); ! 4412: seektonull(fidomsg); ! 4413: printf("Grunged message!\n"); ! 4414: continue; ! 4415: } ! 4416: ! 4417: if(i) ! 4418: fseek(fidomsg,(long)-(i+1),SEEK_CUR); ! 4419: ! 4420: truncsp(str); ! 4421: p=strstr(str,"AREA:"); ! 4422: if(p!=str) { /* Netmail */ ! 4423: start_tick=0; ! 4424: if(import_netmail("",hdr,fidomsg)) ! 4425: seektonull(fidomsg); ! 4426: printf("\n"); ! 4427: continue; ! 4428: } ! 4429: ! 4430: if(!(misc&IMPORT_ECHOMAIL)) { ! 4431: start_tick=0; ! 4432: printf("EchoMail Ignored"); ! 4433: seektonull(fidomsg); ! 4434: printf("\n"); ! 4435: continue; ! 4436: } ! 4437: ! 4438: p+=5; /* Skip "AREA:" */ ! 4439: SKIP_WHITESPACE(p); /* Skip any white space */ ! 4440: printf("%21s: ",p); /* Show areaname: */ ! 4441: SAFECOPY(areatagstr,p); ! 4442: strupr(p); ! 4443: areatag=crc32(p,0); ! 4444: ! 4445: for(i=0;i<cfg.areas;i++) /* Do we carry this area? */ ! 4446: if(cfg.area[i].tag==areatag) { ! 4447: if(cfg.area[i].sub!=INVALID_SUB) ! 4448: printf("%s ",scfg.sub[cfg.area[i].sub]->code); ! 4449: else ! 4450: printf("(Passthru) "); ! 4451: fmsgbuf=getfmsg(fidomsg,NULL); ! 4452: gen_psb(&msg_seen,&msg_path,fmsgbuf,pkthdr.destzone); ! 4453: break; ! 4454: } ! 4455: ! 4456: if(i==cfg.areas) { ! 4457: printf("(Unknown) "); ! 4458: if(cfg.badecho>=0) { ! 4459: i=cfg.badecho; ! 4460: if(cfg.area[i].sub!=INVALID_SUB) ! 4461: printf("%s ",scfg.sub[cfg.area[i].sub]->code); ! 4462: else ! 4463: printf("(Passthru) "); ! 4464: fmsgbuf=getfmsg(fidomsg,NULL); ! 4465: gen_psb(&msg_seen,&msg_path,fmsgbuf,pkthdr.destzone); ! 4466: } ! 4467: else { ! 4468: start_tick=0; ! 4469: printf("Skipped\n"); ! 4470: seektonull(fidomsg); ! 4471: continue; ! 4472: } ! 4473: } ! 4474: ! 4475: if(misc&SECURE && cfg.area[i].sub!=INVALID_SUB) { ! 4476: for(j=0;j<cfg.area[i].uplinks;j++) ! 4477: if(!memcmp(&cfg.area[i].uplink[j],&pkt_faddr,sizeof(faddr_t))) ! 4478: break; ! 4479: if(j==cfg.area[i].uplinks) { ! 4480: if(cfg.log&LOG_SECURE) ! 4481: logprintf("%s: Security violation - %s not in AREAS.BBS" ! 4482: ,areatagstr,smb_faddrtoa(&pkt_faddr,NULL)); ! 4483: printf("Security Violation (Not in AREAS.BBS)\n"); ! 4484: seektonull(fidomsg); ! 4485: continue; ! 4486: } ! 4487: } ! 4488: ! 4489: /* From here on out, i = area number and area[i].sub = sub number */ ! 4490: ! 4491: memcpy(&curarea,&cfg.area[i],sizeof(areasbbs_t)); ! 4492: curarea.name=areatagstr; ! 4493: ! 4494: if(cfg.area[i].sub==INVALID_SUB) { /* Passthru */ ! 4495: start_tick=0; ! 4496: strip_psb(fmsgbuf); ! 4497: pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen,msg_path,0); ! 4498: printf("\n"); ! 4499: continue; ! 4500: } /* On to the next message */ ! 4501: ! 4502: ! 4503: if(cfg.check_path) { ! 4504: for(j=0;j<scfg.total_faddrs;j++) ! 4505: if(check_psb(&msg_path,scfg.faddr[j])) ! 4506: break; ! 4507: if(j<scfg.total_faddrs) { ! 4508: start_tick=0; ! 4509: printf("Circular path (%s) ",smb_faddrtoa(&scfg.faddr[j],NULL)); ! 4510: cfg.area[i].circular++; ! 4511: if(cfg.log&LOG_CIRCULAR) ! 4512: logprintf("%s: Circular path detected for %s" ! 4513: ,areatagstr,smb_faddrtoa(&scfg.faddr[j],NULL)); ! 4514: strip_psb(fmsgbuf); ! 4515: pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen,msg_path,0); ! 4516: printf("\n"); ! 4517: continue; ! 4518: } ! 4519: } ! 4520: ! 4521: for(j=0;j<MAX_OPEN_SMBS;j++) ! 4522: if(subnum[j]==cfg.area[i].sub) ! 4523: break; ! 4524: if(j<MAX_OPEN_SMBS) /* already open */ ! 4525: cur_smb=j; ! 4526: else { ! 4527: if(smb[cur_smb].shd_fp) /* If open */ ! 4528: cur_smb=!cur_smb; /* toggle between 0 and 1 */ ! 4529: smb_close(&smb[cur_smb]); /* close, if open */ ! 4530: subnum[cur_smb]=INVALID_SUB; /* reset subnum (just incase) */ ! 4531: } ! 4532: ! 4533: if(smb[cur_smb].shd_fp==NULL) { /* Currently closed */ ! 4534: sprintf(smb[cur_smb].file,"%s%s",scfg.sub[cfg.area[i].sub]->data_dir ! 4535: ,scfg.sub[cfg.area[i].sub]->code); ! 4536: smb[cur_smb].retry_time=scfg.smb_retry_time; ! 4537: if((j=smb_open(&smb[cur_smb]))!=SMB_SUCCESS) { ! 4538: sprintf(str,"ERROR %d opening %s area #%d, sub #%d)" ! 4539: ,j,smb[cur_smb].file,i+1,cfg.area[i].sub+1); ! 4540: printf(str); ! 4541: logprintf(str); ! 4542: strip_psb(fmsgbuf); ! 4543: pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen ! 4544: ,msg_path,0); ! 4545: printf("\n"); ! 4546: continue; ! 4547: } ! 4548: if(!filelength(fileno(smb[cur_smb].shd_fp))) { ! 4549: smb[cur_smb].status.max_crcs=scfg.sub[cfg.area[i].sub]->maxcrcs; ! 4550: smb[cur_smb].status.max_msgs=scfg.sub[cfg.area[i].sub]->maxmsgs; ! 4551: smb[cur_smb].status.max_age=scfg.sub[cfg.area[i].sub]->maxage; ! 4552: smb[cur_smb].status.attr=scfg.sub[cfg.area[i].sub]->misc&SUB_HYPER ! 4553: ? SMB_HYPERALLOC:0; ! 4554: if((j=smb_create(&smb[cur_smb]))!=SMB_SUCCESS) { ! 4555: sprintf(str,"ERROR %d creating %s",j,smb[cur_smb].file); ! 4556: printf(str); ! 4557: logprintf(str); ! 4558: smb_close(&smb[cur_smb]); ! 4559: strip_psb(fmsgbuf); ! 4560: pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen ! 4561: ,msg_path,0); ! 4562: printf("\n"); ! 4563: continue; ! 4564: } ! 4565: } ! 4566: ! 4567: subnum[cur_smb]=cfg.area[i].sub; ! 4568: } ! 4569: ! 4570: if(hdr.attr&FIDO_PRIVATE && !(scfg.sub[cfg.area[i].sub]->misc&SUB_PRIV)) { ! 4571: if(misc&IMPORT_PRIVATE) ! 4572: hdr.attr&=~FIDO_PRIVATE; ! 4573: else { ! 4574: start_tick=0; ! 4575: printf("Private posts disallowed."); ! 4576: if(cfg.log&LOG_PRIVATE) ! 4577: logprintf("%s: Private posts disallowed" ! 4578: ,areatagstr); ! 4579: strip_psb(fmsgbuf); ! 4580: pkt_to_pkt(fmsgbuf,curarea,pkt_faddr,hdr,msg_seen ! 4581: ,msg_path,0); ! 4582: printf("\n"); ! 4583: continue; ! 4584: } ! 4585: } ! 4586: ! 4587: if(!(hdr.attr&FIDO_PRIVATE) && scfg.sub[cfg.area[i].sub]->misc&SUB_PONLY) ! 4588: hdr.attr|=MSG_PRIVATE; ! 4589: ! 4590: /**********************/ ! 4591: /* Importing EchoMail */ ! 4592: /**********************/ ! 4593: j=fmsgtosmsg(fmsgbuf,hdr,0,cfg.area[i].sub); ! 4594: ! 4595: if(start_tick) { ! 4596: import_ticks+=msclock()-start_tick; ! 4597: start_tick=0; ! 4598: } ! 4599: ! 4600: if(j==SMB_DUPE_MSG) { ! 4601: if(cfg.log&LOG_DUPES) ! 4602: logprintf("%s Duplicate message",areatagstr); ! 4603: cfg.area[i].dupes++; ! 4604: } ! 4605: else { /* Not a dupe */ ! 4606: strip_psb(fmsgbuf); ! 4607: pkt_to_pkt(fmsgbuf,curarea,pkt_faddr ! 4608: ,hdr,msg_seen,msg_path,0); ! 4609: } ! 4610: ! 4611: if(j==0) { /* Successful import */ ! 4612: echomail++; ! 4613: cfg.area[i].imported++; ! 4614: if(misc&NOTIFY_RECEIPT && (m=matchname(hdr.to))!=0) { ! 4615: sprintf(str ! 4616: ,"\7\1n\1hSBBSecho: \1m%.*s \1n\1msent you EchoMail on " ! 4617: "\1h%s \1n\1m%s\1n\r\n" ! 4618: ,FIDO_NAME_LEN-1 ! 4619: ,hdr.from ! 4620: ,scfg.grp[scfg.sub[cfg.area[i].sub]->grp]->sname ! 4621: ,scfg.sub[cfg.area[i].sub]->sname); ! 4622: putsmsg(&scfg,m,str); ! 4623: } ! 4624: } ! 4625: printf("\n"); ! 4626: } ! 4627: fclose(fidomsg); ! 4628: ! 4629: if(misc&DELETE_PACKETS) ! 4630: if(delfile(packet)) ! 4631: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,packet ! 4632: ,strerror(errno)); ! 4633: } ! 4634: globfree(&g); ! 4635: ! 4636: if(start_tick) { ! 4637: import_ticks+=msclock()-start_tick; ! 4638: start_tick=0; ! 4639: } ! 4640: ! 4641: } while(!kbhit() && unpack_bundle()); ! 4642: ! 4643: if(kbhit()) lprintf(LOG_NOTICE,"\nKey pressed - premature termination"); ! 4644: while(kbhit()) getch(); ! 4645: ! 4646: } /* End of Secure : Inbound loop */ ! 4647: ! 4648: if(start_tick) /* Last possible increment of import_ticks */ ! 4649: import_ticks+=msclock()-start_tick; ! 4650: ! 4651: for(j=MAX_OPEN_SMBS-1;(int)j>=0;j--) /* Close open bases */ ! 4652: if(smb[j].shd_fp) ! 4653: smb_close(&smb[j]); ! 4654: ! 4655: pkt_to_pkt(fmsgbuf,fakearea,pkt_faddr,hdr,msg_seen,msg_path,1); ! 4656: ! 4657: /******* END OF IMPORT PKT ROUTINE *******/ ! 4658: ! 4659: if(cfg.log&LOG_AREA_TOTALS) { ! 4660: for(i=0;i<cfg.areas;i++) { ! 4661: if(cfg.area[i].imported) ! 4662: lprintf(LOG_INFO,"Imported: %5u msgs %8s <- %s" ! 4663: ,cfg.area[i].imported,scfg.sub[cfg.area[i].sub]->code ! 4664: ,cfg.area[i].name); } ! 4665: for(i=0;i<cfg.areas;i++) { ! 4666: if(cfg.area[i].circular) ! 4667: lprintf(LOG_INFO,"Circular: %5u detected in %s" ! 4668: ,cfg.area[i].circular,cfg.area[i].name); } ! 4669: for(i=0;i<cfg.areas;i++) { ! 4670: if(cfg.area[i].dupes) ! 4671: lprintf(LOG_INFO,"Duplicate: %5u detected in %s" ! 4672: ,cfg.area[i].dupes,cfg.area[i].name); } } ! 4673: ! 4674: import_time=((float)import_ticks)/(float)MSCLOCKS_PER_SEC; ! 4675: if(cfg.log&LOG_TOTALS && import_time && echomail) { ! 4676: lprintf(LOG_INFO,"Imported: %5lu msgs in %.1f sec (%.1f/min %.1f/sec)" ! 4677: ,echomail,import_time ! 4678: ,import_time/60.0 ? (float)echomail/(import_time/60.0) :(float)echomail ! 4679: ,(float)echomail/import_time); ! 4680: } ! 4681: if(fmsgbuf) { ! 4682: free(fmsgbuf); ! 4683: fmsgbuf=0; } ! 4684: ! 4685: } ! 4686: ! 4687: if(misc&IMPORT_NETMAIL) { ! 4688: ! 4689: lprintf(LOG_DEBUG,"\nScanning for Inbound NetMail Messages..."); ! 4690: ! 4691: #ifdef __unix__ ! 4692: sprintf(str,"%s*.[Mm][Ss][Gg]",scfg.netmail_dir); ! 4693: #else ! 4694: sprintf(str,"%s*.msg",scfg.netmail_dir); ! 4695: #endif ! 4696: glob(str,0,NULL,&g); ! 4697: for(f=0;f<g.gl_pathc && !kbhit();f++) { ! 4698: ! 4699: strcpy(path,g.gl_pathv[f]); ! 4700: ! 4701: if((fidomsg=fnopen(&fmsg,path,O_RDWR))==NULL) { ! 4702: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,path ! 4703: ,strerror(errno)); ! 4704: continue; } ! 4705: if(filelength(fmsg)<sizeof(fmsghdr_t)) { ! 4706: lprintf(LOG_ERR,"ERROR line %d invalid length of %lu bytes for %s",__LINE__ ! 4707: ,filelength(fmsg),path); ! 4708: fclose(fidomsg); ! 4709: continue; } ! 4710: if(fread(&hdr,sizeof(fmsghdr_t),1,fidomsg)!=1) { ! 4711: fclose(fidomsg); ! 4712: lprintf(LOG_ERR,"ERROR line %d reading %u bytes from %s",__LINE__ ! 4713: ,sizeof(fmsghdr_t),path); ! 4714: continue; } ! 4715: i=import_netmail(path,hdr,fidomsg); ! 4716: /**************************************/ ! 4717: /* Delete source netmail if specified */ ! 4718: /**************************************/ ! 4719: if(i==0) { ! 4720: if(misc&DELETE_NETMAIL) { ! 4721: fclose(fidomsg); ! 4722: if(delfile(path)) ! 4723: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,path ! 4724: ,strerror(errno)); } ! 4725: else { ! 4726: hdr.attr|=FIDO_RECV; ! 4727: fseek(fidomsg,0L,SEEK_SET); ! 4728: fwrite(&hdr,sizeof(fmsghdr_t),1,fidomsg); ! 4729: fclose(fidomsg); } } ! 4730: else if(i!=-2) ! 4731: fclose(fidomsg); ! 4732: printf("\n"); ! 4733: } ! 4734: globfree(&g); ! 4735: } ! 4736: ! 4737: ! 4738: if(misc&EXPORT_ECHOMAIL) { ! 4739: memset(&addr,0,sizeof(faddr_t)); ! 4740: export_echomail(sub_code,addr); ! 4741: } ! 4742: ! 4743: ! 4744: if(misc&PACK_NETMAIL) { ! 4745: ! 4746: memset(&msg_seen,0,sizeof(addrlist_t)); ! 4747: memset(&msg_path,0,sizeof(addrlist_t)); ! 4748: memset(&fakearea,0,sizeof(areasbbs_t)); ! 4749: ! 4750: lprintf(LOG_DEBUG,"\nPacking Outbound NetMail..."); ! 4751: ! 4752: #ifdef __unix__ ! 4753: sprintf(str,"%s*.[Mm][Ss][Gg]",scfg.netmail_dir); ! 4754: #else ! 4755: sprintf(str,"%s*.msg",scfg.netmail_dir); ! 4756: #endif ! 4757: glob(str,0,NULL,&g); ! 4758: for(f=0;f<g.gl_pathc && !kbhit();f++) { ! 4759: ! 4760: strcpy(path,g.gl_pathv[f]); ! 4761: ! 4762: if((fidomsg=fnopen(&fmsg,path,O_RDWR))==NULL) { ! 4763: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,path ! 4764: ,strerror(errno)); ! 4765: continue; } ! 4766: if(filelength(fmsg)<sizeof(fmsghdr_t)) { ! 4767: lprintf(LOG_WARNING,"%s Invalid length of %lu bytes",path,filelength(fmsg)); ! 4768: fclose(fidomsg); ! 4769: continue; } ! 4770: if(fread(&hdr,sizeof(fmsghdr_t),1,fidomsg)!=1) { ! 4771: fclose(fidomsg); ! 4772: lprintf(LOG_ERR,"ERROR line %d reading %u bytes from %s",__LINE__ ! 4773: ,sizeof(fmsghdr_t),path); ! 4774: continue; } ! 4775: hdr.destzone=hdr.origzone=sys_faddr.zone; ! 4776: hdr.destpoint=hdr.origpoint=0; ! 4777: getzpt(fidomsg,&hdr); /* use kludge if found */ ! 4778: addr.zone=hdr.destzone; ! 4779: addr.net=hdr.destnet; ! 4780: addr.node=hdr.destnode; ! 4781: addr.point=hdr.destpoint; ! 4782: for(i=0;i<scfg.total_faddrs;i++) ! 4783: if(!memcmp(&addr,&scfg.faddr[i],sizeof(faddr_t))) ! 4784: break; ! 4785: if(i<scfg.total_faddrs) { /* In-bound, so ignore */ ! 4786: fclose(fidomsg); ! 4787: continue; ! 4788: } ! 4789: printf("\n%s to %s ",path,smb_faddrtoa(&addr,NULL)); ! 4790: if(cfg.log&LOG_PACKING) ! 4791: logprintf("Packing %s (%s)",path,smb_faddrtoa(&addr,NULL)); ! 4792: fmsgbuf=getfmsg(fidomsg,NULL); ! 4793: if(!fmsgbuf) { ! 4794: lprintf(LOG_ERR,"ERROR line %d allocating memory for NetMail fmsgbuf" ! 4795: ,__LINE__); ! 4796: bail(1); } ! 4797: fclose(fidomsg); ! 4798: ! 4799: attr=0; ! 4800: node=matchnode(addr,0); ! 4801: if(node<cfg.nodecfgs && cfg.nodecfg[node].route.zone ! 4802: && !(hdr.attr&(FIDO_CRASH|FIDO_HOLD))) { ! 4803: addr=cfg.nodecfg[node].route; /* Routed */ ! 4804: if(cfg.log&LOG_ROUTING) ! 4805: logprintf("Routing %s to %s",path,smb_faddrtoa(&addr,NULL)); ! 4806: node=matchnode(addr,0); ! 4807: } ! 4808: if(node<cfg.nodecfgs) ! 4809: attr=cfg.nodecfg[node].attr; ! 4810: ! 4811: if(misc&FLO_MAILER) { ! 4812: if(hdr.attr&FIDO_CRASH) ! 4813: attr|=ATTR_CRASH; ! 4814: else if(hdr.attr&FIDO_HOLD) ! 4815: attr|=ATTR_HOLD; ! 4816: if(attr&ATTR_CRASH) ch='c'; ! 4817: else if(attr&ATTR_HOLD) ch='h'; ! 4818: else if(attr&ATTR_DIRECT) ch='d'; ! 4819: else ch='o'; ! 4820: if(addr.zone==sys_faddr.zone) /* Default zone, use default outbound */ ! 4821: strcpy(outbound,cfg.outbound); ! 4822: else { /* Inter-zone outbound is OUTBOUND.XXX */ ! 4823: sprintf(outbound,"%.*s.%03x" ! 4824: ,(int)strlen(cfg.outbound)-1,cfg.outbound,addr.zone); ! 4825: MKDIR(outbound); ! 4826: backslash(outbound); ! 4827: } ! 4828: if(addr.point) { /* Point destination is OUTBOUND.PNT */ ! 4829: sprintf(str,"%04x%04x.pnt" ! 4830: ,addr.net,addr.node); ! 4831: strcat(outbound,str); } ! 4832: if(outbound[strlen(outbound)-1]=='\\' ! 4833: || outbound[strlen(outbound)-1]=='/') ! 4834: outbound[strlen(outbound)-1]=0; ! 4835: MKDIR(outbound); ! 4836: backslash(outbound); ! 4837: if(addr.point) ! 4838: sprintf(packet,"%s%08x.%cut",outbound,addr.point,ch); ! 4839: else ! 4840: sprintf(packet,"%s%04x%04x.%cut",outbound,addr.net,addr.node,ch); ! 4841: if(hdr.attr&FIDO_FILE) ! 4842: if(write_flofile(hdr.subj,addr,FALSE /* !bundle */)) ! 4843: bail(1); } ! 4844: else ! 4845: strcpy(packet,pktname(/* Temp? */ FALSE)); ! 4846: ! 4847: now=time(NULL); ! 4848: tm=localtime(&now); ! 4849: if((stream=fnopen(&file,packet,O_RDWR|O_CREAT))==NULL) { ! 4850: lprintf(LOG_ERR,"ERROR line %d opening %s %s",__LINE__,packet ! 4851: ,strerror(errno)); ! 4852: bail(1); ! 4853: } ! 4854: ! 4855: if(filelength(file) < sizeof(pkthdr_t)) { ! 4856: chsize(file,0); ! 4857: rewind(stream); ! 4858: memset(&pkthdr,0,sizeof(pkthdr)); ! 4859: pkthdr.orignode=hdr.orignode; ! 4860: pkthdr.destnode=addr.node; ! 4861: pkthdr.year=tm->tm_year+1900; ! 4862: pkthdr.month=tm->tm_mon; ! 4863: pkthdr.day=tm->tm_mday; ! 4864: pkthdr.hour=tm->tm_hour; ! 4865: pkthdr.min=tm->tm_min; ! 4866: pkthdr.sec=tm->tm_sec; ! 4867: pkthdr.baud=0x00; ! 4868: pkthdr.pkttype=0x0002; ! 4869: pkthdr.orignet=hdr.orignet; ! 4870: pkthdr.destnet=addr.net; ! 4871: pkthdr.prodcode=0x00; ! 4872: pkthdr.sernum=0; ! 4873: pkthdr.origzone=hdr.origzone; ! 4874: pkthdr.destzone=addr.zone; ! 4875: if(node<cfg.nodecfgs) { ! 4876: if(cfg.nodecfg[node].pkt_type==PKT_TWO_PLUS) { ! 4877: memset(&two_plus,0,sizeof(two_plus)); ! 4878: if(hdr.origpoint) { ! 4879: pkthdr.orignet=-1; ! 4880: two_plus.auxnet=hdr.orignet; ! 4881: } ! 4882: two_plus.cwcopy=0x0100; ! 4883: two_plus.prodcode=pkthdr.prodcode; ! 4884: two_plus.revision=pkthdr.sernum; ! 4885: two_plus.cword=0x0001; ! 4886: two_plus.origzone=pkthdr.origzone; ! 4887: two_plus.destzone=pkthdr.destzone; ! 4888: two_plus.origpoint=hdr.origpoint; ! 4889: two_plus.destpoint=addr.point; ! 4890: memcpy(&pkthdr.empty,&two_plus,sizeof(pkthdr.empty)); ! 4891: } ! 4892: memcpy(pkthdr.password,cfg.nodecfg[node].pktpwd,sizeof(pkthdr.password)); ! 4893: } ! 4894: fwrite(&pkthdr,sizeof(pkthdr_t),1,stream); ! 4895: } else ! 4896: fseek(stream,find_packet_terminator(stream),SEEK_SET); ! 4897: ! 4898: putfmsg(stream,fmsgbuf,hdr,fakearea,msg_seen,msg_path); ! 4899: ! 4900: /* Write packet terminator */ ! 4901: terminate_packet(stream); ! 4902: ! 4903: free(fmsgbuf); ! 4904: fclose(stream); ! 4905: /**************************************/ ! 4906: /* Delete source netmail if specified */ ! 4907: /**************************************/ ! 4908: if(misc&DELETE_NETMAIL) ! 4909: if(delfile(path)) ! 4910: lprintf(LOG_ERR,"ERROR line %d removing %s %s",__LINE__,path ! 4911: ,strerror(errno)); ! 4912: printf("\n"); ! 4913: } ! 4914: globfree(&g); ! 4915: } ! 4916: ! 4917: if(misc&UPDATE_MSGPTRS) { ! 4918: ! 4919: lprintf(LOG_DEBUG,"\nUpdating Message Pointers to Last Posted Message..."); ! 4920: ! 4921: for(grp=0;grp<scfg.total_grps;grp++) { ! 4922: for(i=0;i<scfg.total_subs;i++) { ! 4923: if(scfg.sub[i]->misc&SUB_FIDO && scfg.sub[i]->grp==grp) { ! 4924: lprintf(LOG_DEBUG,"\n%-15.15s %s" ! 4925: ,scfg.grp[scfg.sub[i]->grp]->sname,scfg.sub[i]->lname); ! 4926: getlastmsg(i,&l,0); ! 4927: sprintf(str,"%s%s.sfp",scfg.sub[i]->data_dir,scfg.sub[i]->code); ! 4928: if((file=nopen(str,O_WRONLY|O_CREAT))==-1) { ! 4929: lprintf(LOG_ERR,"ERROR %d line %d opening/creating %s" ! 4930: ,errno,__LINE__,str); } ! 4931: else { ! 4932: write(file,&l,sizeof(time_t)); ! 4933: close(file); ! 4934: } ! 4935: } ! 4936: } ! 4937: } ! 4938: } ! 4939: ! 4940: if(misc&(IMPORT_NETMAIL|IMPORT_ECHOMAIL) && misc&REPORT) { ! 4941: now=time(NULL); ! 4942: sprintf(str,"%ssbbsecho.msg",scfg.text_dir); ! 4943: if((file=nopen(str,O_WRONLY|O_CREAT|O_TRUNC))==-1) { ! 4944: lprintf(LOG_ERR,"ERROR line %d opening %s",__LINE__,str); ! 4945: bail(1); } ! 4946: sprintf(fname,"\1c\1h " ! 4947: "���������������������������������������������������\r\n"); ! 4948: sprintf(path,"\1c\1h " ! 4949: "���������������������������������������������������\r\n"); ! 4950: write(file,fname,strlen(fname)); ! 4951: sprintf(str," \1n\1k\0016" ! 4952: " Last FidoNet Transfer on %.24s \1n\r\n",ctime(&now)); ! 4953: write(file,str,strlen(str)); ! 4954: write(file,path,strlen(path)); ! 4955: write(file,fname,strlen(fname)); ! 4956: sprintf(tmp,"Imported %lu EchoMail and %lu NetMail Messages" ! 4957: ,echomail,netmail); ! 4958: sprintf(str," \1n\1k\0016 %-50.50s\1n\r\n",tmp); ! 4959: write(file,str,strlen(str)); ! 4960: write(file,path,strlen(path)); ! 4961: close(file); ! 4962: } ! 4963: ! 4964: pkt_to_pkt(NULL,fakearea,pkt_faddr,hdr,msg_seen,msg_path,1); ! 4965: if(email->shd_fp) ! 4966: smb_close(email); ! 4967: ! 4968: free(smb); ! 4969: free(email); ! 4970: ! 4971: bail(0); ! 4972: return(0); ! 4973: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.