home *** CD-ROM | disk | FTP | other *** search
- /*
- * Name: getpath -- return the full usenet path of the given name
- *
- * Paramaters: sysname (input) -- The system name to be expanded
- * pathname (output) The usenet path of the given system name
- * pathfile (input) the file to search for the system name
- *
- * Returns: EX_OK -- path found
- * EX_NOHOST -- path not found
- * EX_NOINPUT-- unable to open usemap
- * EX_TEMPFAIL -- database being rebuilt
- *
- * Author: J. Donnelly 3/82
- *
- */
-
- /* IF YOU ARE USING A DBM DATABASE, READ THIS!
- * If the special sentinel value of @@@ is not present in the
- * database, then it is assumed that the database is being
- * rebuilt and the requesting process is blocked for TIMEOUT
- * (default = 180) seconds. If, after 5 such blocks, the
- * sentinel is not present, the error code EX_TEMPFAIL is returned.
- * The same is true if the dbm files cannot be initialized.
- */
-
- /* 22-jun-83 Sheppard
- * modified to rewind path file (if open), rather than open again
- *
- * $Log: getpath.c,v $
- * Revision 1.14 85/12/13 15:23:21 sob
- * Added patches from umd-cs!steve
- *
- * Revision 1.13 85/12/10 20:36:58 sob
- * Added modifications suggested in gatech's version of uumail.
- * Now, the DBM version of the database needs to have a SENTINAL in it
- * to indicate that the DATABASE is not being updated. Also added similiar
- * indicators to the non-DBM version to compare modification times and act
- * accordingly.
- *
- * Revision 1.12 85/12/02 15:48:39 sob
- * Combined speed hacks and old way of reading database and
- * added compile flag SORTED. If database is SORTED and not DBM, use
- * -DSORTED in CFLAGS to make it fast. If database is not sorted
- * DO NOT use this flag.
- *
- * Revision 1.11 85/11/24 15:03:41 sob
- * Added changes suggested by regina!mark
- *
- * Revision 1.10 85/11/24 04:21:45 sob
- * Added efficiency hacks supplied by meccts!asby (Shane P. McCarron)
- *
- * Revision 1.9 85/11/14 20:21:49 sob
- * Added #ifdef DEBUG to allow compilation without DEBUG
- *
- * Revision 1.8 85/11/08 03:04:49 sob
- * release version
- *
- * Revision 1.7 85/09/30 02:47:40 sob
- * Altered to use path filename from global variable.
- *
- * Revision 1.6 85/08/03 00:48:57 UUCP
- * Cleaned up with lint.
- * Stan Barber
- *
- * Revision 1.5 85/07/19 17:45:13 UUCP
- * Added \t as a valid seperation character for the database
- * in the non DBM case. This is what pathalias uses.
- *
- * Revision 1.4 85/07/19 16:44:07 UUCP
- * revised to return proper things in accordance with sysexits
- * Stan
- *
- * Revision 1.3 85/07/11 19:30:31 sob
- * added "uuconf.h" include file and deleted duplicated information
- *
- * Revision 1.2 85/07/10 18:30:59 sob
- * updated to add DBM capabilities
- * Stan Barber, Baylor College of Medicine
- *
- * Revision 1.1 85/07/10 18:03:28 sob
- * Initial revision
- *
- */
-
- #include "uuconf.h"
- #ifndef DBM
- #include <sys/types.h>
- #include <sys/stat.h>
- #endif
-
- static char rcsid[] = "$Header: getpath.c,v 1.14 85/12/13 15:23:21 sob Exp $";
-
- FILE * fopen (), *in;
-
- int getpath (sysname, pathname,pathfile)
- char *sysname, *pathname,*pathfile;
- {
- int retval,indx;
- #ifdef DBM
- datum lhs,rhs;
- #else
- struct stat st;
- time_t modtime;
- #ifdef SORTED
- int scomp();
-
- long lo,hi;
- long cur;
- long last;
- static char buf[256];
- #else
- char name[NAMESIZ],*p,t;
- #endif
- #endif
-
- #ifdef DEBUG
- if (Debug>2)
- printf("In getpath: Sysname = %s, Pathfile = %s\n",sysname,paths);
- #endif
-
- #ifdef DBM
- for (indx = 0; indx < 5; indx++)
- {
- if ((retval = dbminit (pathfile)) >= 0)
- break;
-
- #ifdef DEBUG
- if (Debug>2)
- fprintf (stderr, "Database unavailable. Sleeping.\n");
- #endif
- sleep (TIMEOUT);
- }
-
- if (retval < 0)
- return(EX_NOINPUT);
-
- lhs.dptr = SENTINEL;
- lhs.dsize = strlen (SENTINEL) + 1;
- for (indx = 0; indx < 5; indx++)
- {
- rhs = fetch (lhs);
- if (rhs.dsize > 0)
- break;
-
- #ifdef DEBUG
- if (Debug>2)
- fprintf (stderr, "Database incomplete. Sleeping.\n");
- #endif
- sleep (TIMEOUT);
- }
- if (rhs.dsize <= 0)
- return(EX_TEMPFAIL);
-
- lhs.dptr = sysname;
- lhs.dsize = strlen(sysname)+1;
- rhs = fetch(lhs);
- if (rhs.dptr == NULL) return(EX_NOHOST); /* no name found */
- strcpy(pathname,rhs.dptr);
- return(EX_OK); /* system name found */
-
- #else
- if (in == NULL)
- {
- for (indx = 0; indx < 5; indx++)
- {
- if ((in = fopen(pathfile, "r")) != NULL)
- break;
-
- #ifdef DEBUG
- if (Debug>2)
- fprintf (stderr, "Database unavailable. Sleeping.\n");
- #endif
- sleep (TIMEOUT);
- }
- if (in == NULL)
- return(EX_NOINPUT);
- }
- else
- rewind(in);
- indx = 0;
- restart:
- indx++;
- if (indx > 5) return(EX_TEMPFAIL);
- stat(pathfile, &st);
- modtime=st.st_mtime; /* original last modification time */
-
- #ifdef SORTED
- lo = 0;
- hi = st.st_size;
- last = 0;
- cur = hi >> 1;
-
- while (cur > lo && cur < hi)
- {
- stat(pathfile,&st);
- if (st.st_mtime > modtime) goto restart;
- fseek(in, cur, 0);
- fgets(buf, sizeof(buf), in);
- cur = ftell(in);
- fgets(buf, sizeof(buf), in);
-
- #ifdef DEBUG
- if (Debug > 4)
- printf("Found site %s\n", buf);
- #endif
- if (scomp(sysname, buf) < 0) hi = cur;
- else
- if (scomp(sysname, buf) > 0) lo = cur;
- else
- {
- buf[strlen(buf)-1] = '\0';
- strcpy(pathname, (char *)index(buf, '\t') + 1);
- return(EX_OK);
- }
- cur = lo + ((hi - lo)>>1);
- if (last == cur)
- {
- fseek(in, lo, 0);
- do
- {
- fgets(buf, sizeof(buf), in);
- lo = ftell(in);
- if (scomp(sysname, buf) == 0)
- {
- buf[strlen(buf)-1] = '\0';
- strcpy(pathname, (char *)index(buf, '\t') + 1);
- return(EX_OK);
- }
- } while (lo <= hi);
- break;
- } /* end if */
- last = cur;
- } /* end while */
- return(EX_NOHOST);
- #else
-
- for (;;)
- {
- p = &name[0];
- while ((t = getc(in)) != EOF && (*p++ = t) != ' ' && t != '\t'); /* read the system name */
- stat(pathfile,&st);
- if (st.st_mtime > modtime) goto restart; /* database update in progress */
- if( t == EOF) return(EX_NOHOST);
- *--p = '\0'; /* set end of string */
- p = &name[0];
- #ifdef DEBUG
- if (Debug>4) printf("Found %s\n",p);
- #endif
- if (strcmp (p,sysname) == 0)
- break;
- while ((getc (in) != '\n')); /* skip this path */
- }
- p = pathname; /* save start loc of pathname */
- while ((*pathname++ = getc (in)) != '\n');
- *--pathname = '\0';
- pathname = p;
- return(EX_OK); /* system name found */
-
- #endif
- #endif
- }
-
- #ifdef SORTED
- #define MAPTAB(c) ((c=='\t')?'\0':c)
-
- int scomp(a,b)
- char *a,*b;
- {
- int r;
- while (!(r=(MAPTAB(*a)-MAPTAB(*b))) && *a && *b && *a!='\t' && *b!='\t')
- {
- a++; b++;
- }
- return(r);
- }
- #endif
-