ftp.nice.ch/pub/next/graphics/3d/geomview.1.4.1.s.tar.gz#/Geomview/src/lib/oogl/util/findfile.c

This is findfile.c in view mode; [Download] [Up]

/* Copyright (c) 1992 The Geometry Center; University of Minnesota
   1300 South Second Street;  Minneapolis, MN  55454, USA;
   
This file is part of geomview/OOGL. geomview/OOGL is free software;
you can redistribute it and/or modify it only under the terms given in
the file COPYING, which you should have received along with this file.
This and other related software may be obtained via anonymous ftp from
geom.umn.edu; email: software@geom.umn.edu. */
static char *copyright = "Copyright (C) 1992 The Geometry Center";

/* Authors: Charlie Gunn, Stuart Levy, Tamara Munzner, Mark Phillips */

/* $Header: /usrb/gcg/ngrap/src/lib/oogl/util/RCS/findfile.c,v 1.12 1993/03/11 21:37:49 slevy Exp $ */

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "ooglutil.h"

#ifdef NeXT
#include <fcntl.h>
#else
#include <unistd.h>		/* needed for access() */
#endif
#include <stdlib.h>


static char **dirlist = NULL;
static void dirprefix(char *file, char *dir);
char *envexpand(char *s);

/*-----------------------------------------------------------------------
 * Function:	filedirs
 * Description:	set the list of directories to search for files
 * Args:	dirs: NULL-terminated array of pointers to directory
 *		  strings
 * Author:	mbp
 * Date:	Wed Feb 12 14:09:48 1992
 * Notes:	This function sets the list of directories searched by
 *		findfile().   It makes an internal copy of these directories
 *		and expands all environment variables in them.
 */
void
filedirs(char *dirs[])
{
  char buf[1024], **p;
  int i,ndirs;

  if (dirlist) {
    for (p=dirlist; *p!=NULL; ++p) OOGLFree(*p);
    OOGLFree(dirlist);
  }
  for (ndirs=0; dirs[ndirs]!=NULL; ++ndirs);
  dirlist = OOGLNewNE(char *,ndirs+1, "filedirs: dirlist");
  for (i=0; i<ndirs; ++i) {
    strcpy(buf, dirs[i]);
    envexpand(buf);
    dirlist[i] = strdup(buf);
  }
  dirlist[ndirs] = NULL;
}


/*-----------------------------------------------------------------------
 * Function:	getfiledirs
 * Description:	return the list of dirs set by the last call to filedirs()
 * Author:	mbp
 * Date:	Wed Feb 12 14:09:48 1992
 */
char **
getfiledirs()
{
  return dirlist;
}


/*-----------------------------------------------------------------------
 * Function:	findfile
 * Description:	resolve a filename into a pathname
 * Args:	*superfile: containing file
 *		*file: file to look for
 * Returns:	pointer to resolved pathname, or NULL if not found
 * Author:	mbp
 * Date:	Wed Feb 12 14:11:47 1992
 * Notes:
 *
 * findfile() tries to locate a (readable) file in the following way.
 *
 *    If file begins with a '/' it is assumed to be an absolute path.  In
 *    this case we expand any environment variables in file and test for
 *    existence, returning a pointer to the expanded path if the file is
 *    readable, NULL otherwise.
 *
 *    Now assume file does not begin with a '/'.
 *
 *    If superfile is non-NULL, we assume it is the pathname of a file
 *    (not a directory), and we look for file in the directory of that
 *    path.  Environment variables are expanded in file but not in
 *    superfile.
 *
 *    If superfile is NULL, or if file isn't found superfile directory,
 *    we look in each of the directories in the array last passed to
 *    filedirs().  Environment variables are expanded in file and in
 *    each of the directories last passed to filedirs().
 *
 *    We return a pointer to a string containing the entire pathname of
 *    the first location where file is found, or NULL if it is not found.
 *
 *    In all cases the returned pointer points to dynamically allocated
 *    space which will be freed on the next call to findfile().
 *
 *    File existence is tested with a call to access(), checking for read
 *    permission.
 */
char *
findfile(char *superfile, char *file)
{
  static char *path = NULL;
  register char **dirp;
  char pbuf[1024];

  if (path) {
    OOGLFree(path);
    path = NULL;
  }
  if (file == NULL) return NULL;
  if (file[0] == '/' || file[0] == '$') {
    strcpy(pbuf, file);
    envexpand(pbuf);
    if (access(pbuf,R_OK)==0)
      return (path = strdup(pbuf));
    else
      return NULL;
  }
  if (superfile) {
    dirprefix(superfile, pbuf);
    strcat(pbuf, file);
    envexpand(pbuf);
    if (access(pbuf,R_OK)==0)
      return (path = strdup(pbuf));
  }
  if(dirlist == NULL) {
    if(access(file, R_OK) == 0)
	return (path = strdup(file));
  } else {
      for (dirp = dirlist; *dirp != NULL; dirp++) {
	sprintf(pbuf,"%s/%s", *dirp, file);
	envexpand(pbuf);
	if (access(pbuf,R_OK)==0)
	  return (path = strdup(pbuf));
      }
  }
  return (path = NULL);
}
    
/*-----------------------------------------------------------------------
 * Function:	dirprefix
 * Description:	get the directory prefix from a pathname
 * Args:	*path: the pathname
 *		*dir: pointer to location where answer is to be stored
 * Author:	mbp
 * Date:	Wed Feb 12 14:17:36 1992
 * Notes:	Answer always ends with a '/' if path contains a '/',
 *		otherwise dir is set to "".
 */
static void
dirprefix(char *path, char *dir)
{
  register char *end;

  strcpy(dir, path);
  end = dir + strlen(dir) - 1;
  while (end >= dir && *end != '/') --end;
  if (end >= dir) *(end+1) = '\0';
  else dir[0] = '\0';
}

/*-----------------------------------------------------------------------
 * Function:	envexpand
 * Description:	expand environment variables in a string
 * Args:	*s: the string
 * Returns:	s
 * Author:	mbp
 * Date:	Fri Feb 14 09:46:22 1992
 * Notes:	expansion is done inplace; there better be enough room!
 */
char *
envexpand(char *s)
{
  char *c, *env, *envend, *tail;

  c = s;
  if (*c == '~' && (env = getenv("HOME"))) {
    tail = strdup(c+1);
    strcpy(c, env);
    strcat(c, tail);
    c += strlen(env);
    free(tail);
  }
  while (*c != '\0') {
    if (*c == '$') {
      for(envend = c; isalnum(*++envend) || *envend == '_'; ) ;
      tail = strdup(envend);
      *envend = '\0';
      if((env = getenv(c+1)) == NULL) {
	OOGLError(1, "%s : No %s environment variable",s,c+1);
	strcpy(c,tail);
      } else {
	strcpy(c,env);
	strcat(c,tail);
	c += strlen(env);
      }
      free(tail);
    }
    else ++c;
  }
  return s;
}   

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.