1 /* This file is part of the YAZ toolkit.
2 * Copyright (C) Index Data
3 * See the file LICENSE for details.
4 */
5 /**
6 * \file tpath.c
7 * \brief File Path utilities
8 */
9
10 #if HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14
15 #include <stdio.h>
16 #include <string.h>
17 #include <yaz/tpath.h>
18 #include <yaz/log.h>
19 #if HAVE_SYS_TYPES_H
20 #include <sys/types.h>
21 #endif
22 #if HAVE_SYS_STAT_H
23 #include <sys/stat.h>
24 #endif
25 #if WIN32
26 #include <sys/stat.h>
27 #endif
28
29 #if HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
yaz_path_fopen(const char * path,const char * name,const char * mode)33 FILE *yaz_path_fopen(const char *path, const char *name, const char *mode)
34 {
35 return yaz_fopen(path, name, mode, 0);
36 }
37
yaz_fclose(FILE * f)38 int yaz_fclose (FILE *f)
39 {
40 return fclose(f);
41 }
42
43
yaz_filepath_comp(const char ** path_p,const char ** comp)44 size_t yaz_filepath_comp(const char **path_p, const char **comp)
45 {
46 const char *path = *path_p;
47 size_t len;
48 const char *path_sep;
49
50 /* somewhat dirty since we have to consider Windows
51 * drive letters..
52 */
53 if (path[0] && strchr("/\\.", path[0]))
54 path_sep = strchr(path+1, ':');
55 else if (path[0] && path[1])
56 path_sep = strchr(path+2, ':');
57 else
58 path_sep = 0;
59
60 if (path_sep)
61 {
62 len = path_sep - path;
63 *path_p = path + len + 1;
64 }
65 else
66 {
67 len = strlen(path);
68 *path_p = path + len;
69 }
70 *comp = path;
71 return len;
72 }
73
yaz_filepath_resolve(const char * fname,const char * path,const char * base,char * fullpath)74 char *yaz_filepath_resolve(const char *fname, const char *path,
75 const char *base, char *fullpath)
76 {
77 if (path && *path == '\0')
78 path = 0;
79 if (strchr("/\\", *fname))
80 path = 0;
81 for (;;)
82 {
83 struct stat stat_buf;
84 size_t slen = 0;
85
86 *fullpath = '\0';
87 if (path)
88 {
89 const char *comp;
90 size_t len = 0;
91
92 len = yaz_filepath_comp(&path, &comp);
93 if (!len)
94 break;
95
96 if (!strchr("/\\", *comp) && base)
97 {
98 /* yes: make base the first part */
99 strcpy(fullpath, base);
100 slen = strlen(fullpath);
101 fullpath[slen++] = '/';
102 }
103 memcpy(fullpath+slen, comp, len);
104 slen += len;
105 if(slen > 0 && !strchr("/\\", fullpath[slen-1]))
106 fullpath[slen++] = '/';
107 }
108 strcpy(fullpath+slen, fname);
109 if (stat(fullpath, &stat_buf) == 0)
110 return fullpath;
111 if (!path)
112 break;
113 }
114 return 0;
115 }
116
yaz_fopen(const char * path,const char * fname,const char * mode,const char * base)117 FILE *yaz_fopen(const char *path, const char *fname, const char *mode,
118 const char *base)
119 {
120 char fullpath[1024];
121
122 if (!yaz_filepath_resolve(fname, path, base, fullpath))
123 return 0; /* failure */
124 return fopen(fullpath, mode);
125 }
126
yaz_is_abspath(const char * p)127 int yaz_is_abspath(const char *p)
128 {
129 if (*p == '/')
130 return 1;
131 #ifdef WIN32
132 if (*p == '\\')
133 return 1;
134 if (*p && p[1] == ':' &&
135 ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')))
136 return 1;
137 #endif
138 return 0;
139 }
140 /*
141 * Local variables:
142 * c-basic-offset: 4
143 * c-file-style: "Stroustrup"
144 * indent-tabs-mode: nil
145 * End:
146 * vim: shiftwidth=4 tabstop=8 expandtab
147 */
148
149