/************************************************************************** * ROUTE.C * * * * Proces route information for BERMUDA-P. * * * * Written by Jac Kersing * **************************************************************************/ #define MAILER /* needed in PANDORA.H */ #include "pandora.h" /* for structure of the area's etc. */ /*#pragma warn -rng*/ #if TC #include #endif #include "patmat.pro" #include "route.pro" #include "utextra.pro" #define DEBUG 0 /* show debugging info? */ #if MEGAMAX || MWC char *malloc(), *realloc(); #endif #define STRING 0 #define ARCMAIL 1 #define ROUTE_TO 2 #define NO_ROUTE 3 #define FORWARD_FOR 4 #define TO 5 #define NODE 6 #define IF 7 #define REDIRECT 8 #define HOLD 9 #define POLL 10 #ifdef LINN #define NOHOLD 11 #define ZIPMAIL 20 #define LZHMAIL 21 #define ZOOMAIL 22 #define ARJMAIL 23 #endif #define FIRST 0x1000 #define CRASHMAIL 0x2000 #define REQUEST 0x4000 #define KW_FILE 0x8000 #define MASK 0x00ff struct _route { char node[21]; /* spec for a node */ int maxkbfile; /* maximum number of bytes for files */ int flags; } ; extern char *skip_blanks(); extern char *skip_to_blank(); extern char *Bpath; extern struct _aka { int zone; int net; int node; int point; int pointnet; } alias[]; extern int nalias; extern char active[]; FILE *routef; #ifdef LINN #define ARC 0 #define ZIP 1 #define ZOO 2 #define LZH 3 #define ARJ 4 struct _arc { char *address; /* node address */ int archiveur; /* number of archiver */ } *arc; #else char **arc; /* pointer to strings with arcmail specs */ #endif int maxanode; int anode; struct _route *route; /* routing info stored here */ int maxrnode; int rnode; char buffer[255]; /* for parsing of routefile */ char yytext[255]; int token; int store; char pattern[10][40]; /* for pattern matcher */ /* The program.... */ int isok(string) char *string; { char *p; char foundcolon=0, foundslash=0; for (p= string; *p; p++) { if (*p==':') { if (foundcolon) return -1; else foundcolon++; } else if (*p=='/') { if (foundslash) return -1; else foundslash++; } else if (*p=='.' && p==string) continue; else if (isspace(*p)) break; else if (*p=='$' && isdigit(*(p+1))) { p++; continue; } else if (*p!='*' && *p!='?' && !isdigit(*p)) return -1; } return (int) (p-string); } int yyparse() { int i; char *p; int ch; p= buffer; while ((ch=getc(routef))!=EOF && (!isspace(ch) || p==buffer)) { if (!isspace(ch)) { if (ch==';') /* skip comment */ { while( (ch=getc(routef))!=EOF && ch!='\n' && ch!='\r') ; continue; /* OUTER LOOP !! */ } *p++=ch; if (p-buffer > 240) { message(6,"!String > 240 chars in routefile"); exit(2); } } } if (ch==EOF && p==buffer) return EOF; *p='\0'; p= buffer; #if DEBUG message(6," command: %s",p); #endif if (!stricmp(p,"forward-from")) { return FORWARD_FOR; } if (!stricmp(p,"to")) { return TO; } if (!stricmp(p,"route-to")) { return ROUTE_TO; } if (!stricmp(p,"no-route")) { return NO_ROUTE; } if (!stricmp(p,"ARCMAIL")) { return ARCMAIL; } #ifdef LINN if (!stricmp(p,"ZIPMAIL")) { return ZIPMAIL; } if (!stricmp(p,"LZHMAIL")) { return LZHMAIL; } if (!stricmp(p,"ZOOMAIL")) { return ZOOMAIL; } if (!stricmp(p,"ARJMAIL")) { return ARJMAIL; } #endif if (!stricmp(p,"HOLD")) { return HOLD; } #ifdef LINN if(!stricmp(p,"NO-HOLD")) { return NOHOLD; } #endif if (!stricmp(p,"POLL")) { return POLL; } if (!stricmp(p,"CRASH")) { return CRASHMAIL; } if (!stricmp(p,"FILE")) { return KW_FILE; } /* if (!stricmp(p,"REQUEST")) { return REQUEST; } */ if (!stricmp(p,"IF")) { return IF; } if (!stricmp(p,"REDIRECT")) { return REDIRECT; } if (!stricmp(p,"ALL")) { strcpy(yytext,"*"); return NODE; } if (!stricmp(p,"ournet")) { sprint(yytext,"%d:%d/*",alias[0].zone,alias[0].net); return NODE; } if (!stricmp(p,"boss")) { sprint(yytext,"%d:%d/%d",alias[0].zone,alias[0].net,alias[0].node); return NODE; } if (!stricmp(p,"points")) { strcpy(yytext,".*"); return NODE; } i= isok(p); if (i>0) { strncpy(yytext,p,i); yytext[i]= '\0'; if (strchr("?*$",*yytext) != NULL) return (NODE); if (strchr(yytext,'.') != NULL) return NODE; if (strchr(yytext,':') != NULL) return NODE; if (strchr(yytext,'/') == NULL) { char buf[80]; sprint(buf,"%d:%d/%s",alias[0].zone, alias[0].net, yytext); strcpy(yytext,buf); } else { char buf[80]; sprint(buf,"%d:%s", alias[0].zone, yytext); strcpy(yytext,buf); } return NODE; } strcpy(yytext,buffer); return STRING; } void parse() { token= yyparse(); } #ifdef LINN void arcmail(int archiveur) { /* Found ARCMAIL in the input, read nodenumbers next */ do { parse(); if (token==NODE && store) { arc[anode].address= malloc(strlen(yytext)+1); if (arc[anode].address==NULL) { message(6,"!Mem error"); exit(1); } strcpy(arc[anode].address,yytext); arc[anode].archiveur=archiveur; anode++; if (anode>=maxanode) { maxanode += 1000; arc= realloc(arc, maxanode * sizeof(struct _arc)); if (arc==NULL) { message(6,"!Mem error"); exit(1); } } } } while (token==NODE) ; } #else void arcmail() { /* Found ARCMAIL in the input, read nodenumbers next */ do { parse(); if (token==NODE && store) { arc[anode]= malloc(strlen(yytext)+1); if (arc[anode]==NULL) { message(6,"!Mem error"); exit(1); } strcpy(arc[anode],yytext); anode++; if (anode>=maxanode) { maxanode += 1000; arc= realloc(arc, maxanode * sizeof(struct _arc)); if (arc==NULL) { message(6,"!Mem error"); exit(1); } } } } while (token==NODE) ; } #endif void addroute(flags) int flags; { if (!store) return; strncpy(route[rnode].node,yytext,20); route[rnode].node[20]='\0'; route[rnode].flags= flags; route[rnode].maxkbfile= 0; rnode++; if (rnode >= maxrnode) { maxrnode += 1000; route=realloc(route, sizeof(struct _route) * maxrnode); if (route==NULL) { message(6,"!Mem error"); exit(1); } } } void route_to() { int flags= ROUTE_TO|FIRST; do { parse(); if (token==CRASHMAIL) flags |= CRASHMAIL; if (token==KW_FILE) flags |= KW_FILE; if (token==NODE) { addroute(flags); flags &= ~FIRST; } } while (token==NODE || token==CRASHMAIL || token==KW_FILE); } void no_route() { int flags= NO_ROUTE; do { parse(); if (token==CRASHMAIL) flags |= CRASHMAIL; if (token==KW_FILE) flags |= KW_FILE; if (token==NODE) { addroute(flags); } } while (token==NODE || token==CRASHMAIL || token==KW_FILE); } void add_hold() { int flags= HOLD; do { parse(); if (token==NODE) { addroute(flags); } } while (token==NODE); } void add_poll() { int flags= POLL; do { parse(); if (token==NODE) { addroute(flags); } } while (token==NODE); } #ifdef LINN /* ho-hold */ void add_nohold() { int flags= NOHOLD; do { parse(); if (token==NODE) { addroute(flags); } } while (token==NODE); } #endif void forward() { int flags= FORWARD_FOR; do { parse(); if (token==CRASHMAIL) flags |= CRASHMAIL; if (token==KW_FILE) flags |= KW_FILE; if (token==TO) flags= TO | (flags & ~MASK); if (token==NODE) { addroute(flags); } } while (token==NODE || token==CRASHMAIL || token==TO || token==KW_FILE); } void if_ok() { /* Found IF in the input, check for tag next */ parse(); if (token!=STRING) { message(6,"!Invalid TAG"); return; } store= !stricmp(yytext,active); parse(); } void redirect() { /* found redirect in input, now store nodes */ int flags= REDIRECT|FIRST; do { parse(); if (token==CRASHMAIL) flags |= CRASHMAIL; if (token==NODE) { addroute(flags); flags &= ~FIRST; } } while (token==NODE || token==CRASHMAIL); } int parse_route() { sprintf( buffer, "%sbermuda.rte", Bpath); routef= fopen(buffer,"r"); if (routef == NULL) { sprintf( buffer, "%stb.rte", Bpath); routef = fopen(buffer,"r"); } if (routef==NULL) { message(6,"!Can not find ROUTE file, please check!!"); exit(2); } arc=malloc(1000 * sizeof(struct _arc)); maxanode=1000; anode=0; if (arc==NULL) { message(6,"!Mem error"); exit(1); } route=malloc(1000 * sizeof(struct _route)); maxrnode= 1000; rnode= 0; store= 1; parse(); while (token != EOF) { switch(token) { #ifdef LINN case NOHOLD : add_nohold(); break; case ARCMAIL : arcmail(ARC); break; case ZIPMAIL : arcmail(ZIP); break; case LZHMAIL : arcmail(LZH); break; case ARJMAIL : arcmail(ARJ); break; case ZOOMAIL : arcmail(ZOO); break; #else case ARCMAIL : arcmail(); break; #endif case ROUTE_TO: route_to(); break; case NO_ROUTE: no_route(); break; case FORWARD_FOR: forward(); break; case IF : if_ok(); break; case REDIRECT: redirect(); break; case HOLD : add_hold(); break; case POLL : add_poll(); break; default : printf("Error in %s\n",buffer); parse(); } } fclose(routef); return 0; } #ifdef LINN int ArcOk(zone,net,node) int zone, net, node; { char buffer[80]; int i, ret; sprint(buffer,"%d:%d/%d",zone,net,node); for(i=0; i next */ if (file && !(route[i].flags&KW_FILE)) continue; /* crash && forward crash? No -> next */ if (crash && (route[i].flags&CRASHMAIL)) return 1; if (!crash && !(route[i].flags&CRASHMAIL)) return 1; } } } } } return 0; } int match(raw,pat) char *raw, *pat; { int i; for (i=0; i<10; i++) { pattern[i][0]='\0'; } return match1(raw,pat,1); } int match1(raw, pat, level) char *raw; char *pat; int level; { int i ; if ((*pat == '\0') && (*raw == '\0')) /* if it is end of both */ return( 1 ) ; /* strings,then match */ if (*pat == '\0') /* if it is end of only */ return( 0 ) ; /* pat then mismatch */ if (*pat == '*') /* if pattern is a '*' */ { if (*(pat+1) == '\0') /* if it is end of pat */ return( 1 ) ; /* then match */ for(i=0;i<=(int)strlen(raw);i++) /* else hunt for match */ if ((*(raw+i) == *(pat+1)) || /* or wild card */ (*(pat+1) == '?')) { strcpy(pattern[level],raw); pattern[level][i]='\0'; if (match1(raw+i+1,pat+2,level+1) == 1) return( 1 ) ; } } else { if (*raw == '\0') /* if end of raw then */ return( 0 ) ; /* mismatch */ if ((*pat == *raw)) if (match1(raw+1,pat+1,level) == 1) /* try & match rest of it*/ return( 1 ) ; if (*pat == '?') { pattern[level][0]= *raw; pattern[level][1]= '\0'; if (match1(raw+1,pat+1,level+1) == 1) return( 1 ) ; } } return( 0 ) ; /* no match found */ } void getid(nr,zone,net,node) int nr, *zone, *net, *node; { char buffer[80]; char *p= route[nr].node; int i,b; if (strchr(p,'.')!=NULL) { sprint(buffer,"%d:%d/%d",alias[0].zone, alias[0].net, alias[0].node); } else { for(b=i=0;i<(int)strlen(p);i++) { if (p[i]=='$') { i++; strcpy(&buffer[b],pattern[p[i]-'0']); while (buffer[b]) b++; } else buffer[b++]=p[i]; } } #ifdef LINN /* the mysterious bug was here */ buffer[b]='\0'; #endif /* Now the buffer contains an explicit node */ *zone= alias[0].zone; *net= alias[0].net; *node= alias[0].node; sscanf(buffer,"%d:%d/%d",zone,net,node); } void ToWhere(zone, net, node, dzone, dnet, dnode, dpoint, crash, file) int *zone, *net, *node, dzone, dnet, dnode, dpoint, crash, file; { int i; int first; char buffer1[80]; int chk = (crash ? CRASHMAIL : 0) | (file ? KW_FILE : 0); *zone= dzone; *net= dnet; *node= dnode; /* Do something for points here too */ sprint(buffer1,"%d:%d/%d", dzone, dnet, dnode); if (dpoint) { for(i=0; i