From cc63dda7582687ae7253d2e066b51e0387b484bf Mon Sep 17 00:00:00 2001 From: Meep-Eep Date: Sat, 1 Oct 2011 15:55:13 +0000 Subject: [PATCH] Don't require the 'shadow' dir in addon packs, from Alex. git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3700 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/ChangeLog | 1 + sc2/src/libs/uio/io.c | 97 +++++++++++++++++++++++++++++++++++++++++++ sc2/src/libs/uio/io.h | 6 +++ sc2/src/options.c | 8 ++++ 4 files changed, 112 insertions(+) diff --git a/sc2/ChangeLog b/sc2/ChangeLog index 0b79a5283..7e63cb19e 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,5 @@ Changes towards version 0.8: +- Don't require the 'shadow' dir in addon packs, from Alex - Make use of GAME_STATE_FILE consistently, from Scott A. Colcord - Fixed unconst(), from Scott A. Colcord - Fixes to a few small bugs in UIO which shouldn't have had an impact on diff --git a/sc2/src/libs/uio/io.c b/sc2/src/libs/uio/io.c index a7c721e67..247d1e24a 100644 --- a/sc2/src/libs/uio/io.c +++ b/sc2/src/libs/uio/io.c @@ -287,6 +287,103 @@ uio_mountDir(uio_Repository *destRep, const char *mountPoint, } } +// Mount a repository directory into same repository at a different location +// From fossil. +uio_MountHandle * +uio_transplantDir(const char *mountPoint, uio_DirHandle *sourceDir, int flags, + uio_MountHandle *relative) { + uio_MountInfo *relativeInfo; + int numPDirHandles; + uio_PDirHandle **pDirHandles; + uio_MountTreeItem **treeItems; + int i; + uio_MountHandle *handle = NULL; + + if ((flags & uio_MOUNT_RDONLY) != uio_MOUNT_RDONLY) { + // Only read-only transplants supported atm + errno = ENOSYS; + return NULL; + } + + switch (flags & uio_MOUNT_LOCATION_MASK) { + case uio_MOUNT_TOP: + case uio_MOUNT_BOTTOM: + if (relative != NULL) { + errno = EINVAL; + return NULL; + } + relativeInfo = NULL; + break; + case uio_MOUNT_BELOW: + case uio_MOUNT_ABOVE: + if (relative == NULL) { + errno = EINVAL; + return NULL; + } + relativeInfo = relative->mountInfo; + break; + default: + abort(); + } + + if (mountPoint[0] == '/') + mountPoint++; + if (!validPathName(mountPoint, strlen(mountPoint))) { + errno = EINVAL; + return NULL; + } + + if (uio_getPathPhysicalDirs(sourceDir, "", 0, + &pDirHandles, &numPDirHandles, &treeItems) == -1) { + // errno is set + return NULL; + } + if (numPDirHandles == 0) { + errno = ENOENT; + return NULL; + } + + // TODO: We only transplant the first read-only physical dir that we find + // Maybe transplant all of them? We would then have several + // uio_MountHandles to return. + for (i = 0; i < numPDirHandles; ++i) { + uio_PDirHandle *pDirHandle = pDirHandles[i]; + uio_MountInfo *oldMountInfo = treeItems[i]->mountInfo; + uio_Repository *rep = oldMountInfo->mountHandle->repository; + uio_MountInfo *mountInfo; + uio_MountTree *mountTree; + + // Only interested in read-only dirs in this incarnation + if (!uio_mountInfoIsReadOnly(oldMountInfo)) + continue; + + mountInfo = uio_MountInfo_new(oldMountInfo->fsID, NULL, pDirHandle, + uio_strdup(""), oldMountInfo->autoMount, NULL, flags); + // New mount references the same handles + uio_PDirHandle_ref(pDirHandle); + uio_PRoot_refMount(pDirHandle->pRoot); + + uio_repositoryAddMount(rep, mountInfo, + flags & uio_MOUNT_LOCATION_MASK, relativeInfo); + mountTree = uio_mountTreeAddMountInfo(rep, rep->mountTree, + mountInfo, mountPoint, flags & uio_MOUNT_LOCATION_MASK, + relativeInfo); + // mountTree is the node in rep->mountTree where mountInfo leads to + mountInfo->mountTree = mountTree; + mountInfo->mountHandle = uio_MountHandle_new(rep, mountInfo); + handle = mountInfo->mountHandle; + break; + } + + uio_PDirHandles_delete(pDirHandles, numPDirHandles); + uio_free(treeItems); + + if (handle == NULL) + errno = ENOENT; + + return handle; +} + int uio_unmountDir(uio_MountHandle *mountHandle) { uio_PRoot *pRoot; diff --git a/sc2/src/libs/uio/io.h b/sc2/src/libs/uio/io.h index 8e8ce663c..614357a94 100644 --- a/sc2/src/libs/uio/io.h +++ b/sc2/src/libs/uio/io.h @@ -82,6 +82,12 @@ uio_MountHandle *uio_mountDir(uio_Repository *destRep, const char *mountPoint, const char *inPath, uio_AutoMount **autoMount, int flags, uio_MountHandle *relative); +// Mount a repository directory into same repository at a different +// location. +// From fossil. +uio_MountHandle *uio_transplantDir(const char *mountPoint, + uio_DirHandle *sourceDir, int flags, uio_MountHandle *relative); + // Unmount a previously mounted dir. int uio_unmountDir(uio_MountHandle *mountHandle); diff --git a/sc2/src/options.c b/sc2/src/options.c index 98e710251..96c3f350d 100644 --- a/sc2/src/options.c +++ b/sc2/src/options.c @@ -571,6 +571,14 @@ prepareShadowAddons (const char **addons) { log_add (log_Debug, "Mounting shadow content of '%s' addon", addon); mountDirZips (shadowDir, "/", uio_MOUNT_ABOVE, contentMountHandle); + // Mount non-zipped shadow content + if (uio_transplantDir ("/", shadowDir, uio_MOUNT_RDONLY | + uio_MOUNT_ABOVE, contentMountHandle) == NULL) + { + log_add (log_Warning, "Warning: Could not mount shadow content" + " of '%s': %s.", addon, strerror (errno)); + } + uio_closeDir (shadowDir); } uio_closeDir (addonDir);