X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Ftpath.c;h=b802c98033a0af6df45dfc91bfc58f9fdc85e644;hp=38d66ef72185edc23c4ba16f131d3a24db8978be;hb=cf6bf2f04ed7e376bfd9a37f7ef4ab0366f46804;hpb=fb6d99a0c7e07d9cc4a315c447deaf6564a85505 diff --git a/src/tpath.c b/src/tpath.c index 38d66ef..b802c98 100644 --- a/src/tpath.c +++ b/src/tpath.c @@ -1,12 +1,10 @@ -/* - * Copyright (C) 1995-2005, Index Data ApS +/* This file is part of the YAZ toolkit. + * Copyright (C) 1995-2011 Index Data * See the file LICENSE for details. - * - * $Id: tpath.c,v 1.6 2005-06-25 15:46:06 adam Exp $ */ /** * \file tpath.c - * \brief Implements path fopen + * \brief File Path utilities */ #if HAVE_CONFIG_H @@ -16,79 +14,123 @@ #include #include -#include #include #include +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_SYS_STAT_H +#include +#endif +#if WIN32 +#include +#endif + +#if HAVE_UNISTD_H +#include +#endif FILE *yaz_path_fopen(const char *path, const char *name, const char *mode) { - return yaz_fopen (path, name, mode, 0); + return yaz_fopen(path, name, mode, 0); } int yaz_fclose (FILE *f) { - return fclose (f); + return fclose(f); } -FILE *yaz_fopen(const char *path, const char *name, const char *mode, - const char *base) + +size_t yaz_filepath_comp(const char **path_p, const char **comp) { - char spath[1024]; + const char *path = *path_p; + size_t len; + const char *path_sep; - for(;;) + /* somewhat dirty since we have to consider Windows + * drive letters.. + */ + if (path[0] && strchr("/\\.", path[0])) + path_sep = strchr(path+1, ':'); + else if (path[0] && path[1]) + path_sep = strchr(path+2, ':'); + else + path_sep = 0; + + if (path_sep) + { + len = path_sep - path; + *path_p = path + len + 1; + } + else { - FILE *f; + len = strlen(path); + *path_p = path + len; + } + *comp = path; + return len; +} - const char *path_sep = 0; - size_t len = 0; +char *yaz_filepath_resolve(const char *fname, const char *path, + const char *base, char *fullpath) +{ + if (path && *path == '\0') + path = 0; + for (;;) + { + struct stat stat_buf; size_t slen = 0; - - *spath = '\0'; + + *fullpath = '\0'; if (path) { - /* somewhat dirty since we have to consider Windows - * drive letters.. - */ - if (strchr ("/\\.", *path)) - { - path_sep = strchr (path+1, ':'); - } - else if (path[0] && path[1]) - path_sep = strchr (path+2, ':'); - if (path_sep) - len = path_sep - path; - else - len = strlen(path); - if (!strchr ("/\\", *path) && base) + const char *comp; + size_t len = 0; + + len = yaz_filepath_comp(&path, &comp); + if (!len) + break; + + if (!strchr("/\\", *comp) && base) { - strcpy (spath, base); - slen = strlen(spath); - spath[slen++] = '/'; + /* yes: make base the first part */ + strcpy(fullpath, base); + slen = strlen(fullpath); + fullpath[slen++] = '/'; } - memcpy (spath+slen, path, len); + memcpy(fullpath+slen, comp, len); slen += len; - if (!strchr("/\\", spath[slen-1])) - spath[slen++] = '/'; + if(slen > 0 && !strchr("/\\", fullpath[slen-1])) + fullpath[slen++] = '/'; } - strcpy (spath+slen, name); - if ((f = fopen(spath, mode))) - return f; - - if (!path_sep) + strcpy(fullpath+slen, fname); + if (stat(fullpath, &stat_buf) == 0) + return fullpath; + if (!path) break; - path = path_sep+1; } return 0; } -int yaz_is_abspath (const char *p) +FILE *yaz_fopen(const char *path, const char *fname, const char *mode, + const char *base) +{ + char fullpath[1024]; + + if (!yaz_filepath_resolve(fname, path, base, fullpath)) + return 0; /* failure */ + return fopen(fullpath, mode); +} + +int yaz_is_abspath(const char *p) { if (*p == '/') return 1; #ifdef WIN32 if (*p == '\\') return 1; - if (*p && p[1] == ':' && isalpha(*p)) + if (*p && p[1] == ':' && + ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z'))) return 1; #endif return 0; @@ -96,6 +138,7 @@ int yaz_is_abspath (const char *p) /* * Local variables: * c-basic-offset: 4 + * c-file-style: "Stroustrup" * indent-tabs-mode: nil * End: * vim: shiftwidth=4 tabstop=8 expandtab