home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / lib / table / ch_tbdbm.c next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  9.9 KB  |  374 lines

  1. /*
  2.  *     MULTI-CHANNEL MEMO DISTRIBUTION FACILITY  (MMDF)
  3.  *
  4.  *
  5.  *     Copyright (C) 1979,1980,1981  University of Delaware
  6.  *
  7.  *     Department of Electrical Engineering
  8.  *     University of Delaware
  9.  *     Newark, Delaware  19711
  10.  *
  11.  *     Phone:  (302) 738-1163
  12.  *
  13.  *
  14.  *     This program module was developed as part of the University
  15.  *     of Delaware's Multi-Channel Memo Distribution Facility (MMDF).
  16.  *
  17.  *     Acquisition, use, and distribution of this module and its listings
  18.  *     are subject restricted to the terms of a license agreement.
  19.  *     Documents describing systems using this module must cite its source.
  20.  *
  21.  *     The above statements must be retained with all copies of this
  22.  *     program and may not be removed without the consent of the
  23.  *     University of Delaware.
  24.  *
  25.  *
  26.  *     version  -1    David H. Crocker    March   1979
  27.  *     version   0    David H. Crocker    April   1980
  28.  *     version  v7    David H. Crocker    May     1981
  29.  *     version   1    David H. Crocker    October 1981
  30.  *
  31.  */
  32.  
  33. /*  READ "NETWORK" HOST NAME TABLES
  34.  *
  35.  *  These routines use the dbm(3x) procedures of Unix Version 7.
  36.  *  All accesses are via the fetch call of the library. Linkage between
  37.  *  elements of the database are contained within the procedures instead
  38.  *  of the database itself due to the nature of the dbm design.
  39.  *
  40.  *  May 81  Jim Lieb, SRI   rewrite by to use dbm library
  41.  *  Jun 82  D. Crocker      minor cleanup & installation
  42.  *                          force key value to be lower case
  43.  *                          partition sequence #s by channel, not global
  44.  *  Dec 85  P.Cockcroft UCL add nameserver support and add bullet protection
  45.  */
  46. #include "util.h"
  47. #include "mmdf.h"
  48. #include "ch.h"                   /* has table state strcture def       */
  49. #include "dm.h"
  50. #include "chdbm.h"
  51.  
  52. extern LLog *logptr;
  53. extern char *tbldfldir;
  54. extern char *tbldbm;
  55. extern Chan **ch_tbsrch;
  56. extern char *ch_dflnam;
  57.  
  58. extern char *strcpy();
  59.  
  60. typedef struct {char *dptr; int dsize;} datum;
  61.  
  62. extern datum fetch();
  63.  
  64. /* *******************  FIND HOST NAME IN ANY TABLE  ****************** */
  65.  
  66. Chan   *
  67.     ch_h2chan (hostr, pos) /* which chan name table is host in?  */
  68. char   *hostr;                   /* name of host                       */
  69. int     pos;                    /* which position to get  (0 = first) */
  70. {
  71.     register    Chan    *chanptr;
  72.     register    struct DBvalues *dp;
  73.     register    char    *cp;
  74.     DBMValues   dbm;
  75.     Chan    **chp;
  76.     char        hostname[ADDRSIZE];
  77. #ifdef    NAMESERVER
  78.     int         ns_done = 0;
  79. #endif /* NAMESERVER */
  80.     int         dbm_done = 0;
  81.  
  82. /*  the list of channel name tables is first searched.  If a hit is found
  83.  *  in the table for the local channel, OK is returned to indicate a local
  84.  *  reference.
  85.  */
  86.  
  87. #ifdef DEBUG
  88.     ll_log( logptr, LLOGFTR, "h2chan ('%s', %d)", hostr, pos);
  89. #endif
  90.     for (chp = ch_tbsrch; (chanptr = *chp) != (Chan *)0; chp++)
  91.     {
  92. #ifdef DEBUG
  93.     ll_log( logptr, LLOGFTR, "h2chan table '%s'",
  94.         chanptr->ch_table->tb_name);
  95. #endif
  96. #ifdef NAMESERVER
  97.     if ((chanptr -> ch_table -> tb_flags & TB_SRC) == TB_NS) {
  98.         if (!ns_done) {
  99.         /*
  100.          * assumes the fact we are looking for a 'channel'
  101.          * if this is not the case you must do the lookup every
  102.          * time round the loop
  103.          * This code believes all NS channel tables are equivalent,
  104.          * and they will return the same answer.  Not unreasonable
  105.          * at the current time, but watch out.
  106.          */
  107.  
  108.         switch(ns_fetch (chanptr->ch_table, hostr, hostname, 1)){
  109.         case OK:
  110.             ns_done++;
  111.             break;
  112.         case MAYBE:
  113.             return( (Chan *)MAYBE);
  114.         }
  115.         ns_done++;
  116.         }
  117.         if (ns_done == 1)
  118.         continue;
  119.         if(--pos > 0)
  120.         continue;
  121. #if DEBUG > 1
  122.         ll_log( logptr, LLOGFTR, "NSconsider ('%s', '%s')",
  123.         hostname, chanptr->ch_lname);
  124. #endif
  125.         if (lexequ (chanptr -> ch_name, ch_dflnam))
  126.         return( (Chan *)OK );   /* local ref             */
  127.         return( chanptr );
  128.     }
  129.     else
  130. #endif /* NAMESERVER */
  131.     {
  132.         if (!dbm_done) {
  133.         dbm_done++;
  134.         if (tb_fetch (hostr, dbm))
  135.              dbm_done++;
  136.         }
  137.         if (dbm_done == 1)
  138.         continue;
  139.         for (dp = dbm ; (cp = dp->RECname) != NULL ; dp++) {
  140. #if DEBUG > 1
  141.         ll_log( logptr, LLOGFTR, "consider ('%s')", cp);
  142. #endif
  143.         if (lexequ(cp, chanptr -> ch_table -> tb_name)) {
  144.             if (--pos > 0)
  145.             break;
  146.             if (lexequ(chanptr -> ch_name, ch_dflnam))
  147.             return( (Chan *)OK );
  148.             return(chanptr);
  149.         }
  150.         }
  151.     }
  152.     }
  153.  
  154.     return ((Chan *) NOTOK);
  155. }
  156.  
  157. /*  ***********  GIVEN Subdomain, FIND Domain  ***************** */
  158.  
  159. Domain *
  160.     dm_s2dom (subdomain, official, dmbuf)
  161. char    *subdomain;             /* name of subdomain to look up              */
  162. char    *official;              /* Where to put official name */
  163. char    *dmbuf;                 /* Domain route buffer */
  164. {
  165.     register    Domain    *dmnptr;
  166.     register    char    *cp;
  167.     register    struct DBvalues *dp;
  168.     DBMValues   dbm;
  169.     extern    Domain    **dm_list;
  170.     Domain    **dmp;
  171.     char    *argv[DM_NFIELD];
  172.     int         dbm_done = 0;
  173.     char        sdbuf[LINESIZE];
  174.  
  175. #ifdef DEBUG
  176.     ll_log( logptr, LLOGFTR, "dm_s2dom ('%s')", subdomain);
  177. #endif
  178.  
  179.     for (dmp = dm_list; (dmnptr = *dmp) != (Domain *)0; dmp++)
  180.     {
  181.     /* If flags=partial is not set or this is a top domain table    */
  182.     /* (indicating that we've already tried this match as a "route" */
  183.     /* match), skip it.                                             */
  184.     if (((dmnptr -> dm_table -> tb_flags & TB_PARTIAL) != TB_PARTIAL) ||
  185.         (!isstr(dmnptr->dm_domain)))
  186.         continue;
  187. #ifdef NAMESERVER
  188.     if ((dmnptr -> dm_table -> tb_flags & TB_SRC) == TB_NS) {
  189.         sprintf(sdbuf, "%s.%s", subdomain, dmnptr->dm_domain);
  190.         switch (ns_fetch(dmnptr->dm_table,sdbuf,official,1)) {
  191.         case OK:
  192.             /* route is simply official name */
  193.             (void) strcpy(dmbuf,official);
  194.             return( dmnptr );
  195.         case MAYBE:
  196.             return( (Domain *)MAYBE);
  197.         }
  198.     }
  199.     else
  200. #endif /* NAMESERVER */
  201.     {
  202.         if (!dbm_done) {
  203.         dbm_done++;
  204.         if (tb_fetch (subdomain, dbm))
  205.              dbm_done++;
  206.         }
  207.         if (dbm_done == 1)
  208.         continue;
  209.         for ( dp = dbm ; (cp = dp->RECname) != NULL ; dp++) {
  210. #ifdef DEBUG
  211.         ll_log( logptr, LLOGFTR, "dm_s2dom: consider ('%s')", cp);
  212. #endif
  213.         if (!lexequ(cp, dmnptr -> dm_table -> tb_name))
  214.             continue;
  215.         if(dp->RECval == NULL) {    /* should never happen */
  216.             *dmbuf = *official = '\0';
  217.             return(dmnptr);
  218.         }
  219.         (void) strcpy (dmbuf, dp->RECval);
  220.         str2arg(dp->RECval, DM_NFIELD, argv, 0);
  221.         (void) strcpy(official, argv[0]);
  222.         return(dmnptr);
  223.         }
  224.     }
  225.     }
  226.  
  227.     (void) strcpy (official, subdomain);
  228.     return ((Domain *) NOTOK);
  229. }
  230.  
  231. /*  *******  Get a record from the database, given a key    ********** */
  232. /*            Note that the strings are in internal statics             */
  233.  
  234. tb_fetch (name, dbm)                /* return filled entry for name */
  235. char *name;                         /* use this key to fetch entry  */
  236. DBMValues dbm;                      /* put the entry here           */
  237. {
  238.     LOCVAR int dbmopen = FALSE;
  239.     LOCVAR char dbvalue[256];
  240.     datum key, value;
  241.     char *lastchar;
  242.     register char *p, *cp;
  243.     register struct DBvalues *dp;
  244.     register cnt;
  245.  
  246.     if (!dbmopen)
  247.     {
  248.     extern int dbminit();
  249.     char filename[128];
  250.  
  251. #ifdef DEBUG
  252.     ll_log (logptr, LLOGBTR, "tb_fetch: dbminit");
  253. #endif
  254.     getfpath (tbldbm, tbldfldir, filename);
  255.     if (dbminit (filename) < 0)
  256.         err_abrt (LLOGTMP, "Error opening database '%s'", filename);
  257.  
  258.     dbmopen = TRUE;
  259.     }
  260.  
  261. #ifdef DEBUG
  262.     ll_log (logptr, LLOGBTR, "fetch (%s)", name);
  263. #endif
  264.     key.dptr = name;
  265.     key.dsize = strlen (name) + 1;
  266.     for (p = name; *p; p++)
  267.     *p = uptolow (*p);
  268.  
  269.     value = fetch (key);
  270.     if (value.dptr == NULL)
  271.     {
  272. #ifdef DEBUG
  273.     ll_log (logptr, LLOGBTR, "fetch of '%s' failed", name);
  274. #endif
  275.     return (FALSE);
  276.     }
  277.     for (cp = value.dptr, p= dbvalue, lastchar = &p[value.dsize];
  278.         p < lastchar; *p++ = *cp++) ;
  279.     *p = '\0';                  /* copy value to separate storage */
  280.  
  281.     for (p = dbvalue , dp = dbm, cnt = 0; *p && cnt < MAXVAL ; cnt++, dp++)
  282.     {
  283.     for(dp->RECname = p ; *p ; p++)
  284.         if (*p == ' ') {      /* get table name */
  285.         *p++ = '\0';
  286.         break;
  287.         }
  288.     for (dp->RECval = (*p ? p : NULL); *p; p++)
  289.         if (*p == FS) {      /* get value-part */
  290.         *p++ = '\0';
  291.         break;
  292.         }
  293. #ifdef DEBUG
  294.     ll_log (logptr, LLOGFTR, "fetch val(%d)='%s/%s'",
  295.         cnt, dp->RECname, (dp->RECval==NULL) ? "<NULL>": dp->RECval);
  296. #endif
  297.     }
  298.     for(;cnt <= MAXVAL; cnt++, dp++)    /* zero the rest of the structures */
  299.     dp->RECname = dp->RECval = NULL;
  300.  
  301.     return (TRUE);
  302. }
  303.  
  304. /*  *******  FIND VALUE (address), GIVEN ITS KEY (hostname)  ********* */
  305.  
  306.  
  307. tb_k2val (table, first, name, buf) /* use key and return value */
  308. register Table  *table;
  309. int     first;                    /* start at beginning of list?        */
  310. register char  name[];            /* name of ch "member" / key          */
  311. char   *buf;                      /* put value int this buffer          */
  312. {
  313. LOCVAR DBMValues dbm;
  314. LOCVAR struct DBvalues *dp = (struct DBvalues *) 0;
  315.     register char *cp;
  316. #ifdef  NAMESERVER
  317.     int retval;
  318. #endif
  319.     
  320.  
  321. #ifdef DEBUG
  322.     ll_log (logptr, LLOGBTR, "tb_k2val (%s, first=%d, %s)",
  323.             table -> tb_name, first, name);
  324. #endif
  325.  
  326. #ifdef NAMESERVER
  327.     if ((table->tb_flags&TB_SRC) == TB_NS) {
  328.     if ((retval = ns_fetch (table, name, buf, first)) != NOTOK)
  329.         return (retval);
  330. #ifdef DEBUG
  331.     ll_log (logptr, LLOGFTR, "tb_k2val failed");
  332. #endif
  333.     (void) strcpy (buf, "(ERROR)");
  334.     return (NOTOK);
  335.     }
  336. #endif /* NAMESERVER */
  337.  
  338.     if (!first)
  339.     dp++;
  340.     else
  341.     {
  342.     if (tb_fetch (name, dbm))
  343.     {
  344. #ifdef DEBUG
  345.         ll_log (logptr, LLOGFTR, "hit");
  346. #endif
  347.         dp = dbm;
  348.     }
  349.     else
  350.         dp = (struct DBvalues *) 0;  /* none */
  351.     }
  352.  
  353.     if (dp)
  354.     for (; (cp = dp->RECname) != NULL; dp++)
  355.     {
  356.         if (strequ (cp, table -> tb_name))
  357.         {                       /* this is the right channel        */
  358. #ifdef DEBUG
  359.         ll_log (logptr, LLOGFTR, "table(%s)", cp);
  360. #endif
  361.         if(dp->RECval == NULL)
  362.             *buf = '\0';
  363.         else
  364.             (void) strcpy (buf, dp->RECval);
  365.         return (OK);      /* give them the value-part         */
  366.         }
  367.     }
  368. #ifdef DEBUG
  369.     ll_log (logptr, LLOGFTR, "tb_k2val failed");
  370. #endif
  371.     (void) strcpy (buf, "(ERROR)");
  372.     return (NOTOK);
  373. }
  374.