src/path.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- vf_path_core_subst_ext
- vf_path_base
- vf_path_base_core
- vf_path_absolute
- vf_path_terminated_by_delim
- vf_path_terminated_by_2delims
- vf_path_del_terminating_2delims
- vf_path_cons_path
- vf_path_cons_path2
- cons_path
- vf_path_concat
- vf_path_file_read_ok
- vf_path_directory_read_ok
- vf_path_runtime_dir
- vf_path_find_runtime_file
- vf_path_runtime_file2
1 /*
2 * path.c --- path string functions
3 *
4 */
5 /*
6 * Copyright (C) 1996-1999 Hirotsugu Kakugawa.
7 * All rights reserved.
8 *
9 * This file is part of the VFlib Library. This library is free
10 * software; you can redistribute it and/or modify it under the terms of
11 * the GNU Library General Public License as published by the Free
12 * Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. This library is distributed in the hope
14 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
15 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
16 * PURPOSE. See the GNU Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 #include "config.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <ctype.h>
26 #ifdef HAVE_UNISTD_H
27 # include <unistd.h>
28 #endif
29 #if HAVE_STRING_H
30 # include <string.h>
31 #endif
32 #if HAVE_STRINGS_H
33 # include <strings.h>
34 #endif
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #if HAVE_SYS_STAT_H
38 # ifdef __linux__
39 # define __USE_BSD
40 # endif
41 # include <sys/stat.h>
42 #endif
43
44 #include "VFlib-3_6.h"
45 #include "VFsys.h"
46 #include "path.h"
47 #include "vflpaths.h"
48 #include "consts.h"
49 #include "str.h"
50
51
52 Private int cons_path(char *path, int n, char *dir, char *file, char *ext);
53 Private char *vf_path_runtime_file2(char *root, char *subdir, char *file,
54 char *envname);
55
56
57
58 Glocal char*
59 vf_path_core_subst_ext(char *f, char *ext)
/* [<][>][^][v][top][bottom][index][help] */
60 /* "/opt/font/cmr10.300pk" & "vf" => "cmr10.vf" */
61 /* IMPORTANT: CALLER MUST RELEASE RETURNED DATA OBJECT */
62 {
63 char *b, *p, *e;
64
65 if ((f == NULL) || (ext == NULL))
66 return NULL;
67
68 if ((b = vf_path_base(f)) == NULL){
69 vf_error = VF_ERR_NO_MEMORY;
70 return NULL;
71 }
72 if ((p = (char*)malloc(strlen(b) + 1 + strlen(ext) + 1)) == NULL){
73 vf_error = VF_ERR_NO_MEMORY;
74 return NULL;
75 }
76 strcpy(p, b);
77 vf_free(b);
78
79 if ((e = vf_index(p, '.')) != NULL)
80 *e = '\0';
81 if (*ext != '.')
82 strcat(p, ".");
83 strcat(p, ext);
84
85 return p;
86 }
87
88
89 Glocal char*
90 vf_path_base(char *f)
/* [<][>][^][v][top][bottom][index][help] */
91 /* "/opt/font/cmr10.300pk" => "cmr10.300pk" */
92 /* IMPORTANT: CALLER MUST RELEASE RETURNED DATA OBJECT */
93 {
94 char *s, *b;
95 int dl;
96
97 dl = strlen(vf_directory_delimiter);
98 b = f;
99 for (s = f; *s != '\0'; s++){
100 if (strncmp(s, vf_directory_delimiter, dl) == 0)
101 b = &s[dl];
102 }
103 return vf_strdup(b);
104 }
105
106
107 Glocal char*
108 vf_path_base_core(char *f)
/* [<][>][^][v][top][bottom][index][help] */
109 /* "/opt/font/cmr10.300pk" => "cmr10" */
110 /* IMPORTANT: CALLER MUST RELEASE RETURNED DATA OBJECT */
111 {
112 char *p, *core;
113
114 if ((core = vf_path_base(f)) == NULL)
115 return NULL;
116 if ((p = vf_index(core, '.')) != NULL)
117 *p = '\0';
118 return core;
119 }
120
121
122
123
124 Glocal int
125 vf_path_absolute(char *f)
/* [<][>][^][v][top][bottom][index][help] */
126 {
127 if (strncmp(f, vf_directory_delimiter,
128 strlen(vf_directory_delimiter)) == 0){
129 return TRUE;
130 }
131
132 #ifdef MSDOS
133 if ((strlen(f) >= 3)
134 && isalpha(f[0]) && (f[1] == ':')
135 && ((f[2] == '/') || (f[2] == '\\'))){
136 return TRUE;
137 }
138 #endif /*MSDOS*/
139
140 return FALSE;
141 }
142
143 Glocal int
144 vf_path_terminated_by_delim(char *f)
/* [<][>][^][v][top][bottom][index][help] */
145 {
146 int dlen, index;
147
148 dlen = strlen(vf_directory_delimiter);
149
150 if ((index = strlen(f) - dlen) < 0)
151 return FALSE;
152 if (strcmp(&f[index], vf_directory_delimiter) != 0)
153 return FALSE;
154
155 return TRUE;
156 }
157
158 Glocal int
159 vf_path_terminated_by_2delims(char *f)
/* [<][>][^][v][top][bottom][index][help] */
160 {
161 int dlen, index;
162
163 dlen = strlen(vf_directory_delimiter);
164
165 if ((index = strlen(f) - 2*dlen) < 0)
166 return FALSE;
167 if (strncmp(&f[index], vf_directory_delimiter, dlen) != 0)
168 return FALSE;
169 if (strncmp(&f[index+dlen], vf_directory_delimiter, dlen) != 0)
170 return FALSE;
171
172 return TRUE;
173 }
174
175 Glocal void
176 vf_path_del_terminating_2delims(char *f)
/* [<][>][^][v][top][bottom][index][help] */
177 {
178 int dlen;
179
180 if (vf_path_terminated_by_2delims(f) == TRUE){
181 dlen = strlen(vf_directory_delimiter);
182 f[strlen(f)-2*dlen] = '\0';
183 }
184 }
185
186 Glocal int
187 vf_path_cons_path(char *path, int n, char *dir, char *file)
/* [<][>][^][v][top][bottom][index][help] */
188 {
189 return cons_path(path, n, dir, file, NULL);
190 }
191
192 Glocal int
193 vf_path_cons_path2(char *path, int n, char *dir, char *file, char *ext)
/* [<][>][^][v][top][bottom][index][help] */
194 {
195 return cons_path(path, n, dir, file, ext);
196 }
197
198 Private int
199 cons_path(char *path, int n, char *dir, char *file, char *ext)
/* [<][>][^][v][top][bottom][index][help] */
200 {
201 int r;
202
203 r = n;
204 if (vf_path_absolute(file)){
205 strncpy(path, file, n);
206 if ((r -= strlen(file)) < 0)
207 return -1;
208 if (ext != NULL)
209 strncat(path, ext, r);
210 return 0;
211 } else {
212 strncpy(path, dir, r);
213 if ((r -= strlen(dir)) < 0)
214 return -1;
215 if (vf_path_terminated_by_2delims(path) == TRUE)
216 vf_path_del_terminating_2delims(path);
217 strncat(path, vf_directory_delimiter, r);
218 if ((r -= strlen(vf_directory_delimiter)) < 0)
219 return -1;
220 strncat(path, file, r);
221 if ((r -= strlen(file)) < 0)
222 return -1;
223 if (ext != NULL)
224 strncat(path, ext, r);
225 }
226
227 return 0;
228 }
229
230 Glocal int
231 vf_path_concat(char *path, int n, char *f)
/* [<][>][^][v][top][bottom][index][help] */
232 {
233 if (vf_path_terminated_by_2delims(path) == TRUE)
234 vf_path_del_terminating_2delims(path);
235 strncat(path, vf_directory_delimiter, n);
236 strncat(path, f, n - strlen(path));
237
238 return 0;
239 }
240
241
242
243
244 Glocal int
245 vf_path_file_read_ok(char *f)
/* [<][>][^][v][top][bottom][index][help] */
246 {
247 #if HAVE_SYS_STAT_H
248 struct stat st;
249
250 if (stat(f, &st) < 0)
251 return FALSE;
252 if ((st.st_mode & S_IFMT) != S_IFREG)
253 return FALSE;
254 #endif
255
256 if (access(f, R_OK) < 0)
257 return FALSE;
258
259 return TRUE;
260 }
261
262 Glocal int
263 vf_path_directory_read_ok(char *f)
/* [<][>][^][v][top][bottom][index][help] */
264 {
265 #if HAVE_SYS_STAT_H
266 struct stat st;
267
268 if (stat(f, &st) < 0)
269 return FALSE;
270 if ((st.st_mode & S_IFMT) != S_IFDIR)
271 return FALSE;
272 #endif
273
274 if (access(f, R_OK) < 0)
275 return FALSE;
276
277 return TRUE;
278 }
279
280
281 Glocal char*
282 vf_path_runtime_dir(char *subdir, char *envname)
/* [<][>][^][v][top][bottom][index][help] */
283 /* return a absolute directory name of SUBDIR under the default
284 runtime dir. Runtime dir can be overridden by ""
285 It can be overridden by an env var ENVNAME if
286 it is defined. */
287 /* IMPORTANT: CALLER MUST RELEASE RETURNED DATA OBJECT */
288 {
289 char *root, *dir, *s;
290 int sd_len, dir_len;
291
292 if ((root = getenv(VF_ENV_DIR_RUNTIME_LIB)) == NULL)
293 root = DIR_RUNTIME_LIB;
294
295 if ((envname != NULL) && ((s = getenv(envname)) != NULL)){
296 root = s;
297 subdir = NULL;
298 }
299
300 if (subdir == NULL)
301 sd_len = 0;
302 else
303 sd_len = strlen(subdir);
304 dir_len = strlen(root) + strlen(vf_directory_delimiter) + sd_len + 4;
305 ALLOCN_IF_ERR(dir, char, dir_len){
306 return NULL;
307 }
308
309 if ((subdir == NULL) || (strcmp(subdir, "") == 0)){
310 strncpy(dir, root, dir_len);
311 } else {
312 vf_path_cons_path(dir, dir_len, root, subdir);
313 }
314
315 return dir;
316 }
317
318 Glocal char*
319 vf_path_find_runtime_file(char *subdir, char *file, char *envname)
/* [<][>][^][v][top][bottom][index][help] */
320 /* return a absolute directory name of SUBDIR under the default
321 runtime dir. Runtime dir can be overridden by ""
322 It can be overridden by an env var ENVNAME if
323 it is defined. */
324 /* IMPORTANT: CALLER MUST RELEASE RETURNED DATA OBJECT */
325 {
326 char *root, *p;
327
328 if ((root = getenv(VF_ENV_DIR_RUNTIME_SITE_LIB)) == NULL)
329 root = DIR_RUNTIME_SITE_LIB;
330 p = vf_path_runtime_file2(root, subdir, file, envname);
331 if (p != NULL)
332 return p;
333
334 if ((root = getenv(VF_ENV_DIR_RUNTIME_LIB)) == NULL)
335 root = DIR_RUNTIME_LIB;
336 p = vf_path_runtime_file2(root, subdir, file, envname);
337 return p;
338 }
339
340 Private char*
341 vf_path_runtime_file2(char *root, char *subdir, char *file, char *envname)
/* [<][>][^][v][top][bottom][index][help] */
342 {
343 char *dir, *s;
344 int sd_len, dir_len;
345
346 if ((envname != NULL) && ((s = getenv(envname)) != NULL)){
347 root = s;
348 subdir = NULL;
349 }
350
351 if (subdir == NULL)
352 sd_len = 0;
353 else
354 sd_len = strlen(subdir);
355 dir_len = strlen(root) + sd_len + strlen(file)
356 + 2 * strlen(vf_directory_delimiter) + 8;
357 ALLOCN_IF_ERR(dir, char, dir_len){
358 return NULL;
359 }
360
361 if ((subdir == NULL) || (strcmp(subdir, "") == 0)){
362 vf_path_cons_path(dir, dir_len, root, file);
363 } else {
364 vf_path_cons_path(dir, dir_len, root, subdir);
365 vf_path_concat(dir, dir_len, file);
366 }
367 if (vf_path_file_read_ok(dir) == FALSE){
368 vf_free(dir);
369 dir = NULL;
370 }
371
372 return dir;
373 }
374
375
376 /*EOF*/