YAZ  5.34.0
tpath.c
Go to the documentation of this file.
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
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 
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 
38 int yaz_fclose (FILE *f)
39 {
40  return fclose(f);
41 }
42 
43 
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 
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 
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 
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 
char * name
Definition: initopt.c:18
Logging utility.
FILE * yaz_path_fopen(const char *path, const char *name, const char *mode)
opens first file in path in path
Definition: tpath.c:33
size_t yaz_filepath_comp(const char **path_p, const char **comp)
get next path component in filepath
Definition: tpath.c:44
int yaz_fclose(FILE *f)
closes file
Definition: tpath.c:38
FILE * yaz_fopen(const char *path, const char *fname, const char *mode, const char *base)
opens first file in path in path
Definition: tpath.c:117
int yaz_is_abspath(const char *p)
checks whether path is absolute
Definition: tpath.c:127
char * yaz_filepath_resolve(const char *fname, const char *path, const char *base, char *fullpath)
resolve file on path
Definition: tpath.c:74
File Path utilities.