sockets: fix for whether poll is available
[yaz-moved-to-github.git] / src / tpath.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) 1995-2011 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
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     for (;;)
80     {
81         struct stat stat_buf;
82         size_t slen = 0;
83        
84         *fullpath = '\0';
85         if (path)
86         {
87             const char *comp;
88             size_t len = 0;
89
90             len = yaz_filepath_comp(&path, &comp);
91             if (!len)
92                 break;
93
94             if (!strchr("/\\", *comp) && base)
95             {
96                 /* yes: make base the first part */
97                 strcpy(fullpath, base);
98                 slen = strlen(fullpath);
99                 fullpath[slen++] = '/';
100             }
101             memcpy(fullpath+slen, comp, len);
102             slen += len;
103             if(slen > 0 && !strchr("/\\", fullpath[slen-1]))
104                 fullpath[slen++] = '/';
105         }
106         strcpy(fullpath+slen, fname);
107         if (stat(fullpath, &stat_buf) == 0)
108             return fullpath;
109         if (!path)
110             break;
111     }
112     return 0;
113 }
114
115 FILE *yaz_fopen(const char *path, const char *fname, const char *mode,
116                 const char *base)
117 {
118     char fullpath[1024];
119
120     if (!yaz_filepath_resolve(fname, path, base, fullpath))
121         return 0; /* failure */
122     return fopen(fullpath, mode);
123 }
124
125 int yaz_is_abspath(const char *p)
126 {
127     if (*p == '/')
128         return 1;
129 #ifdef WIN32
130     if (*p == '\\')
131         return 1;
132     if (*p && p[1] == ':' && 
133         ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')))
134         return 1;
135 #endif
136     return 0;
137 }
138 /*
139  * Local variables:
140  * c-basic-offset: 4
141  * c-file-style: "Stroustrup"
142  * indent-tabs-mode: nil
143  * End:
144  * vim: shiftwidth=4 tabstop=8 expandtab
145  */
146