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
- *
- */
-
- /* READ "NETWORK" HOST NAME TABLES
- *
- * These routines use the dbm(3x) procedures of Unix Version 7.
- * All accesses are via the fetch call of the library. Linkage between
- * elements of the database are contained within the procedures instead
- * of the database itself due to the nature of the dbm design.
- *
- * May 81 Jim Lieb, SRI rewrite by to use dbm library
- * Jun 82 D. Crocker minor cleanup & installation
- * force key value to be lower case
- * partition sequence #s by channel, not global
- * Dec 85 P.Cockcroft UCL add nameserver support and add bullet protection
- */
- #include "util.h"
- #include "mmdf.h"
- #include "ch.h" /* has table state strcture def */
- #include "dm.h"
- #include "chdbm.h"
-
- extern LLog *logptr;
- extern char *tbldfldir;
- extern char *tbldbm;
- extern Chan **ch_tbsrch;
- extern char *ch_dflnam;
-
- extern char *strcpy();
-
- typedef struct {char *dptr; int dsize;} datum;
-
- extern datum fetch();
-
- /* ******************* FIND HOST NAME IN ANY TABLE ****************** */
-
- Chan *
- ch_h2chan (hostr, pos) /* which chan name table is host in? */
- char *hostr; /* name of host */
- int pos; /* which position to get (0 = first) */
- {
- register Chan *chanptr;
- register struct DBvalues *dp;
- register char *cp;
- DBMValues dbm;
- Chan **chp;
- char hostname[ADDRSIZE];
- #ifdef NAMESERVER
- int ns_done = 0;
- #endif /* NAMESERVER */
- int dbm_done = 0;
-
- /* the list of channel name tables is first searched. If a hit is found
- * in the table for the local channel, OK is returned to indicate a local
- * reference.
- */
-
- #ifdef DEBUG
- ll_log( logptr, LLOGFTR, "h2chan ('%s', %d)", hostr, pos);
- #endif
- for (chp = ch_tbsrch; (chanptr = *chp) != (Chan *)0; chp++)
- {
- #ifdef DEBUG
- ll_log( logptr, LLOGFTR, "h2chan table '%s'",
- chanptr->ch_table->tb_name);
- #endif
- #ifdef NAMESERVER
- if ((chanptr -> ch_table -> tb_flags & TB_SRC) == TB_NS) {
- if (!ns_done) {
- /*
- * assumes the fact we are looking for a 'channel'
- * if this is not the case you must do the lookup every
- * time round the loop
- * This code believes all NS channel tables are equivalent,
- * and they will return the same answer. Not unreasonable
- * at the current time, but watch out.
- */
-
- switch(ns_fetch (chanptr->ch_table, hostr, hostname, 1)){
- case OK:
- ns_done++;
- break;
- case MAYBE:
- return( (Chan *)MAYBE);
- }
- ns_done++;
- }
- if (ns_done == 1)
- continue;
- if(--pos > 0)
- continue;
- #if DEBUG > 1
- ll_log( logptr, LLOGFTR, "NSconsider ('%s', '%s')",
- hostname, chanptr->ch_lname);
- #endif
- if (lexequ (chanptr -> ch_name, ch_dflnam))
- return( (Chan *)OK ); /* local ref */
- return( chanptr );
- }
- else
- #endif /* NAMESERVER */
- {
- if (!dbm_done) {
- dbm_done++;
- if (tb_fetch (hostr, dbm))
- dbm_done++;
- }
- if (dbm_done == 1)
- continue;
- for (dp = dbm ; (cp = dp->RECname) != NULL ; dp++) {
- #if DEBUG > 1
- ll_log( logptr, LLOGFTR, "consider ('%s')", cp);
- #endif
- if (lexequ(cp, chanptr -> ch_table -> tb_name)) {
- if (--pos > 0)
- break;
- if (lexequ(chanptr -> ch_name, ch_dflnam))
- return( (Chan *)OK );
- return(chanptr);
- }
- }
- }
- }
-
- return ((Chan *) NOTOK);
- }
-
- /* *********** GIVEN Subdomain, FIND Domain ***************** */
-
- Domain *
- dm_s2dom (subdomain, official, dmbuf)
- char *subdomain; /* name of subdomain to look up */
- char *official; /* Where to put official name */
- char *dmbuf; /* Domain route buffer */
- {
- register Domain *dmnptr;
- register char *cp;
- register struct DBvalues *dp;
- DBMValues dbm;
- extern Domain **dm_list;
- Domain **dmp;
- char *argv[DM_NFIELD];
- int dbm_done = 0;
- char sdbuf[LINESIZE];
-
- #ifdef DEBUG
- ll_log( logptr, LLOGFTR, "dm_s2dom ('%s')", subdomain);
- #endif
-
- for (dmp = dm_list; (dmnptr = *dmp) != (Domain *)0; dmp++)
- {
- /* If flags=partial is not set or this is a top domain table */
- /* (indicating that we've already tried this match as a "route" */
- /* match), skip it. */
- if (((dmnptr -> dm_table -> tb_flags & TB_PARTIAL) != TB_PARTIAL) ||
- (!isstr(dmnptr->dm_domain)))
- continue;
- #ifdef NAMESERVER
- if ((dmnptr -> dm_table -> tb_flags & TB_SRC) == TB_NS) {
- sprintf(sdbuf, "%s.%s", subdomain, dmnptr->dm_domain);
- switch (ns_fetch(dmnptr->dm_table,sdbuf,official,1)) {
- case OK:
- /* route is simply official name */
- (void) strcpy(dmbuf,official);
- return( dmnptr );
- case MAYBE:
- return( (Domain *)MAYBE);
- }
- }
- else
- #endif /* NAMESERVER */
- {
- if (!dbm_done) {
- dbm_done++;
- if (tb_fetch (subdomain, dbm))
- dbm_done++;
- }
- if (dbm_done == 1)
- continue;
- for ( dp = dbm ; (cp = dp->RECname) != NULL ; dp++) {
- #ifdef DEBUG
- ll_log( logptr, LLOGFTR, "dm_s2dom: consider ('%s')", cp);
- #endif
- if (!lexequ(cp, dmnptr -> dm_table -> tb_name))
- continue;
- if(dp->RECval == NULL) { /* should never happen */
- *dmbuf = *official = '\0';
- return(dmnptr);
- }
- (void) strcpy (dmbuf, dp->RECval);
- str2arg(dp->RECval, DM_NFIELD, argv, 0);
- (void) strcpy(official, argv[0]);
- return(dmnptr);
- }
- }
- }
-
- (void) strcpy (official, subdomain);
- return ((Domain *) NOTOK);
- }
-
- /* ******* Get a record from the database, given a key ********** */
- /* Note that the strings are in internal statics */
-
- tb_fetch (name, dbm) /* return filled entry for name */
- char *name; /* use this key to fetch entry */
- DBMValues dbm; /* put the entry here */
- {
- LOCVAR int dbmopen = FALSE;
- LOCVAR char dbvalue[256];
- datum key, value;
- char *lastchar;
- register char *p, *cp;
- register struct DBvalues *dp;
- register cnt;
-
- if (!dbmopen)
- {
- extern int dbminit();
- char filename[128];
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "tb_fetch: dbminit");
- #endif
- getfpath (tbldbm, tbldfldir, filename);
- if (dbminit (filename) < 0)
- err_abrt (LLOGTMP, "Error opening database '%s'", filename);
-
- dbmopen = TRUE;
- }
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "fetch (%s)", name);
- #endif
- key.dptr = name;
- key.dsize = strlen (name) + 1;
- for (p = name; *p; p++)
- *p = uptolow (*p);
-
- value = fetch (key);
- if (value.dptr == NULL)
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "fetch of '%s' failed", name);
- #endif
- return (FALSE);
- }
- for (cp = value.dptr, p= dbvalue, lastchar = &p[value.dsize];
- p < lastchar; *p++ = *cp++) ;
- *p = '\0'; /* copy value to separate storage */
-
- for (p = dbvalue , dp = dbm, cnt = 0; *p && cnt < MAXVAL ; cnt++, dp++)
- {
- for(dp->RECname = p ; *p ; p++)
- if (*p == ' ') { /* get table name */
- *p++ = '\0';
- break;
- }
- for (dp->RECval = (*p ? p : NULL); *p; p++)
- if (*p == FS) { /* get value-part */
- *p++ = '\0';
- break;
- }
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "fetch val(%d)='%s/%s'",
- cnt, dp->RECname, (dp->RECval==NULL) ? "<NULL>": dp->RECval);
- #endif
- }
- for(;cnt <= MAXVAL; cnt++, dp++) /* zero the rest of the structures */
- dp->RECname = dp->RECval = NULL;
-
- return (TRUE);
- }
-
- /* ******* FIND VALUE (address), GIVEN ITS KEY (hostname) ********* */
-
-
- tb_k2val (table, first, name, buf) /* use key and return value */
- register Table *table;
- int first; /* start at beginning of list? */
- register char name[]; /* name of ch "member" / key */
- char *buf; /* put value int this buffer */
- {
- LOCVAR DBMValues dbm;
- LOCVAR struct DBvalues *dp = (struct DBvalues *) 0;
- register char *cp;
- #ifdef NAMESERVER
- int retval;
- #endif
-
-
- #ifdef DEBUG
- ll_log (logptr, LLOGBTR, "tb_k2val (%s, first=%d, %s)",
- table -> tb_name, first, name);
- #endif
-
- #ifdef NAMESERVER
- if ((table->tb_flags&TB_SRC) == TB_NS) {
- if ((retval = ns_fetch (table, name, buf, first)) != NOTOK)
- return (retval);
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "tb_k2val failed");
- #endif
- (void) strcpy (buf, "(ERROR)");
- return (NOTOK);
- }
- #endif /* NAMESERVER */
-
- if (!first)
- dp++;
- else
- {
- if (tb_fetch (name, dbm))
- {
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "hit");
- #endif
- dp = dbm;
- }
- else
- dp = (struct DBvalues *) 0; /* none */
- }
-
- if (dp)
- for (; (cp = dp->RECname) != NULL; dp++)
- {
- if (strequ (cp, table -> tb_name))
- { /* this is the right channel */
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "table(%s)", cp);
- #endif
- if(dp->RECval == NULL)
- *buf = '\0';
- else
- (void) strcpy (buf, dp->RECval);
- return (OK); /* give them the value-part */
- }
- }
- #ifdef DEBUG
- ll_log (logptr, LLOGFTR, "tb_k2val failed");
- #endif
- (void) strcpy (buf, "(ERROR)");
- return (NOTOK);
- }
-