home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / oogl / util / findfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-11  |  6.0 KB  |  219 lines

  1. /* Copyright (c) 1992 The Geometry Center; University of Minnesota
  2.    1300 South Second Street;  Minneapolis, MN  55454, USA;
  3.    
  4. This file is part of geomview/OOGL. geomview/OOGL is free software;
  5. you can redistribute it and/or modify it only under the terms given in
  6. the file COPYING, which you should have received along with this file.
  7. This and other related software may be obtained via anonymous ftp from
  8. geom.umn.edu; email: software@geom.umn.edu. */
  9. static char *copyright = "Copyright (C) 1992 The Geometry Center";
  10.  
  11. /* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */
  12.  
  13. /* $Header: /usrb/gcg/ngrap/src/lib/oogl/util/RCS/findfile.c,v 1.12 1993/03/11 21:37:49 slevy Exp $ */
  14.  
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include "ooglutil.h"
  19.  
  20. #ifdef NeXT
  21. #include <fcntl.h>
  22. #else
  23. #include <unistd.h>        /* needed for access() */
  24. #endif
  25. #include <stdlib.h>
  26.  
  27.  
  28. static char **dirlist = NULL;
  29. static void dirprefix(char *file, char *dir);
  30. char *envexpand(char *s);
  31.  
  32. /*-----------------------------------------------------------------------
  33.  * Function:    filedirs
  34.  * Description:    set the list of directories to search for files
  35.  * Args:    dirs: NULL-terminated array of pointers to directory
  36.  *          strings
  37.  * Author:    mbp
  38.  * Date:    Wed Feb 12 14:09:48 1992
  39.  * Notes:    This function sets the list of directories searched by
  40.  *        findfile().   It makes an internal copy of these directories
  41.  *        and expands all environment variables in them.
  42.  */
  43. void
  44. filedirs(char *dirs[])
  45. {
  46.   char buf[1024], **p;
  47.   int i,ndirs;
  48.  
  49.   if (dirlist) {
  50.     for (p=dirlist; *p!=NULL; ++p) OOGLFree(*p);
  51.     OOGLFree(dirlist);
  52.   }
  53.   for (ndirs=0; dirs[ndirs]!=NULL; ++ndirs);
  54.   dirlist = OOGLNewNE(char *,ndirs+1, "filedirs: dirlist");
  55.   for (i=0; i<ndirs; ++i) {
  56.     strcpy(buf, dirs[i]);
  57.     envexpand(buf);
  58.     dirlist[i] = strdup(buf);
  59.   }
  60.   dirlist[ndirs] = NULL;
  61. }
  62.  
  63.  
  64. /*-----------------------------------------------------------------------
  65.  * Function:    getfiledirs
  66.  * Description:    return the list of dirs set by the last call to filedirs()
  67.  * Author:    mbp
  68.  * Date:    Wed Feb 12 14:09:48 1992
  69.  */
  70. char **
  71. getfiledirs()
  72. {
  73.   return dirlist;
  74. }
  75.  
  76.  
  77. /*-----------------------------------------------------------------------
  78.  * Function:    findfile
  79.  * Description:    resolve a filename into a pathname
  80.  * Args:    *superfile: containing file
  81.  *        *file: file to look for
  82.  * Returns:    pointer to resolved pathname, or NULL if not found
  83.  * Author:    mbp
  84.  * Date:    Wed Feb 12 14:11:47 1992
  85.  * Notes:
  86.  *
  87.  * findfile() tries to locate a (readable) file in the following way.
  88.  *
  89.  *    If file begins with a '/' it is assumed to be an absolute path.  In
  90.  *    this case we expand any environment variables in file and test for
  91.  *    existence, returning a pointer to the expanded path if the file is
  92.  *    readable, NULL otherwise.
  93.  *
  94.  *    Now assume file does not begin with a '/'.
  95.  *
  96.  *    If superfile is non-NULL, we assume it is the pathname of a file
  97.  *    (not a directory), and we look for file in the directory of that
  98.  *    path.  Environment variables are expanded in file but not in
  99.  *    superfile.
  100.  *
  101.  *    If superfile is NULL, or if file isn't found superfile directory,
  102.  *    we look in each of the directories in the array last passed to
  103.  *    filedirs().  Environment variables are expanded in file and in
  104.  *    each of the directories last passed to filedirs().
  105.  *
  106.  *    We return a pointer to a string containing the entire pathname of
  107.  *    the first location where file is found, or NULL if it is not found.
  108.  *
  109.  *    In all cases the returned pointer points to dynamically allocated
  110.  *    space which will be freed on the next call to findfile().
  111.  *
  112.  *    File existence is tested with a call to access(), checking for read
  113.  *    permission.
  114.  */
  115. char *
  116. findfile(char *superfile, char *file)
  117. {
  118.   static char *path = NULL;
  119.   register char **dirp;
  120.   char pbuf[1024];
  121.  
  122.   if (path) {
  123.     OOGLFree(path);
  124.     path = NULL;
  125.   }
  126.   if (file == NULL) return NULL;
  127.   if (file[0] == '/' || file[0] == '$') {
  128.     strcpy(pbuf, file);
  129.     envexpand(pbuf);
  130.     if (access(pbuf,R_OK)==0)
  131.       return (path = strdup(pbuf));
  132.     else
  133.       return NULL;
  134.   }
  135.   if (superfile) {
  136.     dirprefix(superfile, pbuf);
  137.     strcat(pbuf, file);
  138.     envexpand(pbuf);
  139.     if (access(pbuf,R_OK)==0)
  140.       return (path = strdup(pbuf));
  141.   }
  142.   if(dirlist == NULL) {
  143.     if(access(file, R_OK) == 0)
  144.     return (path = strdup(file));
  145.   } else {
  146.       for (dirp = dirlist; *dirp != NULL; dirp++) {
  147.     sprintf(pbuf,"%s/%s", *dirp, file);
  148.     envexpand(pbuf);
  149.     if (access(pbuf,R_OK)==0)
  150.       return (path = strdup(pbuf));
  151.       }
  152.   }
  153.   return (path = NULL);
  154. }
  155.     
  156. /*-----------------------------------------------------------------------
  157.  * Function:    dirprefix
  158.  * Description:    get the directory prefix from a pathname
  159.  * Args:    *path: the pathname
  160.  *        *dir: pointer to location where answer is to be stored
  161.  * Author:    mbp
  162.  * Date:    Wed Feb 12 14:17:36 1992
  163.  * Notes:    Answer always ends with a '/' if path contains a '/',
  164.  *        otherwise dir is set to "".
  165.  */
  166. static void
  167. dirprefix(char *path, char *dir)
  168. {
  169.   register char *end;
  170.  
  171.   strcpy(dir, path);
  172.   end = dir + strlen(dir) - 1;
  173.   while (end >= dir && *end != '/') --end;
  174.   if (end >= dir) *(end+1) = '\0';
  175.   else dir[0] = '\0';
  176. }
  177.  
  178. /*-----------------------------------------------------------------------
  179.  * Function:    envexpand
  180.  * Description:    expand environment variables in a string
  181.  * Args:    *s: the string
  182.  * Returns:    s
  183.  * Author:    mbp
  184.  * Date:    Fri Feb 14 09:46:22 1992
  185.  * Notes:    expansion is done inplace; there better be enough room!
  186.  */
  187. char *
  188. envexpand(char *s)
  189. {
  190.   char *c, *env, *envend, *tail;
  191.  
  192.   c = s;
  193.   if (*c == '~' && (env = getenv("HOME"))) {
  194.     tail = strdup(c+1);
  195.     strcpy(c, env);
  196.     strcat(c, tail);
  197.     c += strlen(env);
  198.     free(tail);
  199.   }
  200.   while (*c != '\0') {
  201.     if (*c == '$') {
  202.       for(envend = c; isalnum(*++envend) || *envend == '_'; ) ;
  203.       tail = strdup(envend);
  204.       *envend = '\0';
  205.       if((env = getenv(c+1)) == NULL) {
  206.     OOGLError(1, "%s : No %s environment variable",s,c+1);
  207.     strcpy(c,tail);
  208.       } else {
  209.     strcpy(c,env);
  210.     strcat(c,tail);
  211.     c += strlen(env);
  212.       }
  213.       free(tail);
  214.     }
  215.     else ++c;
  216.   }
  217.   return s;
  218. }   
  219.