From c3c71b5f3cddf06ba73dd3c2db7c72831db606c9 Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 5 Oct 2018 17:20:40 +0000 Subject: Post-TIP 505 editing of [lreplace] documentation. --- doc/lreplace.n | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/doc/lreplace.n b/doc/lreplace.n index 35a9130..32b7356 100644 --- a/doc/lreplace.n +++ b/doc/lreplace.n @@ -17,7 +17,7 @@ lreplace \- Replace elements in a list with new elements .BE .SH DESCRIPTION .PP -\fBlreplace\fR returns a new list formed by replacing one or more elements of +\fBlreplace\fR returns a new list formed by replacing zero or more elements of \fIlist\fR with the \fIelement\fR arguments. \fIfirst\fR and \fIlast\fR are index values specifying the first and last elements of the range to replace. @@ -27,36 +27,26 @@ supporting simple index arithmetic and indices relative to the end of the list. 0 refers to the first element of the list, and \fBend\fR refers to the last element of the list. -If \fIlist\fR is empty, then \fIfirst\fR and \fIlast\fR are ignored. .PP -If \fIfirst\fR is less than zero, it is considered to refer to before the -first element of the list. +If either \fIfirst\fR or \fIlast\fR is less than zero, it is considered +to refer to before the first element of the list. This allows \fBlreplace\fR +to prepend elements to \fIlist\fR. .VS TIP505 -If \fIfirst\fR indicates a position greater than the index of the last element -of the list, it is treated as if it is an index one greater than the last -element. This allows this command to append elements to the list. +If either \fIfirst\fR or \fIlast\fR indicates a position greater than the +index of the last element of the list, it is treated as if it is an +index one greater than the last element. This allows \fBlreplace\fR to +append elements to \fIlist\fR. .VE TIP505 -For non-empty lists, the element indicated -by \fIfirst\fR must exist, or \fIfirst\fR must indicate before the -start of the list. .PP If \fIlast\fR is less than \fIfirst\fR, then any specified elements -will be inserted into the list before the point specified by \fIfirst\fR +will be inserted into the list before the element specified by \fIfirst\fR with no elements being deleted. -.VS TIP505 -If \fIlast\fR is greater than the index of the last item of the list, it is -treated as if it is an index one greater than the last element. This means -that if it is also greater than than \fIfirst\fR, all elements from -\fIfirst\fR to the end of the list will be replaced, and otherwise the -elements will be appended. -.VE TIP505 .PP -The \fIelement\fR arguments specify zero or more new arguments to +The \fIelement\fR arguments specify zero or more new elements to be added to the list in place of those that were deleted. Each \fIelement\fR argument will become a separate element of the list. If no \fIelement\fR arguments are specified, then the elements -between \fIfirst\fR and \fIlast\fR are simply deleted. If \fIlist\fR -is empty, any \fIelement\fR arguments are added to the end of the list. +between \fIfirst\fR and \fIlast\fR are simply deleted. .SH EXAMPLES .PP Replacing an element of a list with another: @@ -93,7 +83,7 @@ proc lremove {listVariable value} { .CE .PP .VS TIP505 -Adding elements to the end of the list; note that \fBend+2\fR will initially +Appending elements to the list; note that \fBend+2\fR will initially be treated as if it is \fB6\fR here, but both that and \fB12345\fR are greater than the index of the final item so they behave identically: .PP -- cgit v0.12 From 85aac3aef7c9fa70dc07467858439a6d6f533ac0 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 5 Oct 2018 19:37:38 +0000 Subject: Fix wrong usage of Tcl_WinTCharToUtf() contract: nativePath should never be NULL, but actually it can be. --- win/tclWinFCmd.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c index 52ea8c6..2f28154 100644 --- a/win/tclWinFCmd.c +++ b/win/tclWinFCmd.c @@ -1026,7 +1026,8 @@ DoRemoveJustDirectory( if (nativePath == NULL || nativePath[0] == '\0') { Tcl_SetErrno(ENOENT); - goto end; + Tcl_DStringInit(errorPtr); + return TCL_ERROR; } attr = GetFileAttributes(nativePath); @@ -1108,9 +1109,7 @@ DoRemoveJustDirectory( end: if (errorPtr != NULL) { - char *p; - Tcl_WinTCharToUtf(nativePath, -1, errorPtr); - p = Tcl_DStringValue(errorPtr); + char *p = Tcl_WinTCharToUtf(nativePath, -1, errorPtr); for (; *p; ++p) { if (*p == '\\') *p = '/'; } -- cgit v0.12 From 8985ee2114ddeb7e65148843f592f3270053e269 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 5 Oct 2018 20:54:59 +0000 Subject: Better implementations of Tcl_WinTCharToUtf() and Tcl_WinUtfToTChar(). They don't make any assumption on whether encodings are initialized, or specific win32 handling of special characters. --- generic/tclStubInit.c | 49 ++++++++--------------------------------------- win/tclWin32Dll.c | 53 ++++----------------------------------------------- 2 files changed, 12 insertions(+), 90 deletions(-) diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index b28d501..50bb4a2 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -12,6 +12,10 @@ #include "tclInt.h" #include "tommath.h" +#ifdef __CYGWIN__ +# include +#endif + #ifdef __GNUC__ #pragma GCC dependency "tcl.decls" #pragma GCC dependency "tclInt.decls" @@ -106,10 +110,6 @@ static unsigned short TclWinNToHS(unsigned short ns) { # define TclWinFlushDirtyChannels doNothing # define TclWinResetInterfaces doNothing -#if TCL_UTF_MAX < 4 -static Tcl_Encoding winTCharEncoding; -#endif - static int TclpIsAtty(int fd) { @@ -188,25 +188,8 @@ Tcl_WinUtfToTChar( int len, Tcl_DString *dsPtr) { -#if TCL_UTF_MAX > 3 - WCHAR *wp; - int size = MultiByteToWideChar(CP_UTF8, 0, string, len, 0, 0); - Tcl_DStringInit(dsPtr); - Tcl_DStringSetLength(dsPtr, 2*size+2); - wp = (WCHAR *)Tcl_DStringValue(dsPtr); - MultiByteToWideChar(CP_UTF8, 0, string, len, wp, size+1); - if (len == -1) --size; /* account for 0-byte at string end */ - Tcl_DStringSetLength(dsPtr, 2*size); - wp[size] = 0; - return (char *)wp; -#else - if (!winTCharEncoding) { - winTCharEncoding = Tcl_GetEncoding(0, "unicode"); - } - return Tcl_UtfToExternalDString(winTCharEncoding, - string, len, dsPtr); -#endif + return (char *)Tcl_UtfToUniCharDString(string, len, dsPtr); } char * @@ -215,29 +198,13 @@ Tcl_WinTCharToUtf( int len, Tcl_DString *dsPtr) { -#if TCL_UTF_MAX > 3 - char *p; - int size; - if (len > 0) { len /= 2; + } else if (len == -1) { + len = wcslen((wchar_t *)string); } - size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL); Tcl_DStringInit(dsPtr); - Tcl_DStringSetLength(dsPtr, size+1); - p = (char *)Tcl_DStringValue(dsPtr); - WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL); - if (len == -1) --size; /* account for 0-byte at string end */ - Tcl_DStringSetLength(dsPtr, size); - p[size] = 0; - return p; -#else - if (!winTCharEncoding) { - winTCharEncoding = Tcl_GetEncoding(0, "unicode"); - } - return Tcl_ExternalToUtfDString(winTCharEncoding, - string, len, dsPtr); -#endif + return Tcl_UniCharToUtfDString((Tcl_UniChar *)string, len, dsPtr); } #if defined(TCL_WIDE_INT_IS_LONG) diff --git a/win/tclWin32Dll.c b/win/tclWin32Dll.c index a85dd0c..ca1c856 100644 --- a/win/tclWin32Dll.c +++ b/win/tclWin32Dll.c @@ -33,10 +33,6 @@ static int platformId; /* Running under NT, or 95/98? */ #define cpuid __asm __emit 0fh __asm __emit 0a2h #endif -#if TCL_UTF_MAX < 4 -static Tcl_Encoding winTCharEncoding = NULL; -#endif - /* * The following declaration is for the VC++ DLL entry point. */ @@ -201,8 +197,6 @@ TclWinInit( if (platformId == VER_PLATFORM_WIN32_WINDOWS) { Tcl_Panic("Windows 9x is not a supported platform"); } - - TclWinResetInterfaces(); } /* @@ -282,10 +276,6 @@ TclWinNoBackslash( void TclpSetInterfaces(void) { -#if TCL_UTF_MAX < 4 - TclWinResetInterfaces(); - winTCharEncoding = Tcl_GetEncoding(NULL, "unicode"); -#endif } /* @@ -313,8 +303,6 @@ TclWinEncodingsCleanup(void) { MountPointMap *dlIter, *dlIter2; - TclWinResetInterfaces(); - /* * Clean up the mount point map. */ @@ -348,12 +336,6 @@ TclWinEncodingsCleanup(void) void TclWinResetInterfaces(void) { -#if TCL_UTF_MAX < 4 - if (winTCharEncoding != NULL) { - Tcl_FreeEncoding(winTCharEncoding); - winTCharEncoding = NULL; - } -#endif } /* @@ -565,22 +547,8 @@ Tcl_WinUtfToTChar( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { -#if TCL_UTF_MAX > 3 - TCHAR *wp; - int size = MultiByteToWideChar(CP_UTF8, 0, string, len, 0, 0); - Tcl_DStringInit(dsPtr); - Tcl_DStringSetLength(dsPtr, 2*size+2); - wp = (TCHAR *)Tcl_DStringValue(dsPtr); - MultiByteToWideChar(CP_UTF8, 0, string, len, wp, size+1); - if (len == -1) --size; /* account for 0-byte at string end */ - Tcl_DStringSetLength(dsPtr, 2*size); - wp[size] = 0; - return wp; -#else - return (TCHAR *) Tcl_UtfToExternalDString(winTCharEncoding, - string, len, dsPtr); -#endif + return Tcl_UtfToUniCharDString(string, len, dsPtr); } char * @@ -591,26 +559,13 @@ Tcl_WinTCharToUtf( Tcl_DString *dsPtr) /* Uninitialized or free DString in which the * converted string is stored. */ { -#if TCL_UTF_MAX > 3 - char *p; - int size; - if (len > 0) { len /= 2; + } else if (len < 0) { + len = wcslen(string); } - size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL); Tcl_DStringInit(dsPtr); - Tcl_DStringSetLength(dsPtr, size+1); - p = (char *)Tcl_DStringValue(dsPtr); - WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL); - if (len == -1) --size; /* account for 0-byte at string end */ - Tcl_DStringSetLength(dsPtr, size); - p[size] = 0; - return p; -#else - return Tcl_ExternalToUtfDString(winTCharEncoding, - (const char *) string, len, dsPtr); -#endif + return Tcl_UniCharToUtfDString(string, len, dsPtr); } /* -- cgit v0.12 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