Support drive letters and UNC paths on some non-Windows platforms.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3045 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -32,6 +32,9 @@ Documentation:
|
|||||||
in the directory. "/a/../b" will always be functionally equivalent to
|
in the directory. "/a/../b" will always be functionally equivalent to
|
||||||
"/b", even when "/a" is a symlink.
|
"/b", even when "/a" is a symlink.
|
||||||
|
|
||||||
|
Testing:
|
||||||
|
- Test mounting an UNC directory
|
||||||
|
|
||||||
Bugs:
|
Bugs:
|
||||||
- 'openDir(repository, "dir/")' will have the trailing '/'
|
- 'openDir(repository, "dir/")' will have the trailing '/'
|
||||||
in the dirHandle, which will cause problems.
|
in the dirHandle, which will cause problems.
|
||||||
|
|||||||
@@ -238,12 +238,12 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint,
|
|||||||
uio_MountInfo *mountInfo;
|
uio_MountInfo *mountInfo;
|
||||||
uio_MountTree *mountTree;
|
uio_MountTree *mountTree;
|
||||||
uio_PDirHandle *pRootHandle;
|
uio_PDirHandle *pRootHandle;
|
||||||
#ifdef WIN32
|
#ifdef BACKSLASH_IS_PATH_SEPARATOR
|
||||||
char *unixPath;
|
char *unixPath;
|
||||||
|
|
||||||
unixPath = dosToUnixPath(inPath);
|
unixPath = dosToUnixPath(inPath);
|
||||||
inPath = unixPath;
|
inPath = unixPath;
|
||||||
#endif
|
#endif /* BACKSLASH_IS_PATH_SEPARATOR */
|
||||||
|
|
||||||
if (inPath[0] == '/')
|
if (inPath[0] == '/')
|
||||||
inPath++;
|
inPath++;
|
||||||
@@ -252,9 +252,9 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint,
|
|||||||
&endDirHandle, &endInPath);
|
&endDirHandle, &endInPath);
|
||||||
if (*endInPath != '\0') {
|
if (*endInPath != '\0') {
|
||||||
// Path inside the filesystem to mount does not exist.
|
// Path inside the filesystem to mount does not exist.
|
||||||
#ifdef WIN32
|
#ifdef BACKSLASH_IS_PATH_SEPARATOR
|
||||||
uio_free(unixPath);
|
uio_free(unixPath);
|
||||||
#endif
|
#endif /* BACKSLASH_IS_PATH_SEPARATOR */
|
||||||
uio_PDirHandle_unref(endDirHandle);
|
uio_PDirHandle_unref(endDirHandle);
|
||||||
uio_PRoot_unrefMount(pRoot);
|
uio_PRoot_unrefMount(pRoot);
|
||||||
if (handle)
|
if (handle)
|
||||||
@@ -266,10 +266,10 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint,
|
|||||||
dirName = uio_malloc(endInPath - inPath + 1);
|
dirName = uio_malloc(endInPath - inPath + 1);
|
||||||
memcpy(dirName, inPath, endInPath - inPath);
|
memcpy(dirName, inPath, endInPath - inPath);
|
||||||
dirName[endInPath - inPath] = '\0';
|
dirName[endInPath - inPath] = '\0';
|
||||||
#ifdef WIN32
|
#ifdef BACKSLASH_IS_PATH_SEPARATOR
|
||||||
// InPath is a copy with the paths fixed.
|
// InPath is a copy with the paths fixed.
|
||||||
uio_free(unixPath);
|
uio_free(unixPath);
|
||||||
#endif
|
#endif /* BACKSLASH_IS_PATH_SEPARATOR */
|
||||||
mountInfo = uio_MountInfo_new(fsType, NULL, endDirHandle, dirName,
|
mountInfo = uio_MountInfo_new(fsType, NULL, endDirHandle, dirName,
|
||||||
autoMount, NULL, flags);
|
autoMount, NULL, flags);
|
||||||
uio_repositoryAddMount(destRep, mountInfo,
|
uio_repositoryAddMount(destRep, mountInfo,
|
||||||
|
|||||||
@@ -367,9 +367,9 @@ decomposePath(const char *path, uio_PathComp **pathComp,
|
|||||||
uio_PathComp **endResult = &result;
|
uio_PathComp **endResult = &result;
|
||||||
uio_bool absolute = false;
|
uio_bool absolute = false;
|
||||||
char *name;
|
char *name;
|
||||||
#ifdef WIN32
|
#ifdef HAVE_UNC_PATHS
|
||||||
size_t nameLen;
|
size_t nameLen;
|
||||||
#endif
|
#endif /* HAVE_UNC_PATHS */
|
||||||
|
|
||||||
if (path[0] == '\0') {
|
if (path[0] == '\0') {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
@@ -377,7 +377,7 @@ decomposePath(const char *path, uio_PathComp **pathComp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
last = NULL;
|
last = NULL;
|
||||||
#ifdef WIN32
|
#ifdef HAVE_UNC_PATHS
|
||||||
path += uio_getUNCServerShare(path, &name, &nameLen);
|
path += uio_getUNCServerShare(path, &name, &nameLen);
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
// UNC path
|
// UNC path
|
||||||
@@ -386,7 +386,10 @@ decomposePath(const char *path, uio_PathComp **pathComp,
|
|||||||
endResult = &last->next;
|
endResult = &last->next;
|
||||||
|
|
||||||
absolute = true;
|
absolute = true;
|
||||||
} else if (isDriveLetter(path[0]) && path[1] == ':') {
|
} else
|
||||||
|
#endif /* HAVE_UNC_PATHS */
|
||||||
|
#ifdef HAVE_DRIVE_LETTERS
|
||||||
|
if (isDriveLetter(path[0]) && path[1] == ':') {
|
||||||
// DOS/Windows drive letter.
|
// DOS/Windows drive letter.
|
||||||
if (path[2] != '\0' && !isPathDelimiter(path[2])) {
|
if (path[2] != '\0' && !isPathDelimiter(path[2])) {
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
@@ -398,7 +401,7 @@ decomposePath(const char *path, uio_PathComp **pathComp,
|
|||||||
endResult = &last->next;
|
endResult = &last->next;
|
||||||
absolute = true;
|
absolute = true;
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif /* HAVE_DRIVE_LETTERS */
|
||||||
{
|
{
|
||||||
if (isPathDelimiter(*path)) {
|
if (isPathDelimiter(*path)) {
|
||||||
absolute = true;
|
absolute = true;
|
||||||
@@ -457,17 +460,20 @@ composePath(const uio_PathComp *pathComp, uio_bool absolute,
|
|||||||
pathPtr = result;
|
pathPtr = result;
|
||||||
ptr = pathComp;
|
ptr = pathComp;
|
||||||
if (absolute) {
|
if (absolute) {
|
||||||
#ifdef WIN32
|
#ifdef HAVE_UNC_PATHS
|
||||||
if (ptr->name[0] == '\\') {
|
if (ptr->name[0] == '\\') {
|
||||||
// UNC path
|
// UNC path
|
||||||
assert(ptr->name[1] == '\\');
|
assert(ptr->name[1] == '\\');
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
} else if (ptr->nameLen == 2 && ptr->name[1] == ':'
|
} else
|
||||||
|
#endif /* HAVE_UNC_PATHS */
|
||||||
|
#ifdef HAVE_DRIVE_LETTERS
|
||||||
|
if (ptr->nameLen == 2 && ptr->name[1] == ':'
|
||||||
&& isDriveLetter(ptr->name[0])) {
|
&& isDriveLetter(ptr->name[0])) {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif /* HAVE_DRIVE_LETTERS */
|
||||||
{
|
{
|
||||||
*(pathPtr++) = '/';
|
*(pathPtr++) = '/';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,22 +61,22 @@ size_t uio_skipUNCServerShare(const char *inPath);
|
|||||||
size_t uio_getUNCServerShare(const char *inPath, char **outPath,
|
size_t uio_getUNCServerShare(const char *inPath, char **outPath,
|
||||||
size_t *outLen);
|
size_t *outLen);
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef HAVE_DRIVE_LETTERS
|
||||||
static inline int
|
static inline int
|
||||||
isDriveLetter(int c)
|
isDriveLetter(int c)
|
||||||
{
|
{
|
||||||
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* HAVE_DRIVE_LETTERS */
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
isPathDelimiter(int c)
|
isPathDelimiter(int c)
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef BACKSLASH_IS_PATH_SEPARATOR
|
||||||
return c == '/' || c == '\\';
|
return c == '/' || c == '\\';
|
||||||
#else
|
#else
|
||||||
return c == '/';
|
return c == '/';
|
||||||
#endif
|
#endif /* BACKSLASH_IS_PATH_SEPARATOR */
|
||||||
}
|
}
|
||||||
|
|
||||||
int decomposePath(const char *path, uio_PathComp **pathComp,
|
int decomposePath(const char *path, uio_PathComp **pathComp,
|
||||||
|
|||||||
@@ -340,20 +340,24 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) {
|
|||||||
const char *pathUpTo;
|
const char *pathUpTo;
|
||||||
char *path;
|
char *path;
|
||||||
struct stat statBuf;
|
struct stat statBuf;
|
||||||
#ifdef WIN32
|
#ifdef HAVE_DRIVE_LETTERS
|
||||||
char driveName[3];
|
char driveName[3];
|
||||||
#endif
|
#endif /* HAVE_DRIVE_LETTERS */
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
|
||||||
if (pDirHandle->extra->extra->upDir == NULL) {
|
if (pDirHandle->extra->extra->upDir == NULL) {
|
||||||
// Top dir. Contains only drive letters and UNC \\server\share
|
// Top dir. Contains only drive letters and UNC \\server\share
|
||||||
// parts.
|
// parts.
|
||||||
|
#ifdef HAVE_DRIVE_LETTERS
|
||||||
if (isDriveLetter(name[0]) && name[1] == ':' && name[2] == '\0') {
|
if (isDriveLetter(name[0]) && name[1] == ':' && name[2] == '\0') {
|
||||||
driveName[0] = tolower(name[0]);
|
driveName[0] = tolower(name[0]);
|
||||||
driveName[1] = ':';
|
driveName[1] = ':';
|
||||||
driveName[2] = '\0';
|
driveName[2] = '\0';
|
||||||
name = driveName;
|
name = driveName;
|
||||||
} else {
|
} else
|
||||||
|
#endif /* HAVE_DRIVE_LETTERS */
|
||||||
|
#ifdef HAVE_UNC_PATHS
|
||||||
|
{
|
||||||
size_t uncLen;
|
size_t uncLen;
|
||||||
|
|
||||||
uncLen = uio_skipUNCServerShare(name);
|
uncLen = uio_skipUNCServerShare(name);
|
||||||
@@ -363,14 +367,20 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else /* !defined(HAVE_UNC_PATHS) */
|
||||||
|
{
|
||||||
|
// Make sure that there is an 'else' case if HAVE_DRIVE_LETTERS
|
||||||
|
// is defined.
|
||||||
|
}
|
||||||
|
#endif /* HAVE_UNC_PATHS */
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
|
||||||
|
|
||||||
result = uio_GPDir_getPDirEntryHandle(pDirHandle, name);
|
result = uio_GPDir_getPDirEntryHandle(pDirHandle, name);
|
||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
|
||||||
if (pDirHandle->extra->extra->upDir == NULL) {
|
if (pDirHandle->extra->extra->upDir == NULL) {
|
||||||
// Need to create a 'directory' for the drive letter or UNC
|
// Need to create a 'directory' for the drive letter or UNC
|
||||||
// "\\server\share" part.
|
// "\\server\share" part.
|
||||||
@@ -383,7 +393,7 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) {
|
|||||||
return (uio_PDirEntryHandle *) uio_PDirHandle_new(
|
return (uio_PDirEntryHandle *) uio_PDirHandle_new(
|
||||||
pDirHandle->pRoot, gPDir);
|
pDirHandle->pRoot, gPDir);
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
|
||||||
|
|
||||||
pathUpTo = stdio_getPath(pDirHandle->extra);
|
pathUpTo = stdio_getPath(pDirHandle->extra);
|
||||||
if (pathUpTo == NULL) {
|
if (pathUpTo == NULL) {
|
||||||
@@ -434,12 +444,12 @@ stdio_mount(uio_Handle *handle, int flags) {
|
|||||||
assert (handle == NULL);
|
assert (handle == NULL);
|
||||||
extra = stdio_GPDirData_new(
|
extra = stdio_GPDirData_new(
|
||||||
uio_strdup("") /* name */,
|
uio_strdup("") /* name */,
|
||||||
#ifdef WIN32
|
#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
|
||||||
// In MS Windows, full paths start with a drive letter.
|
// Full paths start with a drive letter or \\server\share
|
||||||
uio_strdup("") /* cached path */,
|
uio_strdup("") /* cached path */,
|
||||||
#else
|
#else
|
||||||
uio_strdup("/") /* cached path */,
|
uio_strdup("/") /* cached path */,
|
||||||
#endif
|
#endif /* HAVE_DRIVE_LETTERS */
|
||||||
NULL /* parent dir */);
|
NULL /* parent dir */);
|
||||||
|
|
||||||
result = uio_GPRoot_makePRoot(
|
result = uio_GPRoot_makePRoot(
|
||||||
@@ -711,15 +721,15 @@ stdio_getPath(uio_GPDir *gPDir) {
|
|||||||
size_t upPathLen, nameLen;
|
size_t upPathLen, nameLen;
|
||||||
|
|
||||||
if (gPDir->extra->upDir == NULL) {
|
if (gPDir->extra->upDir == NULL) {
|
||||||
#ifdef WIN32
|
#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
|
||||||
// Drive letter still needs to follow.
|
// Drive letter or UNC \\server\share still needs to follow.
|
||||||
gPDir->extra->cachedPath = uio_malloc(1);
|
gPDir->extra->cachedPath = uio_malloc(1);
|
||||||
gPDir->extra->cachedPath[0] = '\0';
|
gPDir->extra->cachedPath[0] = '\0';
|
||||||
#else
|
#else
|
||||||
gPDir->extra->cachedPath = uio_malloc(2);
|
gPDir->extra->cachedPath = uio_malloc(2);
|
||||||
gPDir->extra->cachedPath[0] = '/';
|
gPDir->extra->cachedPath[0] = '/';
|
||||||
gPDir->extra->cachedPath[1] = '\0';
|
gPDir->extra->cachedPath[1] = '\0';
|
||||||
#endif
|
#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
|
||||||
return gPDir->extra->cachedPath;
|
return gPDir->extra->cachedPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -729,21 +739,22 @@ stdio_getPath(uio_GPDir *gPDir) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WIN32
|
#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS)
|
||||||
if (upPath[0] == '\0') {
|
if (upPath[0] == '\0') {
|
||||||
// The up dir is the root dir. Directly below the root dir are
|
// The up dir is the root dir. Directly below the root dir are
|
||||||
// only dirs for drive letters. No '/' needs to be attached.
|
// only dirs for drive letters and UNC \\share\server parts.
|
||||||
|
// No '/' needs to be attached.
|
||||||
gPDir->extra->cachedPath = uio_strdup(gPDir->extra->name);
|
gPDir->extra->cachedPath = uio_strdup(gPDir->extra->name);
|
||||||
return gPDir->extra->cachedPath;
|
return gPDir->extra->cachedPath;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */
|
||||||
upPathLen = strlen(upPath);
|
upPathLen = strlen(upPath);
|
||||||
#ifndef WIN32
|
#if !defined(HAVE_DRIVE_LETTERS) && !defined(HAVE_UNC_PATHS)
|
||||||
if (upPath[upPathLen - 1] == '/') {
|
if (upPath[upPathLen - 1] == '/') {
|
||||||
// should only happen for "/"
|
// should only happen for "/"
|
||||||
upPathLen--;
|
upPathLen--;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* !defined(HAVE_DRIVE_LETTERS) && !defined(HAVE_UNC_PATHS) */
|
||||||
nameLen = strlen(gPDir->extra->name);
|
nameLen = strlen(gPDir->extra->name);
|
||||||
if (upPathLen + nameLen + 1 >= PATH_MAX) {
|
if (upPathLen + nameLen + 1 >= PATH_MAX) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
|
|||||||
@@ -65,6 +65,23 @@
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Variations in path handling
|
||||||
|
#if defined(WIN32) || defined(__SYMBIAN32__)
|
||||||
|
// HAVE_DRIVE_LETTERS is defined to signify that DOS/Windows style drive
|
||||||
|
// letters are to be recognised on this platform.
|
||||||
|
# define HAVE_DRIVE_LETTERS
|
||||||
|
// BACKSLASH_IS_PATH_SEPARATOR is defined to signify that the backslash
|
||||||
|
// character is to be recognised as a path separator on this platform.
|
||||||
|
// This does not affect the acceptance of forward slashes as path
|
||||||
|
// separators.
|
||||||
|
# define BACKSLASH_IS_PATH_SEPARATOR
|
||||||
|
#endif
|
||||||
|
#if defined(WIN32)
|
||||||
|
// HAVE_UNC_PATHS is defined to signify that Universal Naming Convention
|
||||||
|
// style paths are to be recognised on this platform.
|
||||||
|
# define HAVE_UNC_PATHS
|
||||||
|
#endif
|
||||||
|
|
||||||
// User ids
|
// User ids
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
typedef short uid_t;
|
typedef short uid_t;
|
||||||
|
|||||||
Reference in New Issue
Block a user