From 0efc494b97376d9e9c735047787b9b329b767931 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 6 Oct 2018 06:22:57 +0000 Subject: More tidying up of zipfs --- generic/tclZipfs.c | 990 +++++++++++++++++++++++++++-------------------------- 1 file changed, 506 insertions(+), 484 deletions(-) diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 4e6cd8a..c66a447 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -1,10 +1,10 @@ /* * tclZipfs.c -- * - * Implementation of the ZIP filesystem used in TIP 430 - * Adapted from the implentation for AndroWish. + * Implementation of the ZIP filesystem used in TIP 430 + * Adapted from the implentation for AndroWish. * - * Coptright (c) 2016-2017 Sean Woods + * Copyright (c) 2016-2017 Sean Woods * Copyright (c) 2013-2015 Christian Werner * * See the file "license.terms" for information on usage and redistribution of @@ -120,21 +120,28 @@ #define ZIP_PASSWORD_END_SIG 0x5a5a4b50 -/* Macro to report errors only if an interp is present */ +/* Macros to report errors only if an interp is present */ #define ZIPFS_ERROR(interp,errstr) \ do { \ if (interp != NULL) { \ Tcl_SetObjResult(interp, Tcl_NewStringObj(errstr, -1)); \ } \ } while (0) +#define ZIPFS_POSIX_ERROR(interp,errstr) \ + do { \ + if (interp != NULL) { \ + Tcl_SetObjResult(interp, Tcl_ObjPrintf( \ + "%s: %s", errstr, Tcl_PosixError(interp))); \ + } \ + } while (0) /* * Macros to read and write 16 and 32 bit integers from/to ZIP archives. */ -#define zip_read_int(p) \ +#define ZipReadInt(p) \ ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24)) -#define zip_read_short(p) \ +#define ZipReadShort(p) \ ((p)[0] | ((p)[1] << 8)) #define zip_write_int(p, v) \ @@ -351,7 +358,7 @@ static int Zip_FSMatchInDirectoryProc(Tcl_Interp *interp, const char *pattern, Tcl_GlobTypeData *types); static Tcl_Obj * Zip_FSListVolumesProc(void); static const char *const *Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, - Tcl_Obj** objPtrRef); + Tcl_Obj **objPtrRef); static int Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); static int Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, @@ -369,7 +376,7 @@ MODULE_SCOPE const Tcl_Filesystem zipfsFilesystem; const Tcl_Filesystem zipfsFilesystem = { "zipfs", - sizeof (Tcl_Filesystem), + sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_2, Zip_FSPathInFilesystemProc, NULL, /* dupInternalRepProc */ @@ -398,20 +405,26 @@ const Tcl_Filesystem zipfsFilesystem = { NULL, /* lstatProc */ (Tcl_FSLoadFileProc *) Zip_FSLoadFile, NULL, /* getCwdProc */ - NULL, /* chdirProc*/ + NULL, /* chdirProc */ }; + +/* + * Miscellaneous constants. + */ + +#define ERROR_LENGTH ((size_t) -1) /* *------------------------------------------------------------------------- * * ReadLock, WriteLock, Unlock -- * - * POSIX like rwlock functions to support multiple readers and single - * writer on internal structs. + * POSIX like rwlock functions to support multiple readers and single + * writer on internal structs. * - * Limitations: - * - a read lock cannot be promoted to a write lock - * - a write lock may not be nested + * Limitations: + * - a read lock cannot be promoted to a write lock + * - a write lock may not be nested * *------------------------------------------------------------------------- */ @@ -489,7 +502,7 @@ DosTimeDate( time_t ret; memset(&tm, 0, sizeof(struct tm)); - tm.tm_year = (((dosDate & 0xfe00) >> 9) + 80); + tm.tm_year = ((dosDate & 0xfe00) >> 9) + 80; tm.tm_mon = ((dosDate & 0x1e0) >> 5) - 1; tm.tm_mday = dosDate & 0x1f; tm.tm_hour = (dosTime & 0xf800) >> 11; @@ -647,10 +660,8 @@ CanonicalPath( strncmp(tail, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) == 0) { isvfs = 2; } - if (isvfs != 1) { - if ((root[0] == '/') && (root[1] == '/')) { - isunc = 1; - } + if (isvfs != 1 && (root[0] == '/') && (root[1] == '/')) { + isunc = 1; } } @@ -738,7 +749,7 @@ CanonicalPath( continue; } if ((c3 == '.') - && ((path[i + 3] == '/') || (path [i + 3] == '\0'))) { + && ((path[i + 3] == '/') || (path[i + 3] == '\0'))) { i += 2; while ((j > 0) && (path[j - 1] != '/')) { j--; @@ -795,8 +806,6 @@ ZipFSLookup( return z; } -#ifdef NEVER_USED - /* *------------------------------------------------------------------------- * @@ -814,27 +823,24 @@ ZipFSLookup( *------------------------------------------------------------------------- */ +#ifdef NEVER_USED static int ZipFSLookupMount( char *filename) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; - ZipFile *zf; - int match = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) == NULL) { - continue; - } - if (strcmp(zf->mntpt, filename) == 0) { - match = 1; - break; + ZipFile *zf = Tcl_GetHashValue(hPtr); + + if (zf != NULL && strcmp(zf->mntpt, filename) == 0) { + return 1; } hPtr = Tcl_NextHashEntry(&search); } - return match; + return 0; } #endif /* NEVER_USED */ @@ -857,7 +863,7 @@ ZipFSLookupMount( static void ZipFSCloseArchive( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ ZipFile *zf) { if (zf->namelen) { @@ -920,7 +926,7 @@ ZipFSCloseArchive( static int ZipFS_Find_TOC( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. NULLable. */ int needZip, ZipFile *zf) { @@ -930,7 +936,7 @@ ZipFS_Find_TOC( p = zf->data + zf->length - ZIP_CENTRAL_END_LEN; while (p >= zf->data) { if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) { - if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) { + if (ZipReadInt(p) == ZIP_CENTRAL_END_SIG) { break; } p -= ZIP_SIG_LEN; @@ -946,7 +952,7 @@ ZipFS_Find_TOC( ZIPFS_ERROR(interp, "wrong end signature"); goto error; } - zf->nfiles = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS); + zf->nfiles = ZipReadShort(p + ZIP_CENTRAL_ENTS_OFFS); if (zf->nfiles == 0) { if (!needZip) { zf->baseoffs = zf->baseoffsp = zf->length; @@ -955,10 +961,10 @@ ZipFS_Find_TOC( ZIPFS_ERROR(interp, "empty archive"); goto error; } - q = zf->data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS); - p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS); + q = zf->data + ZipReadInt(p + ZIP_CENTRAL_DIRSTART_OFFS); + p -= ZipReadInt(p + ZIP_CENTRAL_DIRSIZE_OFFS); if ((p < zf->data) || (p > zf->data + zf->length) - || (q < zf->data) || (q > (zf->data + zf->length))) { + || (q < zf->data) || (q > zf->data + zf->length)) { if (!needZip) { zf->baseoffs = zf->baseoffsp = zf->length; return TCL_OK; @@ -976,17 +982,17 @@ ZipFS_Find_TOC( ZIPFS_ERROR(interp, "wrong header length"); goto error; } - if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) { + if (ZipReadInt(q) != ZIP_CENTRAL_HEADER_SIG) { ZIPFS_ERROR(interp, "wrong header signature"); goto error; } - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + pathlen = ZipReadShort(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = ZipReadShort(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = ZipReadShort(q + ZIP_CENTRAL_EXTRALEN_OFFS); q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } q = zf->data + zf->baseoffs; - if ((zf->baseoffs >= 6) && (zip_read_int(q - 4) == ZIP_PASSWORD_END_SIG)) { + if ((zf->baseoffs >= 6) && (ZipReadInt(q - 4) == ZIP_PASSWORD_END_SIG)) { i = q[-5]; if (q - 5 - i > zf->data) { zf->pwbuf[0] = i; @@ -1025,10 +1031,10 @@ ZipFS_Find_TOC( static int ZipFSOpenArchive( - Tcl_Interp *interp, - const char *zipname, - int needZip, - ZipFile *zf) + Tcl_Interp *interp, /* Current interpreter. NULLable. */ + const char *zipname, /* Path to ZIP file to open. */ + int needZip, + ZipFile *zf) { size_t i; ClientData handle; @@ -1046,22 +1052,25 @@ ZipFSOpenArchive( zf->baseoffs = zf->baseoffsp = 0; zf->tofree = NULL; zf->pwbuf[0] = 0; - zf->chan = Tcl_OpenFileChannel(interp, zipname, "r", 0); + zf->chan = Tcl_OpenFileChannel(interp, zipname, "rb", 0); if (zf->chan == NULL) { return TCL_ERROR; } if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { - if (Tcl_SetChannelOption(interp, zf->chan, "-translation", - "binary") != TCL_OK) { + zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); + if (zf->length == ERROR_LENGTH) { + ZIPFS_POSIX_ERROR(interp, "seek error"); goto error; } - zf->length = Tcl_Seek(zf->chan, 0, SEEK_END); if ((zf->length - ZIP_CENTRAL_END_LEN) > (64 * 1024 * 1024 - ZIP_CENTRAL_END_LEN)) { ZIPFS_ERROR(interp, "illegal file size"); goto error; } - Tcl_Seek(zf->chan, 0, SEEK_SET); + if (Tcl_Seek(zf->chan, 0, SEEK_SET) == -1) { + ZIPFS_POSIX_ERROR(interp, "seek error"); + goto error; + } zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); if (zf->tofree == NULL) { ZIPFS_ERROR(interp, "out of memory"); @@ -1069,7 +1078,7 @@ ZipFSOpenArchive( } i = Tcl_Read(zf->chan, (char *) zf->data, zf->length); if (i != zf->length) { - ZIPFS_ERROR(interp, "file read error"); + ZIPFS_POSIX_ERROR(interp, "file read error"); goto error; } Tcl_Close(interp, zf->chan); @@ -1085,31 +1094,31 @@ ZipFSOpenArchive( readSuccessful = (zf->length != (size_t) INVALID_FILE_SIZE); # endif /* _WIN64 */ if (!readSuccessful || (zf->length < ZIP_CENTRAL_END_LEN)) { - ZIPFS_ERROR(interp, "invalid file size"); + ZIPFS_POSIX_ERROR(interp, "invalid file size"); goto error; } zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, zf->length, 0); if (zf->mh == INVALID_HANDLE_VALUE) { - ZIPFS_ERROR(interp, "file mapping failed"); + ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); if (zf->data == NULL) { - ZIPFS_ERROR(interp, "file mapping failed"); + ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } #else /* !_WIN32 */ zf->length = lseek(PTR2INT(handle), 0, SEEK_END); - if ((zf->length == (size_t)-1) || (zf->length < ZIP_CENTRAL_END_LEN)) { - ZIPFS_ERROR(interp, "invalid file size"); + if (zf->length == ERROR_LENGTH || zf->length < ZIP_CENTRAL_END_LEN) { + ZIPFS_POSIX_ERROR(interp, "invalid file size"); goto error; } lseek(PTR2INT(handle), 0, SEEK_SET); zf->data = (unsigned char *) mmap(0, zf->length, PROT_READ, MAP_FILE | MAP_PRIVATE, PTR2INT(handle), 0); if (zf->data == MAP_FAILED) { - ZIPFS_ERROR(interp, "file mapping failed"); + ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } #endif /* _WIN32 */ @@ -1126,23 +1135,26 @@ ZipFSOpenArchive( * * ZipFSRootNode -- * - * This function generates the root node for a ZIPFS filesystem + * This function generates the root node for a ZIPFS filesystem. * * Results: - * TCL_OK on success, TCL_ERROR otherwise with an error message - * placed into the given "interp" if it is not NULL. + * TCL_OK on success, TCL_ERROR otherwise with an error message placed + * into the given "interp" if it is not NULL. * * Side effects: + * ... + * *------------------------------------------------------------------------- */ static int ZipFS_Catalogue_Filesystem( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. NULLable. */ ZipFile *zf0, - const char *mntpt, - const char *passwd, - const char *zipname) + const char *mntpt, /* Mount point path. */ + const char *passwd, /* Password for opening the ZIP, or NULL if + * the ZIP is unprotected. */ + const char *zipname) /* Path to ZIP file to build a catalog of. */ { int pwlen, isNew; size_t i; @@ -1184,16 +1196,16 @@ ZipFS_Catalogue_Filesystem( } hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mntpt, &isNew); if (!isNew) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); + zf = Tcl_GetHashValue(hPtr); if (interp != NULL) { - Tcl_AppendResult(interp, zf->name, " is already mounted on ", - mntpt, (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s is already mounted on %s", zf->name, mntpt)); } Unlock(); ZipFSCloseArchive(interp, zf0); return TCL_ERROR; } - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); + zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1259,9 +1271,9 @@ ZipFS_Catalogue_Filesystem( unsigned char *lq, *gq = NULL; char *fullpath, *path; - pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS); - comlen = zip_read_short(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); - extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS); + pathlen = ZipReadShort(q + ZIP_CENTRAL_PATHLEN_OFFS); + comlen = ZipReadShort(q + ZIP_CENTRAL_FCOMMENTLEN_OFFS); + extra = ZipReadShort(q + ZIP_CENTRAL_EXTRALEN_OFFS); Tcl_DStringSetLength(&ds, 0); Tcl_DStringAppend(&ds, (char *) q + ZIP_CENTRAL_HEADER_LEN, pathlen); path = Tcl_DStringValue(&ds); @@ -1274,22 +1286,22 @@ ZipFS_Catalogue_Filesystem( goto nextent; } lq = zf->data + zf->baseoffs - + zip_read_int(q + ZIP_CENTRAL_LOCALHDR_OFFS); + + ZipReadInt(q + ZIP_CENTRAL_LOCALHDR_OFFS); if ((lq < zf->data) || (lq > zf->data + zf->length)) { goto nextent; } - nbcompr = zip_read_int(lq + ZIP_LOCAL_COMPLEN_OFFS); + nbcompr = ZipReadInt(lq + ZIP_LOCAL_COMPLEN_OFFS); if (!isdir && (nbcompr == 0) - && (zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) - && (zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { + && (ZipReadInt(lq + ZIP_LOCAL_UNCOMPLEN_OFFS) == 0) + && (ZipReadInt(lq + ZIP_LOCAL_CRC32_OFFS) == 0)) { gq = q; - nbcompr = zip_read_int(gq + ZIP_CENTRAL_COMPLEN_OFFS); + nbcompr = ZipReadInt(gq + ZIP_CENTRAL_COMPLEN_OFFS); } offs = (lq - zf->data) + ZIP_LOCAL_HEADER_LEN - + zip_read_short(lq + ZIP_LOCAL_PATHLEN_OFFS) - + zip_read_short(lq + ZIP_LOCAL_EXTRALEN_OFFS); - if ((offs + nbcompr) > zf->length) { + + ZipReadShort(lq + ZIP_LOCAL_PATHLEN_OFFS) + + ZipReadShort(lq + ZIP_LOCAL_EXTRALEN_OFFS); + if (offs + nbcompr > zf->length) { goto nextent; } if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { @@ -1333,23 +1345,23 @@ ZipFS_Catalogue_Filesystem( z->depth = CountSlashes(fullpath); z->zipfile = zf; z->isdir = isdir; - z->isenc = (zip_read_short(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) + z->isenc = (ZipReadShort(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) && (nbcompr > 12); z->offset = offs; if (gq != NULL) { - z->crc32 = zip_read_int(gq + ZIP_CENTRAL_CRC32_OFFS); - dosDate = zip_read_short(gq + ZIP_CENTRAL_MDATE_OFFS); - dosTime = zip_read_short(gq + ZIP_CENTRAL_MTIME_OFFS); + z->crc32 = ZipReadInt(gq + ZIP_CENTRAL_CRC32_OFFS); + dosDate = ZipReadShort(gq + ZIP_CENTRAL_MDATE_OFFS); + dosTime = ZipReadShort(gq + ZIP_CENTRAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = zip_read_int(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); - z->cmeth = zip_read_short(gq + ZIP_CENTRAL_COMPMETH_OFFS); + z->nbyte = ZipReadInt(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); + z->cmeth = ZipReadShort(gq + ZIP_CENTRAL_COMPMETH_OFFS); } else { - z->crc32 = zip_read_int(lq + ZIP_LOCAL_CRC32_OFFS); - dosDate = zip_read_short(lq + ZIP_LOCAL_MDATE_OFFS); - dosTime = zip_read_short(lq + ZIP_LOCAL_MTIME_OFFS); + z->crc32 = ZipReadInt(lq + ZIP_LOCAL_CRC32_OFFS); + dosDate = ZipReadShort(lq + ZIP_LOCAL_MDATE_OFFS); + dosTime = ZipReadShort(lq + ZIP_LOCAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = zip_read_int(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); - z->cmeth = zip_read_short(lq + ZIP_LOCAL_COMPMETH_OFFS); + z->nbyte = ZipReadInt(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); + z->cmeth = ZipReadShort(lq + ZIP_LOCAL_COMPMETH_OFFS); } z->nbytecompr = nbcompr; z->data = NULL; @@ -1377,8 +1389,8 @@ ZipFS_Catalogue_Filesystem( end = strrchr(dir, '/'); while ((end != NULL) && (end != dir)) { Tcl_DStringSetLength(&ds, end - dir); - hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, dir); - if (hPtr != NULL) { + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); + if (!isNew) { break; } zd = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); @@ -1394,19 +1406,13 @@ ZipFS_Catalogue_Filesystem( zd->nbyte = zd->nbytecompr = 0; zd->cmeth = ZIP_COMPMETH_STORED; zd->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); - if (!isNew) { - /* should not happen but skip it anyway */ - Tcl_Free((char *) zd); - } else { - Tcl_SetHashValue(hPtr, zd); - zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); - zd->next = zf->entries; - zf->entries = zd; - if ((mntpt[0] == '\0') && (zd->depth == 1)) { - zd->tnext = zf->topents; - zf->topents = zd; - } + Tcl_SetHashValue(hPtr, zd); + zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); + zd->next = zf->entries; + zf->entries = zd; + if ((mntpt[0] == '\0') && (zd->depth == 1)) { + zd->tnext = zf->topents; + zf->topents = zd; } end = strrchr(dir, '/'); } @@ -1463,10 +1469,11 @@ TclZipfs_C_Init(void) int TclZipfs_Mount( - Tcl_Interp *interp, - const char *mntpt, - const char *zipname, - const char *passwd) + Tcl_Interp *interp, /* Current interpreter. NULLable. */ + const char *mntpt, /* Mount point path. */ + const char *zipname, /* Path to ZIP file to mount. */ + const char *passwd) /* Password for opening the ZIP, or NULL if + * the ZIP is unprotected. */ { int i, pwlen; ZipFile *zf; @@ -1483,7 +1490,8 @@ TclZipfs_Mount( i = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + zf = Tcl_GetHashValue(hPtr); + if (zf != NULL) { if (interp != NULL) { Tcl_AppendElement(interp, zf->mntpt); Tcl_AppendElement(interp, zf->name); @@ -1501,11 +1509,11 @@ TclZipfs_Mount( if (zipname == NULL) { if (interp != NULL) { - Tcl_HashEntry *hPtr; + Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); if (hPtr != NULL) { - if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { + zf = Tcl_GetHashValue(hPtr); + if (zf != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); } } @@ -1525,7 +1533,7 @@ TclZipfs_Mount( return TCL_ERROR; } } - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); + zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1558,13 +1566,12 @@ TclZipfs_Mount( int TclZipfs_Mount_Buffer( - Tcl_Interp *interp, - const char *mntpt, + Tcl_Interp *interp, /* Current interpreter. NULLable. */ + const char *mntpt, /* Mount point path. */ unsigned char *data, size_t datalen, int copy) { - int i; ZipFile *zf; ReadLock(); @@ -1574,32 +1581,33 @@ TclZipfs_Mount_Buffer( if (mntpt == NULL) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; - int ret = TCL_OK; + int ret = (interp ? TCL_BREAK : TCL_OK); - i = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + zf = Tcl_GetHashValue(hPtr); + if (zf != NULL) { if (interp != NULL) { Tcl_AppendElement(interp, zf->mntpt); Tcl_AppendElement(interp, zf->name); + } else { + ret = TCL_OK; + /* + * Stop searching here if we're not returning a list. + */ + break; } - ++i; } hPtr = Tcl_NextHashEntry(&search); } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } Unlock(); return ret; } if (data == NULL) { if (interp != NULL) { - Tcl_HashEntry *hPtr; + Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); if (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); if (zf != NULL) { @@ -1660,8 +1668,8 @@ TclZipfs_Mount_Buffer( int TclZipfs_Unmount( - Tcl_Interp *interp, - const char *mntpt) + Tcl_Interp *interp, /* Current interpreter. NULLable. */ + const char *mntpt) /* Mount point path. */ { ZipFile *zf; ZipEntry *z, *znext; @@ -1688,7 +1696,7 @@ TclZipfs_Unmount( goto done; } - zf = (ZipFile *) Tcl_GetHashValue(hPtr); + zf = Tcl_GetHashValue(hPtr); if (zf->nopen > 0) { ZIPFS_ERROR(interp, "filesystem is busy"); ret = TCL_ERROR; @@ -1736,7 +1744,7 @@ TclZipfs_Unmount( static int ZipFSMountObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -1747,8 +1755,8 @@ ZipFSMountObjCmd( } return TclZipfs_Mount(interp, (objc > 1) ? Tcl_GetString(objv[1]) : NULL, - (objc > 2) ? Tcl_GetString(objv[2]) : NULL, - (objc > 3) ? Tcl_GetString(objv[3]) : NULL); + (objc > 2) ? Tcl_GetString(objv[2]) : NULL, + (objc > 3) ? Tcl_GetString(objv[3]) : NULL); } /* @@ -1770,11 +1778,11 @@ ZipFSMountObjCmd( static int ZipFSMountBufferObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { - const char *mntpt; + const char *mntpt; /* Mount point path. */ unsigned char *data; int length; @@ -1783,28 +1791,21 @@ ZipFSMountBufferObjCmd( return TCL_ERROR; } if (objc < 2) { - int i; Tcl_HashEntry *hPtr; Tcl_HashSearch search; int ret = TCL_OK; - ZipFile *zf; ReadLock(); - i = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; + ZipFile *zf = Tcl_GetHashValue(hPtr); + + if (zf != NULL) { + Tcl_AppendElement(interp, zf->mntpt); + Tcl_AppendElement(interp, zf->name); } hPtr = Tcl_NextHashEntry(&search); } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } Unlock(); return ret; } @@ -1812,15 +1813,14 @@ ZipFSMountBufferObjCmd( mntpt = Tcl_GetString(objv[1]); if (objc < 3) { Tcl_HashEntry *hPtr; - ZipFile *zf; - if (interp != NULL) { - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); - if (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } + ReadLock(); + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + if (hPtr != NULL) { + ZipFile *zf = Tcl_GetHashValue(hPtr); + + if (zf != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); } } Unlock(); @@ -1850,7 +1850,7 @@ ZipFSMountBufferObjCmd( static int ZipFSRootObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -1877,7 +1877,7 @@ ZipFSRootObjCmd( static int ZipFSUnmountObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -1908,7 +1908,7 @@ ZipFSUnmountObjCmd( static int ZipFSMkKeyObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -1968,11 +1968,12 @@ ZipFSMkKeyObjCmd( static int ZipAddFile( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ const char *path, const char *name, Tcl_Channel out, - const char *passwd, + const char *passwd, /* Password for encoding the file, or NULL if + * the file is to be unprotected. */ char *buf, int bufsize, Tcl_HashTable *fileHash) @@ -1998,16 +1999,15 @@ ZipAddFile( } zpathlen = strlen(zpath); if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { - Tcl_AppendResult(interp, "path too long for \"", path, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "path too long for \"%s\"", path)); return TCL_ERROR; } - in = Tcl_OpenFileChannel(interp, path, "r", 0); - if ((in == NULL) || Tcl_SetChannelOption(interp, in, - "-translation", "binary") != TCL_OK) { + in = Tcl_OpenFileChannel(interp, path, "rb", 0); + if (in == NULL) { #ifdef _WIN32 - /* hopefully a directory */ - if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { + /* hopefully a directory */ + if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { Tcl_Close(interp, in); return TCL_OK; } @@ -2031,22 +2031,19 @@ ZipAddFile( crc = crc32(crc, (unsigned char *) buf, len); nbyte += len; } - if (len == (size_t)-1) { - if (nbyte == 0) { - if (strcmp("illegal operation on a directory", - Tcl_PosixError(interp)) == 0) { - Tcl_Close(interp, in); - return TCL_OK; - } + if (len == ERROR_LENGTH) { + if (nbyte == 0 && errno == EISDIR) { + Tcl_Close(interp, in); + return TCL_OK; } - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("read error on \"%s\": %s", + path, Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } if (Tcl_Seek(in, 0, SEEK_SET) == -1) { - Tcl_AppendResult(interp, "seek error on \"", path, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf("seek error on \"%s\": %s", + path, Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2054,9 +2051,10 @@ ZipAddFile( memset(buf, '\0', ZIP_LOCAL_HEADER_LEN); memcpy(buf + ZIP_LOCAL_HEADER_LEN, zpath, zpathlen); len = zpathlen + ZIP_LOCAL_HEADER_LEN; - if ((size_t)Tcl_Write(out, buf, len) != len) { + if ((size_t) Tcl_Write(out, buf, len) != len) { wrerr: - Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error on %s: %s", path, Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2083,55 +2081,60 @@ ZipAddFile( init_keys(passwd, keys, crc32tab); for (i = 0; i < 12 - 2; i++) { - if (Tcl_EvalEx(interp, "expr int(rand() * 256) % 256", -1, - 0) != TCL_OK) { - Tcl_AppendResult(interp, "PRNG error", (char *) NULL); + double r; + + if (Tcl_EvalEx(interp, "::tcl::mathfunc::rand", -1, 0) != TCL_OK) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("PRNG error: %s", + Tcl_GetString(Tcl_GetObjResult(interp)))); Tcl_Close(interp, in); return TCL_ERROR; } ret = Tcl_GetObjResult(interp); - if (Tcl_GetIntFromObj(interp, ret, &ch) != TCL_OK) { + if (Tcl_GetDoubleFromObj(interp, ret, &r) != TCL_OK) { Tcl_Close(interp, in); return TCL_ERROR; } + ch = (int) (r * 256); kvbuf[i + 12] = (unsigned char) zencode(keys, crc32tab, ch, tmp); } Tcl_ResetResult(interp); init_keys(passwd, keys, crc32tab); for (i = 0; i < 12 - 2; i++) { - kvbuf[i] = (unsigned char) zencode(keys, crc32tab, kvbuf[i + 12], tmp); + kvbuf[i] = (unsigned char) + zencode(keys, crc32tab, kvbuf[i + 12], tmp); } kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 16, tmp); kvbuf[i++] = (unsigned char) zencode(keys, crc32tab, crc >> 24, tmp); len = Tcl_Write(out, (char *) kvbuf, 12); memset(kvbuf, 0, 24); if (len != 12) { - Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error on %s: %s", path, Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } - memcpy(keys0, keys, sizeof (keys0)); + memcpy(keys0, keys, sizeof(keys0)); nbytecompr += 12; } Tcl_Flush(out); pos[2] = Tcl_Tell(out); cmeth = ZIP_COMPMETH_DEFLATED; - memset(&stream, 0, sizeof (stream)); + memset(&stream, 0, sizeof(z_stream)); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; if (deflateInit2(&stream, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY) != Z_OK) { - Tcl_AppendResult(interp, "compression init error on \"", path, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "compression init error on \"%s\"", path)); Tcl_Close(interp, in); return TCL_ERROR; } do { len = Tcl_Read(in, buf, bufsize); - if (len == (size_t)-1) { - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); + if (len == ERROR_LENGTH) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "read error on %s: %s", path, Tcl_PosixError(interp))); deflateEnd(&stream); Tcl_Close(interp, in); return TCL_ERROR; @@ -2140,17 +2143,17 @@ ZipAddFile( stream.next_in = (unsigned char *) buf; flush = Tcl_Eof(in) ? Z_FINISH : Z_NO_FLUSH; do { - stream.avail_out = sizeof (obuf); + stream.avail_out = sizeof(obuf); stream.next_out = (unsigned char *) obuf; len = deflate(&stream, flush); - if (len == (size_t)Z_STREAM_ERROR) { - Tcl_AppendResult(interp, "deflate error on \"", path, "\"", - (char *) NULL); + if (len == (size_t) Z_STREAM_ERROR) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "deflate error on %s", path)); deflateEnd(&stream); Tcl_Close(interp, in); return TCL_ERROR; } - olen = sizeof (obuf) - stream.avail_out; + olen = sizeof(obuf) - stream.avail_out; if (passwd != NULL) { size_t i; int tmp; @@ -2159,8 +2162,9 @@ ZipAddFile( obuf[i] = (char) zencode(keys, crc32tab, obuf[i], tmp); } } - if (olen && ((size_t)Tcl_Write(out, obuf, olen) != olen)) { - Tcl_AppendResult(interp, "write error", (char *) NULL); + if (olen && ((size_t) Tcl_Write(out, obuf, olen) != olen)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); deflateEnd(&stream); Tcl_Close(interp, in); return TCL_ERROR; @@ -2181,15 +2185,17 @@ ZipAddFile( if (Tcl_Seek(out, pos[2], SEEK_SET) != pos[2]) { seekErr: Tcl_Close(interp, in); - Tcl_AppendResult(interp, "seek error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } nbytecompr = (passwd != NULL) ? 12 : 0; while (1) { len = Tcl_Read(in, buf, bufsize); - if (len == (size_t)-1) { - Tcl_AppendResult(interp, "read error on \"", path, "\"", - (char *) NULL); + if (len == ERROR_LENGTH) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "read error on \"%s\": %s", + path, Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } else if (len == 0) { @@ -2203,8 +2209,9 @@ ZipAddFile( buf[i] = (char) zencode(keys0, crc32tab, buf[i], tmp); } } - if ((size_t)Tcl_Write(out, buf, len) != len) { - Tcl_AppendResult(interp, "write error", (char *) NULL); + if ((size_t) Tcl_Write(out, buf, len) != len) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); Tcl_Close(interp, in); return TCL_ERROR; } @@ -2217,7 +2224,7 @@ ZipAddFile( } Tcl_Close(interp, in); - z = (ZipEntry *) Tcl_Alloc(sizeof (*z)); + z = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); z->name = NULL; z->tnext = NULL; z->depth = 0; @@ -2233,8 +2240,8 @@ ZipAddFile( z->data = NULL; hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); if (!isNew) { - Tcl_AppendResult(interp, "non-unique path name \"", path, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "non-unique path name \"%s\"", path)); Tcl_Free((char *) z); return TCL_ERROR; } else { @@ -2260,20 +2267,23 @@ ZipAddFile( if (Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { Tcl_DeleteHashEntry(hPtr); Tcl_Free((char *) z); - Tcl_AppendResult(interp, "seek error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } if (Tcl_Write(out, buf, ZIP_LOCAL_HEADER_LEN) != ZIP_LOCAL_HEADER_LEN) { Tcl_DeleteHashEntry(hPtr); Tcl_Free((char *) z); - Tcl_AppendResult(interp, "write error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } Tcl_Flush(out); if (Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { Tcl_DeleteHashEntry(hPtr); Tcl_Free((char *) z); - Tcl_AppendResult(interp, "seek error", (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } return TCL_OK; @@ -2301,7 +2311,7 @@ ZipAddFile( static int ZipFSMkZipOrImgObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int isImg, int isList, int objc, @@ -2318,21 +2328,10 @@ ZipFSMkZipOrImgObjCmd( Tcl_HashTable fileHash; char *strip = NULL, *pw = NULL, pwbuf[264], buf[4096]; - if (isList) { - if ((objc < 3) || (objc > (isImg ? 5 : 4))) { - Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile inlist ?password infile?" : - "outfile inlist ?password?"); - return TCL_ERROR; - } - } else { - if ((objc < 3) || (objc > (isImg ? 6 : 5))) { - Tcl_WrongNumArgs(interp, 1, objv, isImg ? - "outfile indir ?strip? ?password? ?infile?" : - "outfile indir ?strip? ?password?"); - return TCL_ERROR; - } - } + /* + * Caller has verified that the number of arguments is correct. + */ + pwbuf[0] = 0; if (objc > (isList ? 3 : 4)) { pw = Tcl_GetString(objv[isList ? 3 : 4]); @@ -2376,11 +2375,9 @@ ZipFSMkZipOrImgObjCmd( Tcl_SetObjResult(interp, Tcl_NewStringObj("empty archive", -1)); return TCL_ERROR; } - out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "w", 0755); - if ((out == NULL) || (Tcl_SetChannelOption(interp, out, - "-translation", "binary") != TCL_OK)) { + out = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "wb", 0755); + if (out == NULL) { Tcl_DecrRefCount(list); - Tcl_Close(interp, out); return TCL_ERROR; } if (pwlen <= 0) { @@ -2421,7 +2418,8 @@ ZipFSMkZipOrImgObjCmd( WriteLock(); hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { + zf = Tcl_GetHashValue(hPtr); + if (zf != NULL) { if (strcmp(zf->name, imgName) == 0) { isMounted = 1; zf->nopen++; @@ -2437,9 +2435,10 @@ ZipFSMkZipOrImgObjCmd( if (isMounted || ZipFSOpenArchive(interp, imgName, 0, zf) == TCL_OK) { if ((size_t) Tcl_Write(out, (char *) zf->data, zf->baseoffsp) != zf->baseoffsp) { - memset(pwbuf, 0, sizeof (pwbuf)); + memset(pwbuf, 0, sizeof(pwbuf)); Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); Tcl_Close(interp, out); if (zf == &zf0) { ZipFSCloseArchive(interp, zf); @@ -2469,20 +2468,20 @@ ZipFSMkZipOrImgObjCmd( */ Tcl_ResetResult(interp); - in = Tcl_OpenFileChannel(interp, imgName, "r", 0644); + in = Tcl_OpenFileChannel(interp, imgName, "rb", 0644); if (in == NULL) { - memset(pwbuf, 0, sizeof (pwbuf)); + memset(pwbuf, 0, sizeof(pwbuf)); Tcl_DecrRefCount(list); Tcl_Close(interp, out); return TCL_ERROR; } - Tcl_SetChannelOption(interp, in, "-translation", "binary"); i = Tcl_Seek(in, 0, SEEK_END); - if (i == (size_t)-1) { + if (i == ERROR_LENGTH) { cperr: - memset(pwbuf, 0, sizeof (pwbuf)); + memset(pwbuf, 0, sizeof(pwbuf)); Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1)); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "%s: %s", errMsg, Tcl_PosixError(interp))); Tcl_Close(interp, out); Tcl_Close(interp, in); return TCL_ERROR; @@ -2491,8 +2490,8 @@ ZipFSMkZipOrImgObjCmd( k = 0; while (k < i) { m = i - k; - if (m > (int)sizeof (buf)) { - m = (int)sizeof (buf); + if (m > (int) sizeof(buf)) { + m = (int) sizeof(buf); } n = Tcl_Read(in, buf, m); if (n == -1) { @@ -2515,12 +2514,13 @@ ZipFSMkZipOrImgObjCmd( i = Tcl_Write(out, pwbuf, len); if (i != len) { Tcl_DecrRefCount(list); - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); Tcl_Close(interp, out); return TCL_ERROR; } } - memset(pwbuf, 0, sizeof (pwbuf)); + memset(pwbuf, 0, sizeof(pwbuf)); Tcl_Flush(out); } Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); @@ -2529,7 +2529,7 @@ ZipFSMkZipOrImgObjCmd( strip = Tcl_GetString(objv[3]); slen = strlen(strip); } - for (i = 0; i < (size_t)lobjc; i += (isList ? 2 : 1)) { + for (i = 0; i < (size_t) lobjc; i += (isList ? 2 : 1)) { const char *path, *name; path = Tcl_GetString(lobjv[i]); @@ -2551,14 +2551,14 @@ ZipFSMkZipOrImgObjCmd( if (name[0] == '\0') { continue; } - if (ZipAddFile(interp, path, name, out, pw, buf, sizeof (buf), - &fileHash) != TCL_OK) { + if (ZipAddFile(interp, path, name, out, pw, buf, sizeof(buf), + &fileHash) != TCL_OK) { goto done; } } pos[1] = Tcl_Tell(out); count = 0; - for (i = 0; i < (size_t)lobjc; i += (isList ? 2 : 1)) { + for (i = 0; i < (size_t) lobjc; i += (isList ? 2 : 1)) { const char *path, *name; path = Tcl_GetString(lobjv[i]); @@ -2605,8 +2605,9 @@ ZipFSMkZipOrImgObjCmd( zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) - || ((size_t)Tcl_Write(out, z->name, len) != len)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + || ((size_t) Tcl_Write(out, z->name, len) != len)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); goto done; } count++; @@ -2622,11 +2623,13 @@ ZipFSMkZipOrImgObjCmd( zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("write error", -1)); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "write error: %s", Tcl_PosixError(interp))); goto done; } Tcl_Flush(out); ret = TCL_OK; + done: if (ret == TCL_OK) { ret = Tcl_Close(interp, out); @@ -2636,7 +2639,7 @@ ZipFSMkZipOrImgObjCmd( Tcl_DecrRefCount(list); hPtr = Tcl_FirstHashEntry(&fileHash, &search); while (hPtr != NULL) { - z = (ZipEntry *) Tcl_GetHashValue(hPtr); + z = Tcl_GetHashValue(hPtr); Tcl_Free((char *) z); Tcl_DeleteHashEntry(hPtr); hPtr = Tcl_NextHashEntry(&search); @@ -2665,20 +2668,28 @@ ZipFSMkZipOrImgObjCmd( static int ZipFSMkZipObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { + if (objc < 3 || objc > 5) { + Tcl_WrongNumArgs(interp, 1, objv, "outfile indir ?strip? ?password?"); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv); } static int ZipFSLMkZipObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { + if (objc < 3 || objc > 4) { + Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password?"); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv); } @@ -2702,20 +2713,29 @@ ZipFSLMkZipObjCmd( static int ZipFSMkImgObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { + if (objc < 3 || objc > 6) { + Tcl_WrongNumArgs(interp, 1, objv, + "outfile indir ?strip? ?password? ?infile?"); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv); } static int ZipFSLMkImgObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { + if (objc < 3 || objc > 5) { + Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password infile?"); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv); } @@ -2739,16 +2759,16 @@ ZipFSLMkImgObjCmd( static int ZipFSCanonicalObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, - Tcl_Obj *const objv[] -) { + Tcl_Obj *const objv[]) +{ char *mntpoint = NULL; char *filename = NULL; char *result; Tcl_DString dPath; - if (objc != 2 && objc != 3 && objc != 4) { + if (objc < 2 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "?mntpnt? filename ?ZIPFS?"); return TCL_ERROR; } @@ -2795,7 +2815,7 @@ ZipFSCanonicalObjCmd( static int ZipFSExistsObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -2848,7 +2868,7 @@ ZipFSExistsObjCmd( static int ZipFSInfoObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -2897,7 +2917,7 @@ ZipFSInfoObjCmd( static int ZipFSListObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -2923,8 +2943,8 @@ ZipFSListObjCmd( return TCL_ERROR; } } else { - Tcl_AppendResult(interp, "unknown option \"", what, "\"", - (char *) NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown option \"%s\"", what)); return TCL_ERROR; } } else if (objc == 2) { @@ -2966,6 +2986,7 @@ ZipFSListObjCmd( #ifdef _WIN32 #define LIBRARY_SIZE 64 + static int ToUtf( const WCHAR *wSrc, @@ -2981,7 +3002,7 @@ ToUtf( *dst = '\0'; return (int) (dst - start); } -#endif +#endif /* _WIN32 */ Tcl_Obj * TclZipfs_TclLibrary(void) @@ -3010,7 +3031,7 @@ TclZipfs_TclLibrary(void) return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } -#ifdef _WIN32 +#if defined(_WIN32) if (GetModuleFileNameW(hModule, wName, MAX_PATH) == 0) { GetModuleFileNameA(hModule, dllname, MAX_PATH); } else { @@ -3024,8 +3045,7 @@ TclZipfs_TclLibrary(void) if (TclZipfs_AppHook_FindTclInit(dllname) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } -#else /* !_WIN32 */ -#ifdef CFG_RUNTIME_DLLFILE +#elif /* !_WIN32 && */ defined(CFG_RUNTIME_DLLFILE) /* * Mount zip file and dll before releasing to search. */ @@ -3033,8 +3053,7 @@ TclZipfs_TclLibrary(void) CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } -#endif /* CFG_RUNTIME_DLLFILE */ -#endif /* _WIN32 */ +#endif /* _WIN32 || CFG_RUNTIME_DLLFILE */ #ifdef CFG_RUNTIME_ZIPFILE if (TclZipfs_AppHook_FindTclInit( @@ -3075,7 +3094,7 @@ TclZipfs_TclLibrary(void) static int ZipFSTclLibraryObjCmd( ClientData clientData, - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int objc, Tcl_Obj *const objv[]) { @@ -3107,7 +3126,7 @@ ZipFSTclLibraryObjCmd( static int ZipChannelClose( ClientData instanceData, - Tcl_Interp *interp) + Tcl_Interp *interp) /* Current interpreter. */ { ZipChannel *info = (ZipChannel *) instanceData; @@ -3117,7 +3136,7 @@ ZipChannelClose( } if (info->isenc) { info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); + memset(info->keys, 0, sizeof(info->keys)); } if (info->iswr) { ZipEntry *z = info->zipentry; @@ -3153,13 +3172,13 @@ ZipChannelClose( * * ZipChannelRead -- * - * This function is called to read data from channel. + * This function is called to read data from channel. * * Results: - * Number of bytes read or -1 on error with error number set. + * Number of bytes read or -1 on error with error number set. * * Side effects: - * Data is read and file pointer is advanced. + * Data is read and file pointer is advanced. * *------------------------------------------------------------------------- */ @@ -3179,6 +3198,7 @@ ZipChannelRead( * Special case: when executable combined with ZIP archive file read * data in front of ZIP, i.e. the executable itself. */ + nextpos = info->nread + toRead; if (nextpos > info->zipfile->baseoffs) { toRead = info->zipfile->baseoffs - info->nread; @@ -3205,10 +3225,11 @@ ZipChannelRead( return 0; } if (info->isenc) { - int i, ch; + int i; for (i = 0; i < toRead; i++) { - ch = info->ubuf[i + info->nread]; + int ch = info->ubuf[i + info->nread]; + buf[i] = zdecode(info->keys, crc32tab, ch); } } else { @@ -3271,13 +3292,13 @@ ZipChannelWrite( * * ZipChannelSeek -- * - * This function is called to position file pointer of channel. + * This function is called to position file pointer of channel. * * Results: - * New file position or -1 on error with error number set. + * New file position or -1 on error with error number set. * * Side effects: - * File pointer is repositioned according to offset and mode. + * File pointer is repositioned according to offset and mode. * *------------------------------------------------------------------------- */ @@ -3394,8 +3415,7 @@ ZipChannelGetFile( static Tcl_ChannelType ZipChannelType = { "zip", /* Type name. */ -#ifdef TCL_CHANNEL_VERSION_4 - TCL_CHANNEL_VERSION_4, + TCL_CHANNEL_VERSION_5, ZipChannelClose, /* Close channel, clean instance data */ ZipChannelRead, /* Handle read request */ ZipChannelWrite, /* Handle write request */ @@ -3410,17 +3430,7 @@ static Tcl_ChannelType ZipChannelType = { NULL, /* Function to handle event, NULL'able */ NULL, /* Wide seek function, NULL'able */ NULL, /* Thread action function, NULL'able */ -#else - NULL, /* Set blocking/nonblocking behaviour, NULL'able */ - ZipChannelClose, /* Close channel, clean instance data */ - ZipChannelRead, /* Handle read request */ - ZipChannelWrite, /* Handle write request */ - ZipChannelSeek, /* Move location of access point, NULL'able */ - NULL, /* Set options, NULL'able */ - NULL, /* Get options, NULL'able */ - ZipChannelWatchChannel, /* Initialize notifier */ - ZipChannelGetFile, /* Get OS handle from the channel */ -#endif + NULL, /* Truncate function, NULL'able */ }; /* @@ -3428,21 +3438,21 @@ static Tcl_ChannelType ZipChannelType = { * * ZipChannelOpen -- * - * This function opens a Tcl_Channel on a file from a mounted ZIP - * archive according to given open mode. + * This function opens a Tcl_Channel on a file from a mounted ZIP archive + * according to given open mode. * * Results: - * Tcl_Channel on success, or NULL on error. + * Tcl_Channel on success, or NULL on error. * * Side effects: - * Memory is allocated, the file from the ZIP archive is uncompressed. + * Memory is allocated, the file from the ZIP archive is uncompressed. * *------------------------------------------------------------------------- */ static Tcl_Channel ZipChannelOpen( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ char *filename, int mode, int permissions) @@ -3464,8 +3474,8 @@ ZipChannelOpen( z = ZipFSLookup(filename); if (z == NULL) { if (interp != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj("file not found", -1)); - Tcl_AppendResult(interp, " \"", filename, "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "file not found \"%s\"", filename)); } goto error; } @@ -3492,7 +3502,7 @@ ZipChannelOpen( } else { flags = TCL_WRITABLE; } - info = (ZipChannel *) Tcl_AttemptAlloc(sizeof (*info)); + info = (ZipChannel *) Tcl_AttemptAlloc(sizeof(ZipChannel)); if (info == NULL) { ZIPFS_ERROR(interp, "out of memory"); goto error; @@ -3520,97 +3530,96 @@ ZipChannelOpen( memset(info->ubuf, 0, info->nmax); if (trunc) { info->nbyte = 0; + } else if (z->data != NULL) { + unsigned int j = z->nbyte; + + if (j > info->nmax) { + j = info->nmax; + } + memcpy(info->ubuf, z->data, j); + info->nbyte = j; } else { - if (z->data != NULL) { - unsigned int j = z->nbyte; + unsigned char *zbuf = z->zipfile->data + z->offset; - if (j > info->nmax) { - j = info->nmax; - } - memcpy(info->ubuf, z->data, j); - info->nbyte = j; - } else { - unsigned char *zbuf = z->zipfile->data + z->offset; + if (z->isenc) { + int len = z->zipfile->pwbuf[0]; + char pwbuf[260]; + for (i = 0; i < len; i++) { + ch = z->zipfile->pwbuf[len - i]; + pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + } + pwbuf[i] = '\0'; + init_keys(pwbuf, info->keys, crc32tab); + memset(pwbuf, 0, sizeof(pwbuf)); + for (i = 0; i < 12; i++) { + ch = info->ubuf[i]; + zdecode(info->keys, crc32tab, ch); + } + zbuf += i; + } + if (z->cmeth == ZIP_COMPMETH_DEFLATED) { + z_stream stream; + int err; + unsigned char *cbuf = NULL; + + memset(&stream, 0, sizeof(z_stream)); + stream.zalloc = Z_NULL; + stream.zfree = Z_NULL; + stream.opaque = Z_NULL; + stream.avail_in = z->nbytecompr; if (z->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; + unsigned int j; - for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + stream.avail_in -= 12; + cbuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); + if (cbuf == NULL) { + goto merror0; } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof (pwbuf)); - for (i = 0; i < 12; i++) { - ch = info->ubuf[i]; - zdecode(info->keys, crc32tab, ch); + for (j = 0; j < stream.avail_in; j++) { + ch = info->ubuf[j]; + cbuf[j] = zdecode(info->keys, crc32tab, ch); } - zbuf += i; + stream.next_in = cbuf; + } else { + stream.next_in = zbuf; } - if (z->cmeth == ZIP_COMPMETH_DEFLATED) { - z_stream stream; - int err; - unsigned char *cbuf = NULL; - - memset(&stream, 0, sizeof (stream)); - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (z->isenc) { - unsigned int j; - - stream.avail_in -= 12; - cbuf = (unsigned char *) - Tcl_AttemptAlloc(stream.avail_in); - if (cbuf == NULL) { - goto merror0; - } - for (j = 0; j < stream.avail_in; j++) { - ch = info->ubuf[j]; - cbuf[j] = zdecode(info->keys, crc32tab, ch); - } - stream.next_in = cbuf; - } else { - stream.next_in = zbuf; - } - stream.next_out = info->ubuf; - stream.avail_out = info->nmax; - if (inflateInit2(&stream, -15) != Z_OK) goto cerror0; - err = inflate(&stream, Z_SYNC_FLUSH); - inflateEnd(&stream); - if ((err == Z_STREAM_END) - || ((err == Z_OK) && (stream.avail_in == 0))) { - if (cbuf != NULL) { - memset(info->keys, 0, sizeof (info->keys)); - Tcl_Free((char *) cbuf); - } - goto wrapchan; - } - cerror0: + stream.next_out = info->ubuf; + stream.avail_out = info->nmax; + if (inflateInit2(&stream, -15) != Z_OK) { + goto cerror0; + } + err = inflate(&stream, Z_SYNC_FLUSH); + inflateEnd(&stream); + if ((err == Z_STREAM_END) + || ((err == Z_OK) && (stream.avail_in == 0))) { if (cbuf != NULL) { - memset(info->keys, 0, sizeof (info->keys)); + memset(info->keys, 0, sizeof(info->keys)); Tcl_Free((char *) cbuf); } - if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); - } - Tcl_Free((char *) info); - ZIPFS_ERROR(interp, "decompression error"); - goto error; - } else if (z->isenc) { - for (i = 0; i < z->nbyte - 12; i++) { - ch = zbuf[i]; - info->ubuf[i] = zdecode(info->keys, crc32tab, ch); - } - } else { - memcpy(info->ubuf, zbuf, z->nbyte); + goto wrapchan; } - memset(info->keys, 0, sizeof (info->keys)); - goto wrapchan; + cerror0: + if (cbuf != NULL) { + memset(info->keys, 0, sizeof(info->keys)); + Tcl_Free((char *) cbuf); + } + if (info->ubuf != NULL) { + Tcl_Free((char *) info->ubuf); + } + Tcl_Free((char *) info); + ZIPFS_ERROR(interp, "decompression error"); + goto error; + } else if (z->isenc) { + for (i = 0; i < z->nbyte - 12; i++) { + ch = zbuf[i]; + info->ubuf[i] = zdecode(info->keys, crc32tab, ch); + } + } else { + memcpy(info->ubuf, zbuf, z->nbyte); } + memset(info->keys, 0, sizeof(info->keys)); + goto wrapchan; } } else if (z->data != NULL) { flags |= TCL_READABLE; @@ -3640,7 +3649,7 @@ ZipChannelOpen( } pwbuf[i] = '\0'; init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof (pwbuf)); + memset(pwbuf, 0, sizeof(pwbuf)); for (i = 0; i < 12; i++) { ch = info->ubuf[i]; zdecode(info->keys, crc32tab, ch); @@ -3653,7 +3662,7 @@ ZipChannelOpen( unsigned char *ubuf = NULL; unsigned int j; - memset(&stream, 0, sizeof (stream)); + memset(&stream, 0, sizeof(z_stream)); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; @@ -3679,7 +3688,7 @@ ZipChannelOpen( merror: if (ubuf != NULL) { info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); + memset(info->keys, 0, sizeof(info->keys)); Tcl_Free((char *) ubuf); } Tcl_Free((char *) info); @@ -3699,7 +3708,7 @@ ZipChannelOpen( || ((err == Z_OK) && (stream.avail_in == 0))) { if (ubuf != NULL) { info->isenc = 0; - memset(info->keys, 0, sizeof (info->keys)); + memset(info->keys, 0, sizeof(info->keys)); Tcl_Free((char *) ubuf); } goto wrapchan; @@ -3718,6 +3727,7 @@ ZipChannelOpen( goto error; } } + wrapchan: sprintf(cname, "zipfs_%" TCL_LL_MODIFIER "x_%d", z->offset, ZipFS.idCount++); @@ -3758,7 +3768,7 @@ ZipEntryStat( ReadLock(); z = ZipFSLookup(path); if (z != NULL) { - memset(buf, 0, sizeof (Tcl_StatBuf)); + memset(buf, 0, sizeof(Tcl_StatBuf)); if (z->isdir) { buf->st_mode = S_IFDIR | 0555; } else { @@ -3821,7 +3831,7 @@ ZipEntryAccess( static Tcl_Channel Zip_FSOpenFileChannelProc( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *pathPtr, int mode, int permissions) @@ -3942,9 +3952,10 @@ Zip_FSFilesystemSeparatorProc( * *------------------------------------------------------------------------- */ + static int Zip_FSMatchInDirectoryProc( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *result, Tcl_Obj *pathPtr, const char *pattern, @@ -3952,24 +3963,29 @@ Zip_FSMatchInDirectoryProc( { Tcl_HashEntry *hPtr; Tcl_HashSearch search; - Tcl_Obj *normPathPtr; + Tcl_Obj *normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); int scnt, l, dirOnly = -1, prefixLen, strip = 0; size_t len; char *pat, *prefix, *path; Tcl_DString dsPref; - if (!(normPathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) { + if (!normPathPtr) { return -1; } - if (types != NULL) { dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; } - /* the prefix that gets prepended to results */ + /* + * The prefix that gets prepended to results. + */ + prefix = Tcl_GetStringFromObj(pathPtr, &prefixLen); - /* the (normalized) path we're searching */ + /* + * The (normalized) path we're searching. + */ + path = Tcl_GetString(normPathPtr); len = normPathPtr->length; @@ -3999,12 +4015,14 @@ Zip_FSMatchInDirectoryProc( } hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - ZipFile *zf = (ZipFile *) Tcl_GetHashValue(hPtr); + ZipFile *zf = Tcl_GetHashValue(hPtr); if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - while (z != NULL) { + ZipEntry *z; + + for (z = zf->topents; z != NULL; z = z->tnext) { size_t lenz = strlen(z->name); + if ((lenz > len + 1) && (strncmp(z->name, path, len) == 0) && (z->name[len] == '/') && (CountSlashes(z->name) == l) @@ -4021,7 +4039,6 @@ Zip_FSMatchInDirectoryProc( Tcl_NewStringObj(z->name, lenz)); } } - z = z->tnext; } } else if ((zf->mntptlen > len + 1) && (strncmp(zf->mntpt, path, len) == 0) @@ -4047,7 +4064,7 @@ Zip_FSMatchInDirectoryProc( if ((pattern == NULL) || (pattern[0] == '\0')) { hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); if (hPtr != NULL) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + ZipEntry *z = Tcl_GetHashValue(hPtr); if ((dirOnly < 0) || (!dirOnly && !z->isdir) || (dirOnly && z->isdir)) { @@ -4080,7 +4097,8 @@ Zip_FSMatchInDirectoryProc( scnt = CountSlashes(pat); for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ZipEntry *z = (ZipEntry *) Tcl_GetHashValue(hPtr); + ZipEntry *z = Tcl_GetHashValue(hPtr); + if ((dirOnly >= 0) && ((dirOnly && !z->isdir) || (!dirOnly && z->isdir))) { continue; @@ -4135,7 +4153,8 @@ Zip_FSPathInFilesystemProc( size_t len; char *path; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) { + pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); + if (!pathPtr) { return -1; } @@ -4155,17 +4174,17 @@ Zip_FSPathInFilesystemProc( hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { - zf = (ZipFile *) Tcl_GetHashValue(hPtr); + zf = Tcl_GetHashValue(hPtr); if (zf->mntptlen == 0) { - ZipEntry *z = zf->topents; - while (z != NULL) { + ZipEntry *z; + + for (z = zf->topents; z != NULL; z = z->tnext) { size_t lenz = strlen(z->name); if ((len >= lenz) && (strncmp(path, z->name, lenz) == 0)) { ret = TCL_OK; goto endloop; } - z = z->tnext; } } else if ((len >= zf->mntptlen) && (strncmp(path, zf->mntpt, zf->mntptlen) == 0)) { @@ -4223,7 +4242,7 @@ Zip_FSListVolumesProc(void) static const char *const * Zip_FSFileAttrStringsProc( Tcl_Obj *pathPtr, - Tcl_Obj** objPtrRef) + Tcl_Obj **objPtrRef) { static const char *const attrs[] = { "-uncompsize", @@ -4259,7 +4278,7 @@ Zip_FSFileAttrStringsProc( static int Zip_FSFileAttrsGetProc( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef) @@ -4268,7 +4287,8 @@ Zip_FSFileAttrsGetProc( char *path; ZipEntry *z; - if (!(pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr))) { + pathPtr = Tcl_FSGetNormalizedPath(NULL, pathPtr); + if (!pathPtr) { return -1; } path = Tcl_GetStringFromObj(pathPtr, &len); @@ -4325,7 +4345,7 @@ Zip_FSFileAttrsGetProc( static int Zip_FSFileAttrsSetProc( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr) @@ -4378,7 +4398,7 @@ Zip_FSFilesystemPathTypeProc( static int Zip_FSLoadFile( - Tcl_Interp *interp, + Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, @@ -4401,6 +4421,7 @@ Zip_FSLoadFile( #else /* !ANDROID */ Tcl_Obj *altPath = NULL; int ret = TCL_ERROR; + Tcl_Obj *objs[2] = { NULL, NULL }; if (Tcl_FSAccess(path, R_OK) == 0) { /* @@ -4410,56 +4431,55 @@ Zip_FSLoadFile( Tcl_SetErrno(EXDEV); ZIPFS_ERROR(interp, Tcl_PosixError(interp)); return ret; - } else { - Tcl_Obj *objs[2] = { NULL, NULL }; + } - objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); - if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { - const char *execName = Tcl_GetNameOfExecutable(); + objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); + if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { + const char *execName = Tcl_GetNameOfExecutable(); - /* - * Shared object is not in ZIP but its path prefix is, thus try to - * load from directory where the executable came from. - */ + /* + * Shared object is not in ZIP but its path prefix is, thus try to + * load from directory where the executable came from. + */ - TclDecrRefCount(objs[1]); - objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); + TclDecrRefCount(objs[1]); + objs[1] = TclPathPart(interp, path, TCL_PATH_TAIL); - /* - * Get directory name of executable manually to deal with cases - * where [file dirname [info nameofexecutable]] is equal to [info - * nameofexecutable] due to VFS effects. - */ + /* + * Get directory name of executable manually to deal with cases where + * [file dirname [info nameofexecutable]] is equal to [info + * nameofexecutable] due to VFS effects. + */ - if (execName != NULL) { - const char *p = strrchr(execName, '/'); + if (execName != NULL) { + const char *p = strrchr(execName, '/'); - if (p > execName + 1) { - --p; - objs[0] = Tcl_NewStringObj(execName, p - execName); - } - } - if (objs[0] == NULL) { - objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), - TCL_PATH_DIRNAME); - } - if (objs[0] != NULL) { - altPath = TclJoinPath(2, objs); - if (altPath != NULL) { - Tcl_IncrRefCount(altPath); - if (Tcl_FSAccess(altPath, R_OK) == 0) { - path = altPath; - } - } + if (p > execName + 1) { + --p; + objs[0] = Tcl_NewStringObj(execName, p - execName); } } - if (objs[0] != NULL) { - Tcl_DecrRefCount(objs[0]); + if (objs[0] == NULL) { + objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), + TCL_PATH_DIRNAME); } - if (objs[1] != NULL) { - Tcl_DecrRefCount(objs[1]); + if (objs[0] != NULL) { + altPath = TclJoinPath(2, objs); + if (altPath != NULL) { + Tcl_IncrRefCount(altPath); + if (Tcl_FSAccess(altPath, R_OK) == 0) { + path = altPath; + } + } } } + if (objs[0] != NULL) { + Tcl_DecrRefCount(objs[0]); + } + if (objs[1] != NULL) { + Tcl_DecrRefCount(objs[1]); + } + loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; if (loadFileProc != NULL) { ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); @@ -4495,7 +4515,7 @@ Zip_FSLoadFile( MODULE_SCOPE int TclZipfs_Init( - Tcl_Interp *interp) + Tcl_Interp *interp) /* Current interpreter. */ { #ifdef HAVE_ZLIB /* one-time initialization */ @@ -4507,10 +4527,10 @@ TclZipfs_Init( Unlock(); if (interp != NULL) { static const EnsembleImplMap initMap[] = { - {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, - {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, - {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, - {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, + {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 1}, + {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 1}, + {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 1}, + {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 1}, /* The 4 entries above are not available in safe interpreters */ {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, @@ -4525,23 +4545,22 @@ TclZipfs_Init( {NULL, NULL, NULL, NULL, NULL, 0} }; static const char findproc[] = - "namespace eval ::tcl::zipfs::zipfs {}\n" - "proc ::tcl::zipfs::find dir {\n" + "namespace eval ::tcl::zipfs {}\n" + "proc ::tcl::zipfs::Find dir {\n" " set result {}\n" - " if {[catch {glob -directory $dir -tails -nocomplain * .*} list]} {\n" + " if {[catch {glob -directory $dir -nocomplain * .*} list]} {\n" " return $result\n" " }\n" " foreach file $list {\n" - " if {$file eq \".\" || $file eq \"..\"} {\n" + " if {[file tail $file] in {. ..}} {\n" " continue\n" " }\n" - " set file [file join $dir $file]\n" - " lappend result $file\n" - " foreach file [::tcl::zipfs::find $file] {\n" - " lappend result $file\n" - " }\n" + " lappend result $file {*}[Find $file]\n" " }\n" - " return [lsort $result]\n" + " return $result\n" + "}\n" + "proc ::tcl::zipfs::find dir {\n" + " return [lsort [Find $dir]]\n" "}\n"; Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, @@ -4606,20 +4625,20 @@ TclZipfs_AppHook_FindTclInit( int TclZipfs_AppHook( - int *argc, + int *argcPtr, #ifdef _WIN32 TCHAR #else /* !_WIN32 */ char #endif /* _WIN32 */ - ***argv) + ***argvPtr) { #ifdef _WIN32 Tcl_DString ds; #endif /* _WIN32 */ char *archive; - Tcl_FindExecutable((*argv)[0]); + Tcl_FindExecutable((*argvPtr)[0]); archive = (char *) Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); @@ -4659,18 +4678,19 @@ TclZipfs_AppHook( return TCL_OK; } } - } else if (*argc>1) { - return TCL_OK; +#ifdef SUPPORT_BUILTIN_ZIP_INSTALL + } else if (*argcPtr > 1) { + /* + * If the first argument is "install", run the supplied installer + * script. + */ + #ifdef _WIN32 - archive = Tcl_WinTCharToUtf((*argv)[1], -1, &ds); -#else - archive = (*argv)[1]; -#endif + archive = Tcl_WinTCharToUtf((*argvPtr)[1], -1, &ds); +#else /* !_WIN32 */ + archive = (*argvPtr)[1]; +#endif /* _WIN32 */ if (strcmp(archive, "install") == 0) { - /* - * If the first argument is mkzip, run the mkzip program. - */ - Tcl_Obj *vfsinitscript; /* @@ -4715,6 +4735,7 @@ TclZipfs_AppHook( #ifdef _WIN32 Tcl_DStringFree(&ds); #endif /* _WIN32 */ +#endif /* SUPPORT_BUILTIN_ZIP_INSTALL */ } return TCL_OK; } @@ -4733,18 +4754,19 @@ TclZipfs_AppHook( int TclZipfs_Mount( - Tcl_Interp *interp, - const char *mntpt, - const char *zipname, - const char *passwd) + Tcl_Interp *interp, /* Current interpreter. */ + const char *mntpt, /* Mount point path. */ + const char *zipname, /* Path to ZIP file to mount. */ + const char *passwd) /* Password for opening the ZIP, or NULL if + * the ZIP is unprotected. */ { return TclZipfs_Init(interp, 1); } int TclZipfs_Unmount( - Tcl_Interp *interp, - const char *zipname) + Tcl_Interp *interp, /* Current interpreter. */ + const char *mntpt) /* Mount point path. */ { return TclZipfs_Init(interp, 1); } -- cgit v0.12 From a557024511668b3e4b5276a0b5334546d0807ddd Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 6 Oct 2018 06:41:28 +0000 Subject: Cleanup work on zipfs(n) --- doc/zipfs.n | 127 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 70 insertions(+), 57 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 31a0707..9a241f4 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -19,19 +19,20 @@ zipfs \- Mount and work with ZIP files within Tcl \fBzipfs exists\fR \fIfilename\fR \fBzipfs find\fR \fIdir\fR \fBzipfs info\fR \fIfilename\fR -\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR -\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR +\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR? +\fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? \fBzipfs mkkey\fR \fIpassword\fR -\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR -\fBzipfs mount\fR \fI?mountpoint?\fR \fI?zipfile?\fR \fI?password?\fR +\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? +\fBzipfs mount\fR ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR? \fBzipfs root\fR \fBzipfs unmount\fR \fImountpoint\fR .fi .BE .SH DESCRIPTION .PP -The \fBzipfs\fR package provides tcl with the ability to mount -the contents of a zip file as a virtual file system. +The \fBzipfs\fR command (the sole public command provided by the built-in +package with the same name) provides Tcl with the ability to mount the +contents of a ZIP file as a virtual file system. .TP \fBzipfs exists\fR \fIfilename\fR . @@ -39,50 +40,84 @@ Return 1 if the given filename exists in the mounted zipfs and 0 if it does not. .TP \fBzipfs find\fR \fIdir\fR . -Recursively lists files including and below the directory \fIdir\fR. -The result list consists of relative path names starting from the -given directory. This command is also used by the \fBzipfs mkzip\fR -and \fBzipfs mkimg\fR commands. +Recursively lists files including and below the directory \fIdir\fR. The +result list consists of relative path names starting from the given +directory. This command is also used by the \fBzipfs mkzip\fR and \fBzipfs +mkimg\fR commands. .TP \fBzipfs info\fR \fIfile\fR . -Return information about the given file in the mounted zipfs. The information -consists of (1) the name of the ZIP archive file that contains the file, -(2) the size of the file after decompressions, (3) the compressed size of -the file, and (4) the offset of the compressed data in the ZIP archive file. +Return information about the given \fIfile\fR in the mounted zipfs. The +information consists of: .RS +.IP (1) +the name of the ZIP archive file that contains the file, +.IP (2) +the size of the file after decompressions, +.IP (3) +the compressed size of the file, and +.IP (4) +the offset of the compressed data in the ZIP archive file. .PP -Note: querying the mount point gives the start of zip data offset in (4), -which can be used to truncate the zip info off an executable. +Note: querying the mount point gives the start of the zip data as the offset +in (4), which can be used to truncate the zip information from an executable. .RE .TP -\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR +\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? \fI?pattern?\fR . -Return a list of all files in the mounted zipfs. The order of the names -in the list is arbitrary. +Return a list of all files in the mounted zipfs, or just those matching +\fIpattern\fR (optionally controlled by the option parameters). The order of +the names in the list is arbitrary. .TP -\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR +\fBzipfs mount ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR? +. +The \fBzipfs mount\fR command mounts a ZIP archive file as a Tcl virtual +filesystem at \fImountpoint\fR. After this command executes, files contained +in \fIzipfile\fR will appear to Tcl to be regular files at the mount point. +.RS +.PP +With no \fIzipfile\fR, returns the zipfile mounted at \fImountpoint\fR. With +no \fImountpoint\fR, return all zipfile/mount pairs. If \fImountpoint\fR is +specified as an empty string, mount on file path. +.RE +.TP +\fBzipfs root\fR +. +Returns a constant string which indicates the mount point for zipfs volumes +for the current platform. On Windows, this value is +.QW \fBzipfs:/\fR . +On Unix, this value is +.QW \fB//zipfs:/\fR . +.RE +.TP +\fBzipfs unmount \fImountpoint\fR +. +Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR. +.SS "ZIP CREATION COMMANDS" +This package also provides several commands to aid the creation of ZIP +archives as Tcl applications. +.TP +\fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR? . -Creates an image (potentially a new executable file) similar to -\fBzipfs mkzip\fR. If the \fIinfile\fR parameter is specified, -this file is prepended in front of the ZIP archive, otherwise the file -returned by \fBTcl_NameOfExecutable(3)\fR (i.e. the executable file of -the running process) is used. If the \fIpassword\fR parameter is not empty, -an obfuscated version of that password is placed between the image and ZIP -chunks of the output file and the contents of the ZIP chunk are protected -with that password. +Creates an image (potentially a new executable file) similar to \fBzipfs +mkzip\fR. If the \fIinfile\fR parameter is specified, this file is prepended +in front of the ZIP archive, otherwise the file returned by \fBinfo +nameofexecutable\fR (i.e., the executable file of the running process) is +used. If the \fIpassword\fR parameter is not empty, an obfuscated version of +that password is placed between the image and ZIP chunks of the output file +and the contents of the ZIP chunk are protected with that password. .RS .PP -Caution: highly experimental, not usable on Android, only partially tested -on Linux and Windows. +Caution: highly experimental, not usable on Android, only partially tested on +Linux and Windows. .RE .TP \fBzipfs mkkey\fR \fIpassword\fR . -For the clear text \fIpassword\fR argument an obfuscated string version -is returned with the same format used in the \fBzipfs mkimg\fR command. +For the clear text \fIpassword\fR argument, an obfuscated string version is +returned with the same format used in the \fBzipfs mkimg\fR command. .TP -\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR +\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? . Creates a ZIP archive file named \fIoutfile\fR from the contents of the input directory \fIindir\fR (contained regular files only) with optional ZIP @@ -91,31 +126,9 @@ optional file name prefix given in \fIstrip\fR is stripped off the beginning of the respective file name. .RS .PP -Caution: the choice of the \fIindir\fR parameter -(less the optional stripped prefix) determines the later root name of the -archive's content. +Caution: the choice of the \fIindir\fR parameter (less the optional stripped +prefix) determines the later root name of the archive's content. .RE -.TP -\fBzipfs mount ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR? -. -The \fBzipfs mount\fR command mounts a ZIP archive file as a VFS. -After this command executes, files contained in \fIzipfile\fR -will appear to Tcl to be regular files at the mount point. -.RS -.PP -With no \fIzipfile\fR, returns the zipfile mounted at \fImountpoint\fR. -With no \fImountpoint\fR, return all zipfile/mount pairs. -If \fImountpoint\fR is specified as an empty string, mount on file path. -.RE -.TP -\fBzipfs root\fR -Returns a constant string which indicates the mount point for zipfs volumes -for the current platform. On Windows, this value is zipfs:/. On Unux, //zipfs:/ -.RE -.TP -\fBzipfs unmount \fImountpoint\fR -. -Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR. .SH "SEE ALSO" tclsh(1), file(n), zlib(n) .SH "KEYWORDS" -- cgit v0.12 From ffc7a9f0b97478b4efb04f82c7414b24c94409af Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 6 Oct 2018 13:07:52 +0000 Subject: More cleaning up. --- doc/zipfs.n | 8 +- generic/tclZipfs.c | 977 +++++++++++++++++++++++++++-------------------------- unix/Makefile.in | 4 +- 3 files changed, 508 insertions(+), 481 deletions(-) diff --git a/doc/zipfs.n b/doc/zipfs.n index 9a241f4..3600e64 100644 --- a/doc/zipfs.n +++ b/doc/zipfs.n @@ -101,10 +101,10 @@ archives as Tcl applications. . Creates an image (potentially a new executable file) similar to \fBzipfs mkzip\fR. If the \fIinfile\fR parameter is specified, this file is prepended -in front of the ZIP archive, otherwise the file returned by \fBinfo -nameofexecutable\fR (i.e., the executable file of the running process) is -used. If the \fIpassword\fR parameter is not empty, an obfuscated version of -that password is placed between the image and ZIP chunks of the output file +in front of the ZIP archive, otherwise the file returned by +\fBinfo nameofexecutable\fR (i.e., the executable file of the running process) +is used. If the \fIpassword\fR parameter is not empty, an obfuscated version +of that password is placed between the image and ZIP chunks of the output file and the contents of the ZIP chunk are protected with that password. .RS .PP diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index c66a447..4a0d24c 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -144,14 +144,14 @@ #define ZipReadShort(p) \ ((p)[0] | ((p)[1] << 8)) -#define zip_write_int(p, v) \ +#define ZipWriteInt(p, v) \ do { \ (p)[0] = (v) & 0xff; \ (p)[1] = ((v) >> 8) & 0xff; \ (p)[2] = ((v) >> 16) & 0xff; \ (p)[3] = ((v) >> 24) & 0xff; \ } while (0) -#define zip_write_short(p, v) \ +#define ZipWriteShort(p, v) \ do { \ (p)[0] = (v) & 0xff; \ (p)[1] = ((v) >> 8) & 0xff; \ @@ -180,25 +180,24 @@ TCL_DECLARE_MUTEX(localtimeMutex) typedef struct ZipFile { char *name; /* Archive name */ - size_t namelen; - char is_membuf; /* When true, not a file but a memory buffer */ + size_t nameLength; + char isMemBuffer; /* When true, not a file but a memory buffer */ Tcl_Channel chan; /* Channel handle or NULL */ unsigned char *data; /* Memory mapped or malloc'ed file */ size_t length; /* Length of memory mapped file */ - void *tofree; /* Non-NULL if malloc'ed file */ - size_t nfiles; /* Number of files in archive */ - size_t baseoffs; /* Archive start */ - size_t baseoffsp; /* Password start */ - size_t centoffs; /* Archive directory start */ - unsigned char pwbuf[264]; /* Password buffer */ - size_t nopen; /* Number of open files on archive */ + void *ptrToFree; /* Non-NULL if malloc'ed file */ + size_t numFiles; /* Number of files in archive */ + size_t baseOffset; /* Archive start */ + size_t passOffset; /* Password start */ + size_t directoryOffset; /* Archive directory start */ + unsigned char passBuf[264]; /* Password buffer */ + size_t numOpen; /* Number of open files on archive */ struct ZipEntry *entries; /* List of files in archive */ - struct ZipEntry *topents; /* List of top-level dirs in archive */ - size_t mntptlen; - char *mntpt; /* Mount point */ + struct ZipEntry *topEnts; /* List of top-level dirs in archive */ + char *mountPoint; /* Mount point */ + size_t mountPointLen; #ifdef _WIN32 - HANDLE mh; - int mntdrv; /* Drive letter of mount point */ + HANDLE mountHandle; #endif } ZipFile; @@ -339,31 +338,32 @@ const char *zipfs_literal_tcl_library = NULL; /* Function prototypes */ -int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, - const char *zipname, const char *passwd); +int TclZipfs_Mount(Tcl_Interp *interp, + const char *mountPoint, const char *zipname, + const char *passwd); int TclZipfs_Mount_Buffer(Tcl_Interp *interp, - const char *mntpt, unsigned char *data, + const char *mountPoint, unsigned char *data, size_t datalen, int copy); -static int TclZipfs_AppHook_FindTclInit(const char *archive); -static int Zip_FSPathInFilesystemProc(Tcl_Obj *pathPtr, +static int ZipfsAppHookFindTclInit(const char *archive); +static int ZipFSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr); -static Tcl_Obj * Zip_FSFilesystemPathTypeProc(Tcl_Obj *pathPtr); -static Tcl_Obj * Zip_FSFilesystemSeparatorProc(Tcl_Obj *pathPtr); -static int Zip_FSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); -static int Zip_FSAccessProc(Tcl_Obj *pathPtr, int mode); -static Tcl_Channel Zip_FSOpenFileChannelProc(Tcl_Interp *interp, +static Tcl_Obj * ZipFSFilesystemPathTypeProc(Tcl_Obj *pathPtr); +static Tcl_Obj * ZipFSFilesystemSeparatorProc(Tcl_Obj *pathPtr); +static int ZipFSStatProc(Tcl_Obj *pathPtr, Tcl_StatBuf *buf); +static int ZipFSAccessProc(Tcl_Obj *pathPtr, int mode); +static Tcl_Channel ZipFSOpenFileChannelProc(Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); -static int Zip_FSMatchInDirectoryProc(Tcl_Interp *interp, +static int ZipFSMatchInDirectoryProc(Tcl_Interp *interp, Tcl_Obj *result, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); -static Tcl_Obj * Zip_FSListVolumesProc(void); -static const char *const *Zip_FSFileAttrStringsProc(Tcl_Obj *pathPtr, +static Tcl_Obj * ZipFSListVolumesProc(void); +static const char *const *ZipFSFileAttrStringsProc(Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); -static int Zip_FSFileAttrsGetProc(Tcl_Interp *interp, int index, +static int ZipFSFileAttrsGetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); -static int Zip_FSFileAttrsSetProc(Tcl_Interp *interp, int index, +static int ZipFSFileAttrsSetProc(Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); -static int Zip_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, +static int ZipFSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); static void TclZipfs_C_Init(void); @@ -378,24 +378,24 @@ const Tcl_Filesystem zipfsFilesystem = { "zipfs", sizeof(Tcl_Filesystem), TCL_FILESYSTEM_VERSION_2, - Zip_FSPathInFilesystemProc, + ZipFSPathInFilesystemProc, NULL, /* dupInternalRepProc */ NULL, /* freeInternalRepProc */ NULL, /* internalToNormalizedProc */ NULL, /* createInternalRepProc */ NULL, /* normalizePathProc */ - Zip_FSFilesystemPathTypeProc, - Zip_FSFilesystemSeparatorProc, - Zip_FSStatProc, - Zip_FSAccessProc, - Zip_FSOpenFileChannelProc, - Zip_FSMatchInDirectoryProc, + ZipFSFilesystemPathTypeProc, + ZipFSFilesystemSeparatorProc, + ZipFSStatProc, + ZipFSAccessProc, + ZipFSOpenFileChannelProc, + ZipFSMatchInDirectoryProc, NULL, /* utimeProc */ NULL, /* linkProc */ - Zip_FSListVolumesProc, - Zip_FSFileAttrStringsProc, - Zip_FSFileAttrsGetProc, - Zip_FSFileAttrsSetProc, + ZipFSListVolumesProc, + ZipFSFileAttrStringsProc, + ZipFSFileAttrsGetProc, + ZipFSFileAttrsSetProc, NULL, /* createDirectoryProc */ NULL, /* removeDirectoryProc */ NULL, /* deleteFileProc */ @@ -403,7 +403,7 @@ const Tcl_Filesystem zipfsFilesystem = { NULL, /* renameFileProc */ NULL, /* copyDirectoryProc */ NULL, /* lstatProc */ - (Tcl_FSLoadFileProc *) Zip_FSLoadFile, + (Tcl_FSLoadFileProc *) ZipFSLoadFile, NULL, /* getCwdProc */ NULL, /* chdirProc */ }; @@ -630,61 +630,61 @@ CanonicalPath( int ZIPFSPATH) { char *path; - int i, j, c, isunc = 0, isvfs = 0, n = 0; - int zipfspath = 1; + int i, j, c, isUNC = 0, isVfs = 0, n = 0; + int haveZipfsPath = 1; #ifdef _WIN32 if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) && (tail[1] == ':')) { tail += 2; - zipfspath = 0; + haveZipfsPath = 0; } /* UNC style path */ if (tail[0] == '\\') { root = ""; ++tail; - zipfspath = 0; + haveZipfsPath = 0; } if (tail[0] == '\\') { root = "/"; ++tail; - zipfspath = 0; + haveZipfsPath = 0; } #endif /* _WIN32 */ - if (zipfspath) { + if (haveZipfsPath) { /* UNC style path */ if (root && strncmp(root, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) == 0) { - isvfs = 1; + isVfs = 1; } else if (tail && strncmp(tail, ZIPFS_VOLUME, ZIPFS_VOLUME_LEN) == 0) { - isvfs = 2; + isVfs = 2; } - if (isvfs != 1 && (root[0] == '/') && (root[1] == '/')) { - isunc = 1; + if (isVfs != 1 && (root[0] == '/') && (root[1] == '/')) { + isUNC = 1; } } - if (isvfs != 2) { + if (isVfs != 2) { if (tail[0] == '/') { - if (isvfs != 1) { + if (isVfs != 1) { root = ""; } ++tail; - isunc = 0; + isUNC = 0; } if (tail[0] == '/') { - if (isvfs != 1) { + if (isVfs != 1) { root = "/"; } ++tail; - isunc = 1; + isUNC = 1; } } i = strlen(root); j = strlen(tail); - switch (isvfs) { + switch (isVfs) { case 1: if (i > ZIPFS_VOLUME_LEN) { Tcl_DStringSetLength(dsPtr, i + j + 1); @@ -754,9 +754,9 @@ CanonicalPath( while ((j > 0) && (path[j - 1] != '/')) { j--; } - if (j > isunc) { + if (j > isUNC) { --j; - while ((j > 1 + isunc) && (path[j - 2] == '/')) { + while ((j > 1 + isUNC) && (path[j - 2] == '/')) { j--; } } @@ -835,7 +835,7 @@ ZipFSLookupMount( while (hPtr != NULL) { ZipFile *zf = Tcl_GetHashValue(hPtr); - if (zf != NULL && strcmp(zf->mntpt, filename) == 0) { + if (strcmp(zf->mountPoint, filename) == 0) { return 1; } hPtr = Tcl_NextHashEntry(&search); @@ -866,37 +866,37 @@ ZipFSCloseArchive( Tcl_Interp *interp, /* Current interpreter. */ ZipFile *zf) { - if (zf->namelen) { - free(zf->name); /* Allocated by strdup */ + if (zf->nameLength) { + ckfree(zf->name); } - if (zf->is_membuf == 1) { + if (zf->isMemBuffer) { /* Pointer to memory */ - if (zf->tofree != NULL) { - Tcl_Free(zf->tofree); - zf->tofree = NULL; + if (zf->ptrToFree != NULL) { + ckfree(zf->ptrToFree); + zf->ptrToFree = NULL; } zf->data = NULL; return; } #ifdef _WIN32 - if ((zf->data != NULL) && (zf->tofree == NULL)) { + if ((zf->data != NULL) && (zf->ptrToFree == NULL)) { UnmapViewOfFile(zf->data); zf->data = NULL; } - if (zf->mh != INVALID_HANDLE_VALUE) { - CloseHandle(zf->mh); + if (zf->mountHandle != INVALID_HANDLE_VALUE) { + CloseHandle(zf->mountHandle); } #else /* !_WIN32 */ - if ((zf->data != MAP_FAILED) && (zf->tofree == NULL)) { + if ((zf->data != MAP_FAILED) && (zf->ptrToFree == NULL)) { munmap(zf->data, zf->length); zf->data = MAP_FAILED; } #endif /* _WIN32 */ - if (zf->tofree != NULL) { - Tcl_Free(zf->tofree); - zf->tofree = NULL; + if (zf->ptrToFree != NULL) { + ckfree(zf->ptrToFree); + zf->ptrToFree = NULL; } if (zf->chan != NULL) { Tcl_Close(interp, zf->chan); @@ -907,7 +907,7 @@ ZipFSCloseArchive( /* *------------------------------------------------------------------------- * - * ZipFS_Find_TOC -- + * ZipFSFindTOC -- * * This function takes a memory mapped zip file and indexes the contents. * When "needZip" is zero an embedded ZIP archive in an executable file @@ -925,7 +925,7 @@ ZipFSCloseArchive( */ static int -ZipFS_Find_TOC( +ZipFSFindTOC( Tcl_Interp *interp, /* Current interpreter. NULLable. */ int needZip, ZipFile *zf) @@ -946,16 +946,16 @@ ZipFS_Find_TOC( } if (p < zf->data) { if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; + zf->baseOffset = zf->passOffset = zf->length; return TCL_OK; } ZIPFS_ERROR(interp, "wrong end signature"); goto error; } - zf->nfiles = ZipReadShort(p + ZIP_CENTRAL_ENTS_OFFS); - if (zf->nfiles == 0) { + zf->numFiles = ZipReadShort(p + ZIP_CENTRAL_ENTS_OFFS); + if (zf->numFiles == 0) { if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; + zf->baseOffset = zf->passOffset = zf->length; return TCL_OK; } ZIPFS_ERROR(interp, "empty archive"); @@ -966,16 +966,16 @@ ZipFS_Find_TOC( if ((p < zf->data) || (p > zf->data + zf->length) || (q < zf->data) || (q > zf->data + zf->length)) { if (!needZip) { - zf->baseoffs = zf->baseoffsp = zf->length; + zf->baseOffset = zf->passOffset = zf->length; return TCL_OK; } ZIPFS_ERROR(interp, "archive directory not found"); goto error; } - zf->baseoffs = zf->baseoffsp = p - q; - zf->centoffs = p - zf->data; + zf->baseOffset = zf->passOffset = p - q; + zf->directoryOffset = p - zf->data; q = p; - for (i = 0; i < zf->nfiles; i++) { + for (i = 0; i < zf->numFiles; i++) { int pathlen, comlen, extra; if (q + ZIP_CENTRAL_HEADER_LEN > zf->data + zf->length) { @@ -991,13 +991,13 @@ ZipFS_Find_TOC( extra = ZipReadShort(q + ZIP_CENTRAL_EXTRALEN_OFFS); q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN; } - q = zf->data + zf->baseoffs; - if ((zf->baseoffs >= 6) && (ZipReadInt(q - 4) == ZIP_PASSWORD_END_SIG)) { + q = zf->data + zf->baseOffset; + if ((zf->baseOffset >= 6) && (ZipReadInt(q - 4) == ZIP_PASSWORD_END_SIG)) { i = q[-5]; if (q - 5 - i > zf->data) { - zf->pwbuf[0] = i; - memcpy(zf->pwbuf + 1, q - 5 - i, i); - zf->baseoffsp -= i ? (5 + i) : 0; + zf->passBuf[0] = i; + memcpy(zf->passBuf + 1, q - 5 - i, i); + zf->passOffset -= i ? (5 + i) : 0; } } return TCL_OK; @@ -1039,19 +1039,19 @@ ZipFSOpenArchive( size_t i; ClientData handle; - zf->namelen = 0; - zf->is_membuf = 0; + zf->nameLength = 0; + zf->isMemBuffer = 0; #ifdef _WIN32 zf->data = NULL; - zf->mh = INVALID_HANDLE_VALUE; + zf->mountHandle = INVALID_HANDLE_VALUE; #else /* !_WIN32 */ zf->data = MAP_FAILED; #endif /* _WIN32 */ zf->length = 0; - zf->nfiles = 0; - zf->baseoffs = zf->baseoffsp = 0; - zf->tofree = NULL; - zf->pwbuf[0] = 0; + zf->numFiles = 0; + zf->baseOffset = zf->passOffset = 0; + zf->ptrToFree = NULL; + zf->passBuf[0] = 0; zf->chan = Tcl_OpenFileChannel(interp, zipname, "rb", 0); if (zf->chan == NULL) { return TCL_ERROR; @@ -1071,8 +1071,8 @@ ZipFSOpenArchive( ZIPFS_POSIX_ERROR(interp, "seek error"); goto error; } - zf->tofree = zf->data = (unsigned char *) Tcl_AttemptAlloc(zf->length); - if (zf->tofree == NULL) { + zf->ptrToFree = zf->data = attemptckalloc(zf->length); + if (zf->ptrToFree == NULL) { ZIPFS_ERROR(interp, "out of memory"); goto error; } @@ -1097,13 +1097,14 @@ ZipFSOpenArchive( ZIPFS_POSIX_ERROR(interp, "invalid file size"); goto error; } - zf->mh = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, 0, - zf->length, 0); - if (zf->mh == INVALID_HANDLE_VALUE) { + zf->mountHandle = CreateFileMapping((HANDLE) handle, 0, PAGE_READONLY, + 0, zf->length, 0); + if (zf->mountHandle == INVALID_HANDLE_VALUE) { ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } - zf->data = MapViewOfFile(zf->mh, FILE_MAP_READ, 0, 0, zf->length); + zf->data = MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0, + zf->length); if (zf->data == NULL) { ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; @@ -1123,7 +1124,7 @@ ZipFSOpenArchive( } #endif /* _WIN32 */ } - return ZipFS_Find_TOC(interp, needZip, zf); + return ZipFSFindTOC(interp, needZip, zf); error: ZipFSCloseArchive(interp, zf); @@ -1148,10 +1149,10 @@ ZipFSOpenArchive( */ static int -ZipFS_Catalogue_Filesystem( +ZipFSCatalogFilesystem( Tcl_Interp *interp, /* Current interpreter. NULLable. */ ZipFile *zf0, - const char *mntpt, /* Mount point path. */ + const char *mountPoint, /* Mount point path. */ const char *passwd, /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ const char *zipname) /* Path to ZIP file to build a catalog of. */ @@ -1189,23 +1190,23 @@ ZipFS_Catalogue_Filesystem( Tcl_DStringInit(&ds); Tcl_DStringInit(&dsm); - if (strcmp(mntpt, "/") == 0) { - mntpt = ""; + if (strcmp(mountPoint, "/") == 0) { + mountPoint = ""; } else { - mntpt = CanonicalPath("", mntpt, &dsm, 1); + mountPoint = CanonicalPath("", mountPoint, &dsm, 1); } - hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mntpt, &isNew); + hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mountPoint, &isNew); if (!isNew) { - zf = Tcl_GetHashValue(hPtr); if (interp != NULL) { + zf = Tcl_GetHashValue(hPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "%s is already mounted on %s", zf->name, mntpt)); + "%s is already mounted on %s", zf->name, mountPoint)); } Unlock(); ZipFSCloseArchive(interp, zf0); return TCL_ERROR; } - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); + zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1217,55 +1218,53 @@ ZipFS_Catalogue_Filesystem( Unlock(); *zf = *zf0; - zf->mntpt = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); - zf->mntptlen = strlen(zf->mntpt); - zf->name = strdup(zipname); - zf->namelen = strlen(zipname); + zf->mountPoint = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); + zf->mountPointLen = strlen(zf->mountPoint); + zf->nameLength = strlen(zipname); + zf->name = ckalloc(zf->nameLength + 1); + memcpy(zf->name, zipname, zf->nameLength + 1); zf->entries = NULL; - zf->topents = NULL; - zf->nopen = 0; + zf->topEnts = NULL; + zf->numOpen = 0; Tcl_SetHashValue(hPtr, zf); - if ((zf->pwbuf[0] == 0) && pwlen) { + if ((zf->passBuf[0] == 0) && pwlen) { int k = 0; i = pwlen; - zf->pwbuf[k++] = i; + zf->passBuf[k++] = i; while (i > 0) { - zf->pwbuf[k] = (passwd[i - 1] & 0x0f) + zf->passBuf[k] = (passwd[i - 1] & 0x0f) | pwrot[(passwd[i - 1] >> 4) & 0x0f]; k++; i--; } - zf->pwbuf[k] = '\0'; + zf->passBuf[k] = '\0'; } - if (mntpt[0] != '\0') { - z = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); - z->name = NULL; - z->tnext = NULL; - z->depth = CountSlashes(mntpt); - z->zipfile = zf; - z->isdir = (zf->baseoffs == 0) ? 1 : -1; /* root marker */ - z->isenc = 0; - z->offset = zf->baseoffs; - z->crc32 = 0; - z->timestamp = 0; - z->nbyte = z->nbytecompr = 0; - z->cmeth = ZIP_COMPMETH_STORED; - z->data = NULL; - hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mntpt, &isNew); - if (!isNew) { - /* skip it */ - Tcl_Free((char *) z); - } else { + if (mountPoint[0] != '\0') { + hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, mountPoint, &isNew); + if (isNew) { + z = ckalloc(sizeof(ZipEntry)); Tcl_SetHashValue(hPtr, z); + + z->tnext = NULL; + z->depth = CountSlashes(mountPoint); + z->zipfile = zf; + z->isdir = (zf->baseOffset == 0) ? 1 : -1; /* root marker */ + z->isenc = 0; + z->offset = zf->baseOffset; + z->crc32 = 0; + z->timestamp = 0; + z->nbyte = z->nbytecompr = 0; + z->cmeth = ZIP_COMPMETH_STORED; + z->data = NULL; z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; zf->entries = z; } } - q = zf->data + zf->centoffs; + q = zf->data + zf->directoryOffset; Tcl_DStringInit(&fpBuf); - for (i = 0; i < zf->nfiles; i++) { + for (i = 0; i < zf->numFiles; i++) { int extra, isdir = 0, dosTime, dosDate, nbcompr; size_t offs, pathlen, comlen; unsigned char *lq, *gq = NULL; @@ -1285,7 +1284,7 @@ ZipFS_Catalogue_Filesystem( if ((strcmp(path, ".") == 0) || (strcmp(path, "..") == 0)) { goto nextent; } - lq = zf->data + zf->baseoffs + lq = zf->data + zf->baseOffset + ZipReadInt(q + ZIP_CENTRAL_LOCALHDR_OFFS); if ((lq < zf->data) || (lq > zf->data + zf->length)) { goto nextent; @@ -1304,7 +1303,7 @@ ZipFS_Catalogue_Filesystem( if (offs + nbcompr > zf->length) { goto nextent; } - if (!isdir && (mntpt[0] == '\0') && !CountSlashes(path)) { + if (!isdir && (mountPoint[0] == '\0') && !CountSlashes(path)) { #ifdef ANDROID /* * When mounting the ZIP archive on the root directory try to @@ -1338,8 +1337,8 @@ ZipFS_Catalogue_Filesystem( #endif /* ANDROID */ } Tcl_DStringSetLength(&fpBuf, 0); - fullpath = CanonicalPath(mntpt, path, &fpBuf, 1); - z = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); + fullpath = CanonicalPath(mountPoint, path, &fpBuf, 1); + z = ckalloc(sizeof(ZipEntry)); z->name = NULL; z->tnext = NULL; z->depth = CountSlashes(fullpath); @@ -1368,15 +1367,15 @@ ZipFS_Catalogue_Filesystem( hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); if (!isNew) { /* should not happen but skip it anyway */ - Tcl_Free((char *) z); + ckfree(z); } else { Tcl_SetHashValue(hPtr, z); z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; zf->entries = z; - if (isdir && (mntpt[0] == '\0') && (z->depth == 1)) { - z->tnext = zf->topents; - zf->topents = z; + if (isdir && (mountPoint[0] == '\0') && (z->depth == 1)) { + z->tnext = zf->topEnts; + zf->topEnts = z; } if (!z->isdir && (z->depth > 1)) { char *dir, *end; @@ -1393,7 +1392,7 @@ ZipFS_Catalogue_Filesystem( if (!isNew) { break; } - zd = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); + zd = ckalloc(sizeof(ZipEntry)); zd->name = NULL; zd->tnext = NULL; zd->depth = CountSlashes(dir); @@ -1410,9 +1409,9 @@ ZipFS_Catalogue_Filesystem( zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); zd->next = zf->entries; zf->entries = zd; - if ((mntpt[0] == '\0') && (zd->depth == 1)) { - zd->tnext = zf->topents; - zf->topents = zd; + if ((mountPoint[0] == '\0') && (zd->depth == 1)) { + zd->tnext = zf->topEnts; + zf->topEnts = zd; } end = strrchr(dir, '/'); } @@ -1428,25 +1427,37 @@ ZipFS_Catalogue_Filesystem( return TCL_OK; } +/* + *------------------------------------------------------------------------- + * + * TclZipfs_C_Init -- + * + * Common initialisation code. ZipFS.initialized must *not* be set prior + * to the call. + * + *------------------------------------------------------------------------- + */ + static void TclZipfs_C_Init(void) { +#ifdef TCL_THREADS static const Tcl_Time t = { 0, 0 }; - if (!ZipFS.initialized) { -#ifdef TCL_THREADS - /* - * Inflate condition variable. - */ - Tcl_MutexLock(&ZipFSMutex); - Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); - Tcl_MutexUnlock(&ZipFSMutex); + /* + * Inflate condition variable. + */ + + Tcl_MutexLock(&ZipFSMutex); + Tcl_ConditionWait(&ZipFSCond, &ZipFSMutex, &t); + Tcl_MutexUnlock(&ZipFSMutex); #endif /* TCL_THREADS */ - Tcl_FSRegister(NULL, &zipfsFilesystem); - Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); - Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); - ZipFS.initialized = ZipFS.idCount = 1; - } + + Tcl_FSRegister(NULL, &zipfsFilesystem); + Tcl_InitHashTable(&ZipFS.fileHash, TCL_STRING_KEYS); + Tcl_InitHashTable(&ZipFS.zipHash, TCL_STRING_KEYS); + ZipFS.idCount = 1; + ZipFS.initialized = 1; } /* @@ -1470,7 +1481,7 @@ TclZipfs_C_Init(void) int TclZipfs_Mount( Tcl_Interp *interp, /* Current interpreter. NULLable. */ - const char *mntpt, /* Mount point path. */ + const char *mountPoint, /* Mount point path. */ const char *zipname, /* Path to ZIP file to mount. */ const char *passwd) /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ @@ -1482,7 +1493,7 @@ TclZipfs_Mount( if (!ZipFS.initialized) { TclZipfs_C_Init(); } - if (mntpt == NULL) { + if (mountPoint == NULL) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; int ret = TCL_OK; @@ -1491,13 +1502,11 @@ TclZipfs_Mount( hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } - ++i; + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mountPoint); + Tcl_AppendElement(interp, zf->name); } + ++i; hPtr = Tcl_NextHashEntry(&search); } if (interp == NULL) { @@ -1509,13 +1518,12 @@ TclZipfs_Mount( if (zipname == NULL) { if (interp != NULL) { - Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + Tcl_HashEntry *hPtr = + Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); if (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); } } Unlock(); @@ -1533,7 +1541,7 @@ TclZipfs_Mount( return TCL_ERROR; } } - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); + zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1543,7 +1551,7 @@ TclZipfs_Mount( if (ZipFSOpenArchive(interp, zipname, 1, zf) != TCL_OK) { return TCL_ERROR; } - return ZipFS_Catalogue_Filesystem(interp, zf, mntpt, passwd, zipname); + return ZipFSCatalogFilesystem(interp, zf, mountPoint, passwd, zipname); } /* @@ -1567,7 +1575,7 @@ TclZipfs_Mount( int TclZipfs_Mount_Buffer( Tcl_Interp *interp, /* Current interpreter. NULLable. */ - const char *mntpt, /* Mount point path. */ + const char *mountPoint, /* Mount point path. */ unsigned char *data, size_t datalen, int copy) @@ -1578,7 +1586,7 @@ TclZipfs_Mount_Buffer( if (!ZipFS.initialized) { TclZipfs_C_Init(); } - if (mntpt == NULL) { + if (mountPoint == NULL) { Tcl_HashEntry *hPtr; Tcl_HashSearch search; int ret = (interp ? TCL_BREAK : TCL_OK); @@ -1586,17 +1594,15 @@ TclZipfs_Mount_Buffer( hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } else { - ret = TCL_OK; - /* - * Stop searching here if we're not returning a list. - */ - break; - } + if (interp != NULL) { + Tcl_AppendElement(interp, zf->mountPoint); + Tcl_AppendElement(interp, zf->name); + } else { + ret = TCL_OK; + /* + * Stop searching here if we're not returning a list. + */ + break; } hPtr = Tcl_NextHashEntry(&search); } @@ -1606,13 +1612,12 @@ TclZipfs_Mount_Buffer( if (data == NULL) { if (interp != NULL) { - Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + Tcl_HashEntry *hPtr = + Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); if (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); } } Unlock(); @@ -1620,17 +1625,17 @@ TclZipfs_Mount_Buffer( } Unlock(); - zf = (ZipFile *) Tcl_AttemptAlloc(sizeof(ZipFile) + strlen(mntpt) + 1); + zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } return TCL_ERROR; } - zf->is_membuf = 1; + zf->isMemBuffer = 1; zf->length = datalen; if (copy) { - zf->data = (unsigned char *) Tcl_AttemptAlloc(datalen); + zf->data = attemptckalloc(datalen); if (zf->data == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); @@ -1638,15 +1643,15 @@ TclZipfs_Mount_Buffer( return TCL_ERROR; } memcpy(zf->data, data, datalen); - zf->tofree = zf->data; + zf->ptrToFree = zf->data; } else { zf->data = data; - zf->tofree = NULL; + zf->ptrToFree = NULL; } - if (ZipFS_Find_TOC(interp, 0, zf) != TCL_OK) { + if (ZipFSFindTOC(interp, 0, zf) != TCL_OK) { return TCL_ERROR; } - return ZipFS_Catalogue_Filesystem(interp, zf, mntpt, NULL, + return ZipFSCatalogFilesystem(interp, zf, mountPoint, NULL, "Memory Buffer"); } @@ -1669,7 +1674,7 @@ TclZipfs_Mount_Buffer( int TclZipfs_Unmount( Tcl_Interp *interp, /* Current interpreter. NULLable. */ - const char *mntpt) /* Mount point path. */ + const char *mountPoint) /* Mount point path. */ { ZipFile *zf; ZipEntry *z, *znext; @@ -1688,16 +1693,16 @@ TclZipfs_Unmount( */ Tcl_DStringInit(&dsm); - mntpt = CanonicalPath("", mntpt, &dsm, 1); + mountPoint = CanonicalPath("", mountPoint, &dsm, 1); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); /* don't report no-such-mount as an error */ if (hPtr == NULL) { goto done; } zf = Tcl_GetHashValue(hPtr); - if (zf->nopen > 0) { + if (zf->numOpen > 0) { ZIPFS_ERROR(interp, "filesystem is busy"); ret = TCL_ERROR; goto done; @@ -1710,12 +1715,12 @@ TclZipfs_Unmount( Tcl_DeleteHashEntry(hPtr); } if (z->data != NULL) { - Tcl_Free((char *) z->data); + ckfree(z->data); } - Tcl_Free((char *) z); + ckfree(z); } ZipFSCloseArchive(interp, zf); - Tcl_Free((char *) zf); + ckfree(zf); unmounted = 1; done: Unlock(); @@ -1782,7 +1787,7 @@ ZipFSMountBufferObjCmd( int objc, Tcl_Obj *const objv[]) { - const char *mntpt; /* Mount point path. */ + const char *mountPoint; /* Mount point path. */ unsigned char *data; int length; @@ -1800,35 +1805,31 @@ ZipFSMountBufferObjCmd( while (hPtr != NULL) { ZipFile *zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - Tcl_AppendElement(interp, zf->mntpt); - Tcl_AppendElement(interp, zf->name); - } + Tcl_AppendElement(interp, zf->mountPoint); + Tcl_AppendElement(interp, zf->name); hPtr = Tcl_NextHashEntry(&search); } Unlock(); return ret; } - mntpt = Tcl_GetString(objv[1]); + mountPoint = Tcl_GetString(objv[1]); if (objc < 3) { Tcl_HashEntry *hPtr; ReadLock(); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); if (hPtr != NULL) { ZipFile *zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); } Unlock(); return TCL_OK; } data = Tcl_GetByteArrayFromObj(objv[2], &length); - return TclZipfs_Mount_Buffer(interp, mntpt, data, length, 1); + return TclZipfs_Mount_Buffer(interp, mountPoint, data, length, 1); } /* @@ -1913,7 +1914,7 @@ ZipFSMkKeyObjCmd( Tcl_Obj *const objv[]) { int len, i = 0; - char *pw, pwbuf[264]; + char *pw, passBuf[264]; if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "password"); @@ -1931,18 +1932,18 @@ ZipFSMkKeyObjCmd( while (len > 0) { int ch = pw[len - 1]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; i++; len--; } - pwbuf[i] = i; + passBuf[i] = i; ++i; - pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); - pwbuf[i] = '\0'; - Tcl_AppendResult(interp, pwbuf, (char *) NULL); + passBuf[i++] = (char) ZIP_PASSWORD_END_SIG; + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); + passBuf[i] = '\0'; + Tcl_AppendResult(interp, passBuf, (char *) NULL); return TCL_OK; } @@ -2067,9 +2068,9 @@ ZipAddFile( */ align = 4 + ((len + pos[0]) & 3); - zip_write_short(abuf, 0xffff); - zip_write_short(abuf + 2, align - 4); - zip_write_int(abuf + 4, 0x03020100); + ZipWriteShort(abuf, 0xffff); + ZipWriteShort(abuf + 2, align - 4); + ZipWriteInt(abuf + 4, 0x03020100); if ((size_t) Tcl_Write(out, (const char *) abuf, align) != align) { goto wrerr; } @@ -2224,7 +2225,7 @@ ZipAddFile( } Tcl_Close(interp, in); - z = (ZipEntry *) Tcl_Alloc(sizeof(ZipEntry)); + z = ckalloc(sizeof(ZipEntry)); z->name = NULL; z->tnext = NULL; z->depth = 0; @@ -2242,10 +2243,10 @@ ZipAddFile( if (!isNew) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "non-unique path name \"%s\"", path)); - Tcl_Free((char *) z); + ckfree(z); return TCL_ERROR; } else { - Tcl_SetHashValue(hPtr, (ClientData) z); + Tcl_SetHashValue(hPtr, z); z->name = Tcl_GetHashKey(fileHash, hPtr); z->next = NULL; } @@ -2253,27 +2254,27 @@ ZipAddFile( /* * Write final local header information. */ - zip_write_int(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); - zip_write_short(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_LOCAL_FLAGS_OFFS, z->isenc); - zip_write_short(buf + ZIP_LOCAL_COMPMETH_OFFS, z->cmeth); - zip_write_short(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); - zip_write_short(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); - zip_write_int(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); - zip_write_int(buf + ZIP_LOCAL_COMPLEN_OFFS, z->nbytecompr); - zip_write_int(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->nbyte); - zip_write_short(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); - zip_write_short(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); + ZipWriteInt(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); + ZipWriteShort(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(buf + ZIP_LOCAL_FLAGS_OFFS, z->isenc); + ZipWriteShort(buf + ZIP_LOCAL_COMPMETH_OFFS, z->cmeth); + ZipWriteShort(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); + ZipWriteShort(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); + ZipWriteInt(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); + ZipWriteInt(buf + ZIP_LOCAL_COMPLEN_OFFS, z->nbytecompr); + ZipWriteInt(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->nbyte); + ZipWriteShort(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); + ZipWriteShort(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); if (Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); + ckfree(z); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } if (Tcl_Write(out, buf, ZIP_LOCAL_HEADER_LEN) != ZIP_LOCAL_HEADER_LEN) { Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); + ckfree(z); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write error: %s", Tcl_PosixError(interp))); return TCL_ERROR; @@ -2281,7 +2282,7 @@ ZipAddFile( Tcl_Flush(out); if (Tcl_Seek(out, pos[1], SEEK_SET) != pos[1]) { Tcl_DeleteHashEntry(hPtr); - Tcl_Free((char *) z); + ckfree(z); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; @@ -2326,13 +2327,13 @@ ZipFSMkZipOrImgObjCmd( Tcl_HashEntry *hPtr; Tcl_HashSearch search; Tcl_HashTable fileHash; - char *strip = NULL, *pw = NULL, pwbuf[264], buf[4096]; + char *strip = NULL, *pw = NULL, passBuf[264], buf[4096]; /* * Caller has verified that the number of arguments is correct. */ - pwbuf[0] = 0; + passBuf[0] = 0; if (objc > (isList ? 3 : 4)) { pw = Tcl_GetString(objv[isList ? 3 : 4]); pwlen = strlen(pw); @@ -2402,29 +2403,27 @@ ZipFSMkZipOrImgObjCmd( while (len > 0) { int ch = pw[len - 1]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; i++; len--; } - pwbuf[i] = i; + passBuf[i] = i; ++i; - pwbuf[i++] = (char) ZIP_PASSWORD_END_SIG; - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); - pwbuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); - pwbuf[i] = '\0'; + passBuf[i++] = (char) ZIP_PASSWORD_END_SIG; + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 8); + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 16); + passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); + passBuf[i] = '\0'; } /* Check for mounted image */ WriteLock(); hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf != NULL) { - if (strcmp(zf->name, imgName) == 0) { - isMounted = 1; - zf->nopen++; - break; - } + if (strcmp(zf->name, imgName) == 0) { + isMounted = 1; + zf->numOpen++; + break; } hPtr = Tcl_NextHashEntry(&search); } @@ -2434,8 +2433,8 @@ ZipFSMkZipOrImgObjCmd( } if (isMounted || ZipFSOpenArchive(interp, imgName, 0, zf) == TCL_OK) { if ((size_t) Tcl_Write(out, (char *) zf->data, - zf->baseoffsp) != zf->baseoffsp) { - memset(pwbuf, 0, sizeof(pwbuf)); + zf->passOffset) != zf->passOffset) { + memset(passBuf, 0, sizeof(passBuf)); Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write error: %s", Tcl_PosixError(interp))); @@ -2444,7 +2443,7 @@ ZipFSMkZipOrImgObjCmd( ZipFSCloseArchive(interp, zf); } else { WriteLock(); - zf->nopen--; + zf->numOpen--; Unlock(); } return TCL_ERROR; @@ -2453,7 +2452,7 @@ ZipFSMkZipOrImgObjCmd( ZipFSCloseArchive(interp, zf); } else { WriteLock(); - zf->nopen--; + zf->numOpen--; Unlock(); } } else { @@ -2470,7 +2469,7 @@ ZipFSMkZipOrImgObjCmd( Tcl_ResetResult(interp); in = Tcl_OpenFileChannel(interp, imgName, "rb", 0644); if (in == NULL) { - memset(pwbuf, 0, sizeof(pwbuf)); + memset(passBuf, 0, sizeof(passBuf)); Tcl_DecrRefCount(list); Tcl_Close(interp, out); return TCL_ERROR; @@ -2478,7 +2477,7 @@ ZipFSMkZipOrImgObjCmd( i = Tcl_Seek(in, 0, SEEK_END); if (i == ERROR_LENGTH) { cperr: - memset(pwbuf, 0, sizeof(pwbuf)); + memset(passBuf, 0, sizeof(passBuf)); Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s: %s", errMsg, Tcl_PosixError(interp))); @@ -2509,9 +2508,9 @@ ZipFSMkZipOrImgObjCmd( } Tcl_Close(interp, in); } - len = strlen(pwbuf); + len = strlen(passBuf); if (len > 0) { - i = Tcl_Write(out, pwbuf, len); + i = Tcl_Write(out, passBuf, len); if (i != len) { Tcl_DecrRefCount(list); Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -2520,7 +2519,7 @@ ZipFSMkZipOrImgObjCmd( return TCL_ERROR; } } - memset(pwbuf, 0, sizeof(pwbuf)); + memset(passBuf, 0, sizeof(passBuf)); Tcl_Flush(out); } Tcl_InitHashTable(&fileHash, TCL_STRING_KEYS); @@ -2586,23 +2585,23 @@ ZipFSMkZipOrImgObjCmd( } z = Tcl_GetHashValue(hPtr); len = strlen(z->name); - zip_write_int(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); - zip_write_short(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); - zip_write_short(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); - zip_write_short(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); - zip_write_short(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); - zip_write_short(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); - zip_write_int(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); - zip_write_int(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); - zip_write_int(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); - zip_write_short(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); - zip_write_short(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_IATTR_OFFS, 0); - zip_write_int(buf + ZIP_CENTRAL_EATTR_OFFS, 0); - zip_write_int(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); + ZipWriteInt(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); + ZipWriteShort(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); + ZipWriteShort(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); + ZipWriteShort(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); + ZipWriteShort(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); + ZipWriteShort(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); + ZipWriteInt(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); + ZipWriteInt(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); + ZipWriteInt(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); + ZipWriteShort(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); + ZipWriteShort(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_DISKFILE_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_IATTR_OFFS, 0); + ZipWriteInt(buf + ZIP_CENTRAL_EATTR_OFFS, 0); + ZipWriteInt(buf + ZIP_CENTRAL_LOCALHDR_OFFS, z->offset - pos[0]); if ((Tcl_Write(out, buf, ZIP_CENTRAL_HEADER_LEN) != ZIP_CENTRAL_HEADER_LEN) || ((size_t) Tcl_Write(out, z->name, len) != len)) { @@ -2614,14 +2613,14 @@ ZipFSMkZipOrImgObjCmd( } Tcl_Flush(out); pos[2] = Tcl_Tell(out); - zip_write_int(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); - zip_write_short(buf + ZIP_CENTRAL_DISKNO_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); - zip_write_short(buf + ZIP_CENTRAL_ENTS_OFFS, count); - zip_write_short(buf + ZIP_CENTRAL_TOTALENTS_OFFS, count); - zip_write_int(buf + ZIP_CENTRAL_DIRSIZE_OFFS, pos[2] - pos[1]); - zip_write_int(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); - zip_write_short(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); + ZipWriteInt(buf + ZIP_CENTRAL_END_SIG_OFFS, ZIP_CENTRAL_END_SIG); + ZipWriteShort(buf + ZIP_CENTRAL_DISKNO_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_DISKDIR_OFFS, 0); + ZipWriteShort(buf + ZIP_CENTRAL_ENTS_OFFS, count); + ZipWriteShort(buf + ZIP_CENTRAL_TOTALENTS_OFFS, count); + ZipWriteInt(buf + ZIP_CENTRAL_DIRSIZE_OFFS, pos[2] - pos[1]); + ZipWriteInt(buf + ZIP_CENTRAL_DIRSTART_OFFS, pos[1] - pos[0]); + ZipWriteShort(buf + ZIP_CENTRAL_COMMENTLEN_OFFS, 0); if (Tcl_Write(out, buf, ZIP_CENTRAL_END_LEN) != ZIP_CENTRAL_END_LEN) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write error: %s", Tcl_PosixError(interp))); @@ -2640,7 +2639,7 @@ ZipFSMkZipOrImgObjCmd( hPtr = Tcl_FirstHashEntry(&fileHash, &search); while (hPtr != NULL) { z = Tcl_GetHashValue(hPtr); - Tcl_Free((char *) z); + ckfree(z); Tcl_DeleteHashEntry(hPtr); hPtr = Tcl_NextHashEntry(&search); } @@ -2676,6 +2675,11 @@ ZipFSMkZipObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "outfile indir ?strip? ?password?"); return TCL_ERROR; } + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "operation not permitted in a safe interpreter", -1)); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 0, objc, objv); } @@ -2690,6 +2694,11 @@ ZipFSLMkZipObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password?"); return TCL_ERROR; } + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "operation not permitted in a safe interpreter", -1)); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 0, 1, objc, objv); } @@ -2722,6 +2731,11 @@ ZipFSMkImgObjCmd( "outfile indir ?strip? ?password? ?infile?"); return TCL_ERROR; } + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "operation not permitted in a safe interpreter", -1)); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 0, objc, objv); } @@ -2736,6 +2750,11 @@ ZipFSLMkImgObjCmd( Tcl_WrongNumArgs(interp, 1, objv, "outfile inlist ?password infile?"); return TCL_ERROR; } + if (Tcl_IsSafe(interp)) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + "operation not permitted in a safe interpreter", -1)); + return TCL_ERROR; + } return ZipFSMkZipOrImgObjCmd(clientData, interp, 1, 1, objc, objv); } @@ -3042,29 +3061,29 @@ TclZipfs_TclLibrary(void) * Mount zip file and dll before releasing to search. */ - if (TclZipfs_AppHook_FindTclInit(dllname) == TCL_OK) { + if (ZipfsAppHookFindTclInit(dllname) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } #elif /* !_WIN32 && */ defined(CFG_RUNTIME_DLLFILE) /* * Mount zip file and dll before releasing to search. */ - if (TclZipfs_AppHook_FindTclInit( + if (ZipfsAppHookFindTclInit( CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_DLLFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } #endif /* _WIN32 || CFG_RUNTIME_DLLFILE */ #ifdef CFG_RUNTIME_ZIPFILE - if (TclZipfs_AppHook_FindTclInit( + if (ZipfsAppHookFindTclInit( CFG_RUNTIME_LIBDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } - if (TclZipfs_AppHook_FindTclInit( + if (ZipfsAppHookFindTclInit( CFG_RUNTIME_SCRDIR "/" CFG_RUNTIME_ZIPFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } - if (TclZipfs_AppHook_FindTclInit(CFG_RUNTIME_ZIPFILE) == TCL_OK) { + if (ZipfsAppHookFindTclInit(CFG_RUNTIME_ZIPFILE) == TCL_OK) { return Tcl_NewStringObj(zipfs_literal_tcl_library, -1); } #endif /* CFG_RUNTIME_ZIPFILE */ @@ -3128,10 +3147,10 @@ ZipChannelClose( ClientData instanceData, Tcl_Interp *interp) /* Current interpreter. */ { - ZipChannel *info = (ZipChannel *) instanceData; + ZipChannel *info = instanceData; if (info->iscompr && (info->ubuf != NULL)) { - Tcl_Free((char *) info->ubuf); + ckfree(info->ubuf); info->ubuf = NULL; } if (info->isenc) { @@ -3140,13 +3159,11 @@ ZipChannelClose( } if (info->iswr) { ZipEntry *z = info->zipentry; - unsigned char *newdata; + unsigned char *newdata = attemptckrealloc(info->ubuf, info->nread); - newdata = (unsigned char *) - Tcl_AttemptRealloc((char *) info->ubuf, info->nread); if (newdata != NULL) { if (z->data != NULL) { - Tcl_Free((char *) z->data); + ckfree(z->data); } z->data = newdata; z->nbyte = z->nbytecompr = info->nbyte; @@ -3157,13 +3174,13 @@ ZipChannelClose( z->offset = 0; z->crc32 = 0; } else { - Tcl_Free((char *) info->ubuf); + ckfree(info->ubuf); } } WriteLock(); - info->zipfile->nopen--; + info->zipfile->numOpen--; Unlock(); - Tcl_Free((char *) info); + ckfree(info); return TCL_OK; } @@ -3200,9 +3217,9 @@ ZipChannelRead( */ nextpos = info->nread + toRead; - if (nextpos > info->zipfile->baseoffs) { - toRead = info->zipfile->baseoffs - info->nread; - nextpos = info->zipfile->baseoffs; + if (nextpos > info->zipfile->baseOffset) { + toRead = info->zipfile->baseOffset - info->nread; + nextpos = info->zipfile->baseOffset; } if (toRead == 0) { return 0; @@ -3318,7 +3335,7 @@ ZipChannelSeek( * Special case: when executable combined with ZIP archive file, seek * within front of ZIP, i.e. the executable itself. */ - end = info->zipfile->baseoffs; + end = info->zipfile->baseOffset; } else if (info->isdir) { *errloc = EINVAL; return -1; @@ -3492,7 +3509,7 @@ ZipChannelOpen( } if (!trunc) { flags |= TCL_READABLE; - if (z->isenc && (z->zipfile->pwbuf[0] == 0)) { + if (z->isenc && (z->zipfile->passBuf[0] == 0)) { ZIPFS_ERROR(interp, "decryption failed"); goto error; } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { @@ -3502,7 +3519,7 @@ ZipChannelOpen( } else { flags = TCL_WRITABLE; } - info = (ZipChannel *) Tcl_AttemptAlloc(sizeof(ZipChannel)); + info = attemptckalloc(sizeof(ZipChannel)); if (info == NULL) { ZIPFS_ERROR(interp, "out of memory"); goto error; @@ -3517,13 +3534,13 @@ ZipChannelOpen( info->nmax = ZipFS.wrmax; info->iscompr = 0; info->isenc = 0; - info->ubuf = (unsigned char *) Tcl_AttemptAlloc(info->nmax); + info->ubuf = attemptckalloc(info->nmax); if (info->ubuf == NULL) { merror0: if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); + ckfree(info->ubuf); } - Tcl_Free((char *) info); + ckfree(info); ZIPFS_ERROR(interp, "out of memory"); goto error; } @@ -3542,16 +3559,16 @@ ZipChannelOpen( unsigned char *zbuf = z->zipfile->data + z->offset; if (z->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; + int len = z->zipfile->passBuf[0]; + char passBuf[260]; for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + ch = z->zipfile->passBuf[len - i]; + passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof(pwbuf)); + passBuf[i] = '\0'; + init_keys(passBuf, info->keys, crc32tab); + memset(passBuf, 0, sizeof(passBuf)); for (i = 0; i < 12; i++) { ch = info->ubuf[i]; zdecode(info->keys, crc32tab, ch); @@ -3572,7 +3589,7 @@ ZipChannelOpen( unsigned int j; stream.avail_in -= 12; - cbuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); + cbuf = attemptckalloc(stream.avail_in); if (cbuf == NULL) { goto merror0; } @@ -3595,19 +3612,19 @@ ZipChannelOpen( || ((err == Z_OK) && (stream.avail_in == 0))) { if (cbuf != NULL) { memset(info->keys, 0, sizeof(info->keys)); - Tcl_Free((char *) cbuf); + ckfree(cbuf); } goto wrapchan; } cerror0: if (cbuf != NULL) { memset(info->keys, 0, sizeof(info->keys)); - Tcl_Free((char *) cbuf); + ckfree(cbuf); } if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); + ckfree(info->ubuf); } - Tcl_Free((char *) info); + ckfree(info); ZIPFS_ERROR(interp, "decompression error"); goto error; } else if (z->isenc) { @@ -3640,16 +3657,16 @@ ZipChannelOpen( info->nbyte = z->nbyte; info->nmax = 0; if (info->isenc) { - int len = z->zipfile->pwbuf[0]; - char pwbuf[260]; + int len = z->zipfile->passBuf[0]; + char passBuf[260]; for (i = 0; i < len; i++) { - ch = z->zipfile->pwbuf[len - i]; - pwbuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; + ch = z->zipfile->passBuf[len - i]; + passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; } - pwbuf[i] = '\0'; - init_keys(pwbuf, info->keys, crc32tab); - memset(pwbuf, 0, sizeof(pwbuf)); + passBuf[i] = '\0'; + init_keys(passBuf, info->keys, crc32tab); + memset(passBuf, 0, sizeof(passBuf)); for (i = 0; i < 12; i++) { ch = info->ubuf[i]; zdecode(info->keys, crc32tab, ch); @@ -3669,7 +3686,7 @@ ZipChannelOpen( stream.avail_in = z->nbytecompr; if (info->isenc) { stream.avail_in -= 12; - ubuf = (unsigned char *) Tcl_AttemptAlloc(stream.avail_in); + ubuf = attemptckalloc(stream.avail_in); if (ubuf == NULL) { info->ubuf = NULL; goto merror; @@ -3682,19 +3699,18 @@ ZipChannelOpen( } else { stream.next_in = info->ubuf; } - stream.next_out = info->ubuf = (unsigned char *) - Tcl_AttemptAlloc(info->nbyte); + stream.next_out = info->ubuf = attemptckalloc(info->nbyte); if (info->ubuf == NULL) { merror: if (ubuf != NULL) { info->isenc = 0; memset(info->keys, 0, sizeof(info->keys)); - Tcl_Free((char *) ubuf); + ckfree(ubuf); } - Tcl_Free((char *) info); + ckfree(info); if (interp != NULL) { Tcl_SetObjResult(interp, - Tcl_NewStringObj("out of memory", -1)); + Tcl_NewStringObj("out of memory", -1)); } goto error; } @@ -3709,7 +3725,7 @@ ZipChannelOpen( if (ubuf != NULL) { info->isenc = 0; memset(info->keys, 0, sizeof(info->keys)); - Tcl_Free((char *) ubuf); + ckfree(ubuf); } goto wrapchan; } @@ -3717,12 +3733,12 @@ ZipChannelOpen( if (ubuf != NULL) { info->isenc = 0; memset(info->keys, 0, sizeof(info->keys)); - Tcl_Free((char *) ubuf); + ckfree(ubuf); } if (info->ubuf != NULL) { - Tcl_Free((char *) info->ubuf); + ckfree(info->ubuf); } - Tcl_Free((char *) info); + ckfree(info); ZIPFS_ERROR(interp, "decompression error"); goto error; } @@ -3731,7 +3747,7 @@ ZipChannelOpen( wrapchan: sprintf(cname, "zipfs_%" TCL_LL_MODIFIER "x_%d", z->offset, ZipFS.idCount++); - z->zipfile->nopen++; + z->zipfile->numOpen++; Unlock(); return Tcl_CreateChannel(&ZipChannelType, cname, (ClientData) info, flags); @@ -3820,7 +3836,7 @@ ZipEntryAccess( /* *------------------------------------------------------------------------- * - * Zip_FSOpenFileChannelProc -- + * ZipFSOpenFileChannelProc -- * * Results: * @@ -3830,7 +3846,7 @@ ZipEntryAccess( */ static Tcl_Channel -Zip_FSOpenFileChannelProc( +ZipFSOpenFileChannelProc( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *pathPtr, int mode, @@ -3849,7 +3865,7 @@ Zip_FSOpenFileChannelProc( /* *------------------------------------------------------------------------- * - * Zip_FSStatProc -- + * ZipFSStatProc -- * * This function implements the ZIP filesystem specific version of the * library version of stat. @@ -3864,7 +3880,7 @@ Zip_FSOpenFileChannelProc( */ static int -Zip_FSStatProc( +ZipFSStatProc( Tcl_Obj *pathPtr, Tcl_StatBuf *buf) { @@ -3880,7 +3896,7 @@ Zip_FSStatProc( /* *------------------------------------------------------------------------- * - * Zip_FSAccessProc -- + * ZipFSAccessProc -- * * This function implements the ZIP filesystem specific version of the * library version of access. @@ -3895,7 +3911,7 @@ Zip_FSStatProc( */ static int -Zip_FSAccessProc( +ZipFSAccessProc( Tcl_Obj *pathPtr, int mode) { @@ -3911,7 +3927,7 @@ Zip_FSAccessProc( /* *------------------------------------------------------------------------- * - * Zip_FSFilesystemSeparatorProc -- + * ZipFSFilesystemSeparatorProc -- * * This function returns the separator to be used for a given path. The * object returned should have a refCount of zero @@ -3928,7 +3944,7 @@ Zip_FSAccessProc( */ static Tcl_Obj * -Zip_FSFilesystemSeparatorProc( +ZipFSFilesystemSeparatorProc( Tcl_Obj *pathPtr) { return Tcl_NewStringObj("/", -1); @@ -3937,7 +3953,7 @@ Zip_FSFilesystemSeparatorProc( /* *------------------------------------------------------------------------- * - * Zip_FSMatchInDirectoryProc -- + * ZipFSMatchInDirectoryProc -- * * This routine is used by the globbing code to search a directory for * all files which match a given pattern. @@ -3954,7 +3970,7 @@ Zip_FSFilesystemSeparatorProc( */ static int -Zip_FSMatchInDirectoryProc( +ZipFSMatchInDirectoryProc( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *result, Tcl_Obj *pathPtr, @@ -4017,10 +4033,10 @@ Zip_FSMatchInDirectoryProc( while (hPtr != NULL) { ZipFile *zf = Tcl_GetHashValue(hPtr); - if (zf->mntptlen == 0) { + if (zf->mountPointLen == 0) { ZipEntry *z; - for (z = zf->topents; z != NULL; z = z->tnext) { + for (z = zf->topEnts; z != NULL; z = z->tnext) { size_t lenz = strlen(z->name); if ((lenz > len + 1) && (strncmp(z->name, path, len) == 0) @@ -4040,20 +4056,23 @@ Zip_FSMatchInDirectoryProc( } } } - } else if ((zf->mntptlen > len + 1) - && (strncmp(zf->mntpt, path, len) == 0) - && (zf->mntpt[len] == '/') - && (CountSlashes(zf->mntpt) == l) - && Tcl_StringCaseMatch(zf->mntpt + len + 1, pattern, 0)) { + } else if ((zf->mountPointLen > len + 1) + && (strncmp(zf->mountPoint, path, len) == 0) + && (zf->mountPoint[len] == '/') + && (CountSlashes(zf->mountPoint) == l) + && Tcl_StringCaseMatch(zf->mountPoint + len + 1, + pattern, 0)) { if (prefix != NULL) { - Tcl_DStringAppend(&dsPref, zf->mntpt, zf->mntptlen); + Tcl_DStringAppend(&dsPref, zf->mountPoint, + zf->mountPointLen); Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(Tcl_DStringValue(&dsPref), Tcl_DStringLength(&dsPref))); Tcl_DStringSetLength(&dsPref, prefixLen); } else { Tcl_ListObjAppendElement(NULL, result, - Tcl_NewStringObj(zf->mntpt, zf->mntptlen)); + Tcl_NewStringObj(zf->mountPoint, + zf->mountPointLen)); } } hPtr = Tcl_NextHashEntry(&search); @@ -4084,7 +4103,7 @@ Zip_FSMatchInDirectoryProc( } l = strlen(pattern); - pat = Tcl_Alloc(len + l + 2); + pat = ckalloc(len + l + 2); memcpy(pat, path, len); while ((len > 1) && (pat[len - 1] == '/')) { --len; @@ -4116,7 +4135,7 @@ Zip_FSMatchInDirectoryProc( } } } - Tcl_Free(pat); + ckfree(pat); end: Unlock(); @@ -4127,7 +4146,7 @@ Zip_FSMatchInDirectoryProc( /* *------------------------------------------------------------------------- * - * Zip_FSPathInFilesystemProc -- + * ZipFSPathInFilesystemProc -- * * This function determines if the given path object is in the ZIP * filesystem. @@ -4142,7 +4161,7 @@ Zip_FSMatchInDirectoryProc( */ static int -Zip_FSPathInFilesystemProc( +ZipFSPathInFilesystemProc( Tcl_Obj *pathPtr, ClientData *clientDataPtr) { @@ -4175,10 +4194,10 @@ Zip_FSPathInFilesystemProc( hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { zf = Tcl_GetHashValue(hPtr); - if (zf->mntptlen == 0) { + if (zf->mountPointLen == 0) { ZipEntry *z; - for (z = zf->topents; z != NULL; z = z->tnext) { + for (z = zf->topEnts; z != NULL; z = z->tnext) { size_t lenz = strlen(z->name); if ((len >= lenz) && (strncmp(path, z->name, lenz) == 0)) { @@ -4186,8 +4205,8 @@ Zip_FSPathInFilesystemProc( goto endloop; } } - } else if ((len >= zf->mntptlen) && - (strncmp(path, zf->mntpt, zf->mntptlen) == 0)) { + } else if ((len >= zf->mountPointLen) && + (strncmp(path, zf->mountPoint, zf->mountPointLen) == 0)) { ret = TCL_OK; goto endloop; } @@ -4202,7 +4221,7 @@ Zip_FSPathInFilesystemProc( /* *------------------------------------------------------------------------- * - * Zip_FSListVolumesProc -- + * ZipFSListVolumesProc -- * * Lists the currently mounted ZIP filesystem volumes. * @@ -4216,7 +4235,7 @@ Zip_FSPathInFilesystemProc( */ static Tcl_Obj * -Zip_FSListVolumesProc(void) +ZipFSListVolumesProc(void) { return Tcl_NewStringObj(ZIPFS_VOLUME, -1); } @@ -4224,7 +4243,7 @@ Zip_FSListVolumesProc(void) /* *------------------------------------------------------------------------- * - * Zip_FSFileAttrStringsProc -- + * ZipFSFileAttrStringsProc -- * * This function implements the ZIP filesystem dependent 'file * attributes' subcommand, for listing the set of possible attribute @@ -4240,7 +4259,7 @@ Zip_FSListVolumesProc(void) */ static const char *const * -Zip_FSFileAttrStringsProc( +ZipFSFileAttrStringsProc( Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef) { @@ -4259,7 +4278,7 @@ Zip_FSFileAttrStringsProc( /* *------------------------------------------------------------------------- * - * Zip_FSFileAttrsGetProc -- + * ZipFSFileAttrsGetProc -- * * This function implements the ZIP filesystem specific 'file attributes' * subcommand, for 'get' operations. @@ -4277,7 +4296,7 @@ Zip_FSFileAttrStringsProc( */ static int -Zip_FSFileAttrsGetProc( +ZipFSFileAttrsGetProc( Tcl_Interp *interp, /* Current interpreter. */ int index, Tcl_Obj *pathPtr, @@ -4302,25 +4321,28 @@ Zip_FSFileAttrsGetProc( switch (index) { case 0: *objPtrRef = Tcl_NewWideIntObj(z->nbyte); - goto done; + break; case 1: *objPtrRef = Tcl_NewWideIntObj(z->nbytecompr); - goto done; + break; case 2: *objPtrRef = Tcl_NewWideIntObj(z->offset); - goto done; + break; case 3: - *objPtrRef = Tcl_NewStringObj(z->zipfile->mntpt, z->zipfile->mntptlen); - goto done; + *objPtrRef = Tcl_NewStringObj(z->zipfile->mountPoint, + z->zipfile->mountPointLen); + break; case 4: *objPtrRef = Tcl_NewStringObj(z->zipfile->name, -1); - goto done; + break; case 5: *objPtrRef = Tcl_NewStringObj("0555", -1); - goto done; + break; + default: + ZIPFS_ERROR(interp, "unknown attribute"); + ret = TCL_ERROR; } - ZIPFS_ERROR(interp, "unknown attribute"); - ret = TCL_ERROR; + done: Unlock(); return ret; @@ -4329,7 +4351,7 @@ Zip_FSFileAttrsGetProc( /* *------------------------------------------------------------------------- * - * Zip_FSFileAttrsSetProc -- + * ZipFSFileAttrsSetProc -- * * This function implements the ZIP filesystem specific 'file attributes' * subcommand, for 'set' operations. @@ -4344,7 +4366,7 @@ Zip_FSFileAttrsGetProc( */ static int -Zip_FSFileAttrsSetProc( +ZipFSFileAttrsSetProc( Tcl_Interp *interp, /* Current interpreter. */ int index, Tcl_Obj *pathPtr, @@ -4359,7 +4381,7 @@ Zip_FSFileAttrsSetProc( /* *------------------------------------------------------------------------- * - * Zip_FSFilesystemPathTypeProc -- + * ZipFSFilesystemPathTypeProc -- * * Results: * @@ -4369,7 +4391,7 @@ Zip_FSFileAttrsSetProc( */ static Tcl_Obj * -Zip_FSFilesystemPathTypeProc( +ZipFSFilesystemPathTypeProc( Tcl_Obj *pathPtr) { return Tcl_NewStringObj("zip", -1); @@ -4378,7 +4400,7 @@ Zip_FSFilesystemPathTypeProc( /* *------------------------------------------------------------------------- * - * Zip_FSLoadFile -- + * ZipFSLoadFile -- * * This functions deals with loading native object code. If the given * path object refers to a file within the ZIP filesystem, an approriate @@ -4397,7 +4419,7 @@ Zip_FSFilesystemPathTypeProc( */ static int -Zip_FSLoadFile( +ZipFSLoadFile( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Obj *path, Tcl_LoadHandle *loadHandle, @@ -4434,7 +4456,7 @@ Zip_FSLoadFile( } objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); - if ((objs[1] != NULL) && (Zip_FSAccessProc(objs[1], R_OK) == 0)) { + if ((objs[1] != NULL) && (ZipFSAccessProc(objs[1], R_OK) == 0)) { const char *execName = Tcl_GetNameOfExecutable(); /* @@ -4518,50 +4540,55 @@ TclZipfs_Init( Tcl_Interp *interp) /* Current interpreter. */ { #ifdef HAVE_ZLIB - /* one-time initialization */ + static const EnsembleImplMap initMap[] = { + {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 0}, + {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 0}, + {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 0}, + {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 0}, + /* The 4 entries above are not available in safe interpreters */ + {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, + {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, + {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, + {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, + {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, + {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, + {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, + {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, + {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, + {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 0}, + {NULL, NULL, NULL, NULL, NULL, 0} + }; + static const char findproc[] = + "namespace eval ::tcl::zipfs {}\n" + "proc ::tcl::zipfs::Find dir {\n" + " set result {}\n" + " if {[catch {glob -directory $dir -nocomplain * .*} list]} {\n" + " return $result\n" + " }\n" + " foreach file $list {\n" + " if {[file tail $file] in {. ..}} {\n" + " continue\n" + " }\n" + " lappend result $file {*}[Find $file]\n" + " }\n" + " return $result\n" + "}\n" + "proc ::tcl::zipfs::find dir {\n" + " return [lsort [Find $dir]]\n" + "}\n"; + + /* + * One-time initialization. + */ + WriteLock(); /* Tcl_StaticPackage(interp, "zipfs", TclZipfs_Init, TclZipfs_Init); */ if (!ZipFS.initialized) { TclZipfs_C_Init(); } Unlock(); + if (interp != NULL) { - static const EnsembleImplMap initMap[] = { - {"mkimg", ZipFSMkImgObjCmd, NULL, NULL, NULL, 1}, - {"mkzip", ZipFSMkZipObjCmd, NULL, NULL, NULL, 1}, - {"lmkimg", ZipFSLMkImgObjCmd, NULL, NULL, NULL, 1}, - {"lmkzip", ZipFSLMkZipObjCmd, NULL, NULL, NULL, 1}, - /* The 4 entries above are not available in safe interpreters */ - {"mount", ZipFSMountObjCmd, NULL, NULL, NULL, 0}, - {"mount_data", ZipFSMountBufferObjCmd, NULL, NULL, NULL, 0}, - {"unmount", ZipFSUnmountObjCmd, NULL, NULL, NULL, 0}, - {"mkkey", ZipFSMkKeyObjCmd, NULL, NULL, NULL, 0}, - {"exists", ZipFSExistsObjCmd, NULL, NULL, NULL, 1}, - {"info", ZipFSInfoObjCmd, NULL, NULL, NULL, 1}, - {"list", ZipFSListObjCmd, NULL, NULL, NULL, 1}, - {"canonical", ZipFSCanonicalObjCmd, NULL, NULL, NULL, 1}, - {"root", ZipFSRootObjCmd, NULL, NULL, NULL, 1}, - {"tcl_library", ZipFSTclLibraryObjCmd, NULL, NULL, NULL, 0}, - {NULL, NULL, NULL, NULL, NULL, 0} - }; - static const char findproc[] = - "namespace eval ::tcl::zipfs {}\n" - "proc ::tcl::zipfs::Find dir {\n" - " set result {}\n" - " if {[catch {glob -directory $dir -nocomplain * .*} list]} {\n" - " return $result\n" - " }\n" - " foreach file $list {\n" - " if {[file tail $file] in {. ..}} {\n" - " continue\n" - " }\n" - " lappend result $file {*}[Find $file]\n" - " }\n" - " return $result\n" - "}\n" - "proc ::tcl::zipfs::find dir {\n" - " return [lsort [Find $dir]]\n" - "}\n"; Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, TCL_LINK_INT); @@ -4577,7 +4604,7 @@ TclZipfs_Init( } static int -TclZipfs_AppHook_FindTclInit( +ZipfsAppHookFindTclInit( const char *archive) { Tcl_Obj *vfsinitscript; @@ -4616,7 +4643,7 @@ TclZipfs_AppHook_FindTclInit( /* *------------------------------------------------------------------------- * - * Tclkit_MainHook -- + * TclZipfs_AppHook -- * * Performs the argument munging for the shell * @@ -4625,13 +4652,13 @@ TclZipfs_AppHook_FindTclInit( int TclZipfs_AppHook( - int *argcPtr, + int *argcPtr, /* Pointer to argc */ #ifdef _WIN32 TCHAR #else /* !_WIN32 */ char #endif /* _WIN32 */ - ***argvPtr) + ***argvPtr) /* Pointer to argv */ { #ifdef _WIN32 Tcl_DString ds; @@ -4649,18 +4676,18 @@ TclZipfs_AppHook( if (!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { int found; - Tcl_Obj *vfsinitscript; + Tcl_Obj *vfsInitScript; - vfsinitscript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - if (Tcl_FSAccess(vfsinitscript, F_OK) == 0) { + vfsInitScript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); + Tcl_IncrRefCount(vfsInitScript); + if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { /* * Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript, NULL); + Tcl_SetStartupScript(vfsInitScript, NULL); } else { - Tcl_DecrRefCount(vfsinitscript); + Tcl_DecrRefCount(vfsInitScript); } /* @@ -4668,11 +4695,11 @@ TclZipfs_AppHook( */ if (!zipfs_literal_tcl_library) { - vfsinitscript = Tcl_NewStringObj( + vfsInitScript = Tcl_NewStringObj( ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - found = Tcl_FSAccess(vfsinitscript, F_OK); - Tcl_DecrRefCount(vfsinitscript); + Tcl_IncrRefCount(vfsInitScript); + found = Tcl_FSAccess(vfsInitScript, F_OK); + Tcl_DecrRefCount(vfsInitScript); if (found == TCL_OK) { zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library"; return TCL_OK; @@ -4691,7 +4718,7 @@ TclZipfs_AppHook( archive = (*argvPtr)[1]; #endif /* _WIN32 */ if (strcmp(archive, "install") == 0) { - Tcl_Obj *vfsinitscript; + Tcl_Obj *vfsInitScript; /* * Run this now to ensure the file is present by the time Tcl_Main @@ -4699,34 +4726,34 @@ TclZipfs_AppHook( */ TclZipfs_TclLibrary(); - vfsinitscript = Tcl_NewStringObj( + vfsInitScript = Tcl_NewStringObj( ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - if (Tcl_FSAccess(vfsinitscript, F_OK) == 0) { - Tcl_SetStartupScript(vfsinitscript, NULL); + Tcl_IncrRefCount(vfsInitScript); + if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { + Tcl_SetStartupScript(vfsInitScript, NULL); } return TCL_OK; } else if (!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { int found; - Tcl_Obj *vfsinitscript; + Tcl_Obj *vfsInitScript; - vfsinitscript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - if (Tcl_FSAccess(vfsinitscript, F_OK) == 0) { + vfsInitScript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); + Tcl_IncrRefCount(vfsInitScript); + if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { /* * Startup script should be set before calling Tcl_AppInit */ - Tcl_SetStartupScript(vfsinitscript, NULL); + Tcl_SetStartupScript(vfsInitScript, NULL); } else { - Tcl_DecrRefCount(vfsinitscript); + Tcl_DecrRefCount(vfsInitScript); } /* Set Tcl Encodings */ - vfsinitscript = Tcl_NewStringObj( + vfsInitScript = Tcl_NewStringObj( ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - found = Tcl_FSAccess(vfsinitscript, F_OK); - Tcl_DecrRefCount(vfsinitscript); + Tcl_IncrRefCount(vfsInitScript); + found = Tcl_FSAccess(vfsInitScript, F_OK); + Tcl_DecrRefCount(vfsInitScript); if (found == TCL_OK) { zipfs_literal_tcl_library = ZIPFS_APP_MOUNT "/tcl_library"; return TCL_OK; @@ -4755,7 +4782,7 @@ TclZipfs_AppHook( int TclZipfs_Mount( Tcl_Interp *interp, /* Current interpreter. */ - const char *mntpt, /* Mount point path. */ + const char *mountPoint, /* Mount point path. */ const char *zipname, /* Path to ZIP file to mount. */ const char *passwd) /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ @@ -4766,7 +4793,7 @@ TclZipfs_Mount( int TclZipfs_Unmount( Tcl_Interp *interp, /* Current interpreter. */ - const char *mntpt) /* Mount point path. */ + const char *mountPoint) /* Mount point path. */ { return TclZipfs_Init(interp, 1); } diff --git a/unix/Makefile.in b/unix/Makefile.in index b30d357..c44cc77 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -681,8 +681,8 @@ ${TCL_ZIP_FILE}: ${ZIP_INSTALL_OBJS} @rm -rf ${TCL_VFS_ROOT} @mkdir -p ${TCL_VFS_PATH} cp -a $(TOP_DIR)/library/* ${TCL_VFS_PATH} - ( cd ${TCL_VFS_ROOT} ; \ - ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH}) + -find ${TCL_VFS_ROOT} -type d -empty -delete + ( cd ${TCL_VFS_ROOT} ; ${NATIVE_ZIP} ${ZIP_PROG_OPTIONS} ../${TCL_ZIP_FILE} ${ZIP_PROG_VFSSEARCH}) # The following target is configured by autoconf to generate either a shared # library or non-shared library for Tcl. -- cgit v0.12 From b5f75d3392ae32955aaef38e3d3af58119179a73 Mon Sep 17 00:00:00 2001 From: dkf Date: Sat, 6 Oct 2018 16:49:40 +0000 Subject: More regularizing of function names, field names and testing styles --- doc/zipfs.3 | 30 +- generic/tcl.decls | 17 +- generic/tclDecls.h | 21 +- generic/tclStubInit.c | 2 +- generic/tclZipfs.c | 1020 ++++++++++++++++++++++++++----------------------- tests/zipfs.test | 121 +++--- 6 files changed, 636 insertions(+), 575 deletions(-) diff --git a/doc/zipfs.3 b/doc/zipfs.3 index 568f461..8e2eacc 100644 --- a/doc/zipfs.3 +++ b/doc/zipfs.3 @@ -10,7 +10,7 @@ .so man.macros .BS .SH NAME -TclZipfs_AppHook, Tclzipfs_Mount, Tclzipfs_Unmount \- handle ZIP files as Tcl virtual filesystems +TclZipfs_AppHook, Tclzipfs_Mount, TclZipfs_MountBuffer, Tclzipfs_Unmount \- handle ZIP files as Tcl virtual filesystems .SH SYNOPSIS .nf int @@ -20,7 +20,10 @@ int \fBTclzipfs_Mount\fR(\fIinterp, mountpoint, zipname, password\fR) .sp int -\fBTclzipfs_Unmount\fR(\fIinterp, zipname\fR) +\fBTclZipfs_MountBuffer\fR(\fIinterp, mountpoint, data, dataLen, copy\fR) +.sp +int +\fBTclzipfs_Unmount\fR(\fIinterp, mountpoint\fR) .fi .SH ARGUMENTS .AS Tcl_Interp *mountpoint in @@ -40,6 +43,16 @@ Name of a mount point, which must be a legal Tcl file or directory name. May be NULL to query current mount points. .AP "const char" *password in An (optional) password. Use NULL if no password is wanted to read the file. +.AP "unsigned char" *data in +A data buffer to mount. The data buffer must hold the contents of a ZIP +archive, and must not be NULL. +.AP size_t dataLen in +The number of bytes in the supplied data buffer argument, \fIdata\fR. +.AP int copy in +If non-zero, the ZIP archive in the data buffer will be internally copied +before mounting, allowing the data buffer to be disposed once +\fBTclZipfs_MountBuffer\fR returns. If zero, the caller guarantees that the +buffer will be valid to read from for the duration of the mount. .BE .SH DESCRIPTION \fBTclZipfs_AppHook\fR is a utility function to perform standard application @@ -85,11 +98,20 @@ given in \fImountpoint\fR using the optional ZIP password \fIpassword\fR. Errors during that process are reported in the interpreter \fIinterp\fR. If \fImountpoint\fR is a NULL pointer, information on all currently mounted ZIP file systems is written into \fIinterp\fR's result as a sequence of mount -points and ZIP file names. +points and ZIP file names. The result of this call is a standard Tcl result +code. +.PP +\fBTclzipfs_MountBuffer\fR mounts the ZIP archive in the buffer pointed to by +\fIdata\fR on the mount point given in \fImountpoint\fR. The ZIP archive is +assumed to be not password protected. Errors during that process are reported +in the interpreter \fIinterp\fR. The \fIcopy\fR argument determines whether +the buffer is internally copied before mounting or not. The result of this +call is a standard Tcl result code. .PP \fBTclzipfs_Unmount\fR undoes the effect of \fBTclzipfs_Mount\fR, i.e., it unmounts the mounted ZIP file system that was mounted from \fIzipname\fR (at -\fImountpoint\fR). Errors are reported in the interpreter \fIinterp\fR. +\fImountpoint\fR). Errors are reported in the interpreter \fIinterp\fR. The +result of this call is a standard Tcl result code. .SH "SEE ALSO" zipfs(n) .SH KEYWORDS diff --git a/generic/tcl.decls b/generic/tcl.decls index 61247e6..dfcb822 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2332,25 +2332,18 @@ declare 631 { # TIP #430 declare 632 { - int TclZipfs_Mount( - Tcl_Interp *interp, - const char *mntpt, - const char *zipname, - const char *passwd) + int TclZipfs_Mount(Tcl_Interp *interp, const char *mountPoint, + const char *zipname, const char *passwd) } declare 633 { - int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) + int TclZipfs_Unmount(Tcl_Interp *interp, const char *mountPoint) } declare 634 { Tcl_Obj *TclZipfs_TclLibrary(void) } declare 635 { - int TclZipfs_Mount_Buffer( - Tcl_Interp *interp, - const char *mntpt, - unsigned char *data, - size_t datalen, - int copy) + int TclZipfs_MountBuffer(Tcl_Interp *interp, const char *mountPoint, + unsigned char *data, size_t datalen, int copy) } # ----- BASELINE -- FOR -- 8.7.0 ----- # diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 3fb5355..e20782e 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1863,16 +1863,17 @@ EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 632 */ -EXTERN int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, - const char *zipname, const char *passwd); +EXTERN int TclZipfs_Mount(Tcl_Interp *interp, + const char *mountPoint, const char *zipname, + const char *passwd); /* 633 */ EXTERN int TclZipfs_Unmount(Tcl_Interp *interp, - const char *zipname); + const char *mountPoint); /* 634 */ EXTERN Tcl_Obj * TclZipfs_TclLibrary(void); /* 635 */ -EXTERN int TclZipfs_Mount_Buffer(Tcl_Interp *interp, - const char *mntpt, unsigned char *data, +EXTERN int TclZipfs_MountBuffer(Tcl_Interp *interp, + const char *mountPoint, unsigned char *data, size_t datalen, int copy); typedef struct { @@ -2541,10 +2542,10 @@ typedef struct TclStubs { int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */ void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */ Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */ - int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd); /* 632 */ - int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *zipname); /* 633 */ + int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *mountPoint, const char *zipname, const char *passwd); /* 632 */ + int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *mountPoint); /* 633 */ Tcl_Obj * (*tclZipfs_TclLibrary) (void); /* 634 */ - int (*tclZipfs_Mount_Buffer) (Tcl_Interp *interp, const char *mntpt, unsigned char *data, size_t datalen, int copy); /* 635 */ + int (*tclZipfs_MountBuffer) (Tcl_Interp *interp, const char *mountPoint, unsigned char *data, size_t datalen, int copy); /* 635 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -3845,8 +3846,8 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tclZipfs_Unmount) /* 633 */ #define TclZipfs_TclLibrary \ (tclStubsPtr->tclZipfs_TclLibrary) /* 634 */ -#define TclZipfs_Mount_Buffer \ - (tclStubsPtr->tclZipfs_Mount_Buffer) /* 635 */ +#define TclZipfs_MountBuffer \ + (tclStubsPtr->tclZipfs_MountBuffer) /* 635 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index 5f3fe7b..2e2aa60 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -1574,7 +1574,7 @@ const TclStubs tclStubs = { TclZipfs_Mount, /* 632 */ TclZipfs_Unmount, /* 633 */ TclZipfs_TclLibrary, /* 634 */ - TclZipfs_Mount_Buffer, /* 635 */ + TclZipfs_MountBuffer, /* 635 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index 4a0d24c..b609779 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -21,9 +21,9 @@ #ifdef _WIN32 #include -#else +#else /* !_WIN32 */ #include -#endif +#endif /* _WIN32*/ #include #include #include @@ -33,40 +33,50 @@ #ifndef MAP_FILE #define MAP_FILE 0 -#endif +#endif /* !MAP_FILE */ #ifdef HAVE_ZLIB #include "zlib.h" #include "crypt.h" #ifdef CFG_RUNTIME_DLLFILE + /* ** We are compiling as part of the core. ** TIP430 style zipfs prefix */ + #define ZIPFS_VOLUME "//zipfs:/" #define ZIPFS_VOLUME_LEN 9 #define ZIPFS_APP_MOUNT "//zipfs:/app" #define ZIPFS_ZIP_MOUNT "//zipfs:/lib/tcl" -#else + +#else /* !CFG_RUNTIME_DLLFILE */ + /* ** We are compiling from the /compat folder of tclconfig ** Pre TIP430 style zipfs prefix ** //zipfs:/ doesn't work straight out of the box on either windows or Unix ** without other changes made to tip 430 */ + #define ZIPFS_VOLUME "zipfs:/" #define ZIPFS_VOLUME_LEN 7 #define ZIPFS_APP_MOUNT "zipfs:/app" #define ZIPFS_ZIP_MOUNT "zipfs:/lib/tcl" -#endif + +#endif /* CFG_RUNTIME_DLLFILE */ + /* * Various constants and offsets found in ZIP archive files */ #define ZIP_SIG_LEN 4 -/* Local header of ZIP archive member (at very beginning of each member). */ +/* + * Local header of ZIP archive member (at very beginning of each member). + */ + #define ZIP_LOCAL_HEADER_SIG 0x04034b50 #define ZIP_LOCAL_HEADER_LEN 30 #define ZIP_LOCAL_SIG_OFFS 0 @@ -81,7 +91,10 @@ #define ZIP_LOCAL_PATHLEN_OFFS 26 #define ZIP_LOCAL_EXTRALEN_OFFS 28 -/* Central header of ZIP archive member at end of ZIP file. */ +/* + * Central header of ZIP archive member at end of ZIP file. + */ + #define ZIP_CENTRAL_HEADER_SIG 0x02014b50 #define ZIP_CENTRAL_HEADER_LEN 46 #define ZIP_CENTRAL_SIG_OFFS 0 @@ -102,7 +115,10 @@ #define ZIP_CENTRAL_EATTR_OFFS 38 #define ZIP_CENTRAL_LOCALHDR_OFFS 42 -/* Central end signature at very end of ZIP file. */ +/* + * Central end signature at very end of ZIP file. + */ + #define ZIP_CENTRAL_END_SIG 0x06054b50 #define ZIP_CENTRAL_END_LEN 22 #define ZIP_CENTRAL_END_SIG_OFFS 0 @@ -120,16 +136,19 @@ #define ZIP_PASSWORD_END_SIG 0x5a5a4b50 -/* Macros to report errors only if an interp is present */ +/* + * Macros to report errors only if an interp is present. + */ + #define ZIPFS_ERROR(interp,errstr) \ do { \ - if (interp != NULL) { \ + if (interp) { \ Tcl_SetObjResult(interp, Tcl_NewStringObj(errstr, -1)); \ } \ } while (0) #define ZIPFS_POSIX_ERROR(interp,errstr) \ do { \ - if (interp != NULL) { \ + if (interp) { \ Tcl_SetObjResult(interp, Tcl_ObjPrintf( \ "%s: %s", errstr, Tcl_PosixError(interp))); \ } \ @@ -164,7 +183,7 @@ #ifdef _WIN32 static const char drvletters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; -#endif +#endif /* _WIN32 */ /* * Mutex to protect localtime(3) when no reentrant version available. @@ -172,7 +191,7 @@ static const char drvletters[] = #if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) && defined(TCL_THREADS) TCL_DECLARE_MUTEX(localtimeMutex) -#endif +#endif /* !_WIN32 && !HAVE_LOCALTIME_R && TCL_THREADS */ /* * In-core description of mounted ZIP archive file. @@ -180,7 +199,7 @@ TCL_DECLARE_MUTEX(localtimeMutex) typedef struct ZipFile { char *name; /* Archive name */ - size_t nameLength; + size_t nameLength; /* Length of archive name */ char isMemBuffer; /* When true, not a file but a memory buffer */ Tcl_Channel chan; /* Channel handle or NULL */ unsigned char *data; /* Memory mapped or malloc'ed file */ @@ -194,11 +213,11 @@ typedef struct ZipFile { size_t numOpen; /* Number of open files on archive */ struct ZipEntry *entries; /* List of files in archive */ struct ZipEntry *topEnts; /* List of top-level dirs in archive */ - char *mountPoint; /* Mount point */ - size_t mountPointLen; + char *mountPoint; /* Mount point name */ + size_t mountPointLen; /* Length of mount point name */ #ifdef _WIN32 - HANDLE mountHandle; -#endif + HANDLE mountHandle; /* Handle used for direct file access. */ +#endif /* _WIN32 */ } ZipFile; /* @@ -207,16 +226,16 @@ typedef struct ZipFile { typedef struct ZipEntry { char *name; /* The full pathname of the virtual file */ - ZipFile *zipfile; /* The ZIP file holding this virtual file */ + ZipFile *zipFilePtr; /* The ZIP file holding this virtual file */ Tcl_WideInt offset; /* Data offset into memory mapped ZIP file */ - int nbyte; /* Uncompressed size of the virtual file */ - int nbytecompr; /* Compressed size of the virtual file */ - int cmeth; /* Compress method */ - int isdir; /* Set to 1 if directory, or -1 if root */ + int numBytes; /* Uncompressed size of the virtual file */ + int numCompressedBytes; /* Compressed size of the virtual file */ + int compressMethod; /* Compress method */ + int isDirectory; /* Set to 1 if directory, or -1 if root */ int depth; /* Number of slashes in path. */ int crc32; /* CRC-32 */ int timestamp; /* Modification time */ - int isenc; /* True if data is encrypted */ + int isEncrypted; /* True if data is encrypted */ unsigned char *data; /* File data if written */ struct ZipEntry *next; /* Next file in the same archive */ struct ZipEntry *tnext; /* Next top-level dir in archive */ @@ -227,17 +246,17 @@ typedef struct ZipEntry { */ typedef struct ZipChannel { - ZipFile *zipfile; /* The ZIP file holding this channel */ - ZipEntry *zipentry; /* Pointer back to virtual file */ - size_t nmax; /* Maximum size for write */ - size_t nbyte; /* Number of bytes of uncompressed data */ - size_t nread; /* Position of next byte to be read from the + ZipFile *zipFilePtr; /* The ZIP file holding this channel */ + ZipEntry *zipEntryPtr; /* Pointer back to virtual file */ + size_t maxWrite; /* Maximum size for write */ + size_t numBytes; /* Number of bytes of uncompressed data */ + size_t numRead; /* Position of next byte to be read from the * channel */ unsigned char *ubuf; /* Pointer to the uncompressed data */ int iscompr; /* True if data is compressed */ - int isdir; /* Set to 1 if directory, or -1 if root */ - int isenc; /* True if data is encrypted */ - int iswr; /* True if open for writing */ + int isDirectory; /* Set to 1 if directory, or -1 if root */ + int isEncrypted; /* True if data is encrypted */ + int isWriting; /* True if open for writing */ unsigned long keys[3]; /* Key for decryption */ } ZipChannel; @@ -334,16 +353,13 @@ static const z_crc_t crc32tab[256] = { 0x2d02ef8d, }; -const char *zipfs_literal_tcl_library = NULL; +static const char *zipfs_literal_tcl_library = NULL; /* Function prototypes */ -int TclZipfs_Mount(Tcl_Interp *interp, - const char *mountPoint, const char *zipname, - const char *passwd); -int TclZipfs_Mount_Buffer(Tcl_Interp *interp, - const char *mountPoint, unsigned char *data, - size_t datalen, int copy); +static inline int DescribeMounted(Tcl_Interp *interp, + const char *mountPoint); +static inline int ListMountPoints(Tcl_Interp *interp); static int ZipfsAppHookFindTclInit(const char *archive); static int ZipFSPathInFilesystemProc(Tcl_Obj *pathPtr, ClientData *clientDataPtr); @@ -366,7 +382,19 @@ static int ZipFSFileAttrsSetProc(Tcl_Interp *interp, int index, static int ZipFSLoadFile(Tcl_Interp *interp, Tcl_Obj *path, Tcl_LoadHandle *loadHandle, Tcl_FSUnloadFileProc **unloadProcPtr, int flags); -static void TclZipfs_C_Init(void); +static void ZipfsSetup(void); +static int ZipChannelClose(ClientData instanceData, + Tcl_Interp *interp); +static int ZipChannelGetFile(ClientData instanceData, + int direction, ClientData *handlePtr); +static int ZipChannelRead(ClientData instanceData, char *buf, + int toRead, int *errloc); +static int ZipChannelSeek(ClientData instanceData, long offset, + int mode, int *errloc); +static void ZipChannelWatchChannel(ClientData instanceData, + int mask); +static int ZipChannelWrite(ClientData instanceData, + const char *buf, int toWrite, int *errloc); /* * Define the ZIP filesystem dispatch table. @@ -409,6 +437,30 @@ const Tcl_Filesystem zipfsFilesystem = { }; /* + * The channel type/driver definition used for ZIP archive members. + */ + +static Tcl_ChannelType ZipChannelType = { + "zip", /* Type name. */ + TCL_CHANNEL_VERSION_5, + ZipChannelClose, /* Close channel, clean instance data */ + ZipChannelRead, /* Handle read request */ + ZipChannelWrite, /* Handle write request */ + ZipChannelSeek, /* Move location of access point, NULL'able */ + NULL, /* Set options, NULL'able */ + NULL, /* Get options, NULL'able */ + ZipChannelWatchChannel, /* Initialize notifier */ + ZipChannelGetFile, /* Get OS handle from the channel */ + NULL, /* 2nd version of close channel, NULL'able */ + NULL, /* Set blocking mode for raw channel, NULL'able */ + NULL, /* Function to flush channel, NULL'able */ + NULL, /* Function to handle event, NULL'able */ + NULL, /* Wide seek function, NULL'able */ + NULL, /* Thread action function, NULL'able */ + NULL, /* Truncate function, NULL'able */ +}; + +/* * Miscellaneous constants. */ @@ -634,8 +686,7 @@ CanonicalPath( int haveZipfsPath = 1; #ifdef _WIN32 - if ((tail[0] != '\0') && (strchr(drvletters, tail[0]) != NULL) - && (tail[1] == ':')) { + if (tail[0] != '\0' && strchr(drvletters, tail[0]) && tail[1] == ':') { tail += 2; haveZipfsPath = 0; } @@ -726,7 +777,7 @@ CanonicalPath( path[i] = '/'; } } -#endif +#endif /* _WIN32 */ if (ZIPFSPATH) { n = ZIPFS_VOLUME_LEN; @@ -780,7 +831,8 @@ CanonicalPath( * ZipFSLookup -- * * This function returns the ZIP entry struct corresponding to the ZIP - * archive member of the given file name. + * archive member of the given file name. Caller must hold the right + * lock. * * Results: * Returns the pointer to ZIP entry struct or NULL if the the given file @@ -800,7 +852,7 @@ ZipFSLookup( ZipEntry *z = NULL; hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, filename); - if (hPtr != NULL) { + if (hPtr) { z = Tcl_GetHashValue(hPtr); } return z; @@ -831,14 +883,13 @@ ZipFSLookupMount( Tcl_HashEntry *hPtr; Tcl_HashSearch search; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { ZipFile *zf = Tcl_GetHashValue(hPtr); if (strcmp(zf->mountPoint, filename) == 0) { return 1; } - hPtr = Tcl_NextHashEntry(&search); } return 0; } @@ -871,7 +922,7 @@ ZipFSCloseArchive( } if (zf->isMemBuffer) { /* Pointer to memory */ - if (zf->ptrToFree != NULL) { + if (zf->ptrToFree) { ckfree(zf->ptrToFree); zf->ptrToFree = NULL; } @@ -880,7 +931,7 @@ ZipFSCloseArchive( } #ifdef _WIN32 - if ((zf->data != NULL) && (zf->ptrToFree == NULL)) { + if (zf->data && !zf->ptrToFree) { UnmapViewOfFile(zf->data); zf->data = NULL; } @@ -888,17 +939,17 @@ ZipFSCloseArchive( CloseHandle(zf->mountHandle); } #else /* !_WIN32 */ - if ((zf->data != MAP_FAILED) && (zf->ptrToFree == NULL)) { + if ((zf->data != MAP_FAILED) && !zf->ptrToFree) { munmap(zf->data, zf->length); zf->data = MAP_FAILED; } #endif /* _WIN32 */ - if (zf->ptrToFree != NULL) { + if (zf->ptrToFree) { ckfree(zf->ptrToFree); zf->ptrToFree = NULL; } - if (zf->chan != NULL) { + if (zf->chan) { Tcl_Close(interp, zf->chan); zf->chan = NULL; } @@ -1053,7 +1104,7 @@ ZipFSOpenArchive( zf->ptrToFree = NULL; zf->passBuf[0] = 0; zf->chan = Tcl_OpenFileChannel(interp, zipname, "rb", 0); - if (zf->chan == NULL) { + if (!zf->chan) { return TCL_ERROR; } if (Tcl_GetChannelHandle(zf->chan, TCL_READABLE, &handle) != TCL_OK) { @@ -1072,7 +1123,7 @@ ZipFSOpenArchive( goto error; } zf->ptrToFree = zf->data = attemptckalloc(zf->length); - if (zf->ptrToFree == NULL) { + if (!zf->ptrToFree) { ZIPFS_ERROR(interp, "out of memory"); goto error; } @@ -1105,7 +1156,7 @@ ZipFSOpenArchive( } zf->data = MapViewOfFile(zf->mountHandle, FILE_MAP_READ, 0, 0, zf->length); - if (zf->data == NULL) { + if (!zf->data) { ZIPFS_POSIX_ERROR(interp, "file mapping failed"); goto error; } @@ -1170,9 +1221,9 @@ ZipFSCatalogFilesystem( */ pwlen = 0; - if (passwd != NULL) { + if (passwd) { pwlen = strlen(passwd); - if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + if ((pwlen > 255) || strchr(passwd, 0xff)) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); @@ -1197,7 +1248,7 @@ ZipFSCatalogFilesystem( } hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mountPoint, &isNew); if (!isNew) { - if (interp != NULL) { + if (interp) { zf = Tcl_GetHashValue(hPtr); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s is already mounted on %s", zf->name, mountPoint)); @@ -1207,8 +1258,8 @@ ZipFSCatalogFilesystem( return TCL_ERROR; } zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); - if (zf == NULL) { - if (interp != NULL) { + if (!zf) { + if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } Unlock(); @@ -1230,13 +1281,10 @@ ZipFSCatalogFilesystem( if ((zf->passBuf[0] == 0) && pwlen) { int k = 0; - i = pwlen; - zf->passBuf[k++] = i; - while (i > 0) { - zf->passBuf[k] = (passwd[i - 1] & 0x0f) - | pwrot[(passwd[i - 1] >> 4) & 0x0f]; - k++; - i--; + zf->passBuf[k++] = pwlen; + for (i = pwlen; i-- > 0 ;) { + zf->passBuf[k++] = (passwd[i] & 0x0f) + | pwrot[(passwd[i] >> 4) & 0x0f]; } zf->passBuf[k] = '\0'; } @@ -1248,14 +1296,14 @@ ZipFSCatalogFilesystem( z->tnext = NULL; z->depth = CountSlashes(mountPoint); - z->zipfile = zf; - z->isdir = (zf->baseOffset == 0) ? 1 : -1; /* root marker */ - z->isenc = 0; + z->zipFilePtr = zf; + z->isDirectory = (zf->baseOffset == 0) ? 1 : -1; /* root marker */ + z->isEncrypted = 0; z->offset = zf->baseOffset; z->crc32 = 0; z->timestamp = 0; - z->nbyte = z->nbytecompr = 0; - z->cmeth = ZIP_COMPMETH_STORED; + z->numBytes = z->numCompressedBytes = 0; + z->compressMethod = ZIP_COMPMETH_STORED; z->data = NULL; z->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); z->next = zf->entries; @@ -1319,7 +1367,7 @@ ZipFSCatalogFilesystem( Tcl_DStringAppend(&ds2, "assets/.root/", -1); Tcl_DStringAppend(&ds2, path, -1); hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, Tcl_DStringValue(&ds2)); - if (hPtr != NULL) { + if (hPtr) { /* should not happen but skip it anyway */ Tcl_DStringFree(&ds2); goto nextent; @@ -1342,27 +1390,27 @@ ZipFSCatalogFilesystem( z->name = NULL; z->tnext = NULL; z->depth = CountSlashes(fullpath); - z->zipfile = zf; - z->isdir = isdir; - z->isenc = (ZipReadShort(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) + z->zipFilePtr = zf; + z->isDirectory = isdir; + z->isEncrypted = (ZipReadShort(lq + ZIP_LOCAL_FLAGS_OFFS) & 1) && (nbcompr > 12); z->offset = offs; - if (gq != NULL) { + if (gq) { z->crc32 = ZipReadInt(gq + ZIP_CENTRAL_CRC32_OFFS); dosDate = ZipReadShort(gq + ZIP_CENTRAL_MDATE_OFFS); dosTime = ZipReadShort(gq + ZIP_CENTRAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = ZipReadInt(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); - z->cmeth = ZipReadShort(gq + ZIP_CENTRAL_COMPMETH_OFFS); + z->numBytes = ZipReadInt(gq + ZIP_CENTRAL_UNCOMPLEN_OFFS); + z->compressMethod = ZipReadShort(gq + ZIP_CENTRAL_COMPMETH_OFFS); } else { z->crc32 = ZipReadInt(lq + ZIP_LOCAL_CRC32_OFFS); dosDate = ZipReadShort(lq + ZIP_LOCAL_MDATE_OFFS); dosTime = ZipReadShort(lq + ZIP_LOCAL_MTIME_OFFS); z->timestamp = DosTimeDate(dosDate, dosTime); - z->nbyte = ZipReadInt(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); - z->cmeth = ZipReadShort(lq + ZIP_LOCAL_COMPMETH_OFFS); + z->numBytes = ZipReadInt(lq + ZIP_LOCAL_UNCOMPLEN_OFFS); + z->compressMethod = ZipReadShort(lq + ZIP_LOCAL_COMPMETH_OFFS); } - z->nbytecompr = nbcompr; + z->numCompressedBytes = nbcompr; z->data = NULL; hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, fullpath, &isNew); if (!isNew) { @@ -1377,7 +1425,7 @@ ZipFSCatalogFilesystem( z->tnext = zf->topEnts; zf->topEnts = z; } - if (!z->isdir && (z->depth > 1)) { + if (!z->isDirectory && (z->depth > 1)) { char *dir, *end; ZipEntry *zd; @@ -1385,8 +1433,8 @@ ZipFSCatalogFilesystem( Tcl_DStringSetLength(&ds, 0); Tcl_DStringAppend(&ds, z->name, -1); dir = Tcl_DStringValue(&ds); - end = strrchr(dir, '/'); - while ((end != NULL) && (end != dir)) { + for (end = strrchr(dir, '/'); end && (end != dir); + end = strrchr(dir, '/')) { Tcl_DStringSetLength(&ds, end - dir); hPtr = Tcl_CreateHashEntry(&ZipFS.fileHash, dir, &isNew); if (!isNew) { @@ -1396,14 +1444,14 @@ ZipFSCatalogFilesystem( zd->name = NULL; zd->tnext = NULL; zd->depth = CountSlashes(dir); - zd->zipfile = zf; - zd->isdir = 1; - zd->isenc = 0; + zd->zipFilePtr = zf; + zd->isDirectory = 1; + zd->isEncrypted = 0; zd->offset = z->offset; zd->crc32 = 0; zd->timestamp = z->timestamp; - zd->nbyte = zd->nbytecompr = 0; - zd->cmeth = ZIP_COMPMETH_STORED; + zd->numBytes = zd->numCompressedBytes = 0; + zd->compressMethod = ZIP_COMPMETH_STORED; zd->data = NULL; Tcl_SetHashValue(hPtr, zd); zd->name = Tcl_GetHashKey(&ZipFS.fileHash, hPtr); @@ -1413,7 +1461,6 @@ ZipFSCatalogFilesystem( zd->tnext = zf->topEnts; zf->topEnts = zd; } - end = strrchr(dir, '/'); } } } @@ -1430,7 +1477,7 @@ ZipFSCatalogFilesystem( /* *------------------------------------------------------------------------- * - * TclZipfs_C_Init -- + * ZipfsSetup -- * * Common initialisation code. ZipFS.initialized must *not* be set prior * to the call. @@ -1439,7 +1486,7 @@ ZipFSCatalogFilesystem( */ static void -TclZipfs_C_Init(void) +ZipfsSetup(void) { #ifdef TCL_THREADS static const Tcl_Time t = { 0, 0 }; @@ -1463,6 +1510,83 @@ TclZipfs_C_Init(void) /* *------------------------------------------------------------------------- * + * ListMountPoints -- + * + * This procedure lists the mount points and what's mounted there, or + * reports whether there are any mounts (if there's no interpreter). The + * read lock must be held by the caller. + * + * Results: + * A standard Tcl result. TCL_OK (or TCL_BREAK if no mounts and no + * interpreter). + * + * Side effects: + * Interpreter result may be updated. + * + *------------------------------------------------------------------------- + */ + +static inline int +ListMountPoints( + Tcl_Interp *interp) +{ + Tcl_HashEntry *hPtr; + Tcl_HashSearch search; + ZipFile *zf; + + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { + if (!interp) { + return TCL_OK; + } + zf = Tcl_GetHashValue(hPtr); + Tcl_AppendElement(interp, zf->mountPoint); + Tcl_AppendElement(interp, zf->name); + } + return (interp ? TCL_OK : TCL_BREAK); +} + +/* + *------------------------------------------------------------------------- + * + * DescribeMounted -- + * + * This procedure describes what is mounted at the given the mount point. + * The interpreter result is not updated if there is nothing mounted at + * the given point. The read lock must be held by the caller. + * + * Results: + * A standard Tcl result. TCL_OK (or TCL_BREAK if nothing mounted there + * and no interpreter). + * + * Side effects: + * Interpreter result may be updated. + * + *------------------------------------------------------------------------- + */ + +static inline int +DescribeMounted( + Tcl_Interp *interp, + const char *mountPoint) +{ + Tcl_HashEntry *hPtr; + ZipFile *zf; + + if (interp) { + hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); + if (hPtr) { + zf = Tcl_GetHashValue(hPtr); + Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); + return TCL_OK; + } + } + return (interp ? TCL_OK : TCL_BREAK); +} + +/* + *------------------------------------------------------------------------- + * * TclZipfs_Mount -- * * This procedure is invoked to mount a given ZIP archive file on a given @@ -1486,54 +1610,41 @@ TclZipfs_Mount( const char *passwd) /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ { - int i, pwlen; ZipFile *zf; ReadLock(); if (!ZipFS.initialized) { - TclZipfs_C_Init(); + ZipfsSetup(); } - if (mountPoint == NULL) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - int ret = TCL_OK; - i = 0; - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mountPoint); - Tcl_AppendElement(interp, zf->name); - } - ++i; - hPtr = Tcl_NextHashEntry(&search); - } - if (interp == NULL) { - ret = (i > 0) ? TCL_OK : TCL_BREAK; - } + /* + * No mount point, so list all mount points and what is mounted there. + */ + + if (!mountPoint) { + int ret = ListMountPoints(interp); Unlock(); return ret; } - if (zipname == NULL) { - if (interp != NULL) { - Tcl_HashEntry *hPtr = - Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); + /* + * Mount point but no file, so describe what is mounted at that mount + * point. + */ - if (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } - } + if (!zipname) { + DescribeMounted(interp, mountPoint); Unlock(); return TCL_OK; } Unlock(); - pwlen = 0; - if (passwd != NULL) { - pwlen = strlen(passwd); - if ((pwlen > 255) || (strchr(passwd, 0xff) != NULL)) { + + /* + * Have both a mount point and a file (name) to mount there. + */ + + if (passwd) { + if ((strlen(passwd) > 255) || strchr(passwd, 0xff)) { if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); @@ -1542,8 +1653,8 @@ TclZipfs_Mount( } } zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); - if (zf == NULL) { - if (interp != NULL) { + if (!zf) { + if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } return TCL_ERROR; @@ -1557,10 +1668,10 @@ TclZipfs_Mount( /* *------------------------------------------------------------------------- * - * TclZipfs_Mount_Buffer -- + * TclZipfs_MountBuffer -- * - * This procedure is invoked to mount a given ZIP archive file on - * a given mountpoint with optional ZIP password. + * This procedure is invoked to mount a given ZIP archive file on a given + * mountpoint with optional ZIP password. * * Results: * A standard Tcl result. @@ -1573,7 +1684,7 @@ TclZipfs_Mount( */ int -TclZipfs_Mount_Buffer( +TclZipfs_MountBuffer( Tcl_Interp *interp, /* Current interpreter. NULLable. */ const char *mountPoint, /* Mount point path. */ unsigned char *data, @@ -1584,50 +1695,38 @@ TclZipfs_Mount_Buffer( ReadLock(); if (!ZipFS.initialized) { - TclZipfs_C_Init(); + ZipfsSetup(); } - if (mountPoint == NULL) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - int ret = (interp ? TCL_BREAK : TCL_OK); - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); - if (interp != NULL) { - Tcl_AppendElement(interp, zf->mountPoint); - Tcl_AppendElement(interp, zf->name); - } else { - ret = TCL_OK; - /* - * Stop searching here if we're not returning a list. - */ - break; - } - hPtr = Tcl_NextHashEntry(&search); - } + /* + * No mount point, so list all mount points and what is mounted there. + */ + + if (!mountPoint) { + int ret = ListMountPoints(interp); Unlock(); return ret; } - if (data == NULL) { - if (interp != NULL) { - Tcl_HashEntry *hPtr = - Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); + /* + * Mount point but no data, so describe what is mounted at that mount + * point. + */ - if (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } - } + if (!data) { + DescribeMounted(interp, mountPoint); Unlock(); return TCL_OK; } Unlock(); + /* + * Have both a mount point and data to mount there. + */ + zf = attemptckalloc(sizeof(ZipFile) + strlen(mountPoint) + 1); - if (zf == NULL) { - if (interp != NULL) { + if (!zf) { + if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } return TCL_ERROR; @@ -1636,8 +1735,8 @@ TclZipfs_Mount_Buffer( zf->length = datalen; if (copy) { zf->data = attemptckalloc(datalen); - if (zf->data == NULL) { - if (interp != NULL) { + if (!zf->data) { + if (interp) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } return TCL_ERROR; @@ -1697,7 +1796,7 @@ TclZipfs_Unmount( hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); /* don't report no-such-mount as an error */ - if (hPtr == NULL) { + if (!hPtr) { goto done; } @@ -1714,7 +1813,7 @@ TclZipfs_Unmount( if (hPtr) { Tcl_DeleteHashEntry(hPtr); } - if (z->data != NULL) { + if (z->data) { ckfree(z->data); } ckfree(z); @@ -1767,9 +1866,9 @@ ZipFSMountObjCmd( /* *------------------------------------------------------------------------- * - * ZipFSMountObjCmd -- + * ZipFSMountBufferObjCmd -- * - * This procedure is invoked to process the "zipfs::mount" command. + * This procedure is invoked to process the "zipfs::mount_data" command. * * Results: * A standard Tcl result. @@ -1796,40 +1895,24 @@ ZipFSMountBufferObjCmd( return TCL_ERROR; } if (objc < 2) { - Tcl_HashEntry *hPtr; - Tcl_HashSearch search; - int ret = TCL_OK; + int ret; ReadLock(); - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - ZipFile *zf = Tcl_GetHashValue(hPtr); - - Tcl_AppendElement(interp, zf->mountPoint); - Tcl_AppendElement(interp, zf->name); - hPtr = Tcl_NextHashEntry(&search); - } + ret = ListMountPoints(interp); Unlock(); return ret; } mountPoint = Tcl_GetString(objv[1]); if (objc < 3) { - Tcl_HashEntry *hPtr; - ReadLock(); - hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mountPoint); - if (hPtr != NULL) { - ZipFile *zf = Tcl_GetHashValue(hPtr); - - Tcl_SetObjResult(interp, Tcl_NewStringObj(zf->name, -1)); - } + DescribeMounted(interp, mountPoint); Unlock(); return TCL_OK; } data = Tcl_GetByteArrayFromObj(objv[2], &length); - return TclZipfs_Mount_Buffer(interp, mountPoint, data, length, 1); + return TclZipfs_MountBuffer(interp, mountPoint, data, length, 1); } /* @@ -1925,7 +2008,7 @@ ZipFSMkKeyObjCmd( if (len == 0) { return TCL_OK; } - if ((len > 255) || (strchr(pw, 0xff) != NULL)) { + if ((len > 255) || strchr(pw, 0xff)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); return TCL_ERROR; } @@ -1987,17 +2070,23 @@ ZipAddFile( int crc, flush, zpathlen; size_t nbyte, nbytecompr, len, olen, align = 0; Tcl_WideInt pos[3]; - int mtime = 0, isNew, cmeth; + int mtime = 0, isNew, compMeth; unsigned long keys[3], keys0[3]; char obuf[4096]; + /* + * Trim leading '/' characters. If this results in an empty string, we've + * nothing to do. + */ + zpath = name; - while (zpath != NULL && zpath[0] == '/') { + while (zpath && zpath[0] == '/') { zpath++; } - if ((zpath == NULL) || (zpath[0] == '\0')) { + if (!zpath || (zpath[0] == '\0')) { return TCL_OK; } + zpathlen = strlen(zpath); if (zpathlen + ZIP_CENTRAL_HEADER_LEN > bufsize) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( @@ -2005,7 +2094,7 @@ ZipAddFile( return TCL_ERROR; } in = Tcl_OpenFileChannel(interp, path, "rb", 0); - if (in == NULL) { + if (!in) { #ifdef _WIN32 /* hopefully a directory */ if (strcmp("permission denied", Tcl_PosixError(interp)) == 0) { @@ -2028,19 +2117,23 @@ ZipAddFile( Tcl_ResetResult(interp); crc = 0; nbyte = nbytecompr = 0; - while ((len = Tcl_Read(in, buf, bufsize)) + 1 > 1) { - crc = crc32(crc, (unsigned char *) buf, len); - nbyte += len; - } - if (len == ERROR_LENGTH) { - if (nbyte == 0 && errno == EISDIR) { + while (1) { + len = Tcl_Read(in, buf, bufsize); + if (len == ERROR_LENGTH) { + if (nbyte == 0 && errno == EISDIR) { + Tcl_Close(interp, in); + return TCL_OK; + } + Tcl_SetObjResult(interp, Tcl_ObjPrintf("read error on \"%s\": %s", + path, Tcl_PosixError(interp))); Tcl_Close(interp, in); - return TCL_OK; + return TCL_ERROR; } - Tcl_SetObjResult(interp, Tcl_ObjPrintf("read error on \"%s\": %s", - path, Tcl_PosixError(interp))); - Tcl_Close(interp, in); - return TCL_ERROR; + if (len == 0) { + break; + } + crc = crc32(crc, (unsigned char *) buf, len); + nbyte += len; } if (Tcl_Seek(in, 0, SEEK_SET) == -1) { Tcl_SetObjResult(interp, Tcl_ObjPrintf("seek error on \"%s\": %s", @@ -2075,7 +2168,7 @@ ZipAddFile( goto wrerr; } } - if (passwd != NULL) { + if (passwd) { int i, ch, tmp; unsigned char kvbuf[24]; Tcl_Obj *ret; @@ -2119,7 +2212,7 @@ ZipAddFile( } Tcl_Flush(out); pos[2] = Tcl_Tell(out); - cmeth = ZIP_COMPMETH_DEFLATED; + compMeth = ZIP_COMPMETH_DEFLATED; memset(&stream, 0, sizeof(z_stream)); stream.zalloc = Z_NULL; stream.zfree = Z_NULL; @@ -2155,7 +2248,7 @@ ZipAddFile( return TCL_ERROR; } olen = sizeof(obuf) - stream.avail_out; - if (passwd != NULL) { + if (passwd) { size_t i; int tmp; @@ -2190,7 +2283,7 @@ ZipAddFile( "seek error: %s", Tcl_PosixError(interp))); return TCL_ERROR; } - nbytecompr = (passwd != NULL) ? 12 : 0; + nbytecompr = (passwd ? 12 : 0); while (1) { len = Tcl_Read(in, buf, bufsize); if (len == ERROR_LENGTH) { @@ -2202,7 +2295,7 @@ ZipAddFile( } else if (len == 0) { break; } - if (passwd != NULL) { + if (passwd) { size_t i; int tmp; @@ -2218,7 +2311,7 @@ ZipAddFile( } nbytecompr += len; } - cmeth = ZIP_COMPMETH_STORED; + compMeth = ZIP_COMPMETH_STORED; Tcl_Flush(out); pos[1] = Tcl_Tell(out); Tcl_TruncateChannel(out, pos[1]); @@ -2229,15 +2322,15 @@ ZipAddFile( z->name = NULL; z->tnext = NULL; z->depth = 0; - z->zipfile = NULL; - z->isdir = 0; - z->isenc = (passwd != NULL) ? 1 : 0; + z->zipFilePtr = NULL; + z->isDirectory = 0; + z->isEncrypted = (passwd ? 1 : 0); z->offset = pos[0]; z->crc32 = crc; z->timestamp = mtime; - z->nbyte = nbyte; - z->nbytecompr = nbytecompr; - z->cmeth = cmeth; + z->numBytes = nbyte; + z->numCompressedBytes = nbytecompr; + z->compressMethod = compMeth; z->data = NULL; hPtr = Tcl_CreateHashEntry(fileHash, zpath, &isNew); if (!isNew) { @@ -2256,13 +2349,13 @@ ZipAddFile( */ ZipWriteInt(buf + ZIP_LOCAL_SIG_OFFS, ZIP_LOCAL_HEADER_SIG); ZipWriteShort(buf + ZIP_LOCAL_VERSION_OFFS, ZIP_MIN_VERSION); - ZipWriteShort(buf + ZIP_LOCAL_FLAGS_OFFS, z->isenc); - ZipWriteShort(buf + ZIP_LOCAL_COMPMETH_OFFS, z->cmeth); + ZipWriteShort(buf + ZIP_LOCAL_FLAGS_OFFS, z->isEncrypted); + ZipWriteShort(buf + ZIP_LOCAL_COMPMETH_OFFS, z->compressMethod); ZipWriteShort(buf + ZIP_LOCAL_MTIME_OFFS, ToDosTime(z->timestamp)); ZipWriteShort(buf + ZIP_LOCAL_MDATE_OFFS, ToDosDate(z->timestamp)); ZipWriteInt(buf + ZIP_LOCAL_CRC32_OFFS, z->crc32); - ZipWriteInt(buf + ZIP_LOCAL_COMPLEN_OFFS, z->nbytecompr); - ZipWriteInt(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->nbyte); + ZipWriteInt(buf + ZIP_LOCAL_COMPLEN_OFFS, z->numCompressedBytes); + ZipWriteInt(buf + ZIP_LOCAL_UNCOMPLEN_OFFS, z->numBytes); ZipWriteShort(buf + ZIP_LOCAL_PATHLEN_OFFS, zpathlen); ZipWriteShort(buf + ZIP_LOCAL_EXTRALEN_OFFS, align); if (Tcl_Seek(out, pos[0], SEEK_SET) != pos[0]) { @@ -2337,7 +2430,7 @@ ZipFSMkZipOrImgObjCmd( if (objc > (isList ? 3 : 4)) { pw = Tcl_GetString(objv[isList ? 3 : 4]); pwlen = strlen(pw); - if ((pwlen > 255) || (strchr(pw, 0xff) != NULL)) { + if ((pwlen > 255) || strchr(pw, 0xff)) { Tcl_SetObjResult(interp, Tcl_NewStringObj("illegal password", -1)); return TCL_ERROR; @@ -2399,13 +2492,11 @@ ZipFSMkZipOrImgObjCmd( } if (pwlen) { i = 0; - len = pwlen; - while (len > 0) { - int ch = pw[len - 1]; + for (len = pwlen; len-- > 0;) { + int ch = pw[len]; passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; i++; - len--; } passBuf[i] = i; ++i; @@ -2415,17 +2506,20 @@ ZipFSMkZipOrImgObjCmd( passBuf[i++] = (char) (ZIP_PASSWORD_END_SIG >> 24); passBuf[i] = '\0'; } - /* Check for mounted image */ + + /* + * Check for mounted image. + */ + WriteLock(); - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { zf = Tcl_GetHashValue(hPtr); if (strcmp(zf->name, imgName) == 0) { isMounted = 1; zf->numOpen++; break; } - hPtr = Tcl_NextHashEntry(&search); } Unlock(); if (!isMounted) { @@ -2468,7 +2562,7 @@ ZipFSMkZipOrImgObjCmd( Tcl_ResetResult(interp); in = Tcl_OpenFileChannel(interp, imgName, "rb", 0644); - if (in == NULL) { + if (!in) { memset(passBuf, 0, sizeof(passBuf)); Tcl_DecrRefCount(list); Tcl_Close(interp, out); @@ -2486,8 +2580,7 @@ ZipFSMkZipOrImgObjCmd( return TCL_ERROR; } Tcl_Seek(in, 0, SEEK_SET); - k = 0; - while (k < i) { + for (k = 0; k < i; k += m) { m = i - k; if (m > (int) sizeof(buf)) { m = (int) sizeof(buf); @@ -2504,7 +2597,6 @@ ZipFSMkZipOrImgObjCmd( errMsg = "write error"; goto cperr; } - k += m; } Tcl_Close(interp, in); } @@ -2580,7 +2672,7 @@ ZipFSMkZipOrImgObjCmd( continue; } hPtr = Tcl_FindHashEntry(&fileHash, name); - if (hPtr == NULL) { + if (!hPtr) { continue; } z = Tcl_GetHashValue(hPtr); @@ -2588,13 +2680,13 @@ ZipFSMkZipOrImgObjCmd( ZipWriteInt(buf + ZIP_CENTRAL_SIG_OFFS, ZIP_CENTRAL_HEADER_SIG); ZipWriteShort(buf + ZIP_CENTRAL_VERSIONMADE_OFFS, ZIP_MIN_VERSION); ZipWriteShort(buf + ZIP_CENTRAL_VERSION_OFFS, ZIP_MIN_VERSION); - ZipWriteShort(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isenc ? 1 : 0); - ZipWriteShort(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->cmeth); + ZipWriteShort(buf + ZIP_CENTRAL_FLAGS_OFFS, z->isEncrypted); + ZipWriteShort(buf + ZIP_CENTRAL_COMPMETH_OFFS, z->compressMethod); ZipWriteShort(buf + ZIP_CENTRAL_MTIME_OFFS, ToDosTime(z->timestamp)); ZipWriteShort(buf + ZIP_CENTRAL_MDATE_OFFS, ToDosDate(z->timestamp)); ZipWriteInt(buf + ZIP_CENTRAL_CRC32_OFFS, z->crc32); - ZipWriteInt(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->nbytecompr); - ZipWriteInt(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->nbyte); + ZipWriteInt(buf + ZIP_CENTRAL_COMPLEN_OFFS, z->numCompressedBytes); + ZipWriteInt(buf + ZIP_CENTRAL_UNCOMPLEN_OFFS, z->numBytes); ZipWriteShort(buf + ZIP_CENTRAL_PATHLEN_OFFS, len); ZipWriteShort(buf + ZIP_CENTRAL_EXTRALEN_OFFS, 0); ZipWriteShort(buf + ZIP_CENTRAL_FCOMMENTLEN_OFFS, 0); @@ -2636,12 +2728,11 @@ ZipFSMkZipOrImgObjCmd( Tcl_Close(interp, out); } Tcl_DecrRefCount(list); - hPtr = Tcl_FirstHashEntry(&fileHash, &search); - while (hPtr != NULL) { + for (hPtr = Tcl_FirstHashEntry(&fileHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { z = Tcl_GetHashValue(hPtr); ckfree(z); Tcl_DeleteHashEntry(hPtr); - hPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&fileHash); return ret; @@ -2901,14 +2992,15 @@ ZipFSInfoObjCmd( filename = Tcl_GetStringFromObj(objv[1], 0); ReadLock(); z = ZipFSLookup(filename); - if (z != NULL) { + if (z) { Tcl_Obj *result = Tcl_GetObjResult(interp); Tcl_ListObjAppendElement(interp, result, - Tcl_NewStringObj(z->zipfile->name, -1)); - Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->nbyte)); + Tcl_NewStringObj(z->zipFilePtr->name, -1)); Tcl_ListObjAppendElement(interp, result, - Tcl_NewWideIntObj(z->nbytecompr)); + Tcl_NewWideIntObj(z->numBytes)); + Tcl_ListObjAppendElement(interp, result, + Tcl_NewWideIntObj(z->numCompressedBytes)); Tcl_ListObjAppendElement(interp, result, Tcl_NewWideIntObj(z->offset)); } Unlock(); @@ -2958,7 +3050,7 @@ ZipFSListObjCmd( pattern = Tcl_GetString(objv[2]); } else if ((n >= 2) && (strncmp(what, "-regexp", n) == 0)) { regexp = Tcl_RegExpCompile(interp, Tcl_GetString(objv[2])); - if (regexp == NULL) { + if (!regexp) { return TCL_ERROR; } } else { @@ -2970,7 +3062,7 @@ ZipFSListObjCmd( pattern = Tcl_GetStringFromObj(objv[1], 0); } ReadLock(); - if (pattern != NULL) { + if (pattern) { for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { ZipEntry *z = Tcl_GetHashValue(hPtr); @@ -2980,9 +3072,9 @@ ZipFSListObjCmd( Tcl_NewStringObj(z->name, -1)); } } - } else if (regexp != NULL) { + } else if (regexp) { for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + hPtr; hPtr = Tcl_NextHashEntry(&search)) { ZipEntry *z = Tcl_GetHashValue(hPtr); if (Tcl_RegExpExec(interp, regexp, z->name, z->name)) { @@ -2992,7 +3084,7 @@ ZipFSListObjCmd( } } else { for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + hPtr; hPtr = Tcl_NextHashEntry(&search)) { ZipEntry *z = Tcl_GetHashValue(hPtr); Tcl_ListObjAppendElement(interp, result, @@ -3099,8 +3191,8 @@ TclZipfs_TclLibrary(void) * * ZipFSTclLibraryObjCmd -- * - * This procedure is invoked to process the "zipfs::root" command. It - * returns the root that all zipfs file systems are mounted under. + * This procedure is invoked to process the "zipfs::tcl_library" command. + * It returns the root that all zipfs file systems are mounted under. * * Results: * A standard Tcl result. @@ -3149,28 +3241,28 @@ ZipChannelClose( { ZipChannel *info = instanceData; - if (info->iscompr && (info->ubuf != NULL)) { + if (info->iscompr && info->ubuf) { ckfree(info->ubuf); info->ubuf = NULL; } - if (info->isenc) { - info->isenc = 0; + if (info->isEncrypted) { + info->isEncrypted = 0; memset(info->keys, 0, sizeof(info->keys)); } - if (info->iswr) { - ZipEntry *z = info->zipentry; - unsigned char *newdata = attemptckrealloc(info->ubuf, info->nread); + if (info->isWriting) { + ZipEntry *z = info->zipEntryPtr; + unsigned char *newdata = attemptckrealloc(info->ubuf, info->numRead); - if (newdata != NULL) { - if (z->data != NULL) { + if (newdata) { + if (z->data) { ckfree(z->data); } z->data = newdata; - z->nbyte = z->nbytecompr = info->nbyte; - z->cmeth = ZIP_COMPMETH_STORED; + z->numBytes = z->numCompressedBytes = info->numBytes; + z->compressMethod = ZIP_COMPMETH_STORED; z->timestamp = time(NULL); - z->isdir = 0; - z->isenc = 0; + z->isDirectory = 0; + z->isEncrypted = 0; z->offset = 0; z->crc32 = 0; } else { @@ -3178,7 +3270,7 @@ ZipChannelClose( } } WriteLock(); - info->zipfile->numOpen--; + info->zipFilePtr->numOpen--; Unlock(); ckfree(info); return TCL_OK; @@ -3210,49 +3302,49 @@ ZipChannelRead( ZipChannel *info = (ZipChannel *) instanceData; unsigned long nextpos; - if (info->isdir < 0) { + if (info->isDirectory < 0) { /* * Special case: when executable combined with ZIP archive file read * data in front of ZIP, i.e. the executable itself. */ - nextpos = info->nread + toRead; - if (nextpos > info->zipfile->baseOffset) { - toRead = info->zipfile->baseOffset - info->nread; - nextpos = info->zipfile->baseOffset; + nextpos = info->numRead + toRead; + if (nextpos > info->zipFilePtr->baseOffset) { + toRead = info->zipFilePtr->baseOffset - info->numRead; + nextpos = info->zipFilePtr->baseOffset; } if (toRead == 0) { return 0; } - memcpy(buf, info->zipfile->data, toRead); - info->nread = nextpos; + memcpy(buf, info->zipFilePtr->data, toRead); + info->numRead = nextpos; *errloc = 0; return toRead; } - if (info->isdir) { + if (info->isDirectory) { *errloc = EISDIR; return -1; } - nextpos = info->nread + toRead; - if (nextpos > info->nbyte) { - toRead = info->nbyte - info->nread; - nextpos = info->nbyte; + nextpos = info->numRead + toRead; + if (nextpos > info->numBytes) { + toRead = info->numBytes - info->numRead; + nextpos = info->numBytes; } if (toRead == 0) { return 0; } - if (info->isenc) { + if (info->isEncrypted) { int i; for (i = 0; i < toRead; i++) { - int ch = info->ubuf[i + info->nread]; + int ch = info->ubuf[i + info->numRead]; buf[i] = zdecode(info->keys, crc32tab, ch); } } else { - memcpy(buf, info->ubuf + info->nread, toRead); + memcpy(buf, info->ubuf + info->numRead, toRead); } - info->nread = nextpos; + info->numRead = nextpos; *errloc = 0; return toRead; } @@ -3283,22 +3375,22 @@ ZipChannelWrite( ZipChannel *info = (ZipChannel *) instanceData; unsigned long nextpos; - if (!info->iswr) { + if (!info->isWriting) { *errloc = EINVAL; return -1; } - nextpos = info->nread + toWrite; - if (nextpos > info->nmax) { - toWrite = info->nmax - info->nread; - nextpos = info->nmax; + nextpos = info->numRead + toWrite; + if (nextpos > info->maxWrite) { + toWrite = info->maxWrite - info->numRead; + nextpos = info->maxWrite; } if (toWrite == 0) { return 0; } - memcpy(info->ubuf + info->nread, buf, toWrite); - info->nread = nextpos; - if (info->nread > info->nbyte) { - info->nbyte = info->nread; + memcpy(info->ubuf + info->numRead, buf, toWrite); + info->numRead = nextpos; + if (info->numRead > info->numBytes) { + info->numBytes = info->numRead; } *errloc = 0; return toWrite; @@ -3330,21 +3422,21 @@ ZipChannelSeek( ZipChannel *info = (ZipChannel *) instanceData; unsigned long end; - if (!info->iswr && (info->isdir < 0)) { + if (!info->isWriting && (info->isDirectory < 0)) { /* * Special case: when executable combined with ZIP archive file, seek * within front of ZIP, i.e. the executable itself. */ - end = info->zipfile->baseOffset; - } else if (info->isdir) { + end = info->zipFilePtr->baseOffset; + } else if (info->isDirectory) { *errloc = EINVAL; return -1; } else { - end = info->nbyte; + end = info->numBytes; } switch (mode) { case SEEK_CUR: - offset += info->nread; + offset += info->numRead; break; case SEEK_END: offset += end; @@ -3359,20 +3451,20 @@ ZipChannelSeek( *errloc = EINVAL; return -1; } - if (info->iswr) { - if ((unsigned long) offset > info->nmax) { + if (info->isWriting) { + if ((unsigned long) offset > info->maxWrite) { *errloc = EINVAL; return -1; } - if ((unsigned long) offset > info->nbyte) { - info->nbyte = offset; + if ((unsigned long) offset > info->numBytes) { + info->numBytes = offset; } } else if ((unsigned long) offset > end) { *errloc = EINVAL; return -1; } - info->nread = (unsigned long) offset; - return info->nread; + info->numRead = (unsigned long) offset; + return info->numRead; } /* @@ -3427,30 +3519,6 @@ ZipChannelGetFile( } /* - * The channel type/driver definition used for ZIP archive members. - */ - -static Tcl_ChannelType ZipChannelType = { - "zip", /* Type name. */ - TCL_CHANNEL_VERSION_5, - ZipChannelClose, /* Close channel, clean instance data */ - ZipChannelRead, /* Handle read request */ - ZipChannelWrite, /* Handle write request */ - ZipChannelSeek, /* Move location of access point, NULL'able */ - NULL, /* Set options, NULL'able */ - NULL, /* Get options, NULL'able */ - ZipChannelWatchChannel, /* Initialize notifier */ - ZipChannelGetFile, /* Get OS handle from the channel */ - NULL, /* 2nd version of close channel, NULL'able */ - NULL, /* Set blocking mode for raw channel, NULL'able */ - NULL, /* Function to flush channel, NULL'able */ - NULL, /* Function to handle event, NULL'able */ - NULL, /* Wide seek function, NULL'able */ - NULL, /* Thread action function, NULL'able */ - NULL, /* Truncate function, NULL'able */ -}; - -/* *------------------------------------------------------------------------- * * ZipChannelOpen -- @@ -3481,7 +3549,7 @@ ZipChannelOpen( if ((mode & O_APPEND) || ((ZipFS.wrmax <= 0) && (mode & (O_WRONLY | O_RDWR)))) { - if (interp != NULL) { + if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported open mode", -1)); } @@ -3489,8 +3557,8 @@ ZipChannelOpen( } WriteLock(); z = ZipFSLookup(filename); - if (z == NULL) { - if (interp != NULL) { + if (!z) { + if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "file not found \"%s\"", filename)); } @@ -3498,21 +3566,21 @@ ZipChannelOpen( } trunc = (mode & O_TRUNC) != 0; wr = (mode & (O_WRONLY | O_RDWR)) != 0; - if ((z->cmeth != ZIP_COMPMETH_STORED) - && (z->cmeth != ZIP_COMPMETH_DEFLATED)) { + if ((z->compressMethod != ZIP_COMPMETH_STORED) + && (z->compressMethod != ZIP_COMPMETH_DEFLATED)) { ZIPFS_ERROR(interp, "unsupported compression method"); goto error; } - if (wr && z->isdir) { + if (wr && z->isDirectory) { ZIPFS_ERROR(interp, "unsupported file type"); goto error; } if (!trunc) { flags |= TCL_READABLE; - if (z->isenc && (z->zipfile->passBuf[0] == 0)) { + if (z->isEncrypted && (z->zipFilePtr->passBuf[0] == 0)) { ZIPFS_ERROR(interp, "decryption failed"); goto error; - } else if (wr && (z->data == NULL) && (z->nbyte > ZipFS.wrmax)) { + } else if (wr && !z->data && (z->numBytes > ZipFS.wrmax)) { ZIPFS_ERROR(interp, "file too large"); goto error; } @@ -3520,50 +3588,50 @@ ZipChannelOpen( flags = TCL_WRITABLE; } info = attemptckalloc(sizeof(ZipChannel)); - if (info == NULL) { + if (!info) { ZIPFS_ERROR(interp, "out of memory"); goto error; } - info->zipfile = z->zipfile; - info->zipentry = z; - info->nread = 0; + info->zipFilePtr = z->zipFilePtr; + info->zipEntryPtr = z; + info->numRead = 0; if (wr) { flags |= TCL_WRITABLE; - info->iswr = 1; - info->isdir = 0; - info->nmax = ZipFS.wrmax; + info->isWriting = 1; + info->isDirectory = 0; + info->maxWrite = ZipFS.wrmax; info->iscompr = 0; - info->isenc = 0; - info->ubuf = attemptckalloc(info->nmax); - if (info->ubuf == NULL) { + info->isEncrypted = 0; + info->ubuf = attemptckalloc(info->maxWrite); + if (!info->ubuf) { merror0: - if (info->ubuf != NULL) { + if (info->ubuf) { ckfree(info->ubuf); } ckfree(info); ZIPFS_ERROR(interp, "out of memory"); goto error; } - memset(info->ubuf, 0, info->nmax); + memset(info->ubuf, 0, info->maxWrite); if (trunc) { - info->nbyte = 0; - } else if (z->data != NULL) { - unsigned int j = z->nbyte; + info->numBytes = 0; + } else if (z->data) { + unsigned int j = z->numBytes; - if (j > info->nmax) { - j = info->nmax; + if (j > info->maxWrite) { + j = info->maxWrite; } memcpy(info->ubuf, z->data, j); - info->nbyte = j; + info->numBytes = j; } else { - unsigned char *zbuf = z->zipfile->data + z->offset; + unsigned char *zbuf = z->zipFilePtr->data + z->offset; - if (z->isenc) { - int len = z->zipfile->passBuf[0]; + if (z->isEncrypted) { + int len = z->zipFilePtr->passBuf[0]; char passBuf[260]; for (i = 0; i < len; i++) { - ch = z->zipfile->passBuf[len - i]; + ch = z->zipFilePtr->passBuf[len - i]; passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; } passBuf[i] = '\0'; @@ -3575,7 +3643,7 @@ ZipChannelOpen( } zbuf += i; } - if (z->cmeth == ZIP_COMPMETH_DEFLATED) { + if (z->compressMethod == ZIP_COMPMETH_DEFLATED) { z_stream stream; int err; unsigned char *cbuf = NULL; @@ -3584,13 +3652,13 @@ ZipChannelOpen( stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (z->isenc) { + stream.avail_in = z->numCompressedBytes; + if (z->isEncrypted) { unsigned int j; stream.avail_in -= 12; cbuf = attemptckalloc(stream.avail_in); - if (cbuf == NULL) { + if (!cbuf) { goto merror0; } for (j = 0; j < stream.avail_in; j++) { @@ -3602,7 +3670,7 @@ ZipChannelOpen( stream.next_in = zbuf; } stream.next_out = info->ubuf; - stream.avail_out = info->nmax; + stream.avail_out = info->maxWrite; if (inflateInit2(&stream, -15) != Z_OK) { goto cerror0; } @@ -3610,58 +3678,58 @@ ZipChannelOpen( inflateEnd(&stream); if ((err == Z_STREAM_END) || ((err == Z_OK) && (stream.avail_in == 0))) { - if (cbuf != NULL) { + if (cbuf) { memset(info->keys, 0, sizeof(info->keys)); ckfree(cbuf); } goto wrapchan; } cerror0: - if (cbuf != NULL) { + if (cbuf) { memset(info->keys, 0, sizeof(info->keys)); ckfree(cbuf); } - if (info->ubuf != NULL) { + if (info->ubuf) { ckfree(info->ubuf); } ckfree(info); ZIPFS_ERROR(interp, "decompression error"); goto error; - } else if (z->isenc) { - for (i = 0; i < z->nbyte - 12; i++) { + } else if (z->isEncrypted) { + for (i = 0; i < z->numBytes - 12; i++) { ch = zbuf[i]; info->ubuf[i] = zdecode(info->keys, crc32tab, ch); } } else { - memcpy(info->ubuf, zbuf, z->nbyte); + memcpy(info->ubuf, zbuf, z->numBytes); } memset(info->keys, 0, sizeof(info->keys)); goto wrapchan; } - } else if (z->data != NULL) { + } else if (z->data) { flags |= TCL_READABLE; - info->iswr = 0; + info->isWriting = 0; info->iscompr = 0; - info->isdir = 0; - info->isenc = 0; - info->nbyte = z->nbyte; - info->nmax = 0; + info->isDirectory = 0; + info->isEncrypted = 0; + info->numBytes = z->numBytes; + info->maxWrite = 0; info->ubuf = z->data; } else { flags |= TCL_READABLE; - info->iswr = 0; - info->iscompr = z->cmeth == ZIP_COMPMETH_DEFLATED; - info->ubuf = z->zipfile->data + z->offset; - info->isdir = z->isdir; - info->isenc = z->isenc; - info->nbyte = z->nbyte; - info->nmax = 0; - if (info->isenc) { - int len = z->zipfile->passBuf[0]; + info->isWriting = 0; + info->iscompr = (z->compressMethod == ZIP_COMPMETH_DEFLATED); + info->ubuf = z->zipFilePtr->data + z->offset; + info->isDirectory = z->isDirectory; + info->isEncrypted = z->isEncrypted; + info->numBytes = z->numBytes; + info->maxWrite = 0; + if (info->isEncrypted) { + int len = z->zipFilePtr->passBuf[0]; char passBuf[260]; for (i = 0; i < len; i++) { - ch = z->zipfile->passBuf[len - i]; + ch = z->zipFilePtr->passBuf[len - i]; passBuf[i] = (ch & 0x0f) | pwrot[(ch >> 4) & 0x0f]; } passBuf[i] = '\0'; @@ -3683,11 +3751,11 @@ ZipChannelOpen( stream.zalloc = Z_NULL; stream.zfree = Z_NULL; stream.opaque = Z_NULL; - stream.avail_in = z->nbytecompr; - if (info->isenc) { + stream.avail_in = z->numCompressedBytes; + if (info->isEncrypted) { stream.avail_in -= 12; ubuf = attemptckalloc(stream.avail_in); - if (ubuf == NULL) { + if (!ubuf) { info->ubuf = NULL; goto merror; } @@ -3699,22 +3767,22 @@ ZipChannelOpen( } else { stream.next_in = info->ubuf; } - stream.next_out = info->ubuf = attemptckalloc(info->nbyte); - if (info->ubuf == NULL) { + stream.next_out = info->ubuf = attemptckalloc(info->numBytes); + if (!info->ubuf) { merror: - if (ubuf != NULL) { - info->isenc = 0; + if (ubuf) { + info->isEncrypted = 0; memset(info->keys, 0, sizeof(info->keys)); ckfree(ubuf); } ckfree(info); - if (interp != NULL) { + if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("out of memory", -1)); } goto error; } - stream.avail_out = info->nbyte; + stream.avail_out = info->numBytes; if (inflateInit2(&stream, -15) != Z_OK) { goto cerror; } @@ -3722,20 +3790,20 @@ ZipChannelOpen( inflateEnd(&stream); if ((err == Z_STREAM_END) || ((err == Z_OK) && (stream.avail_in == 0))) { - if (ubuf != NULL) { - info->isenc = 0; + if (ubuf) { + info->isEncrypted = 0; memset(info->keys, 0, sizeof(info->keys)); ckfree(ubuf); } goto wrapchan; } cerror: - if (ubuf != NULL) { - info->isenc = 0; + if (ubuf) { + info->isEncrypted = 0; memset(info->keys, 0, sizeof(info->keys)); ckfree(ubuf); } - if (info->ubuf != NULL) { + if (info->ubuf) { ckfree(info->ubuf); } ckfree(info); @@ -3747,9 +3815,9 @@ ZipChannelOpen( wrapchan: sprintf(cname, "zipfs_%" TCL_LL_MODIFIER "x_%d", z->offset, ZipFS.idCount++); - z->zipfile->numOpen++; + z->zipFilePtr->numOpen++; Unlock(); - return Tcl_CreateChannel(&ZipChannelType, cname, (ClientData) info, flags); + return Tcl_CreateChannel(&ZipChannelType, cname, info, flags); error: Unlock(); @@ -3783,14 +3851,14 @@ ZipEntryStat( ReadLock(); z = ZipFSLookup(path); - if (z != NULL) { + if (z) { memset(buf, 0, sizeof(Tcl_StatBuf)); - if (z->isdir) { + if (z->isDirectory) { buf->st_mode = S_IFDIR | 0555; } else { buf->st_mode = S_IFREG | 0555; } - buf->st_size = z->nbyte; + buf->st_size = z->numBytes; buf->st_mtime = z->timestamp; buf->st_ctime = z->timestamp; buf->st_atime = z->timestamp; @@ -3830,7 +3898,7 @@ ZipEntryAccess( ReadLock(); z = ZipFSLookup(path); Unlock(); - return (z != NULL) ? 0 : -1; + return (z ? 0 : -1); } /* @@ -3988,7 +4056,7 @@ ZipFSMatchInDirectoryProc( if (!normPathPtr) { return -1; } - if (types != NULL) { + if (types) { dirOnly = (types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR; } @@ -4013,30 +4081,30 @@ ZipFSMatchInDirectoryProc( } else { strip = len + 1; } - if (prefix != NULL) { + if (prefix) { Tcl_DStringAppend(&dsPref, "/", 1); prefixLen++; prefix = Tcl_DStringValue(&dsPref); } ReadLock(); - if ((types != NULL) && (types->type == TCL_GLOB_TYPE_MOUNT)) { + if (types && (types->type == TCL_GLOB_TYPE_MOUNT)) { l = CountSlashes(path); if (path[len - 1] == '/') { len--; } else { l++; } - if ((pattern == NULL) || (pattern[0] == '\0')) { + if (!pattern || (pattern[0] == '\0')) { pattern = "*"; } - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { ZipFile *zf = Tcl_GetHashValue(hPtr); if (zf->mountPointLen == 0) { ZipEntry *z; - for (z = zf->topEnts; z != NULL; z = z->tnext) { + for (z = zf->topEnts; z; z = z->tnext) { size_t lenz = strlen(z->name); if ((lenz > len + 1) && (strncmp(z->name, path, len) == 0) @@ -4044,7 +4112,7 @@ ZipFSMatchInDirectoryProc( && (CountSlashes(z->name) == l) && Tcl_StringCaseMatch(z->name + len + 1, pattern, 0)) { - if (prefix != NULL) { + if (prefix) { Tcl_DStringAppend(&dsPref, z->name, lenz); Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(Tcl_DStringValue(&dsPref), @@ -4062,7 +4130,7 @@ ZipFSMatchInDirectoryProc( && (CountSlashes(zf->mountPoint) == l) && Tcl_StringCaseMatch(zf->mountPoint + len + 1, pattern, 0)) { - if (prefix != NULL) { + if (prefix) { Tcl_DStringAppend(&dsPref, zf->mountPoint, zf->mountPointLen); Tcl_ListObjAppendElement(NULL, result, @@ -4075,19 +4143,18 @@ ZipFSMatchInDirectoryProc( zf->mountPointLen)); } } - hPtr = Tcl_NextHashEntry(&search); } goto end; } - if ((pattern == NULL) || (pattern[0] == '\0')) { + if (!pattern || (pattern[0] == '\0')) { hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); - if (hPtr != NULL) { + if (hPtr) { ZipEntry *z = Tcl_GetHashValue(hPtr); - if ((dirOnly < 0) || (!dirOnly && !z->isdir) - || (dirOnly && z->isdir)) { - if (prefix != NULL) { + if ((dirOnly < 0) || (!dirOnly && !z->isDirectory) + || (dirOnly && z->isDirectory)) { + if (prefix) { Tcl_DStringAppend(&dsPref, z->name, -1); Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(Tcl_DStringValue(&dsPref), @@ -4115,15 +4182,15 @@ ZipFSMatchInDirectoryProc( memcpy(pat + len, pattern, l + 1); scnt = CountSlashes(pat); for (hPtr = Tcl_FirstHashEntry(&ZipFS.fileHash, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + hPtr; hPtr = Tcl_NextHashEntry(&search)) { ZipEntry *z = Tcl_GetHashValue(hPtr); - if ((dirOnly >= 0) && ((dirOnly && !z->isdir) - || (!dirOnly && z->isdir))) { + if ((dirOnly >= 0) && ((dirOnly && !z->isDirectory) + || (!dirOnly && z->isDirectory))) { continue; } if ((z->depth == scnt) && Tcl_StringCaseMatch(z->name, pat, 0)) { - if (prefix != NULL) { + if (prefix) { Tcl_DStringAppend(&dsPref, z->name + strip, -1); Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj(Tcl_DStringValue(&dsPref), @@ -4167,7 +4234,6 @@ ZipFSPathInFilesystemProc( { Tcl_HashEntry *hPtr; Tcl_HashSearch search; - ZipFile *zf; int ret = -1; size_t len; char *path; @@ -4186,14 +4252,15 @@ ZipFSPathInFilesystemProc( ReadLock(); hPtr = Tcl_FindHashEntry(&ZipFS.fileHash, path); - if (hPtr != NULL) { + if (hPtr) { ret = TCL_OK; goto endloop; } - hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); - while (hPtr != NULL) { - zf = Tcl_GetHashValue(hPtr); + for (hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); hPtr; + hPtr = Tcl_NextHashEntry(&search)) { + ZipFile *zf = Tcl_GetHashValue(hPtr); + if (zf->mountPointLen == 0) { ZipEntry *z; @@ -4208,9 +4275,8 @@ ZipFSPathInFilesystemProc( } else if ((len >= zf->mountPointLen) && (strncmp(path, zf->mountPoint, zf->mountPointLen) == 0)) { ret = TCL_OK; - goto endloop; + break; } - hPtr = Tcl_NextHashEntry(&search); } endloop: @@ -4313,27 +4379,27 @@ ZipFSFileAttrsGetProc( path = Tcl_GetStringFromObj(pathPtr, &len); ReadLock(); z = ZipFSLookup(path); - if (z == NULL) { + if (!z) { ZIPFS_ERROR(interp, "file not found"); ret = TCL_ERROR; goto done; } switch (index) { case 0: - *objPtrRef = Tcl_NewWideIntObj(z->nbyte); + *objPtrRef = Tcl_NewWideIntObj(z->numBytes); break; case 1: - *objPtrRef = Tcl_NewWideIntObj(z->nbytecompr); + *objPtrRef = Tcl_NewWideIntObj(z->numCompressedBytes); break; case 2: *objPtrRef = Tcl_NewWideIntObj(z->offset); break; case 3: - *objPtrRef = Tcl_NewStringObj(z->zipfile->mountPoint, - z->zipfile->mountPointLen); + *objPtrRef = Tcl_NewStringObj(z->zipFilePtr->mountPoint, + z->zipFilePtr->mountPointLen); break; case 4: - *objPtrRef = Tcl_NewStringObj(z->zipfile->name, -1); + *objPtrRef = Tcl_NewStringObj(z->zipFilePtr->name, -1); break; case 5: *objPtrRef = Tcl_NewStringObj("0555", -1); @@ -4372,7 +4438,7 @@ ZipFSFileAttrsSetProc( Tcl_Obj *pathPtr, Tcl_Obj *objPtr) { - if (interp != NULL) { + if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj("unsupported operation", -1)); } return TCL_ERROR; @@ -4434,7 +4500,7 @@ ZipFSLoadFile( */ loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; - if (loadFileProc != NULL) { + if (loadFileProc) { return loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } Tcl_SetErrno(ENOENT); @@ -4456,7 +4522,7 @@ ZipFSLoadFile( } objs[1] = TclPathPart(interp, path, TCL_PATH_DIRNAME); - if ((objs[1] != NULL) && (ZipFSAccessProc(objs[1], R_OK) == 0)) { + if (objs[1] && (ZipFSAccessProc(objs[1], R_OK) == 0)) { const char *execName = Tcl_GetNameOfExecutable(); /* @@ -4473,7 +4539,7 @@ ZipFSLoadFile( * nameofexecutable] due to VFS effects. */ - if (execName != NULL) { + if (execName) { const char *p = strrchr(execName, '/'); if (p > execName + 1) { @@ -4481,13 +4547,13 @@ ZipFSLoadFile( objs[0] = Tcl_NewStringObj(execName, p - execName); } } - if (objs[0] == NULL) { + if (!objs[0]) { objs[0] = TclPathPart(interp, TclGetObjNameOfExecutable(), TCL_PATH_DIRNAME); } - if (objs[0] != NULL) { + if (objs[0]) { altPath = TclJoinPath(2, objs); - if (altPath != NULL) { + if (altPath) { Tcl_IncrRefCount(altPath); if (Tcl_FSAccess(altPath, R_OK) == 0) { path = altPath; @@ -4495,21 +4561,21 @@ ZipFSLoadFile( } } } - if (objs[0] != NULL) { + if (objs[0]) { Tcl_DecrRefCount(objs[0]); } - if (objs[1] != NULL) { + if (objs[1]) { Tcl_DecrRefCount(objs[1]); } loadFileProc = (Tcl_FSLoadFileProc2 *) tclNativeFilesystem.loadFileProc; - if (loadFileProc != NULL) { + if (loadFileProc) { ret = loadFileProc(interp, path, loadHandle, unloadProcPtr, flags); } else { Tcl_SetErrno(ENOENT); ZIPFS_ERROR(interp, Tcl_PosixError(interp)); } - if (altPath != NULL) { + if (altPath) { Tcl_DecrRefCount(altPath); } return ret; @@ -4584,11 +4650,11 @@ TclZipfs_Init( WriteLock(); /* Tcl_StaticPackage(interp, "zipfs", TclZipfs_Init, TclZipfs_Init); */ if (!ZipFS.initialized) { - TclZipfs_C_Init(); + ZipfsSetup(); } Unlock(); - if (interp != NULL) { + if (interp) { Tcl_EvalEx(interp, findproc, -1, TCL_EVAL_GLOBAL); Tcl_LinkVar(interp, "::tcl::zipfs::wrmax", (char *) &ZipFS.wrmax, TCL_LINK_INT); @@ -4607,7 +4673,7 @@ static int ZipfsAppHookFindTclInit( const char *archive) { - Tcl_Obj *vfsinitscript; + Tcl_Obj *vfsInitScript; int found; if (zipfs_literal_tcl_library) { @@ -4618,20 +4684,20 @@ ZipfsAppHookFindTclInit( return TCL_ERROR; } - vfsinitscript = Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/init.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - found = Tcl_FSAccess(vfsinitscript, F_OK); - Tcl_DecrRefCount(vfsinitscript); + TclNewLiteralStringObj(vfsInitScript, ZIPFS_ZIP_MOUNT "/init.tcl"); + Tcl_IncrRefCount(vfsInitScript); + found = Tcl_FSAccess(vfsInitScript, F_OK); + Tcl_DecrRefCount(vfsInitScript); if (found == 0) { zipfs_literal_tcl_library = ZIPFS_ZIP_MOUNT; return TCL_OK; } - vfsinitscript = Tcl_NewStringObj( - ZIPFS_ZIP_MOUNT "/tcl_library/init.tcl", -1); - Tcl_IncrRefCount(vfsinitscript); - found = Tcl_FSAccess(vfsinitscript, F_OK); - Tcl_DecrRefCount(vfsinitscript); + TclNewLiteralStringObj(vfsInitScript, + ZIPFS_ZIP_MOUNT "/tcl_library/init.tcl"); + Tcl_IncrRefCount(vfsInitScript); + found = Tcl_FSAccess(vfsInitScript, F_OK); + Tcl_DecrRefCount(vfsInitScript); if (found == 0) { zipfs_literal_tcl_library = ZIPFS_ZIP_MOUNT "/tcl_library"; return TCL_OK; @@ -4678,7 +4744,7 @@ TclZipfs_AppHook( int found; Tcl_Obj *vfsInitScript; - vfsInitScript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); + TclNewLiteralStringObj(vfsInitScript, ZIPFS_APP_MOUNT "/main.tcl"); Tcl_IncrRefCount(vfsInitScript); if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { /* @@ -4695,8 +4761,8 @@ TclZipfs_AppHook( */ if (!zipfs_literal_tcl_library) { - vfsInitScript = Tcl_NewStringObj( - ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); + TclNewLiteralStringObj(vfsInitScript, + ZIPFS_APP_MOUNT "/tcl_library/init.tcl"); Tcl_IncrRefCount(vfsInitScript); found = Tcl_FSAccess(vfsInitScript, F_OK); Tcl_DecrRefCount(vfsInitScript); @@ -4726,8 +4792,8 @@ TclZipfs_AppHook( */ TclZipfs_TclLibrary(); - vfsInitScript = Tcl_NewStringObj( - ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl", -1); + TclNewLiteralStringObj(vfsInitScript, + ZIPFS_ZIP_MOUNT "/tcl_library/install.tcl"); Tcl_IncrRefCount(vfsInitScript); if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { Tcl_SetStartupScript(vfsInitScript, NULL); @@ -4737,7 +4803,7 @@ TclZipfs_AppHook( int found; Tcl_Obj *vfsInitScript; - vfsInitScript = Tcl_NewStringObj(ZIPFS_APP_MOUNT "/main.tcl", -1); + TclNewLiteralStringObj(vfsInitScript, ZIPFS_APP_MOUNT "/main.tcl"); Tcl_IncrRefCount(vfsInitScript); if (Tcl_FSAccess(vfsInitScript, F_OK) == 0) { /* @@ -4749,8 +4815,8 @@ TclZipfs_AppHook( Tcl_DecrRefCount(vfsInitScript); } /* Set Tcl Encodings */ - vfsInitScript = Tcl_NewStringObj( - ZIPFS_APP_MOUNT "/tcl_library/init.tcl", -1); + TclNewLiteralStringObj(vfsInitScript, + ZIPFS_APP_MOUNT "/tcl_library/init.tcl"); Tcl_IncrRefCount(vfsInitScript); found = Tcl_FSAccess(vfsInitScript, F_OK); Tcl_DecrRefCount(vfsInitScript); @@ -4772,7 +4838,7 @@ TclZipfs_AppHook( /* *------------------------------------------------------------------------- * - * TclZipfs_Mount, TclZipfs_Unmount -- + * TclZipfs_Mount, TclZipfs_MountBuffer, TclZipfs_Unmount -- * * Dummy version when no ZLIB support available. * @@ -4787,7 +4853,20 @@ TclZipfs_Mount( const char *passwd) /* Password for opening the ZIP, or NULL if * the ZIP is unprotected. */ { - return TclZipfs_Init(interp, 1); + ZIPFS_ERROR(interp, "no zlib available"); + return TCL_ERROR; +} + +int +TclZipfs_MountBuffer( + Tcl_Interp *interp, /* Current interpreter. NULLable. */ + const char *mountPoint, /* Mount point path. */ + unsigned char *data, + size_t datalen, + int copy) +{ + ZIPFS_ERROR(interp, "no zlib available"); + return TCL_ERROR; } int @@ -4795,7 +4874,8 @@ TclZipfs_Unmount( Tcl_Interp *interp, /* Current interpreter. */ const char *mountPoint) /* Mount point path. */ { - return TclZipfs_Init(interp, 1); + ZIPFS_ERROR(interp, "no zlib available"); + return TCL_ERROR; } #endif /* !HAVE_ZLIB */ diff --git a/tests/zipfs.test b/tests/zipfs.test index 1a5225c..9d60f8d 100644 --- a/tests/zipfs.test +++ b/tests/zipfs.test @@ -15,7 +15,10 @@ if {"::tcltest" ni [namespace children]} { namespace import -force ::tcltest::* } -testConstraint zipfs [expr {[llength [info commands zlib]] && [regexp tcltest [info nameofexecutable]]}] +testConstraint zipfs [expr { + [llength [info commands zlib]] && [regexp tcltest [info nameofexecutable]] +}] +testConstraint zipfslib 1 # Removed in tip430 - zipfs is no longer a static package #test zipfs-0.0 {zipfs basics} -constraints zipfs -body { @@ -27,10 +30,9 @@ set CWD [pwd] set tmpdir [file join $CWD tmp] file mkdir $tmpdir -test zipfs-0.1 {zipfs basics} -constraints zipfs -body { +test zipfs-0.0 {zipfs basics} -constraints zipfs -body { package require zipfs } -result {2.0} - test zipfs-0.1 {zipfs basics} -constraints zipfs -body { expr {${ziproot} in [file volumes]} } -result 1 @@ -43,114 +45,95 @@ if {![string match ${ziproot}* $tcl_library]} { # archive ### set tclzip [file join $CWD [::tcl::pkgconfig get zipfile,runtime]] - if {[file exists $tclzip]} { + testConstraint zipfslib [file exists $tclzip] + if {[testConstraint zipfslib]} { zipfs mount /lib/tcl $tclzip set ::tcl_library ${ziproot}lib/tcl/tcl_library - } else { - tcltest::skip zipfs-0.* } } -test zipfs-0.2 {zipfs basics} -constraints zipfs -body { +test zipfs-0.2 {zipfs basics} -constraints zipfslib -body { string match ${ziproot}* $tcl_library } -result 1 - -test zipfs-0.3 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.3 {zipfs basics: glob} -constraints zipfslib -setup { set pwd [pwd] +} -body { cd $tcl_library lsort [glob -dir . http*] } -cleanup { cd $pwd } -result {./http} - -test zipfs-0.4 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.4 {zipfs basics: glob} -constraints zipfslib -setup { set pwd [pwd] +} -body { cd $tcl_library lsort [glob -dir [pwd] http*] } -cleanup { cd $pwd } -result [list $tcl_library/http] - -test zipfs-0.5 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.5 {zipfs basics: glob} -constraints zipfslib -body { lsort [glob -dir $tcl_library http*] } -result [list $tcl_library/http] - -test zipfs-0.6 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.6 {zipfs basics: glob} -constraints zipfslib -body { lsort [glob $tcl_library/http*] } -result [list $tcl_library/http] - -test zipfs-0.7 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.7 {zipfs basics: glob} -constraints zipfslib -body { lsort [glob -tails -dir $tcl_library http*] } -result {http} - -test zipfs-0.8 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.8 {zipfs basics: glob} -constraints zipfslib -body { lsort [glob -nocomplain -tails -types d -dir $tcl_library http*] } -result {http} - -test zipfs-0.9 {zipfs basics: glob} -constraints zipfs -body { +test zipfs-0.9 {zipfs basics: glob} -constraints zipfslib -body { lsort [glob -nocomplain -tails -types f -dir $tcl_library http*] } -result {} - -test zipfs-0.10 {zipfs basics: join} -constraints zipfs -body { +test zipfs-0.10 {zipfs basics: join} -constraints {zipfs zipfslib} -body { file join [zipfs root] bar baz } -result "[zipfs root]bar/baz" - -test zipfs-0.11 {zipfs basics: join} -constraints zipfs -body { +test zipfs-0.11 {zipfs basics: join} -constraints {zipfs zipfslib} -body { file normalize [zipfs root] } -result "[zipfs root]" - -test zipfs-0.12 {zipfs basics: join} -constraints zipfs -body { +test zipfs-0.12 {zipfs basics: join} -constraints {zipfs zipfslib} -body { file normalize [zipfs root]//bar/baz//qux/../ } -result "[zipfs root]bar/baz" test zipfs-1.3 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mount a b c d e f } -result {wrong # args: should be "zipfs mount ?mountpoint? ?zipfile? ?password?"} - test zipfs-1.4 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs unmount a b c d e f } -result {wrong # args: should be "zipfs unmount zipfile"} - test zipfs-1.5 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mkkey a b c d e f } -result {wrong # args: should be "zipfs mkkey password"} - test zipfs-1.6 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mkimg a b c d e f } -result {wrong # args: should be "zipfs mkimg outfile indir ?strip? ?password? ?infile?"} - test zipfs-1.7 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs mkzip a b c d e f } -result {wrong # args: should be "zipfs mkzip outfile indir ?strip? ?password?"} - test zipfs-1.8 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs exists a b c d e f } -result {wrong # args: should be "zipfs exists filename"} - test zipfs-1.9 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs info a b c d e f } -result {wrong # args: should be "zipfs info filename"} - test zipfs-1.10 {zipfs errors} -constraints zipfs -returnCodes error -body { zipfs list a b c d e f } -result {wrong # args: should be "zipfs list ?(-glob|-regexp)? ?pattern?"} file mkdir tmp - test zipfs-2.1 {zipfs mkzip empty archive} -constraints zipfs -returnCodes error -body { zipfs mkzip [file join $tmpdir empty.zip] $tcl_library/xxxx } -result {empty archive} - ### -# The 2.2 series of tests operate within -# a zipfile created a temporary directory +# The next series of tests operate within a zipfile created a temporary +# directory. ### set zipfile [file join $tmpdir abc.zip] if {[file exists $zipfile]} { file delete $zipfile } - -test zipfs-2.2.0 {zipfs mkzip} -constraints zipfs -body { +test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body { cd $tcl_library/encoding zipfs mkzip $zipfile . zipfs mount ${ziproot}abc $zipfile @@ -158,17 +141,12 @@ test zipfs-2.2.0 {zipfs mkzip} -constraints zipfs -body { } -cleanup { cd $CWD } -result "[zipfs root]abc/cp850.enc" - -if {![zipfs exists /abc/cp850.enc]} { - skip [concat [skip] zipfs-2.2.*] -} - -test zipfs-2.2.1 {zipfs info} -constraints zipfs -body { +testConstraint zipfsenc [zipfs exists /abc/cp850.enc] +test zipfs-2.3 {zipfs info} -constraints {zipfs zipfsenc} -body { set r [zipfs info ${ziproot}abc/cp850.enc] lrange $r 0 2 } -result [list $zipfile 1090 527] ;# NOTE: Only the first 3 results are stable - -test zipfs-2.2.3 {zipfs data} -constraints zipfs -body { +test zipfs-2.4 {zipfs data} -constraints {zipfs zipfsenc} -body { set zipfd [open ${ziproot}/abc/cp850.enc] ;# FIXME: leave open - see later test read $zipfd } -result {# Encoding file: cp850, single-byte @@ -192,48 +170,38 @@ S 00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4 00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0 } ;# FIXME: result depends on content of encodings dir - -test zipfs-2.2.4 {zipfs exists} -constraints zipfs -body { +test zipfs-2.5 {zipfs exists} -constraints {zipfs zipfsenc} -body { zipfs exists /abc/cp850.enc } -result 1 - -test zipfs-2.2.5 {zipfs unmount while busy} -constraints zipfs -body { +test zipfs-2.6 {zipfs unmount while busy} -constraints {zipfs zipfsenc} -body { zipfs unmount /abc } -returnCodes error -result {filesystem is busy} - -test zipfs-2.2.6 {zipfs unmount} -constraints zipfs -body { +test zipfs-2.7 {zipfs unmount} -constraints {zipfs zipfsenc} -body { close $zipfd zipfs unmount /abc zipfs exists /abc/cp850.enc } -result 0 - - ### # Repeat the tests for a buffer mounted archive ### -test zipfs-2.3.0 {zipfs mkzip} -constraints zipfs -body { - cd $tcl_library/encoding - zipfs mkzip $zipfile . - set fin [open $zipfile r] - fconfigure $fin -translation binary - set dat [read $fin] - close $fin - zipfs mount_data def $dat +test zipfs-2.8 {zipfs mkzip} -constraints zipfs -body { + cd $tcl_library/encoding + zipfs mkzip $zipfile . + set fin [open $zipfile r] + fconfigure $fin -translation binary + set dat [read $fin] + close $fin + zipfs mount_data def $dat zipfs list -glob ${ziproot}def/cp850.* } -cleanup { cd $CWD } -result "[zipfs root]def/cp850.enc" - -if {![zipfs exists /def/cp850.enc]} { - skip [concat [skip] zipfs-2.3.*] -} - -test zipfs-2.3.1 {zipfs info} -constraints zipfs -body { +testConstraint zipfsencbuf [zipfs exists /def/cp850.enc] +test zipfs-2.9 {zipfs info} -constraints {zipfs zipfsencbuf} -body { set r [zipfs info ${ziproot}def/cp850.enc] lrange $r 0 2 } -result [list {Memory Buffer} 1090 527] ;# NOTE: Only the first 3 results are stable - -test zipfs-2.3.3 {zipfs data} -constraints zipfs -body { +test zipfs-2.10 {zipfs data} -constraints {zipfs zipfsencbuf} -body { set zipfd [open ${ziproot}/def/cp850.enc] ;# FIXME: leave open - see later test read $zipfd } -result {# Encoding file: cp850, single-byte @@ -257,16 +225,13 @@ S 00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4 00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0 } ;# FIXME: result depends on content of encodings dir - -test zipfs-2.3.4 {zipfs exists} -constraints zipfs -body { +test zipfs-2.11 {zipfs exists} -constraints {zipfs zipfsencbuf} -body { zipfs exists /def/cp850.enc } -result 1 - -test zipfs-2.3.5 {zipfs unmount while busy} -constraints zipfs -body { +test zipfs-2.12 {zipfs unmount while busy} -constraints {zipfs zipfsencbuf} -body { zipfs unmount /def } -returnCodes error -result {filesystem is busy} - -test zipfs-2.3.6 {zipfs unmount} -constraints zipfs -body { +test zipfs-2.13 {zipfs unmount} -constraints {zipfs zipfsencbuf} -body { close $zipfd zipfs unmount /def zipfs exists /def/cp850.enc -- cgit v0.12 From ac711bcf45a5b5bd09e3102e5ea08f726237212f Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sat, 6 Oct 2018 17:12:46 +0000 Subject: protect Tcl_WinUtfToTChar/Tcl_WinTCharToUtf against NULL input values: return empty string in that case. Add TIP #494-compatible definitions of TCL_IO_FAILURE/TCL_AUTO_LENGTH, and use it in some appropriate places. --- generic/tcl.h | 9 ++++++++- generic/tclIOCmd.c | 2 +- generic/tclIOUtil.c | 8 ++++---- generic/tclZipfs.c | 6 +++--- generic/tclZlib.c | 6 +++--- win/tclWin32Dll.c | 8 +++++++- 6 files changed, 26 insertions(+), 13 deletions(-) diff --git a/generic/tcl.h b/generic/tcl.h index 2ced16b..0971066 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -224,7 +224,7 @@ extern "C" { * to be included in a shared library, then it should have the DLLEXPORT * storage class. If is being declared for use by a module that is going to * link against the shared library, then it should have the DLLIMPORT storage - * class. If the symbol is beind declared for a static build or for use from a + * class. If the symbol is being declared for a static build or for use from a * stub library, then the storage class should be empty. * * The convention is that a macro called BUILD_xxxx, where xxxx is the name of @@ -2334,6 +2334,13 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp, #define TCL_TCPSERVER_REUSEPORT (1<<1) /* + * Constants for special int-typed values, see TIP #494 + */ + +#define TCL_IO_FAILURE (-1) +#define TCL_AUTO_LENGTH (-1) + +/* *---------------------------------------------------------------------------- * Single public declaration for NRE. */ diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index d38240a..1dd8666 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -991,7 +991,7 @@ Tcl_ExecObjCmd( resultPtr = Tcl_NewObj(); if (Tcl_GetChannelHandle(chan, TCL_READABLE, NULL) == TCL_OK) { - if (Tcl_ReadChars(chan, resultPtr, -1, 0) < 0) { + if (Tcl_ReadChars(chan, resultPtr, -1, 0) == TCL_IO_FAILURE) { /* * TIP #219. * Capture error messages put by the driver into the bypass area diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 11cc22d..63d16be 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -1807,7 +1807,7 @@ Tcl_FSEvalFileEx( * be handled especially. */ - if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) { + if (Tcl_ReadChars(chan, objPtr, 1, 0) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", @@ -1822,7 +1822,7 @@ Tcl_FSEvalFileEx( */ if (Tcl_ReadChars(chan, objPtr, -1, - memcmp(string, "\xef\xbb\xbf", 3)) < 0) { + memcmp(string, "\xef\xbb\xbf", 3)) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", @@ -1942,7 +1942,7 @@ TclNREvalFile( * be handled especially. */ - if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) { + if (Tcl_ReadChars(chan, objPtr, 1, 0) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", @@ -1958,7 +1958,7 @@ TclNREvalFile( */ if (Tcl_ReadChars(chan, objPtr, -1, - memcmp(string, "\xef\xbb\xbf", 3)) < 0) { + memcmp(string, "\xef\xbb\xbf", 3)) == TCL_IO_FAILURE) { Tcl_Close(interp, chan); Tcl_SetObjResult(interp, Tcl_ObjPrintf( "couldn't read file \"%s\": %s", diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c index b609779..5342fb1 100644 --- a/generic/tclZipfs.c +++ b/generic/tclZipfs.c @@ -4726,9 +4726,6 @@ TclZipfs_AppHook( #endif /* _WIN32 */ ***argvPtr) /* Pointer to argv */ { -#ifdef _WIN32 - Tcl_DString ds; -#endif /* _WIN32 */ char *archive; Tcl_FindExecutable((*argvPtr)[0]); @@ -4773,6 +4770,9 @@ TclZipfs_AppHook( } #ifdef SUPPORT_BUILTIN_ZIP_INSTALL } else if (*argcPtr > 1) { +#ifdef _WIN32 + Tcl_DString ds; +#endif /* _WIN32 */ /* * If the first argument is "install", run the supplied installer * script. diff --git a/generic/tclZlib.c b/generic/tclZlib.c index 644ac8b..9bad36d 100644 --- a/generic/tclZlib.c +++ b/generic/tclZlib.c @@ -2931,7 +2931,7 @@ ZlibTransformClose( result = TCL_ERROR; break; } - if (written && Tcl_WriteRaw(cd->parent, cd->outBuffer, written) < 0) { + if (written && Tcl_WriteRaw(cd->parent, cd->outBuffer, written) == TCL_IO_FAILURE) { /* TODO: is this the right way to do errors on close? * Note: when close is called from FinalizeIOSubsystem then * interp may be NULL */ @@ -3130,7 +3130,7 @@ ZlibTransformOutput( break; } - if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) { + if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) == TCL_IO_FAILURE) { *errorCodePtr = Tcl_GetErrno(); return -1; } @@ -3186,7 +3186,7 @@ ZlibTransformFlush( * Write the bytes we've received to the next layer. */ - if (len > 0 && Tcl_WriteRaw(cd->parent, cd->outBuffer, len) < 0) { + if (len > 0 && Tcl_WriteRaw(cd->parent, cd->outBuffer, len) == TCL_IO_FAILURE) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "problem flushing channel: %s", Tcl_PosixError(interp))); diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index 1a33514..04d27dd 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -472,6 +472,9 @@ Tcl_WinUtfToTChar( * converted string is stored. */ { Tcl_DStringInit(dsPtr); + if (!string) { + return (TCHAR *)Tcl_DStringValue(dsPtr); + } return Tcl_UtfToUniCharDString(string, len, dsPtr); } @@ -483,12 +486,15 @@ Tcl_WinTCharToUtf( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { + Tcl_DStringInit(dsPtr); + if (!string) { + return Tcl_DStringValue(dsPtr); + } if (len > 0) { len /= 2; } else if (len < 0) { len = wcslen(string); } - Tcl_DStringInit(dsPtr); return Tcl_UniCharToUtfDString(string, len, dsPtr); } -- cgit v0.12