summaryrefslogtreecommitdiffstats
path: root/generic/tclZipfs.c
diff options
context:
space:
mode:
authordkf <donal.k.fellows@manchester.ac.uk>2021-03-06 16:28:43 (GMT)
committerdkf <donal.k.fellows@manchester.ac.uk>2021-03-06 16:28:43 (GMT)
commita1d8e47ea7ef4acf4228052d71aa77bf788a9d15 (patch)
tree4e7f012e606eb46a1a03e80d4c516762bead6355 /generic/tclZipfs.c
parentdd7f073e8b7bee2631f4a175359de6b99d8f3570 (diff)
downloadtcl-a1d8e47ea7ef4acf4228052d71aa77bf788a9d15.zip
tcl-a1d8e47ea7ef4acf4228052d71aa77bf788a9d15.tar.gz
tcl-a1d8e47ea7ef4acf4228052d71aa77bf788a9d15.tar.bz2
Document that [zipfs mkimg] strips an existing ZIP. We ought to merge instead, but we don't yet.
Diffstat (limited to 'generic/tclZipfs.c')
-rw-r--r--generic/tclZipfs.c130
1 files changed, 85 insertions, 45 deletions
diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c
index ed3b42d..bf74823 100644
--- a/generic/tclZipfs.c
+++ b/generic/tclZipfs.c
@@ -360,7 +360,7 @@ static const Tcl_Filesystem zipfsFilesystem = {
NULL, /* renameFileProc */
NULL, /* copyDirectoryProc */
NULL, /* lstatProc */
- (Tcl_FSLoadFileProc *)(void *)ZipFSLoadFile,
+ (Tcl_FSLoadFileProc *) (void *) ZipFSLoadFile,
NULL, /* getCwdProc */
NULL, /* chdirProc */
};
@@ -779,7 +779,7 @@ ZipFSLookup(
hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, filename);
if (hPtr) {
- z = (ZipEntry *)Tcl_GetHashValue(hPtr);
+ z = (ZipEntry *) Tcl_GetHashValue(hPtr);
}
return z;
}
@@ -867,7 +867,7 @@ ZipFSCloseArchive(
#else /* !_WIN32 */
if ((zf->data != MAP_FAILED) && !zf->ptrToFree) {
munmap(zf->data, zf->length);
- zf->data = (unsigned char *)MAP_FAILED;
+ zf->data = (unsigned char *) MAP_FAILED;
}
#endif /* _WIN32 */
@@ -1037,7 +1037,7 @@ ZipFSOpenArchive(
zf->data = NULL;
zf->mountHandle = INVALID_HANDLE_VALUE;
#else /* !_WIN32 */
- zf->data = (unsigned char *)MAP_FAILED;
+ zf->data = (unsigned char *) MAP_FAILED;
#endif /* _WIN32 */
zf->length = 0;
zf->numFiles = 0;
@@ -1066,7 +1066,7 @@ ZipFSOpenArchive(
ZIPFS_POSIX_ERROR(interp, "seek error");
goto error;
}
- zf->ptrToFree = zf->data = (unsigned char *)attemptckalloc(zf->length);
+ zf->ptrToFree = zf->data = (unsigned char *) attemptckalloc(zf->length);
if (!zf->ptrToFree) {
ZIPFS_ERROR(interp, "out of memory");
if (interp) {
@@ -1101,8 +1101,9 @@ ZipFSOpenArchive(
ZIPFS_POSIX_ERROR(interp, "file mapping failed");
goto error;
}
- zf->data = (unsigned char *)MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0,
- zf->length);
+ zf->data = (unsigned char *)
+ MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0,
+ zf->length);
if (!zf->data) {
ZIPFS_POSIX_ERROR(interp, "file mapping failed");
goto error;
@@ -1197,7 +1198,7 @@ ZipFSCatalogFilesystem(
hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mountPoint, &isNew);
if (!isNew) {
if (interp) {
- zf = (ZipFile *)Tcl_GetHashValue(hPtr);
+ zf = (ZipFile *) Tcl_GetHashValue(hPtr);
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
"%s is already mounted on %s", zf->name, mountPoint));
Tcl_SetErrorCode(interp, "TCL", "ZIPFS", "MOUNTED", NULL);
@@ -1206,7 +1207,7 @@ ZipFSCatalogFilesystem(
ZipFSCloseArchive(interp, zf0);
return TCL_ERROR;
}
- zf = (ZipFile *)attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1);
+ zf = (ZipFile *) attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1);
if (!zf) {
if (interp) {
Tcl_AppendResult(interp, "out of memory", (char *) NULL);
@@ -1219,11 +1220,11 @@ ZipFSCatalogFilesystem(
Unlock();
*zf = *zf0;
- zf->mountPoint = (char *)Tcl_GetHashKey(&ZipFS.zipHash, hPtr);
+ zf->mountPoint = (char *) Tcl_GetHashKey(&ZipFS.zipHash, hPtr);
Tcl_CreateExitHandler(ZipfsExitHandler, zf);
zf->mountPointLen = strlen(zf->mountPoint);
zf->nameLength = strlen(zipname);
- zf->name = (char *)ckalloc(zf->nameLength + 1);
+ zf->name = (char *) ckalloc(zf->nameLength + 1);
memcpy(zf->name, zipname, zf->nameLength + 1);
zf->entries = NULL;
zf->topEnts = NULL;
@@ -1242,7 +1243,7 @@ ZipFSCatalogFilesystem(
if (mountPoint[0] != '\0') {
hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mountPoint, &isNew);
if (isNew) {
- z = (ZipEntry *)ckalloc(sizeof(ZipEntry));
+ z = (ZipEntry *) ckalloc(sizeof(ZipEntry));
Tcl_SetHashValue(hPtr, z);
z->tnext = NULL;
@@ -1256,7 +1257,7 @@ ZipFSCatalogFilesystem(
z->numBytes = z->numCompressedBytes = 0;
z->compressMethod = ZIP_COMPMETH_STORED;
z->data = NULL;
- z->name = (char *)Tcl_GetHashKey(&ZipFS.fileHash, hPtr);
+ z->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr);
z->next = zf->entries;
zf->entries = z;
}
@@ -1337,7 +1338,7 @@ ZipFSCatalogFilesystem(
}
Tcl_DStringSetLength(&fpBuf, 0);
fullpath = CanonicalPath(mountPoint, path, &fpBuf, 1);
- z = (ZipEntry *)ckalloc(sizeof(ZipEntry));
+ z = (ZipEntry *) ckalloc(sizeof(ZipEntry));
z->name = NULL;
z->tnext = NULL;
z->depth = CountSlashes(fullpath);
@@ -1369,7 +1370,7 @@ ZipFSCatalogFilesystem(
ckfree(z);
} else {
Tcl_SetHashValue(hPtr, z);
- z->name = (char *)Tcl_GetHashKey(&ZipFS.fileHash, hPtr);
+ z->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr);
z->next = zf->entries;
zf->entries = z;
if (isdir && (mountPoint[0] == '\0') && (z->depth == 1)) {
@@ -1391,7 +1392,7 @@ ZipFSCatalogFilesystem(
if (!isNew) {
break;
}
- zd = (ZipEntry *)ckalloc(sizeof(ZipEntry));
+ zd = (ZipEntry *) ckalloc(sizeof(ZipEntry));
zd->name = NULL;
zd->tnext = NULL;
zd->depth = CountSlashes(dir);
@@ -1405,7 +1406,7 @@ ZipFSCatalogFilesystem(
zd->compressMethod = ZIP_COMPMETH_STORED;
zd->data = NULL;
Tcl_SetHashValue(hPtr, zd);
- zd->name = (char *)Tcl_GetHashKey(&ZipFS.fileHash, hPtr);
+ zd->name = (char *) Tcl_GetHashKey(&ZipFS.fileHash, hPtr);
zd->next = zf->entries;
zf->entries = zd;
if ((mountPoint[0] == '\0') && (zd->depth == 1)) {
@@ -1491,7 +1492,7 @@ ListMountPoints(
if (!interp) {
return TCL_OK;
}
- zf = (ZipFile *)Tcl_GetHashValue(hPtr);
+ zf = (ZipFile *) Tcl_GetHashValue(hPtr);
Tcl_AppendElement(interp, zf->mountPoint);
Tcl_AppendElement(interp, zf->name);
}
@@ -1528,7 +1529,7 @@ DescribeMounted(
if (interp) {
hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint);
if (hPtr) {
- zf = (ZipFile *)Tcl_GetHashValue(hPtr);
+ zf = (ZipFile *) Tcl_GetHashValue(hPtr);
Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1));
return TCL_OK;
}
@@ -1605,7 +1606,7 @@ TclZipfs_Mount(
return TCL_ERROR;
}
}
- zf = (ZipFile *)attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1);
+ zf = (ZipFile *) attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1);
if (!zf) {
if (interp) {
Tcl_AppendResult(interp, "out of memory", (char *) NULL);
@@ -1686,7 +1687,7 @@ TclZipfs_MountBuffer(
* Have both a mount point and data to mount there.
*/
- zf = (ZipFile *)attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1);
+ zf = (ZipFile *) attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1);
if (!zf) {
if (interp) {
Tcl_AppendResult(interp, "out of memory", (char *) NULL);
@@ -1697,7 +1698,7 @@ TclZipfs_MountBuffer(
zf->isMemBuffer = 1;
zf->length = datalen;
if (copy) {
- zf->data = (unsigned char *)attemptckalloc(datalen);
+ zf->data = (unsigned char *) attemptckalloc(datalen);
if (!zf->data) {
if (interp) {
Tcl_AppendResult(interp, "out of memory", (char *) NULL);
@@ -1767,7 +1768,7 @@ TclZipfs_Unmount(
goto done;
}
- zf = (ZipFile *)Tcl_GetHashValue(hPtr);
+ zf = (ZipFile *) Tcl_GetHashValue(hPtr);
if (zf->numOpen > 0) {
ZIPFS_ERROR(interp, "filesystem is busy");
ret = TCL_ERROR;
@@ -2309,7 +2310,7 @@ ZipAddFile(
return TCL_ERROR;
}
- z = (ZipEntry *)ckalloc(sizeof(ZipEntry));
+ z = (ZipEntry *) ckalloc(sizeof(ZipEntry));
Tcl_SetHashValue(hPtr, z);
z->name = NULL;
z->tnext = NULL;
@@ -2324,7 +2325,7 @@ ZipAddFile(
z->numCompressedBytes = nbytecompr;
z->compressMethod = compMeth;
z->data = NULL;
- z->name = (char *)Tcl_GetHashKey(fileHash, hPtr);
+ z->name = (char *) Tcl_GetHashKey(fileHash, hPtr);
z->next = NULL;
/*
@@ -2425,6 +2426,10 @@ ZipFSMkZipOrImgObjCmd(
} else {
Tcl_Obj *cmd[3];
+ /*
+ * Discover the list of files to add.
+ */
+
cmd[1] = Tcl_NewStringObj("::tcl::zipfs::find", -1);
cmd[2] = objv[2];
cmd[0] = Tcl_NewListObj(2, cmd + 1);
@@ -2463,6 +2468,13 @@ ZipFSMkZipOrImgObjCmd(
pw = NULL;
pwlen = 0;
}
+
+ /*
+ * Copy the existing contents from the image if it is an executable image.
+ * Care must be taken because this might include an existing ZIP, which
+ * needs to be stripped.
+ */
+
if (isImg) {
ZipFile *zf, zf0;
int isMounted = 0;
@@ -2499,7 +2511,7 @@ ZipFSMkZipOrImgObjCmd(
WriteLock();
for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr;
hPtr = Tcl_NextHashEntry(&search)) {
- zf = (ZipFile *)Tcl_GetHashValue(hPtr);
+ zf = (ZipFile *) Tcl_GetHashValue(hPtr);
if (strcmp(zf->name, imgName) == 0) {
isMounted = 1;
zf->numOpen++;
@@ -2507,10 +2519,15 @@ ZipFSMkZipOrImgObjCmd(
}
}
Unlock();
+
if (!isMounted) {
zf = &zf0;
}
if (isMounted || ZipFSOpenArchive(interp, imgName, 0, zf) == TCL_OK) {
+ /*
+ * Copy everything up to the ZIP-related suffix.
+ */
+
if ((size_t) Tcl_Write(out, (char *) zf->data,
zf->passOffset) != zf->passOffset) {
memset(passBuf, 0, sizeof(passBuf));
@@ -2585,6 +2602,11 @@ ZipFSMkZipOrImgObjCmd(
}
Tcl_Close(interp, in);
}
+
+ /*
+ * Store the password so that the automounter can find it.
+ */
+
len = strlen(passBuf);
if (len > 0) {
i = Tcl_Write(out, passBuf, len);
@@ -2599,6 +2621,11 @@ ZipFSMkZipOrImgObjCmd(
memset(passBuf, 0, sizeof(passBuf));
Tcl_Flush(out);
}
+
+ /*
+ * Prepare the contents of the ZIP archive.
+ */
+
Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS);
pos[0] = Tcl_Tell(out);
if (!isList && (objc > 3)) {
@@ -2632,6 +2659,11 @@ ZipFSMkZipOrImgObjCmd(
goto done;
}
}
+
+ /*
+ * Construct the contents of the ZIP central directory.
+ */
+
pos[1] = Tcl_Tell(out);
count = 0;
for (i = 0; i < (size_t) lobjc; i += (isList ? 2 : 1)) {
@@ -2660,7 +2692,7 @@ ZipFSMkZipOrImgObjCmd(
if (!hPtr) {
continue;
}
- z = (ZipEntry *)Tcl_GetHashValue(hPtr);
+ z = (ZipEntry *) Tcl_GetHashValue(hPtr);
len = strlen(z->name);
ZipWriteInt(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG);
ZipWriteShort(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION);
@@ -2688,6 +2720,11 @@ ZipFSMkZipOrImgObjCmd(
}
count++;
}
+
+ /*
+ * Finalize the central directory.
+ */
+
Tcl_Flush(out);
pos[2] = Tcl_Tell(out);
ZipWriteInt(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG);
@@ -2715,7 +2752,7 @@ ZipFSMkZipOrImgObjCmd(
Tcl_DecrRefCount(list);
for (hPtr = Tcl_FirstHashEntry(&fileHash, &search); hPtr;
hPtr = Tcl_NextHashEntry(&search)) {
- z = (ZipEntry *)Tcl_GetHashValue(hPtr);
+ z = (ZipEntry *) Tcl_GetHashValue(hPtr);
ckfree(z);
Tcl_DeleteHashEntry(hPtr);
}
@@ -3055,7 +3092,7 @@ ZipFSListObjCmd(
if (pattern) {
for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search);
hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- ZipEntry *z = (ZipEntry *)Tcl_GetHashValue(hPtr);
+ ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr);
if (Tcl_StringMatch(z->name, pattern)) {
Tcl_ListObjAppendElement(interp, result,
@@ -3065,7 +3102,7 @@ ZipFSListObjCmd(
} else if (regexp) {
for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search);
hPtr; hPtr = Tcl_NextHashEntry(&search)) {
- ZipEntry *z = (ZipEntry *)Tcl_GetHashValue(hPtr);
+ ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr);
if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) {
Tcl_ListObjAppendElement(interp, result,
@@ -3075,7 +3112,7 @@ ZipFSListObjCmd(
} else {
for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search);
hPtr; hPtr = Tcl_NextHashEntry(&search)) {
- ZipEntry *z = (ZipEntry *)Tcl_GetHashValue(hPtr);
+ ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr);
Tcl_ListObjAppendElement(interp, result,
Tcl_NewStringObj(z->name, -1));
@@ -3235,7 +3272,7 @@ ZipChannelClose(
TCL_UNUSED(Tcl_Interp *),
int flags)
{
- ZipChannel *info = (ZipChannel *)instanceData;
+ ZipChannel *info = (ZipChannel *) instanceData;
if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
return EINVAL;
@@ -3251,7 +3288,8 @@ ZipChannelClose(
}
if (info->isWriting) {
ZipEntry *z = info->zipEntryPtr;
- unsigned char *newdata = (unsigned char *)attemptckrealloc(info->ubuf, info->numRead);
+ unsigned char *newdata = (unsigned char *)
+ attemptckrealloc(info->ubuf, info->numRead);
if (newdata) {
if (z->data) {
@@ -3614,7 +3652,7 @@ ZipChannelOpen(
} else {
flags = TCL_WRITABLE;
}
- info = (ZipChannel *)attemptckalloc(sizeof(ZipChannel));
+ info = (ZipChannel *) attemptckalloc(sizeof(ZipChannel));
if (!info) {
ZIPFS_ERROR(interp, "out of memory");
if (interp) {
@@ -3632,7 +3670,7 @@ ZipChannelOpen(
info->maxWrite = ZipFS.wrmax;
info->iscompr = 0;
info->isEncrypted = 0;
- info->ubuf = (unsigned char *)attemptckalloc(info->maxWrite);
+ info->ubuf = (unsigned char *) attemptckalloc(info->maxWrite);
if (!info->ubuf) {
merror0:
if (info->ubuf) {
@@ -3690,7 +3728,7 @@ ZipChannelOpen(
unsigned int j;
stream.avail_in -= 12;
- cbuf = (unsigned char *)attemptckalloc(stream.avail_in);
+ cbuf = (unsigned char *) attemptckalloc(stream.avail_in);
if (!cbuf) {
goto merror0;
}
@@ -3790,7 +3828,7 @@ ZipChannelOpen(
stream.avail_in = z->numCompressedBytes;
if (info->isEncrypted) {
stream.avail_in -= 12;
- ubuf = (unsigned char *)attemptckalloc(stream.avail_in);
+ ubuf = (unsigned char *) attemptckalloc(stream.avail_in);
if (!ubuf) {
info->ubuf = NULL;
goto merror;
@@ -3803,7 +3841,8 @@ ZipChannelOpen(
} else {
stream.next_in = info->ubuf;
}
- stream.next_out = info->ubuf = (unsigned char *)attemptckalloc(info->numBytes);
+ stream.next_out = info->ubuf = (unsigned char *)
+ attemptckalloc(info->numBytes);
if (!info->ubuf) {
merror:
if (ubuf) {
@@ -4164,7 +4203,7 @@ ZipFSMatchInDirectoryProc(
}
for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr;
hPtr = Tcl_NextHashEntry(&search)) {
- ZipFile *zf = (ZipFile *)Tcl_GetHashValue(hPtr);
+ ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr);
if (zf->mountPointLen == 0) {
ZipEntry *z;
@@ -4215,7 +4254,7 @@ ZipFSMatchInDirectoryProc(
if (!pattern || (pattern[0] == '\0')) {
hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path);
if (hPtr) {
- ZipEntry *z = (ZipEntry *)Tcl_GetHashValue(hPtr);
+ ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr);
if ((dirOnly < 0) || (!dirOnly && !z->isDirectory)
|| (dirOnly && z->isDirectory)) {
@@ -4235,7 +4274,7 @@ ZipFSMatchInDirectoryProc(
}
l = strlen(pattern);
- pat = (char *)ckalloc(len + l + 2);
+ pat = (char *) ckalloc(len + l + 2);
memcpy(pat, path, len);
while ((len > 1) && (pat[len - 1] == '/')) {
--len;
@@ -4248,7 +4287,7 @@ ZipFSMatchInDirectoryProc(
scnt = CountSlashes(pat);
for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search);
hPtr; hPtr = Tcl_NextHashEntry(&search)) {
- ZipEntry *z = (ZipEntry *)Tcl_GetHashValue(hPtr);
+ ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr);
if ((dirOnly >= 0) && ((dirOnly && !z->isDirectory)
|| (!dirOnly && z->isDirectory))) {
@@ -4324,7 +4363,7 @@ ZipFSPathInFilesystemProc(
for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr;
hPtr = Tcl_NextHashEntry(&search)) {
- ZipFile *zf = (ZipFile *)Tcl_GetHashValue(hPtr);
+ ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr);
if (zf->mountPointLen == 0) {
ZipEntry *z;
@@ -4636,7 +4675,8 @@ ZipFSLoadFile(
Tcl_DecrRefCount(objs[1]);
}
- loadFileProc = (Tcl_FSLoadFileProc2 *)(void *)tclNativeFilesystem.loadFileProc;
+ loadFileProc = (Tcl_FSLoadFileProc2 *) (void *)
+ tclNativeFilesystem.loadFileProc;
if (loadFileProc) {
ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags);
} else {
@@ -4792,7 +4832,7 @@ static void
ZipfsExitHandler(
ClientData clientData)
{
- ZipFile *zf = (ZipFile *)clientData;
+ ZipFile *zf = (ZipFile *) clientData;
if (TCL_OK != TclZipfs_Unmount(NULL, zf->mountPoint)) {
Tcl_Panic("tried to unmount busy filesystem");