From fe1e30ec10f06a1a2f4607f9c571eea1a9944c87 Mon Sep 17 00:00:00 2001 From: Dave Slattengren Date: Mon, 18 Apr 1983 20:45:55 -0800 Subject: [PATCH] date and time created 83/04/18 13:45:55 by slatteng SCCS-vsn: local/ditroff/ditroff.old.okeeffe/gremlin.aed/gremlin/path.c 1.1 --- .../gremlin.aed/gremlin/path.c | 339 ++++++++++++++++++ 1 file changed, 339 insertions(+) create mode 100644 usr/src/local/ditroff/ditroff.old.okeeffe/gremlin.aed/gremlin/path.c diff --git a/usr/src/local/ditroff/ditroff.old.okeeffe/gremlin.aed/gremlin/path.c b/usr/src/local/ditroff/ditroff.old.okeeffe/gremlin.aed/gremlin/path.c new file mode 100644 index 0000000000..d3550f807c --- /dev/null +++ b/usr/src/local/ditroff/ditroff.old.okeeffe/gremlin.aed/gremlin/path.c @@ -0,0 +1,339 @@ + +/* path.c + * + * Copyright -C- 1982 Barry S. Roitblat + * + * + * This file contains routines that a) implement a path mechanism, whereby + * several places may be searched for files, and b) provide a defaulting + * mechanism for file name extensions. + * + * (modified from code originally written by John Ousterhout for the caesar + * design system) + */ + +#include "gremlin.h" +#include +#include + +/* Imports from config.c: */ + +extern char GLibrary[]; + +/* Library routines: */ + +extern char *strcpy(), *strcpyn(), *index(), *sprintf(), *malloc(); + +/* The following string holds the current path,which consists of a bunch + * of directory names separated by spaces. + */ + +#define PATHSIZE 400 +static char path[PATHSIZE] = "."; + +/* The following string pointers constitute a cache of recently + * referenced tilde names. + */ + +#define NTILDE 10 +static char *tildename[NTILDE] = {NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL}; +static char *realname[NTILDE] = {NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL}; +static int discard = 0; + + +int +PConvertTilde(psource, pdest, size) +char **psource; /* Pointer to a pointer to the source string */ +char **pdest; /* Pointer to a pointer to the dest. string */ +int *size; /* Pointer to no. bytes available at pdest */ + +/*--------------------------------------------------------- + * This routine converts tilde notation into standard directory names. + * + * Results: + * If the conversion was done successfully, then TRUE is returned. + * If a user name couldn't be found in the password file, then + * FALSE is returned. + * + * Side Effects: + * If the first character of the string indicated by psource is a + * tilde ("~") then the subsequent user name is converted to a login + * directory name and stored in the string indicated by pdest. Then + * remaining characters in the file name at psource are copied to + * pdest and both pointers are updated. Upon return, psource points + * to the terminating character in the source file name and pdest + * points to the next character after the last character in the file + * name at that location. If a tilde cannot be converted because the + * user name cannot be found, psource is still advanced past the current + * entry, but pdest is unaffected. At most size characters will be + * stored at pdest, and the size is decremented by the number of + * characters we actually stored. + *--------------------------------------------------------- + */ + +{ + register char *ps, *pd; + struct passwd *passwd, *getpwnam(); + char username[17], *string; + int i, length; + + ps = *psource; + if (*ps == '~') + { + /* Copy the user name into a string (at most 16 characters). + * If we don't have a cached entry for this name, then + * read the password file entry for the user and grab out + * the login directory. + */ + + pd = username; + for (i=0; ; i++) + { + *pd = *++ps; + if (isspace(*pd) || (*pd=='\0') || (*pd=='/') || (*pd==':')) + break; + if (i < 16) pd++; + } + *pd = '\0'; + for (i=0; ipw_dir; + if (passwd != NULL) + { + discard++; + if (discard >= NTILDE) discard = 0; + if (tildename[discard] != NULL) + { + free(tildename[discard]); + free(realname[discard]); + } + tildename[discard] = malloc((unsigned) strlen(username)+1); + strcpy(tildename[discard], username); + realname[discard] = malloc((unsigned) strlen(string)+1); + strcpy(realname[discard], string); + } + else + + /* The entry can't be found, so skip the source entry and return */ + + { + while ((*ps != '\0') && !isspace(*ps) && (*ps != ':')) ps++; + *psource = ps; + return FALSE; + } + gotname: length = strlen(string); + if (length > *size) length = *size; + strcpyn(*pdest, string, length); + *size -= length; + pd = *pdest+length; + } + else pd = *pdest; + + /* Copy the rest of the directory name from the source to the dest. */ + + while ((*ps != '\0') && !isspace(*ps) && (*ps != ':')) + if (*size > 0) + { + *pd++ = *ps++; + (*size)--; + } + else ps++; + *psource = ps; + *pdest = pd; + return TRUE; +} + + +int +PSetPath(string) +char *string; /* Pointer to a string that is to become + * the new fle search path. Must consist + * of one or more directory names separated + * by white space or colons. Two adjacent + * colons are the same as ":.:". Tilde + * notation is ok. + */ + +/*--------------------------------------------------------- + * PSetPath sets up the current search path. + * + * Results: + * -1 is returned if one or more of the paths contained a tilde + * notation that couldn't be converted. -2 is returned if the + * path space was exhausted. Otherwise a value >= 0 is returned. + * + * Side Effects: + * The string is stored as the current path, and all entries with + * tilde notation are converted to non-tilde notation. Tilde entries + * that cannot be converted are ignored. Note: only PATHSIZE total + * bytes of path are stored, after tilde conversion. Excess bytes + * are truncated. + *--------------------------------------------------------- + */ + +{ + int result, spaceleft; + char *p; + + result = 0; + spaceleft = PATHSIZE-1; + p = path; + + if (*string == '\0') + { + path[0] = '.'; + path[1] = '\0'; + return 0; + } + + while (*string != '\0') + { + if (*string == ':') + if ((*++string == ':') && (spaceleft >= 2)) + { + *p++ = '.'; + *p++ = ' '; + spaceleft -= 2; + } + if (spaceleft <= 0) break; + while ((*string == ':') || isspace(*string)) string++; + if (!PConvertTilde(&string, &p, &spaceleft)) result = -1; + else if (spaceleft-- > 0) *p++ = ' '; + } + *p = '\0'; + if (spaceleft < 2) return -2; + return result; +} + + +char * +PGetPath() + +/*--------------------------------------------------------- + * This routine merely returns a poiner to the current path. + * + * Results: + * The address of the current path (with all tildes expanded). + * + * Side Effects: None. + *--------------------------------------------------------- + */ + +{ + return path; +} + + +FILE * +POpen(file, prealname, search) +char *file; /* Name of the file to be opened. */ +char **prealname; /* Pointer to a location that will be filled + * in with the address of the real name of + * the file that was successfully opened. + * If NULL, then nothing is stored. + */ +int search; /* If FALSE, then the search path business + * doesn't happen. A default extension + * will still be added. + */ + +/*--------------------------------------------------------- + * This routine does a file lookup using the current path and + * supplying a default extension. + * + * Results: + * A pointer to a FILE, or NULL if the file couldn't be found. + * + * Side Effects: + * If the first character of the + * file name is "~" or "/" or if search is FALSE, then we try + * to look up the file with the original name, doing tilde + * expansion of course and returning that result. If none of + * these conditions is met, we go through the current path + * trying to look up the file once for each path + * entry by prepending the path entry to the original file name. + * This concatenated name is stored in a static string and made + * available to the caller through prealname if the open succeeds. + * Note: the static string will be trashed on the next call to this + * routine. Also, note that no individual file name is allowed to + * be more than NAMESIZE characters long. Excess characters are lost. + *--------------------------------------------------------- + */ + +{ +#define NAMESIZE 50 + static char realname[NAMESIZE]; + char extendedname[NAMESIZE], *p, *p2; + int length, spaceleft, size; + FILE *f; + + if (file == NULL) return (FILE *) NULL; + if (file[0] == '\0') return (FILE *) NULL; + + if (prealname != NULL) *prealname = realname; + + /* Now try the original name. If it starts with a ~ or / look + * it up directly. + */ + + if (file[0] == '~') + { + p = realname; + length = NAMESIZE-1; + if (!PConvertTilde(&file, &p, &length)) return NULL; + *p = '\0'; + return fopen(realname, "r"); + } + + if ((file[0] == '/') || (search == FALSE)) + { + strcpyn(realname, file, NAMESIZE-1); + realname[NAMESIZE-1] = '\0'; + return fopen(realname, "r"); + } + + /* Now try going through the path. */ + + p = path; + while (*p != '\0') + { + spaceleft = NAMESIZE-1; + p2 = realname; + while (isspace(*p)) p++; + while ((*p != '\0') && !isspace(*p)) + if (spaceleft-- > 0) *p2++ = *p++; + else p++; + if (spaceleft-- > 0) *p2++ = '/'; + if (spaceleft > 0) strcpyn(p2, file, spaceleft); + realname[NAMESIZE-1] = '\0'; + f = fopen(realname, "r"); + if (f != NULL) return f; + } + + /* We've tried the path and that didn't work. As a last shot, + * try the library area. Only use the library for reads. + */ + + p = GLibrary; + p2 = realname; + size = NAMESIZE; + if (!PConvertTilde(&p, &p2, &size)) return FALSE; + (void) strcpyn(p2, file, size); + realname[NAMESIZE-1] = '\0'; + return fopen(realname, "r"); +} -- 2.20.1