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