home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / uumail3 / part2 / getpath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  8.6 KB  |  350 lines

  1. /*
  2.  * Name: getpath -- return the full usenet path of the given name
  3.  *
  4.  * Paramaters: sysname (input) -- The system name to be expanded
  5.  *           pathname (output)  The usenet path of the given system name
  6.  *           pathfile (input) the file to search for the system name
  7.  *
  8.  * Returns: EX_OK     -- path found
  9.  *        EX_NOHOST -- path not found
  10.  *        EX_NOINPUT-- unable to open usemap
  11.  *          EX_TEMPFAIL -- database being rebuilt
  12.  *
  13.  * Original Version Author: J. Donnelly   3/82
  14.  *
  15.  */
  16.  
  17. /*    IF YOU ARE USING A DBM DATABASE, READ THIS!
  18.  *    If the special sentinel value of @@@ is not present in the
  19.  *    database, then it is assumed that the database is being
  20.  *    rebuilt and the requesting process is blocked for TIMEOUT
  21.  *    (default = 180) seconds.  If, after 5 such blocks, the
  22.  *    sentinel is not present, the error code EX_TEMPFAIL is returned.
  23.  *    The same is true if the dbm files cannot be initialized.
  24.  */
  25.  
  26. /***************************************************************************
  27. This work in its current form is Copyright 1986 Stan Barber
  28. with the exception of opath, gethostname and the original getpath which
  29. as far as I know are in the Public Domain. This software may be distributed
  30. freely as long as no profit is made from such distribution and this notice
  31. is reproducted in whole.
  32. ***************************************************************************
  33. This software is provided on an "as is" basis with no guarantee of 
  34. usefulness or correctness of operation for any purpose, intended or
  35. otherwise. The author is in no way liable for this software's performance
  36. or any damage it may cause to any data of any kind anywhere.
  37. ***************************************************************************/
  38. /* 22-jun-83 Sheppard
  39.  * modified to rewind path file (if open), rather than open again
  40.  *
  41.  * $Log:    getpath.c,v $
  42.  * Revision 3.0  86/03/14  12:04:46  sob
  43.  * Release of 3/15/86 --- 3rd Release
  44.  * 
  45.  * Revision 1.19  86/03/14  11:57:23  sob
  46.  * updated copyright
  47.  * 
  48.  * Revision 1.18  86/03/11  11:28:58  sob
  49.  * Added Copyright Notice
  50.  * 
  51.  * Revision 1.17  86/03/03  17:16:59  sob
  52.  * Added fixes provided by desint!geoff.
  53.  * Stan
  54.  * 
  55.  * Revision 1.16  86/02/24  12:45:36  sob
  56.  * Bug fix in scanning the list from uuname.
  57.  * Stan
  58.  * 
  59.  * Revision 1.15  86/02/23  23:01:53  sob
  60.  * This version will use data from the uuname command as well as
  61.  * data from the database
  62.  * 
  63.  * Revision 1.14  85/12/13  15:23:21  sob
  64.  * Added patches from umd-cs!steve
  65.  * 
  66.  * Revision 1.13  85/12/10  20:36:58  sob
  67.  * Added modifications suggested in gatech's version of uumail.
  68.  * Now, the DBM version of the database needs to have a SENTINAL in it
  69.  * to indicate that the DATABASE is not being updated. Also added similiar
  70.  * indicators to the non-DBM version to compare modification times and act
  71.  * accordingly. 
  72.  * 
  73.  * Revision 1.12  85/12/02  15:48:39  sob
  74.  * Combined speed hacks and old way of reading database and
  75.  * added compile flag SORTED. If database is SORTED and not DBM, use
  76.  * -DSORTED in CFLAGS to make it fast. If database is not sorted
  77.  * DO NOT use this flag.
  78.  * 
  79.  * Revision 1.11  85/11/24  15:03:41  sob
  80.  * Added changes suggested by regina!mark
  81.  * 
  82.  * Revision 1.10  85/11/24  04:21:45  sob
  83.  * Added efficiency hacks supplied by meccts!asby (Shane P. McCarron)
  84.  * 
  85.  * Revision 1.9  85/11/14  20:21:49  sob
  86.  * Added #ifdef DEBUG to allow compilation without DEBUG
  87.  * 
  88.  * Revision 1.8  85/11/08  03:04:49  sob
  89.  * release version
  90.  * 
  91.  * Revision 1.7  85/09/30  02:47:40  sob
  92.  * Altered to use path filename from global variable.
  93.  * 
  94.  * Revision 1.6  85/08/03  00:48:57  UUCP
  95.  * Cleaned up with lint.
  96.  * Stan Barber
  97.  * 
  98.  * Revision 1.5  85/07/19  17:45:13  UUCP
  99.  * Added \t as a valid seperation character for the database
  100.  * in the non DBM case. This is what pathalias uses.
  101.  * 
  102.  * Revision 1.4  85/07/19  16:44:07  UUCP
  103.  * revised to return proper things in accordance with sysexits
  104.  * Stan
  105.  * 
  106.  * Revision 1.3  85/07/11  19:30:31  sob
  107.  * added "uuconf.h" include file and deleted duplicated information
  108.  * 
  109.  * Revision 1.2  85/07/10  18:30:59  sob
  110.  * updated to add DBM capabilities
  111.  * Stan Barber, Baylor College of Medicine
  112.  * 
  113.  * Revision 1.1  85/07/10  18:03:28  sob
  114.  * Initial revision
  115.  * 
  116.  */
  117.  
  118. #include    "uuconf.h"
  119. #ifndef DBM
  120. #include <sys/types.h>
  121. #include <sys/stat.h>
  122. #endif
  123.  
  124. static char rcsid[] = "$Header: getpath.c,v 3.0 86/03/14 12:04:46 sob RELEASE_3 $";
  125. extern char * index();
  126.  
  127. extern FILE * fopen (), *popen();
  128. FILE * in;
  129. bool nghborflag;
  130. char neighbors[NEIGHBORS][NAMESIZ]; 
  131.  
  132. int getpath (sysname, pathname,pathfile)
  133. char   *sysname, *pathname,*pathfile;
  134. {
  135.     int retval,indx;
  136. #ifdef DBM
  137.     datum lhs,rhs;
  138. #else
  139.     struct stat st;
  140.         time_t modtime;
  141. #ifdef SORTED
  142.     int scomp();
  143.  
  144.     long lo,hi;
  145.     long cur;
  146.     long last;
  147.     static char buf[256];
  148. #else
  149.     char    name[NAMESIZ],*p,t;
  150. #endif
  151. #endif
  152.  
  153. #ifdef DEBUG
  154. if (Debug>2)
  155.     printf("In getpath: Sysname = %s, Pathfile = %s\n",sysname,paths);
  156. #endif
  157.     if(nghborflag !=TRUE) getneighbors();
  158.     indx = 0;
  159.     while(neighbors[indx][0] != '\0'){
  160.         if(!strcmp(sysname,neighbors[indx])){
  161.         strcpy(pathname,neighbors[indx]);
  162.         strcat(pathname,"!%s");
  163.         return(EX_OK);
  164.         }
  165.         indx++;
  166.     }
  167.  
  168. #ifdef DBM
  169.     for (indx = 0; indx < 5; indx++)
  170.     {
  171.     if ((retval = dbminit (pathfile)) >= 0)
  172.         break;
  173.     
  174. #ifdef DEBUG
  175.     if (Debug>2)
  176.         fprintf (stderr, "Database unavailable.  Sleeping.\n");
  177. #endif
  178.     sleep (TIMEOUT);
  179.     }
  180.  
  181.     if (retval < 0)
  182.     return(EX_NOINPUT);
  183.  
  184.     lhs.dptr = SENTINEL;
  185.     lhs.dsize = strlen (SENTINEL) + 1;
  186.     for (indx = 0; indx < 5; indx++)
  187.     {
  188.     rhs = fetch (lhs);
  189.     if (rhs.dsize > 0)
  190.         break;
  191.     
  192. #ifdef DEBUG
  193.     if (Debug>2)
  194.         fprintf (stderr, "Database incomplete.  Sleeping.\n");
  195. #endif
  196.     sleep (TIMEOUT);
  197.     }
  198.     if (rhs.dsize <= 0)
  199.     return(EX_TEMPFAIL);
  200.  
  201.         lhs.dptr = sysname;
  202.     lhs.dsize = strlen(sysname)+1;
  203.     rhs = fetch(lhs);
  204.     if (rhs.dptr == NULL) return(EX_NOHOST); /* no name found */
  205.     strcpy(pathname,rhs.dptr);
  206.         return(EX_OK);            /* system name found */
  207.  
  208. #else
  209. if (in == NULL) 
  210.     {
  211.     for (indx = 0; indx < 5; indx++)
  212.         {
  213.         if ((in = fopen(pathfile, "r")) != NULL)
  214.             break;
  215.     
  216. #ifdef DEBUG
  217.         if (Debug>2)
  218.             fprintf (stderr, "Database unavailable.  Sleeping.\n");
  219. #endif
  220.         sleep (TIMEOUT);
  221.         }
  222.     if (in == NULL)
  223.     return(EX_NOINPUT);
  224.     }
  225.     else
  226.     rewind(in);
  227.     indx = 0;
  228. restart:
  229.     indx++;
  230.     if (indx > 5) return(EX_TEMPFAIL);
  231.     stat(pathfile, &st);
  232.     modtime=st.st_mtime; /* original last modification time */
  233.  
  234. #ifdef SORTED
  235.     lo = 0;
  236.     hi = st.st_size;
  237.     last = 0;
  238.     cur = hi >> 1;
  239.  
  240.     while (cur > lo && cur < hi)
  241.     {
  242.         stat(pathfile,&st);
  243.         if (st.st_mtime > modtime) goto restart;
  244.         fseek(in, cur, 0);
  245.         fgets(buf, sizeof(buf), in);
  246.         cur = ftell(in);
  247.         fgets(buf, sizeof(buf), in);
  248.  
  249. #ifdef    DEBUG
  250.     if (Debug > 4)
  251.         printf("Found site %s\n", buf);
  252. #endif
  253.         if (scomp(sysname, buf) < 0) hi = cur;
  254.         else
  255.         if (scomp(sysname, buf) > 0) lo = cur;
  256.         else
  257.         {
  258.             buf[strlen(buf)-1] = '\0';
  259.             strcpy(pathname, (char *)index(buf, '\t') + 1);
  260.             return(EX_OK);
  261.         }
  262.         cur = lo + ((hi - lo)>>1);
  263.         if (last == cur) 
  264.         {
  265.             fseek(in, lo, 0);
  266.             do
  267.             {
  268.                 fgets(buf, sizeof(buf), in);
  269.                 lo = ftell(in);
  270.                 if (scomp(sysname, buf) == 0)
  271.                 {
  272.                     buf[strlen(buf)-1] = '\0';
  273.                     strcpy(pathname, (char *)index(buf, '\t') + 1);
  274.                     return(EX_OK);
  275.                 }
  276.             } while (lo <= hi);
  277.             break;
  278.         } /* end if */
  279.         last = cur;
  280.     } /* end while */
  281.     return(EX_NOHOST);
  282. #else
  283.  
  284.     for (;;)
  285.     {
  286.     p = &name[0];
  287.     while ((t = getc(in)) != EOF && (*p++ = t) != ' ' && t != '\t'); /* read the system name */
  288.         stat(pathfile,&st);
  289.         if (st.st_mtime > modtime) goto restart;        /* database update in progress */
  290.     if( t == EOF) return(EX_NOHOST);
  291.     *--p = '\0';                    /* set end of string */
  292.     p = &name[0];
  293. #ifdef DEBUG
  294.     if (Debug>4) printf("Found %s\n",p);
  295. #endif
  296.     if (strcmp (p,sysname) == 0)
  297.         break;
  298.     while ((getc (in) != '\n'));            /* skip this path */
  299.     }
  300.     p = pathname;                    /* save start loc of pathname */
  301.     while ((*pathname++ = getc (in)) != '\n');
  302.     *--pathname = '\0';
  303.     pathname = p;
  304.     return(EX_OK);            /* system name found */
  305.  
  306. #endif
  307. #endif
  308. }
  309.  
  310. #ifdef    SORTED
  311. #define MAPTAB(c) ((c=='\t')?'\0':c)
  312.  
  313. int scomp(a,b)
  314. char *a,*b;
  315. {
  316. int r;
  317.     while (!(r=(MAPTAB(*a)-MAPTAB(*b))) && *a && *b && *a!='\t' && *b!='\t')
  318.     {
  319.            a++; b++;
  320.     }
  321.     return(r);
  322. }
  323. #endif
  324.  
  325. getneighbors()
  326. {
  327.     FILE *ppntr;
  328.     char * ptr;
  329.     int x = 0;
  330.     nghborflag = TRUE;
  331.     if ((ppntr = popen("uuname", "r")) != NULL) {
  332. #ifdef DEBUG
  333.     if (Debug>2)
  334.         fprintf(stderr,"Starting uuname\n");
  335. #endif
  336.     while((fgets(neighbors[x], NAMESIZ,ppntr)) != NULL){
  337.         if ((ptr = index(neighbors[x], '\n')) != NULL)
  338.                 *ptr = '\0';
  339. #ifdef DEBUG
  340.     if (Debug>4)
  341.         fprintf(stderr,"Neighbor # %d: %s\n",x+1,neighbors[x]);
  342. #endif
  343.         x++;
  344.         }    
  345.     (void) pclose(ppntr);
  346.     }
  347.     strcpy(neighbors[x],Myname);
  348. }
  349.  
  350.