Newer
Older
/* 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$ */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#undef isspace /* Hacks for Irix 6.5.x */
#undef isascii
#undef isalnum
/*#include "ooglutil.h"*/
#include "shmem.h"
#if defined(unix) || defined(__unix)
#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;
char **odirlist = 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;
if (odirlist) {
for (p=odirlist; *p!=NULL; ++p) free(*p);
OOGLFree(odirlist);
}
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
}
/*-----------------------------------------------------------------------
* 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];
int trydot = 1;
if (path) {
free(path);
path = NULL;
}
if (file == NULL) return NULL;
if (file[0] == '/' || file[0] == '$' || file[0] == '~'
|| (file[0] == '.' && file[1] == '/') ) {
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
strcpy(pbuf, file);
envexpand(pbuf);
if (access(pbuf,R_OK)==0)
return (path = strdup(pbuf));
else
return NULL;
}
if (superfile) {
dirprefix(superfile, pbuf);
if(pbuf[0] == '\0' || !strcmp(pbuf, "."))
trydot = 0;
strcat(pbuf, file);
envexpand(pbuf);
if (access(pbuf,R_OK)==0)
return (path = strdup(pbuf));
}
if(dirlist != NULL) {
for (dirp = dirlist; *dirp != NULL; dirp++) {
if(!strcmp(*dirp, ".")) trydot = 0;
sprintf(pbuf,"%s/%s", *dirp, file);
envexpand(pbuf);
if (access(pbuf,R_OK)==0)
return (path = strdup(pbuf));
}
}
/* Implicitly add "." at end of search path */
if(trydot && access(file,R_OK) == 0)
return (path = strdup(file));
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) {
fprintf(stderr, "%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;
}