diff --git a/sc2/src/sc2code/libs/uio/doc/todo b/sc2/src/sc2code/libs/uio/doc/todo index 6ac95e14f..e92694b64 100644 --- a/sc2/src/sc2code/libs/uio/doc/todo +++ b/sc2/src/sc2code/libs/uio/doc/todo @@ -32,6 +32,9 @@ Documentation: in the directory. "/a/../b" will always be functionally equivalent to "/b", even when "/a" is a symlink. +Testing: +- Test mounting an UNC directory + Bugs: - 'openDir(repository, "dir/")' will have the trailing '/' in the dirHandle, which will cause problems. diff --git a/sc2/src/sc2code/libs/uio/io.c b/sc2/src/sc2code/libs/uio/io.c index 0e6c9ecd2..bcc8b07fb 100644 --- a/sc2/src/sc2code/libs/uio/io.c +++ b/sc2/src/sc2code/libs/uio/io.c @@ -238,12 +238,12 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint, uio_MountInfo *mountInfo; uio_MountTree *mountTree; uio_PDirHandle *pRootHandle; -#ifdef WIN32 +#ifdef BACKSLASH_IS_PATH_SEPARATOR char *unixPath; unixPath = dosToUnixPath(inPath); inPath = unixPath; -#endif +#endif /* BACKSLASH_IS_PATH_SEPARATOR */ if (inPath[0] == '/') inPath++; @@ -252,9 +252,9 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint, &endDirHandle, &endInPath); if (*endInPath != '\0') { // Path inside the filesystem to mount does not exist. -#ifdef WIN32 +#ifdef BACKSLASH_IS_PATH_SEPARATOR uio_free(unixPath); -#endif +#endif /* BACKSLASH_IS_PATH_SEPARATOR */ uio_PDirHandle_unref(endDirHandle); uio_PRoot_unrefMount(pRoot); if (handle) @@ -266,10 +266,10 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint, dirName = uio_malloc(endInPath - inPath + 1); memcpy(dirName, inPath, endInPath - inPath); dirName[endInPath - inPath] = '\0'; -#ifdef WIN32 +#ifdef BACKSLASH_IS_PATH_SEPARATOR // InPath is a copy with the paths fixed. uio_free(unixPath); -#endif +#endif /* BACKSLASH_IS_PATH_SEPARATOR */ mountInfo = uio_MountInfo_new(fsType, NULL, endDirHandle, dirName, autoMount, NULL, flags); uio_repositoryAddMount(destRep, mountInfo, diff --git a/sc2/src/sc2code/libs/uio/paths.c b/sc2/src/sc2code/libs/uio/paths.c index 144794740..f8411cdb8 100644 --- a/sc2/src/sc2code/libs/uio/paths.c +++ b/sc2/src/sc2code/libs/uio/paths.c @@ -367,9 +367,9 @@ decomposePath(const char *path, uio_PathComp **pathComp, uio_PathComp **endResult = &result; uio_bool absolute = false; char *name; -#ifdef WIN32 +#ifdef HAVE_UNC_PATHS size_t nameLen; -#endif +#endif /* HAVE_UNC_PATHS */ if (path[0] == '\0') { errno = ENOENT; @@ -377,7 +377,7 @@ decomposePath(const char *path, uio_PathComp **pathComp, } last = NULL; -#ifdef WIN32 +#ifdef HAVE_UNC_PATHS path += uio_getUNCServerShare(path, &name, &nameLen); if (name != NULL) { // UNC path @@ -386,7 +386,10 @@ decomposePath(const char *path, uio_PathComp **pathComp, endResult = &last->next; 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. if (path[2] != '\0' && !isPathDelimiter(path[2])) { errno = ENOENT; @@ -398,7 +401,7 @@ decomposePath(const char *path, uio_PathComp **pathComp, endResult = &last->next; absolute = true; } else -#endif +#endif /* HAVE_DRIVE_LETTERS */ { if (isPathDelimiter(*path)) { absolute = true; @@ -457,17 +460,20 @@ composePath(const uio_PathComp *pathComp, uio_bool absolute, pathPtr = result; ptr = pathComp; if (absolute) { -#ifdef WIN32 +#ifdef HAVE_UNC_PATHS if (ptr->name[0] == '\\') { // UNC path assert(ptr->name[1] == '\\'); // 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])) { // Nothing to do. } else -#endif +#endif /* HAVE_DRIVE_LETTERS */ { *(pathPtr++) = '/'; } diff --git a/sc2/src/sc2code/libs/uio/paths.h b/sc2/src/sc2code/libs/uio/paths.h index 7822c6f80..8813c1379 100644 --- a/sc2/src/sc2code/libs/uio/paths.h +++ b/sc2/src/sc2code/libs/uio/paths.h @@ -61,22 +61,22 @@ size_t uio_skipUNCServerShare(const char *inPath); size_t uio_getUNCServerShare(const char *inPath, char **outPath, size_t *outLen); -#ifdef WIN32 +#ifdef HAVE_DRIVE_LETTERS static inline int isDriveLetter(int c) { return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); } -#endif +#endif /* HAVE_DRIVE_LETTERS */ static inline int isPathDelimiter(int c) { -#ifdef WIN32 +#ifdef BACKSLASH_IS_PATH_SEPARATOR return c == '/' || c == '\\'; #else return c == '/'; -#endif +#endif /* BACKSLASH_IS_PATH_SEPARATOR */ } int decomposePath(const char *path, uio_PathComp **pathComp, diff --git a/sc2/src/sc2code/libs/uio/stdio/stdio.c b/sc2/src/sc2code/libs/uio/stdio/stdio.c index e2e20c89c..1a5a994f9 100644 --- a/sc2/src/sc2code/libs/uio/stdio/stdio.c +++ b/sc2/src/sc2code/libs/uio/stdio/stdio.c @@ -340,20 +340,24 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) { const char *pathUpTo; char *path; struct stat statBuf; -#ifdef WIN32 +#ifdef HAVE_DRIVE_LETTERS 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) { // Top dir. Contains only drive letters and UNC \\server\share // parts. +#ifdef HAVE_DRIVE_LETTERS if (isDriveLetter(name[0]) && name[1] == ':' && name[2] == '\0') { driveName[0] = tolower(name[0]); driveName[1] = ':'; driveName[2] = '\0'; name = driveName; - } else { + } else +#endif /* HAVE_DRIVE_LETTERS */ +#ifdef HAVE_UNC_PATHS + { size_t uncLen; uncLen = uio_skipUNCServerShare(name); @@ -363,14 +367,20 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) { 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); if (result != NULL) return result; -#ifdef WIN32 +#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) if (pDirHandle->extra->extra->upDir == NULL) { // Need to create a 'directory' for the drive letter or UNC // "\\server\share" part. @@ -383,7 +393,7 @@ stdio_getPDirEntryHandle(const uio_PDirHandle *pDirHandle, const char *name) { return (uio_PDirEntryHandle *) uio_PDirHandle_new( pDirHandle->pRoot, gPDir); } -#endif +#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */ pathUpTo = stdio_getPath(pDirHandle->extra); if (pathUpTo == NULL) { @@ -434,12 +444,12 @@ stdio_mount(uio_Handle *handle, int flags) { assert (handle == NULL); extra = stdio_GPDirData_new( uio_strdup("") /* name */, -#ifdef WIN32 - // In MS Windows, full paths start with a drive letter. +#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) + // Full paths start with a drive letter or \\server\share uio_strdup("") /* cached path */, #else uio_strdup("/") /* cached path */, -#endif +#endif /* HAVE_DRIVE_LETTERS */ NULL /* parent dir */); result = uio_GPRoot_makePRoot( @@ -711,15 +721,15 @@ stdio_getPath(uio_GPDir *gPDir) { size_t upPathLen, nameLen; if (gPDir->extra->upDir == NULL) { -#ifdef WIN32 - // Drive letter still needs to follow. +#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) + // Drive letter or UNC \\server\share still needs to follow. gPDir->extra->cachedPath = uio_malloc(1); gPDir->extra->cachedPath[0] = '\0'; #else gPDir->extra->cachedPath = uio_malloc(2); gPDir->extra->cachedPath[0] = '/'; gPDir->extra->cachedPath[1] = '\0'; -#endif +#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */ return gPDir->extra->cachedPath; } @@ -729,21 +739,22 @@ stdio_getPath(uio_GPDir *gPDir) { return NULL; } -#ifdef WIN32 +#if defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) if (upPath[0] == '\0') { // 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); return gPDir->extra->cachedPath; } -#endif +#endif /* defined(HAVE_DRIVE_LETTERS) || defined(HAVE_UNC_PATHS) */ upPathLen = strlen(upPath); -#ifndef WIN32 +#if !defined(HAVE_DRIVE_LETTERS) && !defined(HAVE_UNC_PATHS) if (upPath[upPathLen - 1] == '/') { // should only happen for "/" upPathLen--; } -#endif +#endif /* !defined(HAVE_DRIVE_LETTERS) && !defined(HAVE_UNC_PATHS) */ nameLen = strlen(gPDir->extra->name); if (upPathLen + nameLen + 1 >= PATH_MAX) { errno = ENAMETOOLONG; diff --git a/sc2/src/sc2code/libs/uio/uioport.h b/sc2/src/sc2code/libs/uio/uioport.h index 2887a96c7..cfe0f3c33 100644 --- a/sc2/src/sc2code/libs/uio/uioport.h +++ b/sc2/src/sc2code/libs/uio/uioport.h @@ -65,6 +65,23 @@ # 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 #ifdef WIN32 typedef short uid_t;