home *** CD-ROM | disk | FTP | other *** search
- /*
- * MULTI-CHANNEL MEMO DISTRIBUTION FACILITY (MMDF)
- *
- *
- * Copyright (C) 1979,1980,1981 University of Delaware
- *
- * Department of Electrical Engineering
- * University of Delaware
- * Newark, Delaware 19711
- *
- * Phone: (302) 738-1163
- *
- *
- * This program module was developed as part of the University
- * of Delaware's Multi-Channel Memo Distribution Facility (MMDF).
- *
- * Acquisition, use, and distribution of this module and its listings
- * are subject restricted to the terms of a license agreement.
- * Documents describing systems using this module must cite its source.
- *
- * The above statements must be retained with all copies of this
- * program and may not be removed without the consent of the
- * University of Delaware.
- *
- *
- * version -1 David H. Crocker March 1979
- * version 0 David H. Crocker April 1980
- * version v7 David H. Crocker May 1981
- * version 1 David H. Crocker October 1981
- *
- */
-
- #include "util.h"
- #include "mmdf.h"
- #include "ch.h" /* has table state strcture def */
- #include "dm.h"
- #include "chdbm.h"
-
- extern Domain **dm_list;
- extern Domain *dm_s2dom();
- extern struct ll_struct *logptr;
- extern char *strcpy ();
- extern char *index();
- extern char *rindex();
-
- /*
- * when mangling addresses, should we try the reverse before or after
- * the RFC822 direction
- * is set by submit otherwise is as below.
- */
-
- typedef struct {char *dptr; int dsize;} datum;
-
-
- /*
- * Steve Kille jan 84 Redo this module
- *
- * G. Brendan Reilly May 84 take out dependencies on DBM package
- *
- *
- */
-
-
- /* ******* FIND VALUE (address), GIVEN ITS KEY (hostname) ********* */
-
-
- LOCFUN
- dm_k2val (dmntbl, subdmn, domain, dmnroute)
- /* sub-domain spec -> routing host */
- register Domain *dmntbl; /* domain table to look in */
- register char *subdmn; /* name of sub-domain to look for */
- char *domain; /* where to stuff full domain name */
- Dmn_route *dmnroute; /* where to put routing information */
- {
- char *p;
- int retval;
- char sdbuf[LINESIZE];
-
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "dm_k2val (%s, %s)", dmntbl -> dm_name, subdmn);
- #endif
-
- if (((dmntbl->dm_table->tb_flags & TB_SRC) == TB_NS) &&
- isstr(dmntbl->dm_domain)) {
- sprintf(sdbuf, "%s.%s", subdmn, dmntbl->dm_domain);
- retval = tb_k2val (dmntbl->dm_table, TRUE, sdbuf, dmnroute->dm_buf);
- }
- else
- retval = tb_k2val (dmntbl->dm_table, TRUE, subdmn, dmnroute->dm_buf);
-
- switch(retval) {
- case MAYBE:
- return(MAYBE);
- case OK:
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "dm_k2val: hit with '%s'", dmnroute->dm_buf);
- #endif
- dmnroute -> dm_argc = str2arg (dmnroute -> dm_buf,
- DM_NFIELD, dmnroute -> dm_argv, (char *)0);
- (void) strcpy(domain, dmnroute -> dm_argv[0]);
- return (OK);
- }
-
- /* Not found yet--give up if we're not allowed to look for subdomains
- to route via */
- if ((dmntbl->dm_table->tb_flags & TB_ROUTE) != TB_ROUTE)
- return(NOTOK);
-
- /* Here we're going to look for successive subdomains (b.c.d, c.d, d)
- on the chance that we can route via that subdomain to reach a.b.c.d.
- For example, given oxnard.bitnet, we'll look for a table entry such
- as "bitnet:cunyvm.cuny.edu" where cunyvm.cuny.edu is the route to
- *.bitnet */
-
- p = subdmn;
- while ((p = index (p, '.')) != (char *)0)
- {
- char tdmnbuf[LINESIZE];
-
- p++;
- if (((dmntbl->dm_table->tb_flags & TB_SRC) == TB_NS) &&
- isstr(dmntbl->dm_domain)) {
- sprintf(sdbuf, "%s.%s", p, dmntbl->dm_domain);
- retval = tb_k2val (dmntbl->dm_table, TRUE, sdbuf, tdmnbuf);
- }
- else
- retval = tb_k2val (dmntbl->dm_table, TRUE, p, tdmnbuf);
-
- switch(retval) {
- case MAYBE:
- return(MAYBE);
- default:
- continue;
- case OK:
- break;
- }
- /* get the entry */
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "dm_k2val: hit with '%s' for '%s.%s'",
- tdmnbuf, p, dmntbl->dm_domain);
- #endif
- *(p - 1) = '\0'; /* build the domain */
- if (!isstr(dmntbl->dm_domain)) {
- if (*p == '\0')
- (void) strcpy (domain, subdmn);
- else
- sprintf (domain, "%s.%s", subdmn, p);
- }
- else
- sprintf (domain, "%s.%s.%s", subdmn, p, dmntbl -> dm_domain);
-
- sprintf (dmnroute -> dm_buf, "%s %s", domain, tdmnbuf);
- dmnroute -> dm_argc = str2arg (dmnroute -> dm_buf,
- DM_NFIELD, dmnroute -> dm_argv, (char *)0);
- return (OK);
- }
-
- return (NOTOK);
- }
-
- /* *********** GIVEN Subdomain, FIND HOST ROUTE ************* */
- /*
- * If BOTHEND is defined then we are almost certainly running in JNT
- * land and so we should try the reversed address before the RFC822
- * direction, should save some cpu cycles
- */
-
- LOCFUN
- Domain *
- #ifndef BOTHEND
- dm_sd2route (value, domain, dmnroute)
- char *value; /* what the use provides */
- char *domain; /* full domain value */
- Dmn_route *dmnroute; /* source route */
- #else
- dm_sd2route (value, reverse, domain, dmnroute)
- char *value; /* what the use provides */
- char *reverse; /* the same bacwards */
- char *domain; /* full domain value */
- Dmn_route *dmnroute; /* source route */
- #endif
- {
- char *sdptr;
- Domain *dmnptr;
- char official[LINESIZE];
- #ifdef BOTHEND
- char *revsdptr = reverse;
- #endif
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "dm_sd2route (%s)", seenull(value));
- #endif
- /* first try the JNT way round if */
- /* got BOTHEND defined */
- #ifdef BOTHEND
- if ((dmnptr = dm_s2dom (reverse, official, dmnroute -> dm_buf)) !=
- (Domain *) NOTOK || (dmnptr = dm_s2dom (value, official, dmnroute -> dm_buf))
- != (Domain *) NOTOK)
- #else
- if ((dmnptr = dm_s2dom (value, official, dmnroute -> dm_buf))
- != (Domain *) NOTOK)
- #endif
- {
- if(dmnptr == (Domain *)MAYBE)
- return(dmnptr);
- (void) strcpy(domain, official);
- dmnroute -> dm_argc = str2arg (dmnroute -> dm_buf, DM_NFIELD,
- dmnroute -> dm_argv, (char *)0);
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "dm_sd2route: Domain value '%s' from '%s'",
- domain, dmnptr -> dm_show);
- #endif
- return (dmnptr);
- }
-
- /*
- * If not, move in from left. Progressing on both forwards
- * and backwards options.
- */
- sdptr = value;
- while ((sdptr = index (sdptr, '.')) != (char *) 0)
- {
- char tbuf[LINESIZE];
-
- #ifdef BOTHEND
- revsdptr = index (revsdptr, '.') + 1;
- if ((dmnptr = dm_s2dom (revsdptr, official, tbuf)) != (Domain *) NOTOK)
- {
- if(dmnptr == (Domain *)MAYBE)
- return(dmnptr);
- *(revsdptr - 1) = '\0';
- sprintf (domain, "%s.%s", reverse, official);
- sprintf (dmnroute -> dm_buf, "%s %s", domain, tbuf);
- dmnroute -> dm_argc = str2arg (dmnroute -> dm_buf, DM_NFIELD,
- dmnroute -> dm_argv, (char *)0);
- #ifdef DEBUG
- ll_log(logptr,LLOGFTR, "Domain value (rev) '%s' from '%s',o = '%s'",
- domain, dmnptr -> dm_show, official);
- #endif
- return (dmnptr);
- }
- #endif /* BOTHEND */
-
- if ((dmnptr = dm_s2dom (++sdptr, official, tbuf)) != (Domain *) NOTOK)
- {
- if(dmnptr == (Domain *)MAYBE)
- return(dmnptr);
- *(sdptr - 1) = '\0';
- sprintf (domain, "%s.%s", value, official);
- sprintf (dmnroute -> dm_buf, "%s %s", domain, tbuf);
- dmnroute -> dm_argc = str2arg (dmnroute -> dm_buf, DM_NFIELD,
- dmnroute -> dm_argv, (char *)0);
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "Domain value '%s' from '%s', o = '%s'",
- domain, dmnptr -> dm_show, official);
- #endif
- return (dmnptr);
- }
- }
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "'%s' not found", value);
- #endif
- return ((Domain *) NOTOK);
- }
-
- /* *********** GIVEN VALUE, FIND HOST ROUTE ******************** */
-
- /* This will take any value, and map it into a domain route. */
- /* It is optimised for val being a fully qualified domain */
-
- #ifndef BOTHEND
-
- Domain *
- dm_v2route (value, domain, dmnroute)
- char *value; /* what the use provides */
- char *domain; /* full domain value */
- register Dmn_route *dmnroute; /* source route */
- {
- Dmn_route tmpdmn; /* hold parsed domain string */
- register Domain *dmnptr;
- Domain **seed;
- int sublen; /* length of right-hand to look up */
- int ind;
- int perhaps = 0;
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "dm_v2route (%s)", seenull(value));
- #endif
- if (value != (char *) 0)
- (void) strcpy (tmpdmn.dm_buf, value);
- else
- *tmpdmn.dm_buf = '\0';
- tmpdmn.dm_argc = cstr2arg (tmpdmn.dm_buf, DM_NFIELD, tmpdmn.dm_argv, '.');
- if (tmpdmn.dm_argc == NOTOK) {
- #ifdef DEBUG
- ll_log (logptr, LLOGTMP, "Cstr2arg failed (%s)", tmpdmn.dm_buf);
- #endif
- return ( (Domain *)NOTOK);
- }
-
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "%d fields", tmpdmn.dm_argc);
- #endif
-
- dmnroute -> dm_argc = 1; /* initialize with something safe */
- (void) strcpy (dmnroute -> dm_buf, value);
- dmnroute -> dm_argv[0] = dmnroute -> dm_buf;
-
- tmpdmn.dm_argc--;
-
- for (ind = sublen = 0; ind <= tmpdmn.dm_argc; ind++)
- {
- if (ind != 0)
- tmpdmn.dm_buf[sublen - 1] = '.';
- /* undo cstr2arg! */
- sublen += strlen (tmpdmn.dm_argv[ind]);
- /* how much to peel off, from right */
- /* the +1 is for the delimiter */
- if (ind != tmpdmn.dm_argc)
- sublen++; /* point to next if not last */
- seed = (Domain **) 0;
- while ((dmnptr=dm_nm2struct(&value[sublen],&seed)) != (Domain *) NOTOK)
- {
- switch(dm_k2val (dmnptr, tmpdmn.dm_argv[0], domain, dmnroute)){
- case MAYBE:
- if ((dmnptr->dm_table->tb_flags & TB_ABORT) == TB_ABORT)
- return((Domain *) MAYBE);
- perhaps++;
- continue; /* keep trying other domain entries */
- case OK:
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR,
- "%s' hit in domain table '%s' with '%s'",
- value, dmnptr -> dm_show, dmnroute -> dm_buf);
- #endif
- return (dmnptr);
- }
- }
- }
- return (perhaps? (Domain *) MAYBE : dm_sd2route (value, domain, dmnroute));
- }
-
- #else /* BOTHEND */
-
- LOCFUN Domain *
- dm_rv2route (value, domain, dmnroute)
- char *value; /* what the use provides */
- char *domain; /* full domain value */
- register Dmn_route *dmnroute; /* source route */
- {
- Dmn_route tmpdmn; /* hold parsed domain string */
- register Domain *dmnptr;
- int sublen; /* length of right-hand to look up */
- int ind;
- char buf[LINESIZE];
- Domain **seed;
- int perhaps = 0;
-
- (void) strcpy (tmpdmn.dm_buf, value);
- tmpdmn.dm_argc = cstr2arg (tmpdmn.dm_buf, DM_NFIELD, tmpdmn.dm_argv, '.');
- if (tmpdmn.dm_argc == NOTOK) {
- #ifdef DEBUG
- ll_log (logptr, LLOGTMP, "Cstr2arg failed (%s)", tmpdmn.dm_buf);
- #endif
- return ( (Domain *)NOTOK);
- }
-
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "%d fields", tmpdmn.dm_argc);
- #endif
-
- tmpdmn.dm_argc--;
- for (ind = sublen = 0; ind <= tmpdmn.dm_argc; ind++)
- {
- if (ind != 0)
- tmpdmn.dm_buf[sublen - 1] = '.';
- /* undo cstr2arg! */
- sublen += strlen (tmpdmn.dm_argv[ind]);
- /* how much to peel off, from right */
- /* the +1 is for the delimiter */
- if (ind != tmpdmn.dm_argc)
- sublen++; /* point to next if not last */
- seed = (Domain **) 0;
- while ((dmnptr=dm_nm2struct(&value[sublen],&seed)) != (Domain *) NOTOK)
- {
- switch(dm_k2val (dmnptr, tmpdmn.dm_argv[0], domain, dmnroute)){
- case MAYBE:
- if ((dmnptr->dm_table->tb_flags & TB_ABORT) == TB_ABORT)
- return((Domain *) MAYBE);
- perhaps++;
- continue; /* keep trying other domain entries */
- case OK:
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR,
- "%s' hit in domain table '%s' with '%s'",
- value, dmnptr -> dm_show, dmnroute -> dm_buf);
- #endif
- return (dmnptr);
- }
- }
- }
- return (perhaps? (Domain *) MAYBE : (Domain *) 0); /* not found */
- }
-
- Domain *
- dm_v2route (value, domain, dmnroute)
- char *value; /* what the use provides */
- char *domain; /* full domain value */
- Dmn_route *dmnroute; /* source route */
- {
- Domain *dmnptr;
- char *reverse; /* to handle bigend mess */
- extern char *ap_dmflip();
-
- if (value == (char *) 0) value = "";
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "dm_v2route (%s)", value);
- #endif
- dmnroute -> dm_argc = 1; /* initialize with something safe */
- (void) strcpy (dmnroute -> dm_buf, value);
- dmnroute -> dm_argv[0] = dmnroute -> dm_buf;
-
- if ((dmnptr = dm_rv2route (value, domain, dmnroute)) != (Domain *)0)
- return (dmnptr);
- reverse = ap_dmflip (value);
- if( (dmnptr = dm_rv2route (reverse, domain, dmnroute)) != (Domain *)0){
- free (reverse);
- return (dmnptr);
- }
- dmnptr = dm_sd2route (value, reverse, domain, dmnroute);
- free (reverse);
- return (dmnptr);
- }
- #endif /* BOTHEND */
-