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