Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Modifications to the TEA zipfs implementation to index file systems by mount point. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | practcl |
Files: | files | file ages | folders |
SHA3-256: |
02d71a542302232df4ae659badaef8ba |
User & Date: | hypnotoad 2018-01-17 02:44:04.945 |
Context
2018-01-17
| ||
15:59 |
Added facilities to mount data blocks as zip archives
Updated practcl from tcllib with new headers for non tip430 kits check-in: 1871415cb9 user: hypnotoad tags: practcl | |
02:44 | Modifications to the TEA zipfs implementation to index file systems by mount point. check-in: 02d71a5423 user: hypnotoad tags: practcl | |
00:22 | Separated the indexing of zip contents from the opening of the zip file stream check-in: af56cbe24a user: hypnotoad tags: practcl | |
Changes
Changes to compat/tclZipfs.c.
︙ | ︙ | |||
182 183 184 185 186 187 188 | #endif unsigned long nopen; /* Number of open files on archive */ struct ZipEntry *entries; /* List of files in archive */ struct ZipEntry *topents; /* List of top-level dirs in archive */ #if HAS_DRIVES int mntdrv; /* Drive letter of mount point */ #endif | < | > | 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | #endif unsigned long nopen; /* Number of open files on archive */ struct ZipEntry *entries; /* List of files in archive */ struct ZipEntry *topents; /* List of top-level dirs in archive */ #if HAS_DRIVES int mntdrv; /* Drive letter of mount point */ #endif char *mntpt; /* Mount point */ size_t mntptlen; } ZipFile; /* * In-core description of file contained in mounted ZIP archive. */ typedef struct ZipEntry { |
︙ | ︙ | |||
321 322 323 324 325 326 327 | 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, }; const char *zipfs_literal_tcl_library=NULL; /* Function prototypes */ | | | 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 | 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, }; const char *zipfs_literal_tcl_library=NULL; /* Function prototypes */ int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd); static int TclZipfs_AppHook_FindTclInit(const char *archive); static int Zip_FSPathInFilesystemProc(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( |
︙ | ︙ | |||
1191 1192 1193 1194 1195 1196 1197 | * *------------------------------------------------------------------------- */ int TclZipfs_Mount( Tcl_Interp *interp, | | | | | 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 | * *------------------------------------------------------------------------- */ int TclZipfs_Mount( Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd ) { char *realname, *p; int i, pwlen, isNew; ZipFile *zf, zf0; ZipEntry *z; Tcl_HashEntry *hPtr; Tcl_DString ds, dsm, fpBuf; unsigned char *q; #if HAS_DRIVES int drive = 0; #endif ReadLock(); if (!ZipFS.initialized) { TclZipfs_C_Init(); } if (mntpt == NULL) { Tcl_HashSearch search; int ret = TCL_OK; i = 0; hPtr = Tcl_FirstHashEntry(&ZipFS.zipHash, &search); while (hPtr != NULL) { if ((zf = (ZipFile *) Tcl_GetHashValue(hPtr)) != NULL) { |
︙ | ︙ | |||
1232 1233 1234 1235 1236 1237 1238 | } if (interp == NULL) { ret = (i > 0) ? TCL_OK : TCL_BREAK; } Unlock(); return ret; } | > > > > > > > | > | < < < < | < < < < < < < < < < < < < | < | 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 | } if (interp == NULL) { ret = (i > 0) ? TCL_OK : TCL_BREAK; } Unlock(); return ret; } /* * Mount point sometimes is a relative or otherwise denormalized path. * But an absolute name is needed as mount point here. */ Tcl_DStringInit(&dsm); mntpt = CanonicalPath("",mntpt, &dsm, 1); if (zipname == NULL) { if (interp == NULL) { Unlock(); return TCL_OK; } Tcl_DStringInit(&ds); hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); if (hPtr != NULL) { if ((zf = Tcl_GetHashValue(hPtr)) != NULL) { Tcl_SetObjResult(interp,Tcl_NewStringObj(zf->name, -1)); } } Unlock(); return TCL_OK; } Unlock(); pwlen = 0; if (passwd != NULL) { |
︙ | ︙ | |||
1287 1288 1289 1290 1291 1292 1293 | } Tcl_DStringInit(&ds); #if HAS_DRIVES realname = AbsolutePath(zipname, NULL, &ds); #else realname = AbsolutePath(zipname, &ds); #endif | < < < < < < | | < | < | > | 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 | } Tcl_DStringInit(&ds); #if HAS_DRIVES realname = AbsolutePath(zipname, NULL, &ds); #else realname = AbsolutePath(zipname, &ds); #endif WriteLock(); hPtr = Tcl_CreateHashEntry(&ZipFS.zipHash, mntpt, &isNew); if (!isNew) { zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (interp != NULL) { Tcl_AppendResult(interp, zf->name, " is already mounted on ", mntpt, (char *) NULL); } Unlock(); ZipFSCloseArchive(interp, &zf0); return TCL_ERROR; } if (strcmp(mntpt, "/") == 0) { mntpt = ""; } zf = (ZipFile *) Tcl_AttemptAlloc(sizeof (*zf) + strlen(mntpt) + 1); if (zf == NULL) { if (interp != NULL) { Tcl_AppendResult(interp, "out of memory", (char *) NULL); } Unlock(); ZipFSCloseArchive(interp, &zf0); return TCL_ERROR; } *zf = zf0; zf->mntpt = Tcl_GetHashKey(&ZipFS.zipHash, hPtr); zf->mntptlen=strlen(zf->mntpt); zf->name = strdup(zipname); zf->entries = NULL; zf->topents = NULL; zf->nopen = 0; Tcl_SetHashValue(hPtr, (ClientData) zf); if ((zf->pwbuf[0] == 0) && pwlen) { int k = 0; i = pwlen; |
︙ | ︙ | |||
1551 1552 1553 1554 1555 1556 1557 | * Side effects: * A mounted ZIP archive file is unmounted, resources are free'd. * *------------------------------------------------------------------------- */ int | | > > > > > > > | | | 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 | * Side effects: * A mounted ZIP archive file is unmounted, resources are free'd. * *------------------------------------------------------------------------- */ int TclZipfs_Unmount(Tcl_Interp *interp, const char *mntpt) { ZipFile *zf; ZipEntry *z, *znext; Tcl_HashEntry *hPtr; Tcl_DString dsm; int ret = TCL_OK, unmounted = 0; WriteLock(); if (!ZipFS.initialized) goto done; /* * Mount point sometimes is a relative or otherwise denormalized path. * But an absolute name is needed as mount point here. */ Tcl_DStringInit(&dsm); mntpt = CanonicalPath("", mntpt, &dsm, 1); hPtr = Tcl_FindHashEntry(&ZipFS.zipHash, mntpt); /* don't report error */ if (hPtr == NULL) goto done; zf = (ZipFile *) Tcl_GetHashValue(hPtr); if (zf->nopen > 0) { ZIPFS_ERROR(interp,"filesystem is busy"); |
︙ | ︙ | |||
1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 | } if (z->data != NULL) { Tcl_Free((char *) z->data); } Tcl_Free((char *) z); } ZipFSCloseArchive(interp, zf); Tcl_Free((char *) zf); unmounted = 1; done: Unlock(); if (unmounted) { Tcl_FSMountsChanged(NULL); } | > | 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 | } if (z->data != NULL) { Tcl_Free((char *) z->data); } Tcl_Free((char *) z); } ZipFSCloseArchive(interp, zf); free(zf->name); //Allocated by strdup Tcl_Free((char *) zf); unmounted = 1; done: Unlock(); if (unmounted) { Tcl_FSMountsChanged(NULL); } |
︙ | ︙ | |||
3931 3932 3933 3934 3935 3936 3937 | case 1: *objPtrRef= Tcl_NewIntObj(z->nbytecompr); goto done; case 2: *objPtrRef= Tcl_NewLongObj(z->offset); goto done; case 3: | | | 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 | case 1: *objPtrRef= Tcl_NewIntObj(z->nbytecompr); goto done; case 2: *objPtrRef= Tcl_NewLongObj(z->offset); goto done; case 3: *objPtrRef= Tcl_NewStringObj(z->zipfile->mntpt, z->zipfile->mntptlen); goto done; case 4: *objPtrRef= Tcl_NewStringObj(z->zipfile->name, -1); goto done; case 5: *objPtrRef= Tcl_NewStringObj("0555", -1); goto done; |
︙ | ︙ | |||
4214 4215 4216 4217 4218 4219 4220 | static int TclZipfs_AppHook_FindTclInit(const char *archive){ Tcl_Obj *vfsinitscript; int found; if(zipfs_literal_tcl_library) { return TCL_ERROR; } | | | 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 | static int TclZipfs_AppHook_FindTclInit(const char *archive){ Tcl_Obj *vfsinitscript; int found; if(zipfs_literal_tcl_library) { return TCL_ERROR; } if(TclZipfs_Mount(NULL, ZIPFS_ZIP_MOUNT, archive, NULL)) { /* Either the file doesn't exist or it is not a zip archive */ return TCL_ERROR; } vfsinitscript=Tcl_NewStringObj(ZIPFS_ZIP_MOUNT "/init.tcl",-1); Tcl_IncrRefCount(vfsinitscript); found=Tcl_FSAccess(vfsinitscript,F_OK); Tcl_DecrRefCount(vfsinitscript); |
︙ | ︙ | |||
4255 4256 4257 4258 4259 4260 4261 | Tcl_FindExecutable(*argv[0]); archive=(char *)Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); /* ** Look for init.tcl in one of the locations mounted later in this function */ | | | 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 | Tcl_FindExecutable(*argv[0]); archive=(char *)Tcl_GetNameOfExecutable(); TclZipfs_Init(NULL); /* ** Look for init.tcl in one of the locations mounted later in this function */ if(!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { int found; Tcl_Obj *vfsinitscript; 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); |
︙ | ︙ | |||
4297 4298 4299 4300 4301 4302 4303 | 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); } return TCL_OK; } else { | | | 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 | 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); } return TCL_OK; } else { if(!TclZipfs_Mount(NULL, ZIPFS_APP_MOUNT, archive, NULL)) { int found; Tcl_Obj *vfsinitscript; 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); |
︙ | ︙ | |||
4338 4339 4340 4341 4342 4343 4344 | * * Dummy version when no ZLIB support available. * *------------------------------------------------------------------------- */ int | | | 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 | * * Dummy version when no ZLIB support available. * *------------------------------------------------------------------------- */ int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd) { return TclZipfs_Init(interp, 1); } int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname) |
︙ | ︙ |
Changes to practcl.tcl.
︙ | ︙ | |||
4510 4511 4512 4513 4514 4515 4516 4517 4518 | Tcl_FindExecutable(*argv[0]); archive=Tcl_GetNameOfExecutable(); } # We have to initialize the virtual filesystem before calling # Tcl_Init(). Otherwise, Tcl_Init() will not be able to find # its startup script files. if {![$PROJECT define get tip_430 0]} { ::practcl::cputs zvfsboot { TclZipfs_Init(NULL);} } | > > > > > | | 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 | Tcl_FindExecutable(*argv[0]); archive=Tcl_GetNameOfExecutable(); } # We have to initialize the virtual filesystem before calling # Tcl_Init(). Otherwise, Tcl_Init() will not be able to find # its startup script files. if {![$PROJECT define get tip_430 0]} { # Add declarations of functions that tip430 puts in the stub files $PROJECT code header { int TclZipfs_Init(Tcl_Interp *interp); int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd); } ::practcl::cputs zvfsboot { TclZipfs_Init(NULL);} } ::practcl::cputs zvfsboot " if(!TclZipfs_Mount(NULL, \"/app\", archive, NULL)) \x7B " ::practcl::cputs zvfsboot { Tcl_Obj *vfsinitscript; vfsinitscript=Tcl_NewStringObj("%vfs_main%",-1); Tcl_IncrRefCount(vfsinitscript); if(Tcl_FSAccess(vfsinitscript,F_OK)==0) { /* Startup script should be set before calling Tcl_AppInit */ Tcl_SetStartupScript(vfsinitscript,NULL); |
︙ | ︙ |