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