/*************************************************************************** * IMPORT.C * * * * import utility. * * * * This program IMPORTs FidoNet mailpackets and TOSSes mail and * * echomail. * * * * IMPORT is part of the BERMUDA software. BERMUDA is a package of FidoNet * * compatible message/nodelist processing software. * * Please read LICENSE for information about distribution. * * * * Written by Jac Kersing, * * Modifications by Enno Borgsteede and Rinaldo Visscher * * Modifications by Vincent Pomey and Franck Arnaud * ***************************************************************************/ #define MAILER /* needed in PANDORA.H */ #define DEBUG 0 /* Debugging mode (extended info) on/off */ #define DEBUG_SORT 0 /* Debugging info in sort routine? */ #include "pandora.h" /* for structure of the area's etc. */ #include "mail.h" /* pretty obvious if your unpacking mail.. */ #include #if TC #include #include #endif #define __PROTO__ 1 #include "import.pro" #include "utextra.pro" #define UVERSION "1.22" /* version-number */ #define LASTMOD __DATE__ #define isBERMUDA 0xA0 /* productcode for Bermuda */ #define MSGSCANNED 0x8000 /* defines for writemessage */ #define OUTBOUND 0 /* message to mailarea */ #define LOCAL 1 /* message to local msgfile */ #define SCANFILE 2 /* message to node file */ /* defines for SEEN-BY treatement */ #define NOTHING 0 /* no echomail message */ #define POINTS 1 /* add pointlist to message */ #define LOCALS 2 /* add local list to msg */ #define DIFFZONE 4 /* add list for OTHER zone */ #define OTHERS 8 /* add all nodes already there */ struct _passw /* structure for passwords */ { char passw[8]; /* the password itself */ unsigned zone; /* zone number for remote */ unsigned net; /* net number for remote */ unsigned node; /* node number for remote */ unsigned point; /* point number for remote */ int my_aka; /* the number in the addresslist for this sucker */ struct _passw *next; /* pointer to next struct */ } ; struct _aka { unsigned zone; unsigned net; unsigned node; unsigned point; unsigned pointnet; } ; #undef NORMAL void Aopen(), Aclose(), cleanEcho(), renumber(); char progname[]="B-I"; /* program name for logging */ FILE *pkt; /* the mailpacket */ char *Bpath=""; /* path for mailer info */ char packet[80]; /* name of the packet we're dealing with now */ struct _pkthdr phdr; /* storage for packetheader */ struct _pktmsgs mhdr; /* header of current message */ struct Hdr hhdr; /* header for message (in hdr file) */ struct Hdr Mhdr; /* storage for outgoing message header */ char arc_prg[90]; /* archive program name */ char arc_cmd[90]; /* commands for archive program */ #ifdef LINN char zip_prg[90]; char zip_cmd[90]; char zoo_prg[90]; char zoo_cmd[90]; char lzh_prg[90]; char lzh_cmd[90]; char arj_prg[90]; char arj_cmd[90]; char def_prg[90]; /* default archiver */ char def_cmd[90]; #endif int akeep=0; /* keep extracted archives? */ char *ms; /* pointer in message buffer */ int lastarea; /* area last message was stored */ char *AreaPath[N_AREAS]; /* path to message area */ char *AreaName[N_AREAS]; /* name of area */ char *AreaOrig[N_AREAS]; /* the origin line for this area */ int AreaDays[N_AREAS]; /* number of days this area lasts */ unsigned *ToZone[N_AREAS]; /* Zone, Net, */ unsigned *ToNet[N_AREAS]; /* Node and Point */ unsigned *ToNode[N_AREAS]; /* numbers of nodes we're supposed */ unsigned *ToPoint[N_AREAS]; /* to echo messages to.......... */ int nmsgs[N_AREAS]; /* number of messages tossed to this area */ int smsgs[N_AREAS]; /* number of messages to sysop in this area */ #ifdef LINN int emsgs[N_AREAS]; /* number of messages echoed in this area */ #endif int SendTo[51]; /* Send to this node too? */ unsigned TZone[51]; /* Temp. storage for addresses */ unsigned TNet[51]; /* Zone and Net.. */ unsigned TNode[51]; /* Node */ unsigned TPoint[51]; /* Point */ unsigned SeenZone[950]; /* Zone... */ unsigned SeenNet[950]; /* adress of nodes that have seen */ unsigned SeenNode[950]; /* this message */ unsigned SeenPoint[950]; /* Point */ int nSeen; /* number of Seen-bys */ unsigned PathZone[200]; /* Zone of path.. */ unsigned PathNet[200]; /* adresses listed in the */ unsigned PathNode[200]; /* path line */ unsigned PathPoint[200]; /* Ditto */ int nPath; /* number of nodes in Path */ char ThisArea[80]; /* name of this echomail area */ int mailarea; /* number of mailarea */ int badarea; /* number of area for badmessages */ int msgareas; /* number of messageareas */ char *hold; /* path to hold area */ #ifdef LINN char *holdbink; #endif char *mailpath; /* path to mailmsgs */ char *netpath; /* path to netmail */ struct _aka alias[30]; /* aliases */ int nalias; /* number of aliases */ #ifdef LINN int binkley=0; int add_aka=0; /* number of aliases to add to seen-bys */ int no_intl=0; #else int add_aka; /* number of aliases to add to seen-bys */ #endif int verbose=0; /* level for message displaying */ int loglevel; /* level for message logging */ #ifdef LINN int killrouted; /* set flag Kill/Sent for routed msg */ #endif char *logname; /* name of logfile */ FILE *log; /* filepointer for logfile */ struct _passw *pwd; /* password pointer */ char sysop[80]; /* name of sysop */ char *ourorigin; /* line for origin */ unsigned ourzone; /* zone, */ unsigned ournet; /* net and */ unsigned ournode; /* node of our BBS */ unsigned ourpoint; /* point */ unsigned ourpointnet; /* we've got a pointnet too */ char ourpwd[10]; /* the password we're using now */ char *MESSAGE; /* adress of message buffer (malloced) */ char *mend; /* points to end of the message */ char *endbody; /* end of message body WITHOUT seen-bys */ int mlength; /* length of message (including seen-by)*/ int area; /* area we're processing */ int echomsgs=0; /* number of messages generated */ char *origl; /* points to origin line in message */ int ask=0; /* ask for a packetname? */ int arcmail=0; /* unpacking arcmail? */ int use_path; /* do we wanna use the PATH line? */ int use_kludge; /* we want to use the IFNA kludge? */ int use_origin; /* do we wanna have an origin line?? */ int use_readdress; /* readress message (fake from our bbs) */ int use_packet; /* scan messages to packets */ int use_tiny=0; /* tiny adresses (ones I'm sending to) */ int secure=0; /* only import mail from known sources */ FILE *MHDR; FILE *MMSG; FILE *hdr; /* file with message headers */ FILE *msg; /* file with message text */ char oldmsg[80]; /* names of the message and header files */ char oldhdr[80]; int j; /* stupid counter */ int x; /* x position in line */ unsigned pktzone[10]; /* zone, net, node and point */ unsigned pktnet[10]; /* = address for open packet */ unsigned pktnode[10]; /* used for saving messages to */ unsigned pktpoint[10]; unsigned pktfake[10]; unsigned fromzone; /* address this packet was packed */ unsigned fromnet; unsigned fromnode; unsigned frompoint; FILE *pktfile[10]; /* the packet */ /* Ok, so far all definitions. The program is next.. */ char *skip_blanks(string) char *string; { while (*string && isspace(*string)) ++string; return string; } char *skip_to_blank(string) char *string; { while (*string && !isspace(*string)) ++string; return string; } char *myalloc(sp) size_t sp; { char *tmp; if (sp==0) sp=1; tmp=malloc(sp); if (tmp==NULL) { message(6,"!Mem error"); exit(1); } return tmp; } char *ctl_string(string) char *string; { char *p, *d; p=skip_blanks(string); d=myalloc(strlen(p)+1); strcpy(d,p); return d; } char *ctl_path(str) char *str; { char *q; str= skip_blanks(str); for (q=str; *q && !isspace(*q); q++) ; *q= '\0'; #if UNIX if (*(q-1)!='/') strcat(q,"/"); #else if (*(q-1)!='\\') strcat(q,"\\"); #endif return ctl_string(str); } char *ctl_file(str) char *str; { char *q; str= skip_blanks(str); for (q=str; *q && !isspace(*q); q++) ; *q= '\0'; return ctl_string(str); } int init_conf() { FILE *conf; /* filepointer for config-file */ char buffer[256]; /* buffer for 1 line */ char *p; /* workhorse */ #ifdef LINN char *q; /* another one */ #endif int count; /* just a counter... */ char *ffirst(); /* directory find */ char *getenv(); /* get the environment string */ p=getenv("MAILER"); if (!ffirst("bermuda.cfg") && /* check local config */ !ffirst("tb.cfg") && p!=NULL && *p!='\0') { /* no local, and envi contained one */ Bpath= ctl_path(p); } sprintf( buffer, "%sbermuda.cfg", Bpath); conf= fopen(buffer, "r"); if (conf==NULL) { sprintf(buffer,"%stb.cfg", Bpath); conf = fopen(buffer, "r"); } if (verbose > 2) printf("Config: %s\n",buffer); if (conf==NULL) { message(6,"!Configuration file not found, please check!!!"); return 1; /* not found, back */ } /* set all to default values */ loglevel=255; ourzone=ournet=ournode=ourpoint=0; #ifdef LINN killrouted=1; #endif message(-1,"+Parsing configuration file"); while((fgets(buffer, 250, conf))) /* read a line */ { if (verbose > 2) printf("Config: %s\n",buffer); p=skip_blanks(buffer); if (*p==';') continue; /* comment?? */ /* delete ALL chars following (and inclusive) comment sign */ if ((p=strchr(buffer,';'))!=NULL) *p= '\0'; if ((count= (int)strlen(buffer))<3) continue; /* what's the length of the rest? */ p= &buffer[--count]; if (*p=='\n') *p=0; /* delete (possible) newline char */ #ifdef LINN /* process "application bermuda" lines as normal lines */ if (!strnicmp(buffer,"application",11)) { p=skip_blanks(&buffer[11]); if(!strnicmp(p,"bermuda",7)) { p=skip_blanks(&p[7]); strcpy(buffer,p); } } #endif if (!strnicmp(buffer,"sysop",5)) { p=skip_blanks(&buffer[5]); strncpy(sysop,p,79); sysop[79]='\0'; continue; } if (!strnicmp(buffer,"address",7)) { p=skip_blanks(&buffer[7]); if(getaddress(p,&alias[nalias].zone, &alias[nalias].net, &alias[nalias].node, &alias[nalias].point)!=7) { message(3,"!Invalid address in %s",buffer); continue; } p=skip_blanks(skip_to_blank(p)); if (*p=='+' || *p=='*') p=skip_blanks(skip_to_blank(p)); if (*p && isdigit(*p)) { if ((alias[nalias].pointnet=atoi(p))==0) { message(6,"!Invalid pointnet in %s",buffer); continue; } } else alias[nalias].pointnet=0; ++nalias; ourzone=alias[0].zone; ournet=alias[0].net; ournode=alias[0].node; ourpoint=alias[0].point; ourpointnet=alias[0].pointnet; continue; } if (!strnicmp(buffer,"loglevel",8)) { p=skip_blanks(&buffer[8]); if (sscanf(p,"%d", &count)!=1 || count>6 || count<0) message(3,"-Invalid loglevel (%s)", p); else loglevel=count; continue; } if (!strnicmp(buffer, "statuslog",9)) { logname= ctl_string(&buffer[9]); if ((log=fopen(logname, "a"))==NULL) if ((log=fopen(logname, "w+"))==NULL) { message(6,"!Could not create logfile!"); free(logname); logname=NULL; } else { fflush(log); } continue; } if (!strnicmp(buffer,"netfile",7)) { mailpath=ctl_path(&buffer[7]); continue; } if (!strnicmp(buffer,"netmail",7)) { netpath=ctl_string(&buffer[7]); continue; } if (!strnicmp(buffer,"hold",4)) { hold=ctl_path(&buffer[4]); #ifdef LINN holdbink=strdup(hold); holdbink[strlen(holdbink)-1]=0; #endif continue; } if (!strnicmp(buffer,"key",3)) { parsekey(&buffer[3]); continue; } #ifdef LINN if (!strnicmp(buffer,"nokillrouted",12)) { killrouted = 0; continue; } if (!strnicmp(buffer,"arcunpack", 9)) { p=skip_blanks(&buffer[9]); q=p; while (*q && !isspace(*q)) ++q; *q='\0'; strcpy (arc_prg, p); p=skip_blanks(&p[strlen(p)+1]); /* skip to next word */ strcpy (arc_cmd, p); continue; } if (!strnicmp(buffer,"zipunpack", 9)) { p=skip_blanks(&buffer[9]); q=p; while (*q && !isspace(*q)) ++q; *q='\0'; strcpy (zip_prg, p); p=skip_blanks(&p[strlen(p)+1]); /* skip to next word */ strcpy (zip_cmd, p); continue; } if (!strnicmp(buffer,"zoounpack", 9)) { p=skip_blanks(&buffer[9]); q=p; while (*q && !isspace(*q)) ++q; *q='\0'; strcpy (zoo_prg, p); p=skip_blanks(&p[strlen(p)+1]); /* skip to next word */ strcpy (zoo_cmd, p); continue; } if (!strnicmp(buffer,"lzhunpack", 9)) { p=skip_blanks(&buffer[9]); q=p; while (*q && !isspace(*q)) ++q; *q='\0'; strcpy (lzh_prg, p); p=skip_blanks(&p[strlen(p)+1]); /* skip to next word */ strcpy (lzh_cmd, p); continue; } if (!strnicmp(buffer,"arjunpack", 9)) { p=skip_blanks(&buffer[9]); q=p; while (*q && !isspace(*q)) ++q; *q='\0'; strcpy (arj_prg, p); p=skip_blanks(&p[strlen(p)+1]); /* skip to next word */ strcpy (arj_cmd, p); continue; } if (!strnicmp(buffer,"defaultunpack", 13)) { p=skip_blanks(&buffer[13]); q=p; while (*q && !isspace(*q)) ++q; *q='\0'; strcpy (def_prg, p); p=skip_blanks(&p[strlen(p)+1]); /* skip to next word */ strcpy (def_cmd, p); continue; } if (!strnicmp(buffer,"binkley", 7)) { binkley=1; continue; } #endif } fclose(conf); return 0; /* signal OK */ } void parsekey(p) char *p; { int i; char password[9]; struct _passw *pw,*pn; unsigned zone,net,node,point; int my_aka=0; /* get to the end of the list. */ pw=pwd; while (pw->next!=NULL) pw=pw->next; password[0]='\0'; p=skip_blanks(p); while (*p && *p!=';') { if (*p=='!') { strncpy(password,p+1,7); for (i=0; i<7; ++i) { if (isspace(password[i])) break; } password[i]='\0'; /* skip password and go on to node(s) */ p=skip_to_blank(p); p=skip_blanks(p); continue; } if (*p=='#') { if (getaddress(p+1,&zone,&net,&node,&point)) { int found=0; for (i=0; inext= (struct _passw *) myalloc(sizeof(struct _passw)); if (!getaddress(p,&zone,&net,&node,&point)) { free(pn); pw->next=NULL; message(3,"-Invalid address: %s",p); return; } if (point) { for (i=0; i < nalias; i++) { if (alias[i].zone==zone && alias[i].net==net && alias[i].node==node) { net= alias[i].pointnet; node= point; point= 0; break; } } } pn->zone=zone; pn->net=net; pn->node=node; pn->point=point; pn->my_aka=my_aka; strcpy(pn->passw,password); p=skip_to_blank(p); p=skip_blanks(p); pw=pn; pw->next=NULL; } return; } int getint(p,i) /* Mind the calling parms! */ char **p; unsigned *i; { char *q; long temp; q=*p; if (!isdigit(*q)) return (-1); temp=0; do { temp*=10; temp+=(*q++-'0'); } while (isdigit(*q)); *p=q; *i=(int)temp; if (temp>32767) return (-1); return (0); } int getaddress(str, zone, net, node, point) /* Decode zz:nn/mm.pp number */ char *str; /* 0=error | 1=node | 2=net/node | 3=zone:net/node | 4=pnt */ unsigned *zone, *net, *node, *point; { int retcode=0; *zone = alias[0].zone; *net = alias[0].net; *node = alias[0].node; *point = 0; str=skip_blanks(str); if (*str=='.') goto pnt; retcode++; if (getint(&str,node)) { if (strnicmp(str,"ALL",3)) return (0); *zone=*net=*node=65535U; return 10; } if (!*str) return (retcode); if (*str=='.') goto pnt; retcode++; if (*str==':') { str++; *zone=*node; *node=65535U; if (!*str) return (0); if (getint(&str,node)) { if (strnicmp(str,"ALL",3)) return (0); *net=*node=65535U; return 10; } retcode++; } if (*str!='/') return (0); str++; *net=*node; *node=alias[0].node; if (getint(&str,node)) { if (strnicmp(str,"ALL",3)) return (0); *node=65535U; return 10; } if (*str=='.') goto pnt; return (retcode); pnt: str++; if (getint(&str,point)) { if (strnicmp(str,"ALL",3)) return (0); *point=65535U; return 10; } return (4+retcode); } int getalias(zone,net,node,point) unsigned zone,net,node,point; { int i; struct _passw *pw; pw=pwd->next; if (point) { for (i=0; i < nalias; i++) { if (alias[i].zone==zone && alias[i].net==net && alias[i].node==node && alias[i].point==0) { net= alias[i].pointnet; node= point; point= 0; break; } } } while (pw!=NULL) { /* no match at all.. (yet) */ if ((pw->zone==65535U || pw->zone==zone) && /* zone numbers match, now net */ (pw->net==65535U || pw->net==net) && /* zone and net match.. node also? */ (pw->node==65535U || pw->node==node) && /* and how about point */ (pw->point==65535U || pw->point==point)) { ourzone=alias[pw->my_aka].zone; ournet=alias[pw->my_aka].net; ournode=alias[pw->my_aka].node; ourpoint=alias[pw->my_aka].point; ourpointnet=alias[pw->my_aka].pointnet; return 1; } pw=pw->next; } ourzone=alias[0].zone; ournet=alias[0].net; ournode=alias[0].node; ourpoint=alias[0].point; ourpointnet=alias[0].pointnet; return 0; } void get_passw(zone,net,node,point) unsigned zone,net,node,point; { int i; struct _passw *pw; pw=pwd->next; if (point) { for (i=0; i < nalias; i++) { if (alias[i].zone==zone && alias[i].net==net && alias[i].node==node && alias[i].point==0) { net= alias[i].pointnet; node= point; point= 0; break; } } } while (pw!=NULL) { /* vp 27 juil 93 : no wildcards for passwords */ /* no match at all.. (yet) */ if ((/*pw->zone==65535U ||*/ pw->zone==zone) && /* zone numbers match, now net */ (/*pw->net==65535U ||*/ pw->net==net) && /* zone and net match.. node also? */ (/*pw->node==65535U ||*/ pw->node==node) && /* and how about point */ (/*pw->point==65535U ||*/ pw->point==point)) { strcpy(ourpwd,pw->passw); return; } pw=pw->next; } *ourpwd= '\0'; } void init(argc, argv) /* initialize everything needed */ int argc; /* counter */ char *argv[]; /* commandline crap */ { int i,j; /* counter */ char *p, *q; /* nice pointers.. */ char buffer[300]; /* to store lines from AREAS.BBS etc. in */ char temp[80]; /* temp. storage */ char areasbbs[80]; /* name of file for AREAS.BBS */ int the_box=0; /* flags to signal call from The-Box */ FILE *fd; /* file descriptor for control and areas.bbs */ #ifndef LINN long atol(); #endif strcpy(areasbbs, "areas.bbs"); /* default name */ #ifdef LINN /* set all archiver to nothing, except default archiver to ARC */ /* arc.ttp should be actually whatarc.ttp */ lzh_prg[0] = '\0'; arj_prg[0] = '\0'; zoo_prg[0] = '\0'; zip_prg[0] = '\0'; arc_prg[0] = '\0'; #if STTC strcpy(def_prg,"ARC.TTP"); #endif #if TC strcpy(def_prg,"ARC.EXE"); #endif strcpy (def_cmd, "X"); #else #if STTC strcpy(arc_prg,"ARC.TTP"); #endif #if TC strcpy(arc_prg,"ARC.EXE"); #endif strcpy(arc_cmd,"X"); #endif strcpy(areasbbs, "areas.bbs"); /* default name */ pwd= (struct _passw *) myalloc(sizeof(struct _passw)); pwd->zone=pwd->net=pwd->node=pwd->point=0; pwd->next=NULL; if (init_conf()) exit(2); /* first parse config file */ use_path=use_origin=use_readdress=1; use_kludge=0; for (i=1;i2 && msgareas != badarea) { ToZone[msgareas]= (unsigned *) myalloc(sizeof(unsigned) * i); ToNet[msgareas]= (unsigned *) myalloc(sizeof(unsigned) * i); ToNode[msgareas]= (unsigned *) myalloc(sizeof(unsigned) * i); ToPoint[msgareas]= (unsigned *) myalloc(sizeof(unsigned) * i); memmove(ToZone[msgareas],TZone,sizeof(unsigned) * i); memmove(ToNet[msgareas],TNet,sizeof(unsigned) * i); memmove(ToNode[msgareas],TNode,sizeof(unsigned) * i); memmove(ToPoint[msgareas],TPoint,sizeof(unsigned) * i); } if (verbose > 2) { print("%s %s",AreaPath[msgareas],AreaName[msgareas]); if (i>2 && msgareas!=badarea) for(i=0;ToNet[msgareas][i];i++) print(" %u/%u",ToNet[msgareas][i], ToNode[msgareas][i]); print("\n"); } if (AreaOrig[msgareas]==NULL) AreaOrig[msgareas]=ourorigin; ++msgareas; /* next area */ #ifdef LINN if (msgareas==N_AREAS-2) { message(6,"!More than %d areas, areas.bbs read incomplete", N_AREAS); break; } #endif } fclose(fd); } if (mailarea==-1 && netpath) /* if mailarea not defined in AREAS.BBS */ { AreaName[msgareas]=ctl_string("* Network"); AreaPath[msgareas]=ctl_string(netpath); mailarea=msgareas++; /* then use the THE-BOX.CFG one */ } #ifdef LINN for(i=0;i 1) { print("Mail area (%d): %s\n",mailarea,AreaPath[mailarea]); print("Bad area (%d): %s\n",badarea,AreaPath[badarea]); } } #ifdef LINN int extract(archive) char *archive; { FILE *amail; char name[80], buffer2[80]; char *archiver, *comline, *buf; unsigned char c1, c2, c3, c4; int net; sprintf (name, "%s%s", mailpath, archive); amail = fopen(name, "rb"); if (amail == NULL) { return (1); } c1 = fgetc(amail); c2 = fgetc(amail); c3 = fgetc(amail); c4 = fgetc(amail); fclose (amail); archiver = NULL; comline = NULL; if ((c1 == 'P') && (c2 == 'K')) { /* zip mail */ message(2, "+Received zipmail"); archiver = zip_prg; comline = zip_cmd; } if (c1 == 0x1a) { /* arc mail */ message(2, "+Received arcmail"); archiver = arc_prg; comline = arc_cmd; } if ((c3 == '-') && (c4 == 'l')) { /* lzh mail */ message(2, "+Received lzhmail"); archiver = lzh_prg; comline = lzh_cmd; } if ((c1 == 'Z') && (c2 == 'O') && (c3 == 'O')) { /* zoo mail */ message(2, "+Received zoomail"); archiver = zoo_prg; comline = zoo_cmd; } if ((c1 == 0x60) && (c2 == 0xea)) { /* arj mail */ message(2, "+Received arjmail"); archiver = arj_prg; comline = arj_cmd; } if ((archiver == NULL) || (*archiver == '\0')) { /* unknown archive type or uninitialized xxx_prg */ message(2, "+Received compressed mail"); archiver = def_prg; comline = def_prg; } /* set up the command line for archiver */ buf=buffer2+1; /* copy to buffer2 the command line */ while (*comline != '\0') { if (*comline != '%') *buf++ = *comline++; else { switch (*++comline) { case 'd' : /* %d = directory */ strcpy (buf, mailpath); buf = &buf[strlen(buf)]; break; case 'n' : /* %n = archive name */ strcpy (buf, mailpath); strcat (buf, archive); buf = &buf[strlen(buf)]; break; case '%' : *buf++ = *comline; break; case ':' : *buf++ = ';'; break; } if (*comline != '\0') comline++; } } *buf='\0'; *buffer2=strlen((buffer2+1)); if (verbose > 2) print(" Exec: <%s> <%s>\n", archiver, buffer2); /* and execute it... */ net=execute(archiver, buffer2); if (verbose > 2) print("Arc terminated with errorlevel %d\n",net); return (net); } #endif int process_arc() { char buffer1[80], buffer2[140]; char *found; char *ffirst(), *fnext(); int net, node; sprint(buffer1, "%s*.*", mailpath); found= ffirst(buffer1); if (!found) return 0; do { if ( is_arcmail(found,(int)strlen(found)-1) ) { /* Found an arcmail packet right now! */ sscanf( found, "%04x%04x", &net, &node); #ifdef LINN net=extract(found); #else message(3,"+Received arcmail"); /* set up the command line for archiver */ sprint((buffer2+1), "%s %s%s %s*.*", arc_cmd, mailpath, found, mailpath); *buffer2=strlen((buffer2+1)); if (verbose > 2) print(" Exec: <%s> <%s>\n", arc_prg, buffer2); /* and execute it... */ net=execute(arc_prg, buffer2); if (verbose > 2) print("Arc terminated with errorlevel %d\n",net); #endif if (!net) { sprint(buffer1, "%s%s", mailpath, found); if (akeep) { sprint(buffer2, "%s%11.11s%c", mailpath, found, *(found+11) + 'A'); if (rename(buffer1,buffer2)) { message(6,"!Can not rename %s to %s",buffer1, buffer2); exit(2); } } else { if (unlink(buffer1)) { message(6,"!Can not delete %s.",buffer1); exit(2); } } return 1; } else { #ifdef LINN message(6,"!Fatal: Archiver error %d", net); sprint(buffer1,"%s%s",mailpath,found); sprint(buffer2, "%s%11.11s%c", mailpath, found, found[11] + 'A' - '0'); message(6,"!Packet renamed to %11.11s%c", found, *(found+11) + 'A' - '0'); if (rename(buffer1,buffer2)) { message(6,"!Can not rename %s to %s",buffer1, buffer2); exit(2); } #else message(6,"!Fatal: ARChiver error"); #endif return 0; /* Archiver went wrong, abort else end-less loop */ } } found=fnext(); } while (found); return 0; } void mv_pkt() /* rename packet .pkt -> .bkt */ { char tmppkt[80]; if (pkt!=NULL) { fclose(pkt); pkt=NULL; } strcpy(tmppkt,packet); strcpy(&tmppkt[strlen(packet)-3],"BKT"); if (rename(packet,tmppkt)) { message(6,"!Cannot rename %s to %s",packet,tmppkt); exit(2); } else message(6,"!Bad packet (%s > %s)",packet,tmppkt); *packet= '\0'; } int open_pack() /* open mailpacket */ { char *p; /* workhorse.. */ char *ffirst(); /* find file with name */ char temp[80]; /* temp. storage */ #ifdef LINN char type[10]; /* string for packet type */ #endif if (ask) /* should ask for packet-name? */ { print("Packet name: "); scanf("%79s",packet); if (!*packet) return 0; } else { sprint( temp, "%s*.PKT", mailpath); p=ffirst(temp); /* get the first packet */ if (!p || !*p) return 0; /* no packet found */ sprint( packet, "%s%s", mailpath, p); message(2,"+Import %s",packet); } if ((pkt=fopen(packet, BREAD))==NULL) { message(6,"-Fatal: Can't open packet."); exit(1); /* sysop gave wrong name, or it's a system error.. */ } if (fread((char *)&phdr, sizeof(struct _pkthdr), 1, pkt)!=1) { message(6,"-Empty or too small, not a packet!"); mv_pkt(); return open_pack(); } if (phdr.ph_ver!=inteli(0x2)) /* check packet type */ { message(6,"-Not a packet or wrong version"); mv_pkt(); return open_pack(); } #ifdef LINN /* Modification to accept incoming 4D packets */ if(phdr.ph_rate==inteli(0x2)) { /* fsc-0045, type 2.2 */ fromzone= inteli(phdr.ph_ozone); fromnet= inteli(phdr.ph_onet); fromnode= inteli(phdr.ph_onode); frompoint= inteli(phdr.ph_dy); strcpy(type,"2.2"); } else { int cw,cwcheck; /* cap word */ cw=inteli(phdr.ph_rsvd[3]); cwcheck=inteli(phdr.ph_rsvd[1]); /* invert cw validation copy, byte order indep */ cwcheck=((cwcheck << 8) & 0xFF00) | ((cwcheck >> 8) & 0x00FF); if((cw==cwcheck) && (cw & 0x0001)) { /* fsc-0039 & fsc-0048 */ fromzone= inteli(phdr.ph_ozone); fromnet= inteli(phdr.ph_onet); fromnode= inteli(phdr.ph_onode); frompoint= inteli(phdr.ph_rsvd[6]); /* fsc-0048 */ if((fromnet==0xFFFF) && (frompoint!=0)) fromnet= inteli(phdr.ph_rsvd[0]); strcpy(type,"2+"); } else { /* fsc-0001 */ fromzone= inteli(phdr.ph_ozone); fromnet= inteli(phdr.ph_onet); fromnode= inteli(phdr.ph_onode); frompoint= 0; strcpy(type,"2"); } } if (fromzone==0) fromzone=alias[0].zone; /* default zone number to alias[0] rather than zone of latest packet */ #else fromzone= inteli(phdr.ph_ozone); fromnet= inteli(phdr.ph_onet); fromnode= inteli(phdr.ph_onode); frompoint= 0; #endif get_passw(fromzone, fromnet, fromnode, frompoint); if (secure>1 && strncmp(ourpwd,phdr.ph_pwd,6)) { message(6,"-PASSWORD ERROR"); mv_pkt(); return open_pack(); } #ifdef LINN message(2,"+Packet type %s from %u:%u/%u.%u",type, fromzone,fromnet,fromnode,frompoint); #else message(2,"+Packet from %u:%u/%u",inteli(phdr.ph_ozone), inteli(phdr.ph_onet), inteli(phdr.ph_onode)); #endif if (verbose) message(1,"+Assembled: %d-%d-%d %d:%02d:%02d", inteli(phdr.ph_dy), inteli(phdr.ph_mo)+1, inteli(phdr.ph_yr), inteli(phdr.ph_hr), inteli(phdr.ph_mn), inteli(phdr.ph_sc)); #ifndef LINN if (phdr.ph_rate && verbose) message(1,"+Baudrate: %d",inteli(phdr.ph_rate)); #endif return 1; } static int openarea; void open_area(area) /* open a certain message-area */ int area; /* number of area to open */ { char name[80]; /* areaname */ openarea= area; if (area==mailarea) { msg= MMSG; hdr= MHDR; return; } sprint( name, "%s.MSG", AreaPath[area]); if ((msg=fopen(name, BRUP))==NULL) msg=fopen(name, BWUP); sprint( name, "%s.HDR", AreaPath[area]); if ((hdr=fopen(name, BRUP))==NULL) hdr=fopen(name, BWUP); if (!msg || !hdr) /* not open? */ { message(6,"-Error opening file(s) for area: %s",AreaPath[area]); exit(1); } fseek(hdr,0l,2); /* to end of files */ fseek(msg,0l,2); } void close_area() /* close message area */ { if (openarea==mailarea) return; fclose(hdr); fclose(msg); } int read_hdr() /* read header of next message */ { char i,j; /* temp. storage */ while (1) { i=getc(pkt); /* get the first 2 byte of new msg */ j=getc(pkt); if (i==j) { /* this should be the end, but some utils **** up, so better * check it! */ i = getc(pkt); if (feof(pkt) || i == 0x1a) return 0; /* end of package */ /* somehow there's still some data left. Process it! */ ungetc(i,pkt); continue; } if (i!=2 || j!=0) /* check message type */ { /* there we go again, a bad message in this packet, let's resync! */ message(1,"-garbage in '%s' at position %ld",packet,ftell(pkt)); /* resync: */ while (!feof(pkt)) { if ((i=getc(pkt))== 0x02) { /* found possible start of message! Test next byte */ if ((j=getc(pkt)) == 0x00) goto doit; else ungetc(j,pkt); } } /* save packet for closer examination by hand */ mv_pkt(); return 0; } doit: if (fread(((char *)&mhdr)+2, (sizeof(struct _pktmsgs) -2), 1, pkt)!=1) { /* read error? */ message(6,"-Unexpected end of package!"); return 0; } return 1; /* all ok */ } } void conv_hdr() { char temp[200]; /* temp. buffer */ char *p; /* pointer in buffer */ char ch; /* character from packet */ long time(); /* current time */ /* Date routine modified once again. It's still giving LOTS of trouble.. */ /* Drop me a message if you've found a bomb free way to read it! */ ch = -1; for (p=temp; p 3) print("`%02x`",ch); break; default: *ms++=ch; if (verbose > 3) print("%c",ch); } ch=getc(pkt); } *ms++='\n'; *ms++=0; if (feof(pkt) && ch) { message(6,"-Unexpected end of package!"); return -2; } if (ch==2) { message(6,"-Cripled message"); fseek(pkt,-1L,1); } if (ms>=MESSAGE+((30*1024)-10)) { message(2,"-Message too long, will not be echoed anymore"); while (!feof(pkt) && ch) ch=getc(pkt); /* too long, skip rest! */ hhdr.flags |= SENT; /* signal it being sent */ } return -1; } void Iadress(str, zone, net, node) char *str; short *zone, *net, *node; { char *p; int zo, ne, no; for (p=str; *p && isspace(*p); p++) ; if (sscanf(p, "%d:%d/%d", &zo, &ne, &no)!=3) { message(6,"!INTL error in %s.", str); *zone=0; return; } *zone= zo; *node= no; *net= ne; } #define NORMAL 1 #define SKIP 4 int line_type(line) char *line; { char *p, *q; int j; if (*line!=0x01) return NORMAL; if (verbose > 3) print("^A line: %s\n",line+1); /* Parse and remove INTL, FMPT and TOPT */ if (!strnicmp(line+1,"INTL",4)) { /* We've got an international (interzone) adress so parse it */ #ifdef LINN Iadress(line+5,(short *)&hhdr.Dzone,(short *) &hhdr.Dnet,(short *) &hhdr.Dnode); #else Iadress(line+5,(int *)&hhdr.Dzone,(int *) &hhdr.Dnet,(int *) &hhdr.Dnode); #endif p=line+8; while (*p && !isspace(*p)) ++p; #ifdef LINN Iadress(p,(short *) &hhdr.Ozone,(short *) &hhdr.Onet,(short *) &hhdr.Onode); #else Iadress(p,(int *) &hhdr.Ozone,(int *) &hhdr.Onet,(int *) &hhdr.Onode); #endif return SKIP; } if (!strnicmp(line+1,"FMPT",4)) { if (hhdr.Opoint) return NORMAL; for(p=line+5;*p && isspace(*p);++p) ; q = p; j = 0; while (isdigit(*p)) { j *= 10; j += *p-'0'; ++p; } if (j==0) { message(6,"!FMPT error in %s",line+1); return NORMAL; } hhdr.Opoint=j; if (*p=='.') /* more point numbers?? */ { while (*p) *q++=*p++; return NORMAL; } return SKIP; } if (!strnicmp(line+1,"TOPT",4)) { if (verbose > 3) print("TOPT line %s\n",line+1); for(p=line+5;*p && isspace(*p);++p) ; q = p; j = 0; while (isdigit(*p)) { j *= 10; j += *p-'0'; ++p; } if (j==0) { message(6,"!TOPT error in %s",line+1); return NORMAL; } hhdr.Dpoint=j; if (*p=='.') /* more point numbers?? */ { while (*p) *q++=*p++; return NORMAL; } return SKIP; } /* Leave everything we don't know about at the same place in the message */ return NORMAL; } char *next_str (p, lookfor) char *p; char *lookfor; { extern char *strchr(); char *found; if (verbose > 4) print ("Look for '%s'\n", lookfor); found=p; while (1) { found = strchr(found, *lookfor); /* Found anything at all? */ if (found == NULL) { if (verbose > 4) print("End-Of-Message\n"); return NULL; } if (verbose > 4) print ("Match first char in '%20.20s'\n", found); if (strncmp (found, lookfor, strlen(lookfor))) { ++found; if (verbose > 4) print("match FAIL\n"); continue; } else { if (verbose > 4) print("match OK\n"); return found; } } } char *GetArea() { char *p; /* Check for AREA line at start of message */ if (!strncmp(MESSAGE,"AREA:",5)) return MESSAGE; if (!strncmp(MESSAGE,"\01AREA:",6)) return MESSAGE; /* Not at start of message, somewhere else in the message? */ if ( (p=next_str(MESSAGE,"\n\01AREA:"))!=NULL || (p=next_str(MESSAGE,"\nAREA:"))!=NULL ) return p; /* No AREA line found in message */ return NULL; } int read_msg() { char ch; int result; char temp[80]; /* temp. storage */ char *p,*q; /* pointer in MESSAGE buffer */ ms=MESSAGE; /* initiatial state for new message */ if (verbose > 3) print("Message body:\n"); /* Now we're gonna read the entire message */ do { p=ms; result= read_line(); switch (line_type(p)) { case NORMAL: break; case SKIP : ms=p; } } while (!result) ; /* we've got it! is it ECHOmail to us? */ area=mailarea; *ms='\0'; /* Make sure endbody points to the trailing zero */ endbody= ms; while (*endbody=='\0' && endbody>MESSAGE) endbody--; endbody++; if (verbose > 2) print("It is %sto us.\n",ourmessage() ? "" : "not "); if ( (p=GetArea())!=NULL ) { /* Gee, an echomail message! */ hhdr.Dpoint = 0; /* Clear point fields */ hhdr.Opoint = 0; if (ourmessage()) /* only toss our messages */ { q= p; while (!(isspace(*p) || *p==':')) ++p; /* skip to 'spaces' */ while ((isspace(*p) || *p==':')) ++p; /* skip 'spaces' */ ch=0; while (*p && !isspace(*p)) { temp[ch++]=*p++; } temp[ch]=0; if (verbose > 2) print("Its echomail, the area is >%s<\n",temp); for (area=0; area=msgareas) /* unknown? */ { area=badarea; } else { gotit: while (*p=='\n') p++; memmove(q,p,strlen(p)+1); /* get rid of useless line */ /* ^ Don't forget trailing zero!! */ endbody = endbody - (p-q); sprintf(ThisArea,"%sAREA:%s\n", use_kludge ? "\01":"", AreaName[area]); } } } mend= endbody; return (result==-1); /* if result<>-1 serious trouble */ } void GetThem(msg, str, szones, snets, snodes, spoints, tseen) char *msg; char *str; unsigned szones[]; unsigned snets[]; unsigned snodes[]; unsigned spoints[]; int *tseen; { unsigned j, last_net; char *p,*q,*r; #ifdef LINN int i; #endif last_net = 65535U; r=msg; while ((p=next_str(r,str))!=NULL) { q=p; /* get begin of this line */ while (q > MESSAGE && *q!='\n') --q; r=q; if (*p=='\n') ++p; while (*p && *p!='\n') /* not the end of the line */ { /* found a net/node pair? */ if (isdigit(*p)) { /* get the number. */ getint(&p, &j); /* Is it a net/node pair? */ if (*p == ':') { #ifdef LINN /* simply strip the zone number, because there are some problems parsing them and I'm not sure other parts of import would works ok if the parsing was correctly done. VP */ p++; getint (&p, &j); } #else if (getaddress(p+1, &szones[*tseen], &snets[*tseen], &snodes[*tseen], &spoints[*tseen])!=6) { message(6,"!Illegal address %s",p); *tseen--; /* because it's incremented below */ } while (*p && !isspace(*p)) p++; szones[*tseen]=j; } else { #endif szones[*tseen]=ourzone; spoints[*tseen]=0; if (*p == '/') { ++p; last_net = snets[*tseen] = j; getint(&p, &snodes[*tseen]); } else { snets[*tseen] = last_net; snodes[*tseen] = j; } if (last_net==ourpointnet) { spoints[*tseen]=snodes[*tseen]; #ifdef LINN /* pointnet/point -> net/node.point expansion converts to primary address instead of 1st feed alias's pointnet */ for (i=0; i < nalias; i++) { if (alias[i].pointnet==ourpointnet) { snets[*tseen]=alias[i].net; snodes[*tseen]=alias[i].node; break; } } #else snets[*tseen]=ournet; snodes[*tseen]=ournode; #endif } #ifndef LINN } #endif if (verbose > 4) print ("Got %d:%d/%d.%d\n", szones[*tseen],snets[*tseen], snodes[*tseen],spoints[*tseen]); if (*tseen<940) { ++*tseen; } } else { ++p; } } /* end while for this line */ while (*p) { *q++=*p++; /* copy rest of the message to delete line */ } *q=0; mend=q; } /* end while for lines.. */ } /* I've seen better sort algoritmes, so do you undoubtely, but this one works * alright and for these small numbers it doesn't matter. * (Routine taken from a nice book on algorithems by L. Ammeraal as far * as I recall, it's a long time ago I even looked at this code...) */ void SortThem(zones,nets,nodes,points,nr,chpoints) unsigned zones[], nets[], nodes[], points[]; int *nr, chpoints; { register int i, i1, left=0, right=(*nr)-1, temp=0; unsigned ne1,ne2,no1,no2,p1,p2; if (verbose > 5) print("start sorting now....\n"); /* sort them all (not recursive sort to prevent stack problems) */ do { for (i=left; i zones[i1]) || ((zones[i] == zones[i1]) && ((ne1 > ne2) || ((ne1==ne2) && ((no1>no2) || ((no1==no2) && (p1>p2) )))))) { temp=zones[i]; zones[i]=zones[i1]; zones[i1]=temp; temp=nets[i]; nets[i]=nets[i1]; nets[i1]=temp; temp=nodes[i]; nodes[i]=nodes[i1]; nodes[i1]=temp; temp=points[i]; points[i]=points[i1]; points[i1]= temp; temp=i; } } right=temp; /* Still with me? No?!? I'm not sure I do understand it myself * anymore (and the original routine was so simple). */ for(i=right; i>left; i--) { i1=i-1; if (chpoints && points[i]) { ne1=ourpointnet; no1=points[i]; p1=0; } else { ne1=nets[i]; no1=nodes[i]; p1=points[i]; } if (chpoints && points[i1]) { ne2=ourpointnet; no2=points[i1]; p2=0; } else { ne2=nets[i1]; no2=nodes[i1]; p2=points[i1]; } if ((zones[i1] > zones[i]) || ((zones[i1] == zones[i]) && ((ne2 > ne1) || ((ne2==ne1) && ((no2>no1) || ((no2==no1) && (p2>p1) )))))) { temp=zones[i]; zones[i]=zones[i1]; zones[i1]=temp; temp=nets[i]; nets[i]=nets[i1]; nets[i1]=temp; temp=nodes[i]; nodes[i]=nodes[i1]; nodes[i1]=temp; temp=points[i]; points[i]=points[i1]; points[i1]= temp; temp=i; } } left=temp; if (verbose > 5) print("Left: %d Right: %d\n",left,right); } while (left 5) print("Sorted.\n"); /* get rid of duplicates now */ temp=*nr; for(i1=i=1; i 5) print("Original: %d Now: %d\n", i,i1); } /* CheckSeen checks your seen-bys to find any missing nodes you're * supposed to feed this echo to. */ void CheckSeen() { int i, fo, found, k, what; fo= found= 0; i= 1; while (ToZone[area][i] || ToNet[area][i]) { if (verbose > 2) print("Check for send to %u:%u/%u.%u\n",ToZone[area][i],ToNet[area][i], ToNode[area][i],ToPoint[area][i]); for (k=found; k < nSeen; k++) { if (SeenNet[k]==ToNet[area][i] && SeenNode[k]==ToNode[area][i] && SeenPoint[k]==ToPoint[area][i]) { SendTo[i]=0; if (SeenZone[k]==ToZone[area][i]) found=k; break; } } if (k==nSeen) { SendTo[i]=1; fo=1; } ++i; } if (!fo) return; if (verbose > 2) print("Should send message to:"); i=0; while (++i, ToNet[area][i]||ToNode[area][i]) { if (!SendTo[i]) continue; if (verbose > 2) print("%u:%u/%u.%u ",ToZone[area][i],ToNet[area][i], ToNode[area][i],ToPoint[area][i]); SeenZone[nSeen]=ToZone[area][i]; SeenNet[nSeen]=ToNet[area][i]; SeenNode[nSeen]=ToNode[area][i]; SeenPoint[nSeen++]=ToPoint[area][i]; } if (verbose > 2) print("\nSort now.."); SortThem(SeenZone,SeenNet,SeenNode,SeenPoint,&nSeen,1); if (verbose > 2) print("\nCreating message to "); i=0; while (++i, ToNet[area][i]||ToNode[area][i]) { if (!SendTo[i]) continue; if (verbose > 2) print("%u:%u/%u.%u ",ToZone[area][i],ToNet[area][i], ToNode[area][i],ToPoint[area][i]); what= ((ToPoint[area][i]) ? POINTS : 0) | (use_tiny ? LOCALS:OTHERS); writemessage(use_packet ? SCANFILE : OUTBOUND,what, ToZone[area][i],ToNet[area][i],ToNode[area][i],ToPoint[area][i]); } if (verbose > 2) print("\n"); } void PurgeBlanks() /* delete trailing blanks */ { char *p; /* point p at end of message */ p=mend; /* if it's the trailing '\0' then skip it. */ while (p>MESSAGE && *p==0) --p; /* back till begin of message or any non blank */ while (p>MESSAGE && isspace(*p)) --p; /* p points to valid char now (non blank) so increment by one */ *(++p)='\0'; mend=p; } int CheckEcho() { int i; /* first check if msg valid for sending. */ if (hhdr.flags & SENT || hhdr.flags & FILEATCH) return 1; if (next_str(MESSAGE,"\nNOECHO") || next_str(MESSAGE,"\nnoecho")) return 1; /* Get the seen-bys (deletes the lines..) */ nSeen=0; GetThem(MESSAGE, "\n\01SEEN-BY:", SeenZone, SeenNet, SeenNode, SeenPoint, &nSeen); GetThem(MESSAGE, "\nSEEN-BY:", SeenZone, SeenNet, SeenNode, SeenPoint, &nSeen); /* Check the number of seen-bys. If zero it's a bad message */ if (nSeen == 0) { message(6,"-echomail missing seen-by lines --> badmsgs (%d)", #ifdef LINN nmsgs[badarea]+1); #else nmsgs[badarea]); #endif hhdr.mailer[7] |= MSGSCANNED; area = badarea; return 1; } /* Add our primary address */ SeenZone[nSeen]=ourzone; SeenNet[nSeen]=ournet; SeenNode[nSeen]=ournode; SeenPoint[nSeen++]=ourpoint; /* add our own numbers (AKAs etc.) */ for (i=0;i 2) { print("Message SEEN-BY:"); for (i=0;i 2) { print("Message PATH:"); for (i=0;i badmsgs"); hhdr.mailer[7] |= MSGSCANNED; area = badarea; return 1; } #endif endbody=mend; /* message body ends HERE */ /* Now check for nodes to send the message to (and send those msgs) */ CheckSeen(); /* Flag message as scanned */ hhdr.mailer[7] |= MSGSCANNED; return 1; } void add(p) char *p; { while (*p) { *mend++=*p++; x++; } } void AddThem(addstr,zones,nets,nodes,points,nr,dopoints,dozones) char *addstr; unsigned zones[], nets[], nodes[], points[]; int nr, dopoints, dozones; { unsigned lastnet, len, tnet, tnode; int i; char str[20]; x=100; #ifdef LINN lastnet=(unsigned) -1; #else lastnet=-1; #endif for(i=0; i 3) print("%u/%u.%u -> ",nets[i],nodes[i],points[i]); if (points[i]) { tnet=ourpointnet; tnode=points[i]; } else { tnet=nets[i]; tnode=nodes[i]; } if (!dopoints && points[i] && !(points[i]==ourpoint && nodes[i]==ournode && nets[i]==ournet)) continue; if (lastnet==tnet) sprintf(str," %u",tnode); len=(int)strlen(str); if (lastnet!=tnet || (len+x > 76)) sprintf(str," %u/%u",tnet,tnode); } len=(int)strlen(str); if (len+x >76) { x=0; add(addstr); } if (verbose > 3) print("%s\n",str); add(str); lastnet=tnet; } *mend=0; } /* AddSeen adds seen-by lines to a message */ void AddSeen(what) int what; { char sline[20]; int i; sprintf(sline, "\n%sSEEN-BY:", use_kludge ? "\01" : ""); if (what&LOCALS) { for (i=1; ToNet[area][i]|ToNode[area][i]; ++i); AddThem(sline,&ToZone[area][1],&ToNet[area][1], &ToNode[area][1],&ToPoint[area][1],i-1, (what&POINTS),(what&DIFFZONE)); } else AddThem(sline,SeenZone,SeenNet,SeenNode,SeenPoint, nSeen, (what&POINTS), (what&DIFFZONE)); } void AddPath(add) int add; { int th=1; if (PathZone[nPath-1]==ourzone && PathNet[nPath-1]==ournet && PathNode[nPath-1]==ournode && PathPoint[nPath-1]==ourpoint) --th; PathZone[nPath]=ourzone; PathNet[nPath]=ournet; PathNode[nPath]=ournode; PathPoint[nPath]=ourpoint; /* Only add all path nodes when in own zone */ if (!add) AddThem("\n\01PATH:",PathZone,PathNet,PathNode, PathPoint,nPath+th,-1,0); else AddThem("\n\01PATH:",&ourzone,&ournet,&ournode,&ourpoint,1,-1,0); } void OpenPacket(nr,zone,net,node,point) int nr; unsigned zone, net, node, point; { struct time t; struct date d; struct _pkthdr phdr; char fname[80]; int i; int tzone, tnet, tnode, tpoint; tzone= ourzone; tnet= ournet; tnode= ournode; tpoint= ourpoint; if (verbose > 1) print("Open packet %u:%u/%u.%u\n",zone,net,node,point); /* Get password first before all information is destroyed */ get_passw(zone,net,node,point); getalias(zone,net,node,point); /* save the 4-D address first */ pktzone[nr]= zone; pktnet[nr]= net; pktnode[nr]= node; pktpoint[nr]= point; if (point) { for (i=0; i 1) print("Close packet\n"); if (pktfile[nr]) { pktzone[nr]= pktnet[nr]= pktnode[nr]= pktpoint[nr]= 0; if (fwrite("\0\0", 2, 1, pktfile[nr])!=1) { message(6,"!Error writing to package"); exit(1); } fclose(pktfile[nr]); pktfile[nr]= NULL; } } void MakeHdr(nr,Mhdr) int nr; struct Hdr *Mhdr; { struct _pktmsgs mh; if (verbose > 1) print("MakeHdr\n"); mh.pm_ver=inteli(2); mh.pm_onode=inteli(Mhdr->Onode); mh.pm_onet=inteli(Mhdr->Onet); mh.pm_dnode=inteli(Mhdr->Dnode); mh.pm_dnet=inteli(Mhdr->Dnet); mh.pm_attr=inteli(Mhdr->flags&0x3413); mh.pm_cost=inteli(Mhdr->cost); fwrite((char *)&mh, sizeof(struct _pktmsgs), 1, pktfile[nr]); fprintf(pktfile[nr],"%19s",Mhdr->time); putc('\0',pktfile[nr]); fprintf(pktfile[nr],"%s",Mhdr->to); /* from & to */ putc('\0',pktfile[nr]); fprintf(pktfile[nr],"%s",Mhdr->from); putc('\0',pktfile[nr]); fprintf(pktfile[nr],"%s",Mhdr->topic); /* topic */ putc('\0',pktfile[nr]); #ifdef LINN if (no_intl) #endif if (Mhdr->Ozone && Mhdr->Dzone && (Mhdr->Ozone!=Mhdr->Dzone)) fprintf(pktfile[nr],"\01INTL %d:%d/%d %d:%d/%d\r\n", Mhdr->Dzone, Mhdr->Dnet, Mhdr->Dnode, Mhdr->Ozone, Mhdr->Onet, Mhdr->Onode); } void PktWrite(nr, str, len) int nr; char *str; int len; { if (verbose > 1) print("PktWrite\n"); while (len--) { if (*str=='\n') putc('\r',pktfile[nr]); else putc(*str,pktfile[nr]); str++; if (ferror(pktfile[nr])) { exit(1); } } if (ferror(pktfile[nr])) { message(6,"!Error writing to packet-file"); exit(1); } } void writemessage(where,what,zone,net,node,point) int where; int what; unsigned zone,net,node,point; { int i; static int j= -1; char sline[20]; int empty= -1; memmove((char *) &Mhdr, (char *) &hhdr, sizeof(struct Hdr)); #ifdef LINN getalias (zone, net, node, point); #endif mend=endbody; if (what) { if (zone!=ourzone) { unsigned z[3],ne[3],no[3],p[3]; int i; i=2; z[0]=ourzone; z[1]=ourzone; ne[0]=ournet; ne[1]=net; no[0]=ournode; no[1]=node; p[0]=ourpoint; p[1]=0; SortThem(z,ne,no,p,&i,1); sprintf(sline, "\n%sSEEN-BY:", use_kludge ? "\01" : ""); AddThem(sline,z,ne,no,p,2,1,0); } else AddSeen(what); if (use_path) AddPath(zone!=ourzone); if (use_readdress) { Mhdr.Ozone = ourzone; Mhdr.Onet = ournet; Mhdr.Onode = ournode; Mhdr.Opoint= ourpoint; if (ourpoint) { Mhdr.Onet= ourpointnet; Mhdr.Onode= ourpoint; Mhdr.Opoint=0; } } } switch (where) { case OUTBOUND: Mhdr.Mstart= ftell(MMSG); echomsgs++; #ifdef LINN emsgs[area]++; #endif if (what) { if (fwrite(ThisArea, strlen(ThisArea),1, MMSG)!=1) { message(6,"!Fatal error writing to mail"); exit(1); } Mhdr.size=(int)strlen(ThisArea); } else Mhdr.size=0; *mend++='\n'; *mend='\0'; Mhdr.size += (int)(mend-MESSAGE)+2; Mhdr.Dzone = zone; Mhdr.Dnet = net; Mhdr.Dnode = node; Mhdr.Dpoint= point; Mhdr.flags |= (MSGLOCAL|KILLSEND); Mhdr.parent = 0; for (i=0; i<8; i++) Mhdr.mailer[i]=0; Mhdr.cost=0; if (fwrite(MESSAGE, ((mend-MESSAGE)+2), 1, MMSG)!=1) { message(6,"!Fatal error writing to mail"); exit(1); } if (fwrite((char *) &Mhdr, sizeof(struct Hdr), 1, MHDR)!=1) { message(6,"!Fatal error writing to mail"); exit(1); } break; case SCANFILE: echomsgs++; #ifdef LINN emsgs[area]++; #endif for (i=0; i<10; i++) { if (pktfile[i]==NULL) empty= i; if (zone==pktzone[i] && net==pktnet[i] && node==pktnode[i] && point==pktpoint[i]) break; } if (i>=10) { if (empty != -1) { OpenPacket(empty,zone,net,node,point); i= empty; } else { j= (j+1) < 10 ? j+1 : 1; ClosePacket(j); OpenPacket(j,zone,net,node,point); i= j; } } *mend++='\n'; *mend='\0'; if (point) { net = pktfake[i]; node = pktpoint[i]; point = 0; } Mhdr.Dzone = zone; Mhdr.Dnet = net; Mhdr.Dnode = node; Mhdr.Dpoint= point; Mhdr.flags |= (MSGLOCAL); Mhdr.cost=0; MakeHdr(i,&Mhdr); if (what) { PktWrite(i, ThisArea, (int)strlen(ThisArea)); } PktWrite(i, MESSAGE, ((int)(mend-MESSAGE)+1)); break; case LOCAL: default: message(6,"?Internal error %02x in messagewrite",where); } } /* Save message to local messagebase */ void savemessage(where,what) int where; int what; { mend=endbody; #ifdef LINN /* do not save empty messages... usefull ??? */ if (mend==MESSAGE) return; #endif if (what) { AddSeen(what); if (use_path) AddPath(0); } #ifdef LINN /* does not count messages to sysop in echomail */ if ((!what && (!strnicmp(hhdr.to,"sysop",5))) || !strnicmp(hhdr.to,sysop,strlen(sysop))) #else if (!strnicmp(hhdr.to,"sysop",5) || !strnicmp(hhdr.to,sysop,strlen(sysop))) #endif smsgs[area]++; if (verbose) { clprint(": %s ",hhdr.from); if (area==mailarea) clprint("(%d:%d/%d.%d) ",hhdr.Ozone,hhdr.Onet,hhdr.Onode,hhdr.Opoint); clprint("> %s ", hhdr.to); if (area==mailarea) clprint("(%d:%d/%d.%d) ",hhdr.Dzone,hhdr.Dnet,hhdr.Dnode,hhdr.Dpoint); #ifdef LINN clprint(", %s (msg %d)\n",AreaName[area],nmsgs[area]+1); #else clprint(", %s (msg %d)\n",AreaName[area],nmsgs[area]); #endif } nmsgs[area]++; #ifdef LINN /* passthrough area */ if (!stricmp("PASSTHRU", AreaPath[area])) return; #endif if (area!=lastarea) /* same area? */ { if (lastarea!=-1) close_area(); open_area(area); lastarea=area; } switch (where) { case LOCAL: hhdr.Mstart= ftell(msg); hhdr.size = (int) (mend-MESSAGE)+1; if (fwrite(MESSAGE, hhdr.size, 1, msg)!=1) { message(6,"!Fatal error writing message"); exit(1); } if (fwrite((char *) &hhdr, sizeof(struct Hdr), 1, hdr)!=1) { message(6,"!Fatal error writing header"); exit(1); } break; default: message(6,"?Internal error %02x",where); } } void display_results() { int i; /* yep, counter again... */ int flag=0; /* displayed something?? */ for (i=0;i