mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-27 08:49:16 +08:00
de23473ac3
re: Issue https:\\github.com\Unidata\netcdf-c\issues\2060 The path conversion code forgot to consider the case of windows network paths of the form \\svc\x\y... I have added support for it, but I can't really test it since I do not have access to a network drive.
205 lines
6.2 KiB
C
205 lines
6.2 KiB
C
/*
|
|
* Copyright 2018, University Corporation for Atmospheric Research
|
|
* See netcdf/COPYRIGHT file for copying and redistribution conditions.
|
|
*/
|
|
#ifndef _NCPATHMGR_H_
|
|
#define _NCPATHMGR_H_
|
|
|
|
#include "config.h"
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#ifdef HAVE_UNISTD_H
|
|
#include <unistd.h>
|
|
#endif
|
|
#ifdef HAVE_DIRENT_H
|
|
#include <dirent.h>
|
|
#endif
|
|
#ifdef HAVE_SYS_STAT_H
|
|
#include <sys/stat.h>
|
|
#endif
|
|
#ifdef HAVE_FCNTL_H
|
|
#include <fcntl.h>
|
|
#endif
|
|
#include "ncexternl.h"
|
|
|
|
#ifndef WINPATH
|
|
#ifdef _WIN32
|
|
#define WINPATH 1
|
|
#endif
|
|
#ifdef __MINGW32__
|
|
#define WINPATH 1
|
|
#endif
|
|
#endif
|
|
|
|
/* Define wrapper constants for use with NCaccess */
|
|
/* Define wrapper constants for use with NCaccess */
|
|
#ifdef _WIN32
|
|
#define ACCESS_MODE_EXISTS 0
|
|
#define ACCESS_MODE_R 4
|
|
#define ACCESS_MODE_W 2
|
|
#define ACCESS_MODE_RW 6
|
|
#ifndef O_RDONLY
|
|
#define O_RDONLY _O_RDONLY
|
|
#define O_RDWR _O_RDWR
|
|
#define O_APPEND _O_APPEND
|
|
#define O_BINARY _O_BINARY
|
|
#define O_CREAT _O_CREAT
|
|
#define O_EXCL _O_EXCL
|
|
#endif
|
|
#else
|
|
#define ACCESS_MODE_EXISTS (F_OK)
|
|
#define ACCESS_MODE_R (R_OK)
|
|
#define ACCESS_MODE_W (W_OK)
|
|
#define ACCESS_MODE_RW (R_OK|W_OK)
|
|
#endif
|
|
|
|
#ifdef _WIN32
|
|
#ifndef S_IFDIR
|
|
#define S_IFDIR _S_IFDIR
|
|
#define S_IFREG _S_IFREG
|
|
#endif
|
|
#ifndef S_ISDIR
|
|
#define S_ISDIR(mode) ((mode) & _S_IFDIR)
|
|
#define S_ISREG(mode) ((mode) & _S_IFREG)
|
|
#endif
|
|
#endif /*_WIN32*/
|
|
|
|
/*
|
|
WARNING: you should never need to explictly call this function;
|
|
rather it is invoked as part of the wrappers for e.g. NCfopen, etc.
|
|
|
|
This function attempts to take an arbitrary path and convert
|
|
it to a canonical form.
|
|
Assumptions about Input path:
|
|
1. It is a relative or absolute path
|
|
2. It is not a URL
|
|
3. It conforms to the format expected by one of the following:
|
|
Linux (/x/y/...),
|
|
Cygwin (/cygdrive/D/...),
|
|
Windows (D:\...),
|
|
Windows network path (\\mathworks\...)
|
|
MSYS (/D/...),
|
|
or relative (x/y...)
|
|
4. It is encoded in the local platform character set.
|
|
Note that for most systems, this is utf-8. But for Windows,
|
|
the encoding is most likely some form of ANSI code page, probably
|
|
the windows 1252 encoding.
|
|
Note that in any case, the path must be representable in the
|
|
local Code Page.
|
|
|
|
On output it produces a re-written path that has the following
|
|
properties:
|
|
1. The path is normalized to match the platform on which the code
|
|
is running (e.g. cygwin, windows, msys, linux). So for example
|
|
using a cygwin path under visual studio will convert e.g.
|
|
/cygdrive/d/x/y to d:\x\y. See ../unit_test/test_pathcvt.c
|
|
for example conversions.
|
|
It returns the converted path.
|
|
|
|
Note that this function is intended to be Idempotent: f(f(x) == f(x).
|
|
This means it is ok to call it repeatedly with no harm.
|
|
*/
|
|
EXTERNL char* NCpathcvt(const char* path);
|
|
|
|
/**
|
|
It is often convenient to convert a path to some canonical format
|
|
that has some desirable properties:
|
|
1. All backslashes have been converted to forward slash
|
|
2. It can be suffixed or prefixed by simple concatenation
|
|
with a '/' separator. The exception being if the base part
|
|
may be absolute, in which case, suffixing only is allowed;
|
|
the user is responsible for getting this right.
|
|
To this end we choose the linux/cygwin format as our standard canonical form.
|
|
If the path has a windows drive letter, then it is represented
|
|
in the cygwin "/cygdrive/<drive-letter>" form.
|
|
If it is a windows network path, then it starts with "//".
|
|
If it is on *nix* platform, then this sequence will never appear
|
|
and the canonical path will look like a standard *nix* path.
|
|
*/
|
|
EXTERNL int NCpathcanonical(const char* srcpath, char** canonp);
|
|
|
|
EXTERNL int NChasdriveletter(const char* path);
|
|
|
|
EXTERNL int NCisnetworkpath(const char* path);
|
|
|
|
/* Canonicalize and make absolute by prefixing the current working directory */
|
|
EXTERNL char* NCpathabsolute(const char* name);
|
|
|
|
/* Check if this path appears to start with a windows drive letter */
|
|
EXTERNL int NChasdriveletter(const char* path);
|
|
|
|
/* Convert from the local coding (e.g. ANSI) to utf-8;
|
|
note that this can produce unexpected results for Windows
|
|
because it first converts to wide character and then to utf8. */
|
|
EXTERNL int NCpath2utf8(const char* path, char** u8p);
|
|
|
|
/* Wrap various stdio and unistd IO functions.
|
|
It is especially important to use for windows so that
|
|
NCpathcvt (above) is invoked on the path.
|
|
*/
|
|
#if defined(WINPATH)
|
|
/* path converter wrappers*/
|
|
EXTERNL FILE* NCfopen(const char* path, const char* flags);
|
|
EXTERNL int NCopen3(const char* path, int flags, int mode);
|
|
EXTERNL int NCopen2(const char* path, int flags);
|
|
EXTERNL int NCaccess(const char* path, int mode);
|
|
EXTERNL int NCremove(const char* path);
|
|
EXTERNL int NCmkdir(const char* path, int mode);
|
|
EXTERNL int NCrmdir(const char* path);
|
|
EXTERNL char* NCgetcwd(char* cwdbuf, size_t len);
|
|
EXTERNL int NCmkstemp(char* buf);
|
|
|
|
#ifdef HAVE_SYS_STAT_H
|
|
EXTERNL int NCstat(char* path, struct stat* buf);
|
|
#endif
|
|
#ifdef HAVE_DIRENT_H
|
|
EXTERNL DIR* NCopendir(const char* path);
|
|
EXTERNL int NCclosedir(DIR* ent);
|
|
#endif
|
|
#else /*!WINPATH*/
|
|
#define NCfopen(path,flags) fopen((path),(flags))
|
|
#define NCopen3(path,flags,mode) open((path),(flags),(mode))
|
|
#define NCopen2(path,flags) open((path),(flags))
|
|
#define NCremove(path) remove(path)
|
|
#define NCaccess(path,mode) access(path,mode)
|
|
#define NCmkdir(path,mode) mkdir(path,mode)
|
|
#define NCgetcwd(buf,len) getcwd(buf,len)
|
|
#define NCmkstemp(buf) mkstemp(buf);
|
|
#define NCcwd(buf, len) getcwd(buf,len)
|
|
#define NCrmdir(path) rmdir(path)
|
|
#ifdef HAVE_SYS_STAT_H
|
|
#define NCstat(path,buf) stat(path,buf)
|
|
#endif
|
|
#ifdef HAVE_DIRENT_H
|
|
#define NCopendir(path) opendir(path)
|
|
#define NCclosedir(ent) closedir(ent)
|
|
#endif
|
|
#endif /*!WINPATH*/
|
|
|
|
/* Platform independent */
|
|
#define NCclose(fd) close(fd)
|
|
#define NCfstat(fd,buf) fstat(fd,buf)
|
|
|
|
/**************************************************/
|
|
/* Following definitions are for testing only */
|
|
|
|
/* Possible Kinds Of Output */
|
|
#define NCPD_UNKNOWN 0
|
|
#define NCPD_NIX 1
|
|
#define NCPD_MSYS 2
|
|
#define NCPD_CYGWIN 3
|
|
#define NCPD_WIN 4
|
|
#define NCPD_REL 5 /* actual kind is unknown */
|
|
|
|
EXTERNL char* NCpathcvt_test(const char* path, int ukind, int udrive);
|
|
|
|
EXTERNL void printutf8hex(const char* s, char* sx);
|
|
|
|
/**************************************************/
|
|
/* From dutil.c */
|
|
EXTERNL char* NC_backslashEscape(const char* s);
|
|
EXTERNL char* NC_backslashUnescape(const char* esc);
|
|
EXTERNL char* NC_shellUnescape(const char* esc);
|
|
|
|
#endif /* _NCPATHMGR_H_ */
|