home *** CD-ROM | disk | FTP | other *** search
- /* MakeArc copyright (c) 1990 by M. Kimes -- All Rights Reserved */
- /* Version 3.02 You can use this freely. Check with me before */
- /* releasing modified executables or source, please (I'll probably */
- /* allow it). Exceptions: Strict translation to foreign languages */
- /* and ports to other platforms (non-MS/DOS. */
- /* Corrections, bug reports, etc. welcome. Flames ignored by a */
- /* master. Meaningless "bugs" handled via DUFUS verb. */
-
-
- #include <time.h>
- #include <dos.h>
- #include <stdio.h>
- #include <conio.h>
- #include <stdlib.h>
- #include <io.h>
- #include <fcntl.h>
- #include <ctype.h>
- #include <process.h>
- #include <string.h>
-
- typedef unsigned int _word;
-
- /* Message header */
-
- struct _msg {
- char from[36];
- char to[36];
- char subj[72];
- char date[20];
- _word times;
- _word dest;
- _word orig;
- _word cost;
- _word orig_net;
- _word dest_net;
- int msg_filler[4];
- _word reply;
- _word attr;
- _word up;
- };
-
- /* Message attributes */
-
- #define MSGPRIVATE 0x0001
- #define MSGCRASH 0x0002
- #define MSGREAD 0x0004
- #define MSGSENT 0x0008
- #define MSGFILE 0x0010
- #define MSGFWD 0x0020
- #define MSGORPHAN 0x0040
- #define MSGKILL 0x0080
- #define MSGLOCAL 0x0100
- #define MSGXX1 0x0200
- #define MSGXX2 0x0400
- #define MSGFRQ 0x0800
- #define MSGRRQ 0x1000
- #define MSGCPT 0x2000
- #define MSGARQ 0x4000
- #define MSGURQ 0x8000
-
- /* Packet header structure per FSC-0045 */
-
- struct _pkthdr {
- unsigned int
- onode,
- dnode,
- opoint,
- dpoint;
- char
- zeros[8];
- unsigned int
- subver,
- version,
- onet,
- dnet;
- char
- product,
- rev_lev,
- password[8];
- unsigned int
- ozone,
- dzone;
- char
- odomain[8],
- ddomain[8];
- long
- specific;
- unsigned int
- first;
- };
-
- typedef struct _pkthdr PKTHDR;
-
- /* Global flags and variables */
-
- extern unsigned char msgattach; /* Make *.MSG attaches? */
- extern _word myzone; /* For our address */
- extern _word mynet; /* " */
- extern _word mynode; /* " */
- extern _word mypoint; /* " */
- extern char configfile[133]; /* Config file to read */
- extern char root[128]; /* 'Root' outbound dir */
- extern char outbound[133]; /* Extended outbound dir */
- extern char netdir[128]; /* Net msg directory if *.MSG attaches */
- extern char arccmd[128]; /* Default archive command */
- extern unsigned char alltype; /* Default mail type */
- extern unsigned char didbreak; /* CTRL-BREAK flag */
- extern char schedtag[128]; /* Schedule tag */
- extern _word lines; /* For debug info */
- extern unsigned char debug; /* debug on? */
- extern unsigned char more; /* more on? */
- extern unsigned char usingbink; /* Use BINKLEY.CFG? */
- extern _word rzone; /* For routing */
- extern _word rnet; /* " */
- extern _word rnode; /* " */
- extern _word rpoint; /* " */
-
- /* Function definitions */
-
- char _fastcall spawnit (char *a);
- char _fastcall check_4flo (_word zone,_word net,_word node,_word point);
- char * _fastcall stristr (char *t, char *s);
- void _cdecl deinit(void);
- void _fastcall say_error (long lastpos,FILE *fp);
- int _fastcall makearc (char *arcfile,char *pktfile,char *origpkt,char *outbound);
- _word _fastcall makeflo(_word zone,_word net,_word node,_word point,char *sendfile,char type);
- _word _fastcall makemessage (_word zone,_word net,_word node,_word point,char *sendfile,char type);
- void _fastcall next_name(char *);
- void _fastcall make_poll (char *line,long lastpos,FILE *fp);
- FILE * _fastcall analyze(char *);
- char * _fastcall arcname(_word,_word);
- char * _fastcall filename(_word,_word);
- char * _fastcall fidodate(void);
- char * _fastcall lstrip(char *);
- char * _fastcall rstrip(char *);
- char * _fastcall stripcr(char *);
- void _fastcall moveit (struct find_t *f, char *myoutbound, char *outbound, char type, char archive,_word net,_word node,_word fromzone);
- void _fastcall move_prep(char *line,long lastpos,FILE *fp);
- void _fastcall change_mail(char *line,long lastpos,FILE *fp);
- long _fastcall make_msgid(void);
- char * _fastcall find_sched(FILE *fp,char *schedtag,int wholefile);
- char * _fastcall skip_white(char *);
- char * _fastcall skip_nonwhite(char *);
- char * _fastcall to_delim(char *,char *);
-
- /* ID stuff */
-
- #define MAKEVER "302"
-
- #define PID_ID "MA 302"
-
- #define BETA
-
-
-
- void _fastcall move_prep (char *line,long lastpos,FILE *fp) {
-
- char flo[133]; /* Used to find (& destroy) flo files */
- char arc[133]; /* Used to find arc files */
- char pkt[133]; /* Used to find packets */
- unsigned int zone,net,node; /* Address to move to */
- unsigned int fromzone; /* Zone to move mail from */
- char outbound[84]; /* His calculated outbound name */
- struct find_t f; /* The better to find them with, my dearie */
- char *p; /* Used to parse address */
- char type; /* Type of mail ([H]old, [C]rash, etc.) */
-
- lstrip(line);
- stripcr(line);
- rstrip(line);
- p=strtok(line," ");
- if(!p) return;
- fromzone=(_word)atol(p);
- if(!fromzone) return;
- p=strtok(0,":");
- if(!p) return;
- zone=(_word)atol(p);
- if(zone==fromzone) return; /* Duh... */
- if(!zone) return;
- p=strtok(0,"/");
- if(!p) return;
- net=(_word)atol(p);
- if(!net) return;
- p=strtok(0," ");
- if(!p) return;
- node=(_word)atol(p);
- p=strtok(0,";\n");
- type=toupper(*p);
- if(type!='H' && type!='C' && type!='F' && type!='D' && type!='N' && type!='O') return;
-
- /* Make mask for outbound flo, packet and arc files */
-
- if(fromzone!=myzone) {
- sprintf(pkt,"%s.%03x\\%04x%04x.?UT",root,fromzone,net,node);
- sprintf(arc,"%s.%03x\\%04x%04x.*",root,fromzone,mynet-net,mynode-node);
- sprintf(flo,"%s.%03x\\%04x%04x.?LO",root,fromzone,net,node);
- }
- else {
- sprintf(pkt,"%s\\%04x%04x.?UT",root,net,node);
- sprintf(arc,"%s\\%04x%04x.*",root,mynet-net,mynode-node);
- sprintf(flo,"%s\\%04x%04x.?LO",root,net,node);
- }
- if(zone!=myzone) sprintf(outbound,"%s.%03x",root,zone);
- else strcpy(outbound,root);
-
- if(!_dos_findfirst(flo,0,&f)) {
- printf("Removing FLO files addressed to %u:%u/%u\n",fromzone,net,node);
- do {
- if(fromzone==myzone) sprintf(flo,"%s\\%s",root,f.name);
- else sprintf(flo,"%s.%03x\\%s",root,fromzone,f.name);
- unlink(flo);
- } while(!_dos_findnext(&f));
- }
- if(!_dos_findfirst(pkt,0,&f)) {
- if(fromzone==myzone) {
- moveit(&f,root,outbound,type,0,net,node,fromzone);
- }
- else {
- sprintf(flo,"%s.%03x",root,fromzone);
- moveit(&f,flo,outbound,type,0,net,node,fromzone);
- }
- }
- if(!_dos_findfirst(arc,0,&f)) {
- if(fromzone==myzone)moveit(&f,root,outbound,type,1,net,node,fromzone);
- else {
- sprintf(flo,"%s.%03x",root,fromzone);
- moveit(&f,flo,outbound,type,0,net,node,fromzone);
- }
- }
- return;
- }
-
-
-
-
- void _fastcall moveit (struct find_t *f, char *myoutbound, char *outbound, char type, char archive,_word net,_word node,_word fromzone) {
-
- FILE *fp=NULL;
- FILE *fp2;
- char once=0;
- long temp=0L;
-
- char wasname[133];
- char isname[133];
- char scratch[290];
-
- if(archive) { /* If archive, open flo file for append */
- sprintf(wasname,"%s\\%04x%04x.%cLO",outbound,net,node,type);
- fp=fopen(wasname,"at");
- if(fp)fseek(fp,0L,SEEK_END);
- }
-
- do {
- if(!f->size) continue;
- if(!once){
- if(archive)printf("Moving archived mail addressed to %u:%u/%u\n",fromzone,net,node);
- else printf("Moving packets addressed to %u:%u/%u\n",fromzone,net,node);
- }
- once=1;
- sprintf(wasname,"%s\\%s",myoutbound,f->name);
- sprintf(isname,"%s\\%s",outbound,f->name);
- if(!archive) isname[strlen(isname)-3]=type; /* Set mail type */
- sprintf(scratch,"COPY %s %s > NUL",wasname,isname);
- system(scratch);
- unlink(wasname);
- if(archive) { /* Only for archives */
- fp2=fopen(wasname,"wb");
- if(fp2)fclose(fp2); /* Leave truncated filename */
- if(fp) fprintf(fp,"^%s\n",isname); /* Add name to the flo file */
- }
- } while(!_dos_findnext(f)); /* Til there ain't no more */
-
- if(fp) {
- fseek(fp,0L,SEEK_END);
- if(ftell(fp)==0L) {
- fclose(fp);
- sprintf(wasname,"%s\\%04x%04x.%cLO",outbound,net,node,type);
- unlink(wasname);
- }
- else fclose(fp);
- }
- }
-
-
- void _fastcall change_mail (char *line,long lastpos,FILE *fp) {
-
- unsigned int zone,net,node; /* Address to change mail type for */
- char flo[133];
- /* char req[133]; */
- char pkt[133];
- char outbound[84];
- struct find_t f;
- struct find_t f1;
- char *p;
- char type;
- char s[133];
- char s1[133];
- FILE *infile=NULL;
- FILE *outfile;
- unsigned int bytes;
-
- lstrip(line);
- stripcr(line);
- rstrip(line);
- zone=myzone;
- net=0;
- node=0;
- printf("!!!%s!!!\n",line);
- if(!strnicmp(line,"ALL ",4)) { /* This doesn't work yet; don't use it */
- p=line+4;
- lstrip(p);
- printf("!!!%s!!!\n",p);
- if(!strnicmp(p,"ZONE ",5)) {
- p+=5;
- lstrip(p);
- printf("!!!%s!!!\n",p);
- zone=(_word)atol(p);
- if(!zone) {
- fprintf(stderr,"\nZero Zone #\n");
- say_error(lastpos,fp);
- return;
- }
- }
- if(strchr(p,' ')) {
- p=strchr(p,' ');
- p++;
- type=*p;
- }
- else type=alltype;
- p=NULL;
- }
- else {
- p=strtok(line,":");
- if(!p) {
- fprintf(stderr,"\nMissing Zone\n");
- say_error(lastpos,fp);
- return;
- }
- zone=(_word)atol(p);
- if(!zone) {
- fprintf(stderr,"\nZero Zone\n");
- say_error(lastpos,fp);
- return;
- }
- p=strtok(0,"/");
- if(!p) {
- fprintf(stderr,"\nMissing Net\n");
- say_error(lastpos,fp);
- return;
- }
- net=(_word)atol(p);
- if(!net) {
- fprintf(stderr,"\nZero Net\n");
- say_error(lastpos,fp);
- return;
- }
- p=strtok(0," ");
- if(!p) {
- fprintf(stderr,"\nMissing Node\n");
- say_error(lastpos,fp);
- return;
- }
- node=(_word)atol(p);
- p=strtok(0,"; \n");
- if(!p) type=alltype;
- else type=toupper(*p);
- }
- if(type!='H' && type!='C' && type!='F' && type!='D' && type!='N' && type!='O') {
- fprintf(stderr,"\nInvalid mail type `%c'\n",type);
- say_error(lastpos,fp);
- return;
- }
-
- /* Make mask for outbound flo, packet and arc files */
-
- if(zone!=myzone)sprintf(outbound,"%s.%03x",root,zone);
- else strcpy(outbound,root);
-
- if(net)sprintf(pkt,"%s\\%04x%04x.?UT",outbound,net,node);
- else sprintf(pkt,"%s\\*.?UT",outbound);
-
- /* Removed the following since Bink 2.40 no longer forces call for REQ */
- /* Left the code in in case you need it */
-
- /* if(type!='H')sprintf(req,"%s\\%04x%04x.HEQ",outbound,net,node);
- else sprintf(req,"%s\\%04x%04x.REQ",outbound,net,node); */
-
- if(net)sprintf(flo,"%s\\%04x%04x.?LO",outbound,net,node);
- else sprintf(flo,"%s\\*.?LO",outbound);
-
- if(!_dos_findfirst(pkt,0,&f)) {
- if(type=='F') type='N';
- sprintf(s,"%s\\%s",outbound,f.name);
- s[strlen(s)-3]=type;
- if(net)printf("Changing flavor of %u:%u:%01u's mail to %c\n",zone,net,node,type);
- else printf("Changing flavor of Zone #%u's mail to %c\n",zone,type);
- do {
- if(infile==NULL) {
- if(!_dos_findfirst(s,0,&f1)) {
- if(f1.size==0L) unlink(s);
- else {
- infile=fopen(s,"r+b");
- if(!infile) {
- fprintf(stderr,"\nCan't open \'%s\'\n",s);
- break;
- }
- fseek(infile,f.size-4L,SEEK_SET);
- while((char)fgetc(infile)!='\0' && !feof(infile)); /* Should be right after first of last NULLs */
- }
- }
- }
- if(f.name[9]!=type) {
- sprintf(s1,"%s\\%s",outbound,f.name);
- if(!infile)rename(s1,s);
- else {
- outfile=fopen(s1,"rb");
- if(!outfile) {
- fprintf(stderr,"\nCan't open \'%s\'\n",s1);
- fclose(infile);
- infile=NULL;
- break;
- }
- fseek(outfile,(long)sizeof(struct _pkthdr),SEEK_SET); /* skip header to 1st msg */
- while (!feof(outfile)) {
- bytes=fread(s1,1,133,outfile);
- fwrite(s1,1,bytes,infile);
- if(bytes!=133) break;
- }
- fclose(outfile);
- }
- }
- } while(!_dos_findnext(&f));
- }
- if(infile)fclose(infile);
-
- if(!_dos_findfirst(flo,0,&f)) {
- if(type=='N' || type=='O') type='F';
- sprintf(s,"%s\\%s",outbound,f.name);
- s[strlen(s)-3]=type;
- if(net)printf("Changing flavor of %u:%u:%01u's attach(es) to %c\n",zone,net,node,type);
- else printf("Changing flavor of Zone #%u's attach(es) to %c\n",zone,type);
- do {
- if(infile==NULL) {
- if(!_dos_findfirst(s,0,&f1)) {
- /* if(f1.size==0L) unlink(s);
- else {
- */ infile=fopen(s,"r+b");
- if(!infile) {
- fprintf(stderr,"\nCan't open \'%s\'\n",s);
- break;
- }
- fseek(infile,0L,SEEK_END);
- /* } */
- }
- }
- if(f.name[9]!=type) {
- sprintf(s1,"%s\\%s",outbound,f.name);
- if(!infile)rename(s1,s);
- else {
- outfile=fopen(s1,"rb");
- if(!outfile) {
- fprintf(stderr,"\nCan't open \'%s\'\n",s1);
- fclose(infile);
- infile=NULL;
- break;
- }
- fseek(outfile,0L,SEEK_SET);
- while (!feof(outfile)) {
- bytes=fread(s1,1,133,outfile);
- fwrite(s1,1,bytes,infile);
- if(bytes!=133) break;
- }
- fclose(outfile);
- }
- }
- } while(!_dos_findnext(&f));
- }
- if(infile)fclose(infile);
-
- /* if(!_dos_findfirst(req,0,&f)) {
- sprintf(s,"%s\\%s",outbound,f.name);
- if(type=='H')s[strlen(s)-3]='H';
- else {
- type='R';
- s[strlen(s)-3]='R';
- }
- if(net)printf("Changing flavor of %u:%u:%01u's REQ(s) to %c\n",zone,net,node,type);
- else printf("Changing flavor of Zone #%u's REQ(s) to %c\n",zone,type);
- do {
- if(infile==NULL) {
- if(!_dos_findfirst(s,0,&f1)) {
- if(f1.size==0L) unlink(s);
- else {
- infile=fopen(s,"r+b");
- if(!infile) {
- fprintf(stderr,"\nCan't open \'%s\'\n",s);
- break;
- }
- fseek(infile,0L,SEEK_END);
- }
- }
- }
- if(f.name[9]!=type) {
- sprintf(s1,"%s\\%s",outbound,f.name);
- if(!infile)rename(s1,s);
- else {
- outfile=fopen(s1,"rb");
- if(!outfile) {
- fprintf(stderr,"\nCan't open \'%s\'\n",s1);
- fclose(infile);
- infile=NULL;
- break;
- }
- fseek(outfile,0L,SEEK_SET);
- while (!feof(outfile)) {
- bytes=fread(s1,1,133,outfile);
- fwrite(s1,1,bytes,infile);
- if(bytes!=133) break;
- }
- fclose(outfile);
- }
- }
- } while(!_dos_findnext(&f));
- }
- if(infile)fclose(infile);
- */
- }
-
-
- void _fastcall make_poll (char *line,long lastpos,FILE *pf) {
-
- char *p;
- /* char *pw; */
- _word zone,net,node;
- /* _word point; */
- /* FILE *fp; */
- char s[133];
- /* struct _pkthdr ph; */
- struct find_t f;
-
- /* Once created an empty poll packet. Left the code in (commented
- out) in case you need them. What I do now is just create an empty
- *.CLO file, which won't be routed on subsequent passes. */
-
- lstrip(line);
- stripcr(line);
- rstrip(line);
- p=strtok(line,":");
- if(!p) return;
- zone=(_word)atol(p);
- if(!zone) return;
- p=strtok(0,"/");
- if(!p) return;
- net=(_word)atol(p);
- if(!net) return;
- p=strtok(0,". ");
- if(!p) return;
- node=(_word)atol(p);
- /* if(strchr(p,'.')) {
- p=strchr(p,'.');
- p++;
- point=(_word)atol(p);
- }
- else point=0;
- */
-
- /* The empty *.CLO creator */
-
- if(zone!=myzone) sprintf(outbound,"%s\\.%03x",root,zone);
- else strcpy(outbound,root);
- sprintf(s,"%s\\%04x%04x.CLO",outbound,net,node);
- if(_dos_findfirst(s,0,&f)) return;
- fclose(fopen(s,"wb"));
- printf("Created poll attach for %u:%u/%01u\n",zone,net,node);
- return;
-
- /* Code below is the empty packet creator, commented out... */
- /*
- pw=strtok(0,"\n "); */ /* Password if any */
- /*
- if(zone!=myzone) sprintf(outbound,"%s\\.%03x",root,zone);
- else strcpy(outbound,root);
-
- sprintf(s,"%s\\%04x%04x.CUT",outbound,net,node);
- if(!_dos_findfirst(s,0,&f)) return;
-
- fp=fopen(s,"wb");
- if(!fp) {
- fprintf(stderr,"\nCan't open poll packet `%s'\n",s);
- return;
- }
-
- memset(ph,0,sizeof(PKTHDR));
- ph.onode=mynode;
- ph.dnode=node;
- ph.rate=2;
- ph.ver=2;
- ph.onet=mynet;
- ph.dnet=net; */
- /* ph.product=0; */ /* Until I get a product code (snore) */
- /* ph.rev_lev=201; */ /* Well, it's gotta be something... */
- /* if(pw) strcpy(ph.password,pw);
- ph.ozone=myzone;
- ph.dzone=zone;
- ph.opoint=mypoint;
- ph.dpoint=point;
- ph.pr_data=0L;
-
- fwrite(&ph,sizeof(struct _pkthdr),1,fp);
- printf("Created poll packet for %u:%u/%01u.%01u\n",zone,net,node,point);
- fclose(fp);
- */
- }
-
-
-
- char * _fastcall stristr (char *t, char *s) {
-
- char *t1;
- char *s1;
-
- /* Case-insensitive strstr()--Turbo C didn't have one */
-
- while(*t) {
- t1=t;
- s1=s;
- while(*s1) {
- if (toupper(*s1)!=toupper(*t)) break;
- else {
- s1++;
- t++;
- }
- }
- if (!*s1) return t1;
- t=t1+1;
- }
- return NULL;
- }
-
-
-
- char _fastcall spawnit (char *a) {
-
- /* Handle spawning external programs (usually archivers) */
-
- return system(a);
- }
-
-
-
- long _fastcall make_msgid (void) {
-
- time_t t;
- static _word counter = 0;
-
- /* Create a msgid serial number, including a counter */
-
- t = time(NULL);
- t = (t << 4L) | (long)(counter++ & 15);
- return t;
- }
-
-
-
- char * _fastcall find_sched (FILE *pf, char *schedtag, int wholefile) {
-
- char *p;
- char s[256];
-
- /* Given a file pointer and schedule tag string, searches file for
- schedule tag and returns it if found. Returns NULL if not. */
-
- while(1) {
- if(!fgets(s,256,pf)) {
- if(wholefile) { /* Reset and try once more */
- wholefile=0;
- lines=0;
- fseek(pf,0L,SEEK_SET);
- continue;
- }
- fprintf(stderr,"\nRequested schedule tag '%s' not found.\n",schedtag);
- return NULL;
- }
- lines++;
- if(debug)printf("%u. %s",lines,s);
- lstrip(s);
- while(p=strchr(s,'\t')) *p=' ';
- if(p=strchr(s,';')) *p=0;
- p=s;
- if(usingbink) {
- if(strnicmp(p,"APPLICATION MAKEARC ",20)) continue; /* Not ours */
- p+=20;
- lstrip(p);
- }
- if(!strnicmp(p,"SCHED ",6)) {
- p+=6;
- lstrip(p);
- stripcr(p);
- rstrip(p);
-
- if(!stricmp(p,schedtag)) {
- printf("Processing schedule tag '%s'\n",schedtag);
- break;
- }
- }
- }
- return p;
- }
-
-
-
- char * _fastcall skip_white (char *p) {
-
- while(*p && (*p==' ' || *p=='\t')) *p++;
- return p;
- }
-
-
- char * _fastcall skip_nonwhite (char *p) {
-
- while(*p && *p!=' ' && *p!='\t')*p++;
- return p;
- }
-
-
- char * _fastcall to_delim (char *p, char *delim) {
-
- char *d;
-
- while(*p) {
- d=delim;
- while(*d && *p!=*d) d++;
- if(*p==*d) break;
- p++;
- }
- return p;
- }
-
-
-
- char * _fastcall rstrip (char *a) { /* Remove trailing spaces and tabs */
-
- register int x;
-
- x=strlen(a);
- while (x && a && (a[x-1]==' ' || a[x-1]=='\t')) a[--x]=0;
- return a;
- }
-
-
-
-
- char * _fastcall lstrip (char *a) { /* Remove leading spaces and tabs */
-
- register int x;
-
- x=strlen(a);
- while (x && (*a==' ' || *a=='\t')) memmove (a,(a+1),x--);
- return (a);
- }
-
-
-
- char * _fastcall stripcr (char *a) { /* Remove trailing crs and lfs */
-
- register int x;
-
- x=strlen(a);
- while (x && (a[x-1]=='\n' || a[x-1]=='\r')) a[--x]=0;
- return a;
- }
-