|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T g
Length: 5257 (0x1489) Types: TextFile Names: »getpath.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦bfebc70e2⟧ »EurOpenD3/mail/sendmail-5.65b+IDA-1.4.3.tar.Z« └─⟦f9e35cd84⟧ └─⟦this⟧ »sendmail/uiuc/getpath.c«
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include "path.h" static char RCSid[] = "$Header: getpath.c,v 3.4 86/02/05 13:41:26 essick Exp $"; extern int Debug; /* in mainlines */ /* * char *getpath(dest) char *dest; * * look in the routing tables for a path from here to that * specified host. Return the path. * Return NULL if there is no such path. * * The returned path is of the form: * a!b!c!d!dest! (note trailing !) * * The path is saved in a static buffer so you have to save * it or it is destroyed in the next call. * * A re-write of what Jeff Donnelly did a while back. * Ray Essick * * The routing table contains lines of the form: * site<space>path * site = destination site * path = a!b!c!d!site! (note trailing !) * * Must be in alphabetical order since the search gives up * after finding a site "after" the one we want! */ FILE * fopen (); extern char *fgets (); static int Dbm_Ready = 0; /* whether init'ed */ static char *PathMap = PATHTABLE; /* path file */ char *getpath (dest) char *dest; { static char line[BUFSIZ]; FILE * mapfile; register char *p, *path; #ifdef DBM /* * A version of this routine which works with the set of routines * described in dbm(3x). * * Assumes that someone else is keeping the path tables correctly * updated (e.g., does a re-build on the table). */ { struct datum contents; /* returning to him */ struct datum key; /* fetch on this */ if (!Dbm_Ready) { if (dbminit (PathMap) < 0) /* failed */ goto hardway; /* try manually */ Dbm_Ready++; /* mark ready */ } key.dptr = dest; /* build fetch key */ key.dsize = strlen (dest) + 1; contents = fetch (key); /* grab it */ if (contents.dptr == (char *) NULL) goto checkstamps; /* try again */ if (contents.dsize == 0) /* empty! */ return ""; /* convert to null string */ return (contents.dptr); /* give him the path */ } checkstamps: /* failure above */ /* * check the time stamps and complain if they are outdated * so that someone will fix them. If they are correct, * then we should merely return failure */ { char name[1024]; struct stat stat1, stat2; sprintf (name, "%s.dir", PathMap); /* db file */ if (stat (name, &stat1) < 0) /* no db file */ goto hardway; /* force it */ if (stat (name, &stat2) < 0) /* no raw file */ return (char *) NULL; if (stat1.st_mtime >= stat2.st_mtime) /* current */ { return (char *) NULL; } else { /* * could do something about a message to inform * somebody that the database is out of date */ } } hardway: /* failure above */ /* * no database or out of date Do it by hand * and very s...l...o...w...l...y * * This algorithm should really do some sort of binary * search... */ #endif DBM if ((mapfile = fopen (PathMap, "r")) == NULL) return ((char *) NULL); /* no file */ while (fgets (line, BUFSIZ, mapfile) != NULL) { p = line; path = NULL; do { switch (*p) { case ' ': case '\t': /* zap and mark path */ if (path == NULL) /* only once */ { *p++ = '\0'; path = p; } else p++; /* gotta move over it */ break; case '\n': *p = '\0'; /* end of it all */ break; default: p++; break; } } while (*p); /* terminates after newline */ if (strcmp (line, dest) == 0) /* matches */ { break; /* jump and return */ } if (strcmp (line, dest) > 0) /* past it */ { path = NULL; break; } } fclose (mapfile); /* don't litter */ return (path); /* and our answer */ } /* * setpathfile(name) * char *name; * * set the DBM file used by the getpath routine to something * else. Close one if already open. */ setpathfile (name) char *name; { extern char *strsave (); if (Dbm_Ready) { Dbm_Ready = 0; /* * -ldbm makes no provision for closing the database */ } PathMap = strsave (name); /* save it */ } struct findpath_f *findpath (name) char *name; { register char *partial; register char *original; register char *path; register int fullroute; static struct findpath_f results; char *strsave(), *index(); if (name == (char *) NULL) return (struct findpath_f *) NULL; original = partial = strsave (name); path = (char *) NULL; fullroute = 1; while (partial && *partial) { path = getpath (partial); /* probe for a path */ if (Debug) fprintf (stderr, "Route to %s is %s\n", partial, path == (char *) NULL ? "(null)" : path); if (path != (char *) NULL) /* good - break */ break; partial++; /* skip current dot */ partial = index (partial, '.'); /* scan for dot */ fullroute = 0; /* no longer complete */ } if (path == (char *) NULL) return (struct findpath_f *) NULL; /* nothing */ results.fp_path = strsave (path); results.fp_matched = strsave (partial); results.fp_fullroute = fullroute; return (&results); }