Tcl Source Code

Hex Artifact Content
Login

Artifact cb3672a8fcf73a30732ceaa94fe34897ab48d3e9:


0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20  /*.** Copyright 
0010: 28 63 29 20 32 30 30 30 20 44 2e 20 52 69 63 68  (c) 2000 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54  ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66  his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f  ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75  u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20  te it and/or.** 
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20  modify it under 
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65  the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62   GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61  lic.** License a
00b0: 73 20 70 75 62 6c 69 73 68 65 64 20 62 79 20 74  s published by t
00c0: 68 65 20 46 72 65 65 20 53 6f 66 74 77 61 72 65  he Free Software
00d0: 20 46 6f 75 6e 64 61 74 69 6f 6e 3b 20 65 69 74   Foundation; eit
00e0: 68 65 72 0a 2a 2a 20 76 65 72 73 69 6f 6e 20 32  her.** version 2
00f0: 20 6f 66 20 74 68 65 20 4c 69 63 65 6e 73 65 2c   of the License,
0100: 20 6f 72 20 28 61 74 20 79 6f 75 72 20 6f 70 74   or (at your opt
0110: 69 6f 6e 29 20 61 6e 79 20 6c 61 74 65 72 20 76  ion) any later v
0120: 65 72 73 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68  ersion..**.** Th
0130: 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69  is program is di
0140: 73 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65  stributed in the
0150: 20 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69   hope that it wi
0160: 6c 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a  ll be useful,.**
0170: 20 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59   but WITHOUT ANY
0180: 20 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f   WARRANTY; witho
0190: 75 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c  ut even the impl
01a0: 69 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a  ied warranty of.
01b0: 2a 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49  ** MERCHANTABILI
01c0: 54 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f  TY or FITNESS FO
01d0: 52 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50  R A PARTICULAR P
01e0: 55 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65  URPOSE.  See the
01f0: 20 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20   GNU.** General 
0200: 50 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66  Public License f
0210: 6f 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e  or more details.
0220: 0a 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75  .** .** You shou
0230: 6c 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64  ld have received
0240: 20 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47   a copy of the G
0250: 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69  NU General Publi
0260: 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f  c.** License alo
0270: 6e 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62  ng with this lib
0280: 72 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72  rary; if not, wr
0290: 69 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72  ite to the.** Fr
02a0: 65 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e  ee Software Foun
02b0: 64 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39  dation, Inc., 59
02c0: 20 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20   Temple Place - 
02d0: 53 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f  Suite 330,.** Bo
02e0: 73 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d  ston, MA  02111-
02f0: 31 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a  1307, USA..**.**
0300: 20 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20   Author contact 
0310: 69 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20  information:.** 
0320: 20 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a    [email protected].
0330: 2a 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e  **   http://www.
0340: 68 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a  hwaci.com/drh/.*
0350: 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  *.**************
0360: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0370: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0380: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0390: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 20 41  ***********.** A
03a0: 20 5a 49 50 20 61 72 63 68 69 76 65 20 76 69 72   ZIP archive vir
03b0: 74 75 61 6c 20 66 69 6c 65 73 79 73 74 65 6d 20  tual filesystem 
03c0: 66 6f 72 20 54 63 6c 2e 0a 2a 2a 0a 2a 2a 20 54  for Tcl..**.** T
03d0: 68 69 73 20 70 61 63 6b 61 67 65 20 6f 66 20 72  his package of r
03e0: 6f 75 74 69 6e 65 73 20 65 6e 61 62 6c 65 73 20  outines enables 
03f0: 54 63 6c 20 74 6f 20 75 73 65 20 61 20 5a 69 70  Tcl to use a Zip
0400: 20 66 69 6c 65 20 61 73 0a 2a 2a 20 61 20 76 69   file as.** a vi
0410: 72 74 75 61 6c 20 66 69 6c 65 20 73 79 73 74 65  rtual file syste
0420: 6d 2e 20 20 45 61 63 68 20 6f 66 20 74 68 65 20  m.  Each of the 
0430: 63 6f 6e 74 65 6e 74 20 66 69 6c 65 73 20 6f 66  content files of
0440: 20 74 68 65 20 5a 69 70 0a 2a 2a 20 61 72 63 68   the Zip.** arch
0450: 69 76 65 20 61 70 70 65 61 72 73 20 61 73 20 61  ive appears as a
0460: 20 72 65 61 6c 20 66 69 6c 65 20 74 6f 20 54 63   real file to Tc
0470: 6c 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 64 69 66 69 65  l..**.** Modifie
0480: 64 20 74 6f 20 75 73 65 20 54 63 6c 20 56 46 53  d to use Tcl VFS
0490: 20 68 6f 6f 6b 73 20 62 79 20 50 65 74 65 72 20   hooks by Peter 
04a0: 4d 61 63 44 6f 6e 61 6c 64 0a 2a 2a 20 20 20 70  MacDonald.**   p
04b0: 65 74 65 72 40 70 64 71 69 2e 63 6f 6d 0a 2a 2a  [email protected].**
04c0: 20 20 20 68 74 74 70 3a 2f 2f 70 64 71 69 2e 63     http://pdqi.c
04d0: 6f 6d 0a 2a 2a 0a 2a 2a 20 40 28 23 29 20 24 49  om.**.** @(#) $I
04e0: 64 3a 20 7a 76 66 73 2e 63 2c 76 20 31 2e 31 2e  d: zvfs.c,v 1.1.
04f0: 31 2e 31 20 32 30 30 32 2f 30 31 2f 32 37 20 31  1.1 2002/01/27 1
0500: 37 3a 34 34 3a 30 32 20 63 76 73 20 45 78 70 20  7:44:02 cvs Exp 
0510: 24 0a 2a 2a 20 0a 2a 2a 20 20 20 52 65 76 69 73  $.** .**   Revis
0520: 6f 6e 20 20 44 61 74 65 20 20 20 20 20 20 20 20  on  Date        
0530: 20 20 20 41 75 74 68 6f 72 20 20 20 20 20 20 20     Author       
0540: 20 20 20 20 20 20 44 65 73 63 72 69 70 74 69 6f        Descriptio
0550: 6e 0a 2a 2a 20 20 20 2d 2d 2d 2d 2d 2d 2d 20 20  n.**   -------  
0560: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 20 20 2d  -------------  -
0570: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0580: 20 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d    --------------
0590: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
05a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
05b0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 4a  .**            J
05c0: 61 6e 20 20 38 2c 20 32 30 30 36 20 20 20 44 65  an  8, 2006   De
05d0: 6e 6e 69 73 20 52 2e 20 4c 61 42 65 6c 6c 65 20  nnis R. LaBelle 
05e0: 20 4d 6f 64 69 66 69 65 64 20 74 6f 20 73 75 70   Modified to sup
05f0: 70 6f 72 74 20 65 6e 63 72 79 70 74 65 64 20 66  port encrypted f
0600: 69 6c 65 73 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  iles.**.**      
0610: 20 20 20 20 20 20 44 65 63 20 31 36 2c 20 32 30        Dec 16, 20
0620: 30 39 20 20 20 44 65 6e 6e 69 73 20 52 2e 20 4c  09   Dennis R. L
0630: 61 42 65 6c 6c 65 20 20 43 6f 72 72 65 63 74 65  aBelle  Correcte
0640: 64 20 54 6f 62 65 5f 46 53 4d 61 74 63 68 49 6e  d Tobe_FSMatchIn
0650: 44 69 72 65 63 74 6f 72 79 50 72 6f 63 28 29 20  DirectoryProc() 
0660: 66 6f 72 0a 2a 2a 20 20 20 20 20 20 20 20 20 20  for.**          
0670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0690: 20 20 20 20 70 72 6f 70 65 72 20 6f 70 65 72 61      proper opera
06a0: 74 69 6f 6e 20 6f 66 20 67 6c 6f 62 20 63 6f 6d  tion of glob com
06b0: 6d 61 6e 64 20 6f 6e 20 5a 56 46 53 20 66 69 6c  mand on ZVFS fil
06c0: 65 73 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  es.**           
06d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
06f0: 20 20 20 75 6e 64 65 72 20 54 43 4c 20 38 2e 35     under TCL 8.5
0700: 2e 0a 2a 2a 09 20 20 20 20 20 20 4f 63 74 20 31  ..**.      Oct 1
0710: 39 2c 20 32 30 31 34 20 20 20 53 65 61 6e 20 44  9, 2014   Sean D
0720: 2e 20 57 6f 6f 64 73 20 20 20 20 20 20 43 6f 72  . Woods      Cor
0730: 72 65 63 74 65 64 20 54 6f 62 65 5f 46 53 4d 61  rected Tobe_FSMa
0740: 74 63 68 49 6e 44 69 72 65 63 74 6f 72 79 50 72  tchInDirectoryPr
0750: 6f 63 28 29 20 74 6f 20 77 6f 72 6b 20 61 72 6f  oc() to work aro
0760: 75 6e 64 0a 2a 2a 09 09 09 09 09 09 69 73 73 75  und.**......issu
0770: 65 73 20 72 65 73 6f 6c 76 69 6e 67 20 67 6c 6f  es resolving glo
0780: 62 61 6c 20 66 69 6c 65 20 70 61 74 68 73 20 75  bal file paths u
0790: 6e 64 65 72 20 57 69 6e 64 6f 77 73 2e 0a 2a 2a  nder Windows..**
07a0: 09 09 09 09 09 09 57 72 61 70 70 65 64 20 46 72  ......Wrapped Fr
07b0: 65 65 57 72 61 70 20 73 70 65 63 69 66 69 63 20  eeWrap specific 
07c0: 63 61 6c 6c 73 20 69 6e 73 69 64 65 20 6f 66 20  calls inside of 
07d0: 6d 61 63 72 6f 73 2e 0a 2a 2a 09 09 09 09 09 09  macros..**......
07e0: 57 72 61 70 70 65 64 20 63 61 6c 6c 73 20 74 68  Wrapped calls th
07f0: 61 74 20 69 6d 70 6c 65 6d 65 6e 74 20 65 6e 63  at implement enc
0800: 72 79 70 74 69 6f 6e 20 69 6e 73 69 64 65 20 6f  ryption inside o
0810: 66 20 6d 61 63 72 6f 73 2e 20 28 54 68 65 20 73  f macros. (The s
0820: 75 70 70 6f 72 74 69 6e 67 0a 2a 2a 09 09 09 09  upporting.**....
0830: 09 09 6c 69 62 72 61 72 79 20 66 6f 72 20 74 68  ..library for th
0840: 69 73 20 69 73 20 70 61 72 74 20 6f 66 20 5a 69  is is part of Zi
0850: 70 2c 20 61 6e 64 20 6e 6f 74 20 64 69 73 74 72  p, and not distr
0860: 69 62 75 74 65 64 20 77 69 74 68 20 54 63 6c 2e  ibuted with Tcl.
0870: 29 0a 2a 2a 09 09 09 09 09 09 52 65 63 6f 6e 63  ).**......Reconc
0880: 69 6c 65 64 20 74 68 69 73 20 65 64 69 74 69 6f  iled this editio
0890: 6e 20 6f 66 20 5a 76 66 73 20 77 69 74 68 20 70  n of Zvfs with p
08a0: 61 72 61 6c 6c 65 6c 20 77 6f 72 6b 20 6f 6e 20  arallel work on 
08b0: 74 68 65 20 4f 64 69 65 20 70 72 6f 6a 65 63 74  the Odie project
08c0: 2e 0a 2a 2f 0a 0a 23 69 6e 63 6c 75 64 65 20 3c  ..*/..#include <
08d0: 63 74 79 70 65 2e 68 3e 0a 23 69 6e 63 6c 75 64  ctype.h>.#includ
08e0: 65 20 3c 7a 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c  e <zlib.h>.#incl
08f0: 75 64 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69  ude <errno.h>.#i
0900: 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68  nclude <string.h
0910: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f  >.#include <sys/
0920: 73 74 61 74 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  stat.h>.#include
0930: 20 3c 74 69 6d 65 2e 68 3e 0a 23 69 6e 63 6c 75   <time.h>.#inclu
0940: 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69  de <stdlib.h>.#i
0950: 6e 63 6c 75 64 65 20 22 74 63 6c 2e 68 22 0a 0a  nclude "tcl.h"..
0960: 54 43 4c 5f 44 45 43 4c 41 52 45 5f 4d 55 54 45  TCL_DECLARE_MUTE
0970: 58 28 41 72 63 68 69 76 65 46 69 6c 65 41 63 63  X(ArchiveFileAcc
0980: 65 73 73 29 0a 0a 23 75 6e 64 65 66 20 5a 49 50  ess)..#undef ZIP
0990: 56 46 53 43 52 59 50 54 0a 23 69 66 64 65 66 20  VFSCRYPT.#ifdef 
09a0: 5a 49 50 56 46 53 43 52 59 50 54 0a 2f 2a 20 53  ZIPVFSCRYPT./* S
09b0: 6f 6d 65 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e  ome modification
09c0: 73 20 74 6f 20 73 75 70 70 6f 72 74 20 65 6e 63  s to support enc
09d0: 72 79 70 74 65 64 20 66 69 6c 65 73 20 2a 2f 0a  rypted files */.
09e0: 23 64 65 66 69 6e 65 20 75 70 64 61 74 65 5f 6b  #define update_k
09f0: 65 79 73 20 20 20 20 7a 70 5f 75 70 64 61 74 65  eys    zp_update
0a00: 5f 6b 65 79 73 0a 23 64 65 66 69 6e 65 20 69 6e  _keys.#define in
0a10: 69 74 5f 6b 65 79 73 20 20 20 20 20 20 7a 70 5f  it_keys      zp_
0a20: 69 6e 69 74 5f 6b 65 79 73 0a 23 64 65 66 69 6e  init_keys.#defin
0a30: 65 20 64 65 63 72 79 70 74 5f 62 79 74 65 20 20  e decrypt_byte  
0a40: 20 7a 70 5f 64 65 63 72 79 70 74 5f 62 79 74 65   zp_decrypt_byte
0a50: 0a 0a 2f 2a 20 73 6f 6d 65 20 70 72 6f 74 6f 74  ../* some protot
0a60: 79 70 65 20 64 65 66 69 6e 69 74 69 6f 6e 73 20  ype definitions 
0a70: 2a 2f 0a 65 78 74 65 72 6e 20 76 6f 69 64 20 69  */.extern void i
0a80: 6e 69 74 5f 6b 65 79 73 28 63 68 61 72 20 2a 70  nit_keys(char *p
0a90: 77 64 29 3b 0a 65 78 74 65 72 6e 20 69 6e 74 20  wd);.extern int 
0aa0: 75 70 64 61 74 65 5f 6b 65 79 73 28 69 6e 74 20  update_keys(int 
0ab0: 63 29 3b 0a 65 78 74 65 72 6e 20 75 6e 73 69 67  c);.extern unsig
0ac0: 6e 65 64 20 63 68 61 72 20 64 65 63 72 79 70 74  ned char decrypt
0ad0: 5f 62 79 74 65 28 29 3b 0a 65 78 74 65 72 6e 20  _byte();.extern 
0ae0: 63 68 61 72 20 2a 67 65 74 50 77 64 4b 65 79 28  char *getPwdKey(
0af0: 63 68 61 72 20 2a 6b 65 79 62 75 66 29 3b 0a 65  char *keybuf);.e
0b00: 78 74 65 72 6e 20 63 6f 6e 73 74 20 75 6e 73 69  xtern const unsi
0b10: 67 6e 65 64 20 6c 6f 6e 67 20 2a 63 72 63 5f 33  gned long *crc_3
0b20: 32 5f 74 61 62 3b 0a 23 65 6e 64 69 66 0a 0a 2f  2_tab;.#endif../
0b30: 2a 20 45 6e 64 20 6f 66 20 6d 6f 64 69 66 69 63  * End of modific
0b40: 61 74 69 6f 6e 73 20 74 6f 20 73 75 70 70 6f 72  ations to suppor
0b50: 74 20 65 6e 63 72 79 70 74 65 64 20 66 69 6c 65  t encrypted file
0b60: 73 2e 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 53 69 7a  s. */../*.** Siz
0b70: 65 20 6f 66 20 74 68 65 20 64 65 63 6f 6d 70 72  e of the decompr
0b80: 65 73 73 69 6f 6e 20 69 6e 70 75 74 20 62 75 66  ession input buf
0b90: 66 65 72 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 43  fer.*/.#define C
0ba0: 4f 4d 50 52 5f 42 55 46 5f 53 49 5a 45 20 20 20  OMPR_BUF_SIZE   
0bb0: 33 32 37 36 38 0a 73 74 61 74 69 63 20 69 6e 74  32768.static int
0bc0: 20 6f 70 65 6e 61 72 63 68 20 3d 20 30 3b 09 2f   openarch = 0;./
0bd0: 2a 20 53 65 74 20 74 6f 20 31 20 77 68 65 6e 20  * Set to 1 when 
0be0: 6f 70 65 6e 69 6e 67 20 61 72 63 68 69 76 65 2e  opening archive.
0bf0: 20 2a 2f 0a 23 69 66 64 65 66 20 5f 5f 57 49 4e   */.#ifdef __WIN
0c00: 33 32 5f 5f 0a 73 74 61 74 69 63 20 69 6e 74 20  32__.static int 
0c10: 6d 61 70 74 6f 6c 6f 77 65 72 3d 30 3b 0a 23 65  maptolower=0;.#e
0c20: 6e 64 69 66 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 73  ndif./*.** All s
0c30: 74 61 74 69 63 20 76 61 72 69 61 62 6c 65 73 20  tatic variables 
0c40: 61 72 65 20 63 6f 6c 6c 65 63 74 65 64 20 69 6e  are collected in
0c50: 74 6f 20 61 20 73 74 72 75 63 74 75 72 65 20 6e  to a structure n
0c60: 61 6d 65 64 20 22 6c 6f 63 61 6c 22 2e 0a 2a 2a  amed "local"..**
0c70: 20 54 68 61 74 20 77 61 79 2c 20 69 74 20 69 73   That way, it is
0c80: 20 63 6c 65 61 72 20 69 6e 20 74 68 65 20 63 6f   clear in the co
0c90: 64 65 20 77 68 65 6e 20 77 65 20 61 72 65 20 75  de when we are u
0ca0: 73 69 6e 67 20 61 20 73 74 61 74 69 63 0a 2a 2a  sing a static.**
0cb0: 20 76 61 72 69 61 62 6c 65 20 62 65 63 61 75 73   variable becaus
0cc0: 65 20 69 74 73 20 6e 61 6d 65 20 62 65 67 69 6e  e its name begin
0cd0: 73 20 77 69 74 68 20 22 6c 6f 63 61 6c 2e 22 2e  s with "local.".
0ce0: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63  .*/.static struc
0cf0: 74 20 7b 0a 20 20 54 63 6c 5f 48 61 73 68 54 61  t {.  Tcl_HashTa
0d00: 62 6c 65 20 66 69 6c 65 48 61 73 68 3b 20 20 20  ble fileHash;   
0d10: 20 20 2f 2a 20 4f 6e 65 20 65 6e 74 72 79 20 66    /* One entry f
0d20: 6f 72 20 65 61 63 68 20 66 69 6c 65 20 69 6e 20  or each file in 
0d30: 74 68 65 20 5a 56 46 53 2e 20 20 54 68 65 0a 20  the ZVFS.  The. 
0d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d50: 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 2a 20               ** 
0d60: 54 68 65 20 6b 65 79 20 69 73 20 74 68 65 20 76  The key is the v
0d70: 69 72 74 75 61 6c 20 66 69 6c 65 6e 61 6d 65 2e  irtual filename.
0d80: 20 20 54 68 65 20 64 61 74 61 0a 20 20 20 20 20    The data.     
0d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0da0: 20 20 20 20 20 20 20 20 20 2a 2a 20 61 6e 20 61           ** an a
0db0: 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  n instance of th
0dc0: 65 20 5a 76 66 73 46 69 6c 65 20 73 74 72 75 63  e ZvfsFile struc
0dd0: 74 75 72 65 2e 20 2a 2f 0a 20 20 54 63 6c 5f 48  ture. */.  Tcl_H
0de0: 61 73 68 54 61 62 6c 65 20 61 72 63 68 69 76 65  ashTable archive
0df0: 48 61 73 68 3b 20 20 2f 2a 20 4f 6e 65 20 65 6e  Hash;  /* One en
0e00: 74 72 79 20 66 6f 72 20 65 61 63 68 20 61 72 63  try for each arc
0e10: 68 69 76 65 2e 20 20 4b 65 79 20 69 73 20 74 68  hive.  Key is th
0e20: 65 20 6e 61 6d 65 2e 20 0a 20 20 20 20 20 20 20  e name. .       
0e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0e40: 20 20 20 20 20 20 20 2a 2a 20 64 61 74 61 20 69         ** data i
0e50: 73 20 74 68 65 20 5a 76 66 73 41 72 63 68 69 76  s the ZvfsArchiv
0e60: 65 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a 20  e structure */. 
0e70: 20 69 6e 74 20 69 73 49 6e 69 74 3b 20 20 20 20   int isInit;    
0e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
0e90: 54 72 75 65 20 61 66 74 65 72 20 69 6e 69 74 69  True after initi
0ea0: 61 6c 69 7a 61 74 69 6f 6e 20 2a 2f 0a 20 20 63  alization */.  c
0eb0: 68 61 72 20 2a 66 69 72 73 74 4d 6f 75 6e 74 3b  har *firstMount;
0ec0: 09 09 2f 2a 20 54 68 65 20 70 61 74 68 20 74 6f  ../* The path to
0ed0: 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 6d 6f   to the first mo
0ee0: 75 6e 74 65 64 20 66 69 6c 65 2e 20 2a 2f 0a 7d  unted file. */.}
0ef0: 20 6c 6f 63 61 6c 3b 0a 0a 2f 2a 0a 2a 2a 20 45   local;../*.** E
0f00: 61 63 68 20 5a 49 50 20 61 72 63 68 69 76 65 20  ach ZIP archive 
0f10: 66 69 6c 65 20 74 68 61 74 20 69 73 20 6d 6f 75  file that is mou
0f20: 6e 74 65 64 20 69 73 20 72 65 63 6f 72 64 65 64  nted is recorded
0f30: 20 61 73 20 61 6e 20 69 6e 73 74 61 6e 63 65 0a   as an instance.
0f40: 2a 2a 20 6f 66 20 74 68 69 73 20 73 74 72 75 63  ** of this struc
0f50: 74 75 72 65 0a 2a 2f 0a 74 79 70 65 64 65 66 20  ture.*/.typedef 
0f60: 73 74 72 75 63 74 20 5a 76 66 73 41 72 63 68 69  struct ZvfsArchi
0f70: 76 65 20 7b 0a 20 20 63 68 61 72 20 2a 7a 4e 61  ve {.  char *zNa
0f80: 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  me;             
0f90: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20   /* Name of the 
0fa0: 61 72 63 68 69 76 65 20 2a 2f 0a 20 20 63 68 61  archive */.  cha
0fb0: 72 20 2a 7a 4d 6f 75 6e 74 50 6f 69 6e 74 3b 20  r *zMountPoint; 
0fc0: 20 20 20 20 20 20 20 2f 2a 20 57 68 65 72 65 20         /* Where 
0fd0: 74 68 69 73 20 61 72 63 68 69 76 65 20 69 73 20  this archive is 
0fe0: 6d 6f 75 6e 74 65 64 20 2a 2f 0a 20 20 73 74 72  mounted */.  str
0ff0: 75 63 74 20 5a 76 66 73 46 69 6c 65 20 2a 70 46  uct ZvfsFile *pF
1000: 69 6c 65 73 3b 20 20 2f 2a 20 4c 69 73 74 20 6f  iles;  /* List o
1010: 66 20 66 69 6c 65 73 20 69 6e 20 74 68 61 74 20  f files in that 
1020: 61 72 63 68 69 76 65 20 2a 2f 0a 7d 20 5a 76 66  archive */.} Zvf
1030: 73 41 72 63 68 69 76 65 3b 0a 0a 2f 2a 0a 2a 2a  sArchive;../*.**
1040: 20 50 61 72 74 69 63 75 6c 61 72 73 20 61 62 6f   Particulars abo
1050: 75 74 20 65 61 63 68 20 76 69 72 74 75 61 6c 20  ut each virtual 
1060: 66 69 6c 65 20 61 72 65 20 72 65 63 6f 72 64 65  file are recorde
1070: 64 20 69 6e 20 61 6e 20 69 6e 73 74 61 6e 63 65  d in an instance
1080: 0a 2a 2a 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f  .** of the follo
1090: 77 69 6e 67 20 73 74 72 75 63 74 75 72 65 2e 0a  wing structure..
10a0: 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  */.typedef struc
10b0: 74 20 5a 76 66 73 46 69 6c 65 20 7b 0a 20 20 63  t ZvfsFile {.  c
10c0: 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20  har *zName;     
10d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
10e0: 66 75 6c 6c 20 70 61 74 68 6e 61 6d 65 20 6f 66  full pathname of
10f0: 20 74 68 65 20 76 69 72 74 75 61 6c 20 66 69 6c   the virtual fil
1100: 65 20 2a 2f 0a 20 20 5a 76 66 73 41 72 63 68 69  e */.  ZvfsArchi
1110: 76 65 20 2a 70 41 72 63 68 69 76 65 3b 20 20 20  ve *pArchive;   
1120: 20 2f 2a 20 54 68 65 20 5a 49 50 20 61 72 63 68   /* The ZIP arch
1130: 69 76 65 20 68 6f 6c 64 69 6e 67 20 74 68 69 73  ive holding this
1140: 20 66 69 6c 65 20 64 61 74 61 20 2a 2f 0a 20 20   file data */.  
1150: 69 6e 74 20 69 4f 66 66 73 65 74 3b 20 20 20 20  int iOffset;    
1160: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 66 66            /* Off
1170: 73 65 74 20 69 6e 74 6f 20 74 68 65 20 5a 49 50  set into the ZIP
1180: 20 61 72 63 68 69 76 65 20 6f 66 20 74 68 65 20   archive of the 
1190: 64 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20 6e 42  data */.  int nB
11a0: 79 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  yte;            
11b0: 20 20 20 20 2f 2a 20 55 6e 63 6f 6d 70 72 65 73      /* Uncompres
11c0: 73 65 64 20 73 69 7a 65 20 6f 66 20 74 68 65 20  sed size of the 
11d0: 76 69 72 74 75 61 6c 20 66 69 6c 65 20 2a 2f 0a  virtual file */.
11e0: 20 20 69 6e 74 20 6e 42 79 74 65 43 6f 6d 70 72    int nByteCompr
11f0: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43  ;           /* C
1200: 6f 6d 70 72 65 73 73 65 64 20 73 69 7a 65 20 6f  ompressed size o
1210: 66 20 74 68 65 20 76 69 72 74 75 61 6c 20 66 69  f the virtual fi
1220: 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 69 73 64 69  le */.  int isdi
1230: 72 3b 09 09 20 20 20 20 2f 2a 20 53 65 74 20 74  r;..    /* Set t
1240: 6f 20 31 20 69 66 20 64 69 72 65 63 74 6f 72 79  o 1 if directory
1250: 20 2a 2f 0a 20 20 69 6e 74 20 64 65 70 74 68 3b   */.  int depth;
1260: 20 09 09 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72   ..    /* Number
1270: 20 6f 66 20 73 6c 61 73 68 65 73 20 69 6e 20 70   of slashes in p
1280: 61 74 68 2e 20 2a 2f 0a 20 20 69 6e 74 20 74 69  ath. */.  int ti
1290: 6d 65 73 74 61 6d 70 3b 20 20 20 20 20 20 20 20  mestamp;        
12a0: 20 20 20 20 2f 2a 20 4d 6f 64 69 66 69 63 61 74      /* Modificat
12b0: 69 6f 6e 20 74 69 6d 65 20 2a 2f 0a 20 20 69 6e  ion time */.  in
12c0: 74 20 70 65 72 6d 69 73 73 69 6f 6e 73 3b 09 09  t permissions;..
12d0: 2f 2a 20 46 69 6c 65 20 70 65 72 6d 69 73 73 69  /* File permissi
12e0: 6f 6e 73 2e 20 2a 2f 0a 20 20 73 74 72 75 63 74  ons. */.  struct
12f0: 20 5a 76 66 73 46 69 6c 65 20 2a 70 4e 65 78 74   ZvfsFile *pNext
1300: 3b 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 66  ;      /* Next f
1310: 69 6c 65 20 69 6e 20 74 68 65 20 73 61 6d 65 20  ile in the same 
1320: 61 72 63 68 69 76 65 20 2a 2f 0a 20 20 73 74 72  archive */.  str
1330: 75 63 74 20 5a 76 66 73 46 69 6c 65 20 2a 70 4e  uct ZvfsFile *pN
1340: 65 78 74 4e 61 6d 65 3b 20 20 2f 2a 20 41 20 64  extName;  /* A d
1350: 6f 75 62 6c 79 2d 6c 69 6e 6b 65 64 20 6c 69 73  oubly-linked lis
1360: 74 20 6f 66 20 66 69 6c 65 73 20 77 69 74 68 20  t of files with 
1370: 74 68 65 20 73 61 6d 65 20 2a 2f 0a 20 20 73 74  the same */.  st
1380: 72 75 63 74 20 5a 76 66 73 46 69 6c 65 20 2a 70  ruct ZvfsFile *p
1390: 50 72 65 76 4e 61 6d 65 3b 20 20 2f 2a 20 20 6e  PrevName;  /*  n
13a0: 61 6d 65 2e 20 20 4f 6e 6c 79 20 74 68 65 20 66  ame.  Only the f
13b0: 69 72 73 74 20 69 73 20 69 6e 20 6c 6f 63 61 6c  irst is in local
13c0: 2e 66 69 6c 65 48 61 73 68 20 2a 2f 0a 20 20 2f  .fileHash */.  /
13d0: 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  * The following 
13e0: 77 6f 75 6c 64 20 62 65 20 75 73 65 64 20 66 6f  would be used fo
13f0: 72 20 77 72 69 74 61 62 6c 65 20 7a 69 70 73 2e  r writable zips.
1400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1410: 20 20 20 20 20 20 20 20 20 20 20 2a 2f 0a 20 20             */.  
1420: 69 6e 74 20 6e 45 78 74 72 61 3b 20 20 20 20 20  int nExtra;     
1430: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 45 78 74            /* Ext
1440: 72 61 20 73 70 61 63 65 20 69 6e 20 74 68 65 20  ra space in the 
1450: 54 4f 43 20 68 65 61 64 65 72 20 2a 2f 0a 20 20  TOC header */.  
1460: 69 6e 74 20 69 73 53 70 65 63 69 61 6c 3b 20 20  int isSpecial;  
1470: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 6f 74            /* Not
1480: 20 72 65 61 6c 6c 79 20 61 20 66 69 6c 65 20 69   really a file i
1490: 6e 20 74 68 65 20 5a 49 50 20 61 72 63 68 69 76  n the ZIP archiv
14a0: 65 20 2a 2f 0a 20 20 69 6e 74 20 64 6f 73 54 69  e */.  int dosTi
14b0: 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  me;             
14c0: 20 2f 2a 20 4d 6f 64 69 66 69 63 61 74 69 6f 6e   /* Modification
14d0: 20 74 69 6d 65 20 28 44 4f 53 20 66 6f 72 6d 61   time (DOS forma
14e0: 74 29 20 2a 2f 0a 20 20 69 6e 74 20 64 6f 73 44  t) */.  int dosD
14f0: 61 74 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ate;            
1500: 20 20 2f 2a 20 4d 6f 64 69 66 69 63 61 74 69 6f    /* Modificatio
1510: 6e 20 64 61 74 65 20 28 44 4f 53 20 66 6f 72 6d  n date (DOS form
1520: 61 74 29 20 2a 2f 0a 20 20 69 6e 74 20 69 43 52  at) */.  int iCR
1530: 43 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  C;              
1540: 20 20 20 2f 2a 20 43 79 63 6c 69 63 20 52 65 64     /* Cyclic Red
1550: 75 6e 64 61 6e 63 79 20 43 68 65 63 6b 20 6f 66  undancy Check of
1560: 20 74 68 65 20 64 61 74 61 20 2a 2f 0a 7d 20 5a   the data */.} Z
1570: 76 66 73 46 69 6c 65 3b 0a 0a 2f 2a 0a 2a 2a 20  vfsFile;../*.** 
1580: 4d 61 63 72 6f 73 20 74 6f 20 72 65 61 64 20 31  Macros to read 1
1590: 36 2d 62 69 74 20 61 6e 64 20 33 32 2d 62 69 74  6-bit and 32-bit
15a0: 20 62 69 67 2d 65 6e 64 69 61 6e 20 69 6e 74 65   big-endian inte
15b0: 67 65 72 73 20 69 6e 74 6f 20 74 68 65 0a 2a 2a  gers into the.**
15c0: 20 6e 61 74 69 76 65 20 66 6f 72 6d 61 74 20 6f   native format o
15d0: 66 20 74 68 69 73 20 6c 6f 63 61 6c 20 70 72 6f  f this local pro
15e0: 63 65 73 73 6f 72 2e 20 20 42 20 69 73 20 61 6e  cessor.  B is an
15f0: 20 61 72 72 61 79 20 6f 66 0a 2a 2a 20 63 68 61   array of.** cha
1600: 72 61 63 74 65 72 73 20 61 6e 64 20 74 68 65 20  racters and the 
1610: 69 6e 74 65 67 65 72 20 62 65 67 69 6e 73 20 61  integer begins a
1620: 74 20 74 68 65 20 4e 2d 74 68 20 63 68 61 72 61  t the N-th chara
1630: 63 74 65 72 20 6f 66 0a 2a 2a 20 74 68 65 20 61  cter of.** the a
1640: 72 72 61 79 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  rray..*/.#define
1650: 20 49 4e 54 31 36 28 42 2c 20 4e 29 20 28 42 5b   INT16(B, N) (B[
1660: 4e 5d 20 2b 20 28 42 5b 4e 2b 31 5d 3c 3c 38 29  N] + (B[N+1]<<8)
1670: 29 0a 23 64 65 66 69 6e 65 20 49 4e 54 33 32 28  ).#define INT32(
1680: 42 2c 20 4e 29 20 28 49 4e 54 31 36 28 42 2c 4e  B, N) (INT16(B,N
1690: 29 20 2b 20 28 42 5b 4e 2b 32 5d 3c 3c 31 36 29  ) + (B[N+2]<<16)
16a0: 20 2b 20 28 42 5b 4e 2b 33 5d 3c 3c 32 34 29 29   + (B[N+3]<<24))
16b0: 0a 0a 0c 0a 2f 2a 20 43 6f 6e 76 65 72 74 20 44  ..../* Convert D
16c0: 4f 53 20 74 69 6d 65 20 74 6f 20 75 6e 69 78 20  OS time to unix 
16d0: 74 69 6d 65 2e 20 2a 2f 0a 73 74 61 74 69 63 20  time. */.static 
16e0: 74 69 6d 65 5f 74 20 44 6f 73 54 69 6d 65 44 61  time_t DosTimeDa
16f0: 74 65 28 69 6e 74 20 64 6f 73 44 61 74 65 2c 20  te(int dosDate, 
1700: 69 6e 74 20 64 6f 73 54 69 6d 65 29 7b 0a 20 20  int dosTime){.  
1710: 74 69 6d 65 5f 74 20 6e 6f 77 3b 0a 20 20 73 74  time_t now;.  st
1720: 72 75 63 74 20 74 6d 20 2a 74 6d 3b 0a 20 20 6e  ruct tm *tm;.  n
1730: 6f 77 3d 74 69 6d 65 28 4e 55 4c 4c 29 3b 0a 20  ow=time(NULL);. 
1740: 20 74 6d 20 3d 20 6c 6f 63 61 6c 74 69 6d 65 28   tm = localtime(
1750: 26 6e 6f 77 29 3b 0a 20 20 74 6d 2d 3e 74 6d 5f  &now);.  tm->tm_
1760: 79 65 61 72 3d 28 28 28 64 6f 73 44 61 74 65 26  year=(((dosDate&
1770: 30 78 66 65 30 30 29 3e 3e 39 29 20 2b 20 38 30  0xfe00)>>9) + 80
1780: 29 3b 0a 20 20 74 6d 2d 3e 74 6d 5f 6d 6f 6e 3d  );.  tm->tm_mon=
1790: 28 28 64 6f 73 44 61 74 65 26 30 78 31 65 30 29  ((dosDate&0x1e0)
17a0: 3e 3e 35 29 2d 31 3b 0a 20 20 74 6d 2d 3e 74 6d  >>5)-1;.  tm->tm
17b0: 5f 6d 64 61 79 3d 28 64 6f 73 44 61 74 65 20 26  _mday=(dosDate &
17c0: 20 30 78 31 66 29 3b 0a 20 20 74 6d 2d 3e 74 6d   0x1f);.  tm->tm
17d0: 5f 68 6f 75 72 3d 28 64 6f 73 54 69 6d 65 26 30  _hour=(dosTime&0
17e0: 78 66 38 30 30 29 3e 3e 31 31 3b 0a 20 20 74 6d  xf800)>>11;.  tm
17f0: 2d 3e 74 6d 5f 6d 69 6e 3d 28 64 6f 73 54 69 6d  ->tm_min=(dosTim
1800: 65 26 30 78 37 65 29 3e 3e 35 3b 0a 20 20 74 6d  e&0x7e)>>5;.  tm
1810: 2d 3e 74 6d 5f 73 65 63 3d 28 64 6f 73 54 69 6d  ->tm_sec=(dosTim
1820: 65 26 30 78 31 66 29 3b 0a 20 20 72 65 74 75 72  e&0x1f);.  retur
1830: 6e 20 6d 6b 74 69 6d 65 28 74 6d 29 3b 0a 7d 0a  n mktime(tm);.}.
1840: 0a 2f 2a 20 52 65 74 75 72 6e 20 63 6f 75 6e 74  ./* Return count
1850: 20 6f 66 20 63 68 61 72 20 63 68 20 69 6e 20 73   of char ch in s
1860: 74 72 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  tr */.static int
1870: 20 73 74 72 63 68 72 63 6e 74 28 63 68 61 72 20   strchrcnt(char 
1880: 2a 73 74 72 2c 20 63 68 61 72 20 63 68 29 20 7b  *str, char ch) {
1890: 0a 20 20 69 6e 74 20 63 6e 74 3d 30 3b 0a 20 20  .  int cnt=0;.  
18a0: 63 68 61 72 20 2a 63 70 3d 73 74 72 3b 0a 20 20  char *cp=str;.  
18b0: 77 68 69 6c 65 20 28 28 63 70 3d 73 74 72 63 68  while ((cp=strch
18c0: 72 28 63 70 2c 63 68 29 29 29 20 7b 20 63 70 2b  r(cp,ch))) { cp+
18d0: 2b 3b 20 63 6e 74 2b 2b 3b 20 7d 0a 20 20 72 65  +; cnt++; }.  re
18e0: 74 75 72 6e 20 63 6e 74 3b 0a 7d 0a 0a 2f 2a 0a  turn cnt;.}../*.
18f0: 2a 2a 20 43 6f 6e 63 61 74 65 6e 61 74 65 20 7a  ** Concatenate z
1900: 54 61 69 6c 20 6f 6e 74 6f 20 7a 52 6f 6f 74 20  Tail onto zRoot 
1910: 74 6f 20 66 6f 72 6d 20 61 20 70 61 74 68 6e 61  to form a pathna
1920: 6d 65 2e 20 20 7a 52 6f 6f 74 20 77 69 6c 6c 20  me.  zRoot will 
1930: 62 65 67 69 6e 0a 2a 2a 20 77 69 74 68 20 22 2f  begin.** with "/
1940: 22 2e 20 20 41 66 74 65 72 20 63 6f 6e 63 61 74  ".  After concat
1950: 65 6e 61 74 69 6f 6e 2c 20 73 69 6d 70 6c 69 66  enation, simplif
1960: 79 20 74 68 65 20 70 61 74 68 6e 61 6d 65 20 62  y the pathname b
1970: 65 20 72 65 6d 6f 76 69 6e 67 0a 2a 2a 20 75 6e  e removing.** un
1980: 6e 65 63 65 73 73 61 72 79 20 22 2e 2e 22 20 61  necessary ".." a
1990: 6e 64 20 22 2e 22 20 64 69 72 65 63 74 6f 72 69  nd "." directori
19a0: 65 73 2e 20 20 55 6e 64 65 72 20 77 69 6e 64 6f  es.  Under windo
19b0: 77 73 2c 20 6d 61 6b 65 20 61 6c 6c 0a 2a 2a 20  ws, make all.** 
19c0: 63 68 61 72 61 63 74 65 72 73 20 6c 6f 77 65 72  characters lower
19d0: 20 63 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 52 65 73   case..**.** Res
19e0: 75 6c 74 69 6e 67 20 70 61 74 68 6e 61 6d 65 20  ulting pathname 
19f0: 69 73 20 72 65 74 75 72 6e 65 64 2e 20 20 53 70  is returned.  Sp
1a00: 61 63 65 20 74 6f 20 68 6f 6c 64 20 74 68 65 20  ace to hold the 
1a10: 72 65 74 75 72 6e 65 64 20 70 61 74 68 20 69 73  returned path is
1a20: 0a 2a 2a 20 6f 62 74 61 69 6e 65 64 20 66 72 6f  .** obtained fro
1a30: 6d 20 54 63 6c 5f 41 6c 6c 6f 63 28 29 20 61 6e  m Tcl_Alloc() an
1a40: 64 20 73 68 6f 75 6c 64 20 62 65 20 66 72 65 65  d should be free
1a50: 64 20 62 79 20 74 68 65 20 63 61 6c 6c 69 6e 67  d by the calling
1a60: 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74   function..*/.st
1a70: 61 74 69 63 20 63 68 61 72 20 2a 0a 43 61 6e 6f  atic char *.Cano
1a80: 6e 69 63 61 6c 50 61 74 68 28 0a 20 20 20 20 63  nicalPath(.    c
1a90: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 6f 6f 74  onst char *zRoot
1aa0: 2c 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  ,.    const char
1ab0: 20 2a 7a 54 61 69 6c 29 0a 7b 0a 20 20 20 20 63   *zTail).{.    c
1ac0: 68 61 72 20 2a 7a 50 61 74 68 3b 0a 20 20 20 20  har *zPath;.    
1ad0: 69 6e 74 20 69 2c 20 6a 2c 20 63 3b 0a 0a 23 69  int i, j, c;..#i
1ae0: 66 64 65 66 20 5f 5f 57 49 4e 33 32 5f 5f 0a 20  fdef __WIN32__. 
1af0: 20 20 20 69 66 20 28 69 73 61 6c 70 68 61 28 7a     if (isalpha(z
1b00: 54 61 69 6c 5b 30 5d 29 20 26 26 20 7a 54 61 69  Tail[0]) && zTai
1b10: 6c 5b 31 5d 20 3d 3d 20 27 3a 27 29 20 7b 0a 09  l[1] == ':') {..
1b20: 7a 54 61 69 6c 20 2b 3d 20 32 3b 0a 20 20 20 20  zTail += 2;.    
1b30: 7d 0a 20 20 20 20 69 66 20 28 7a 54 61 69 6c 5b  }.    if (zTail[
1b40: 30 5d 20 3d 3d 20 27 5c 5c 27 29 20 7b 0a 09 7a  0] == '\\') {..z
1b50: 52 6f 6f 74 20 3d 20 22 22 3b 0a 09 7a 54 61 69  Root = "";..zTai
1b60: 6c 2b 2b 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69  l++;.    }.#endi
1b70: 66 0a 20 20 20 20 69 66 20 28 7a 54 61 69 6c 5b  f.    if (zTail[
1b80: 30 5d 20 3d 3d 20 27 2f 27 29 20 7b 0a 09 7a 52  0] == '/') {..zR
1b90: 6f 6f 74 20 3d 20 22 22 3b 0a 09 7a 54 61 69 6c  oot = "";..zTail
1ba0: 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a 50  ++;.    }.    zP
1bb0: 61 74 68 20 3d 20 54 63 6c 5f 41 6c 6c 6f 63 28  ath = Tcl_Alloc(
1bc0: 73 74 72 6c 65 6e 28 7a 52 6f 6f 74 29 20 2b 20  strlen(zRoot) + 
1bd0: 73 74 72 6c 65 6e 28 7a 54 61 69 6c 29 20 2b 20  strlen(zTail) + 
1be0: 32 29 3b 0a 20 20 20 20 69 66 20 28 7a 54 61 69  2);.    if (zTai
1bf0: 6c 5b 30 5d 29 20 7b 0a 09 73 70 72 69 6e 74 66  l[0]) {..sprintf
1c00: 28 7a 50 61 74 68 2c 20 22 25 73 2f 25 73 22 2c  (zPath, "%s/%s",
1c10: 20 7a 52 6f 6f 74 2c 20 7a 54 61 69 6c 29 3b 0a   zRoot, zTail);.
1c20: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 09 73 74      } else {..st
1c30: 72 63 70 79 28 7a 50 61 74 68 2c 20 7a 52 6f 6f  rcpy(zPath, zRoo
1c40: 74 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 66 6f  t);.    }.    fo
1c50: 72 20 28 69 3d 6a 3d 30 20 3b 20 28 63 20 3d 20  r (i=j=0 ; (c = 
1c60: 7a 50 61 74 68 5b 69 5d 29 20 21 3d 20 30 20 3b  zPath[i]) != 0 ;
1c70: 20 69 2b 2b 29 20 7b 0a 23 69 66 64 65 66 20 5f   i++) {.#ifdef _
1c80: 5f 57 49 4e 33 32 5f 5f 0a 09 69 66 20 28 69 73  _WIN32__..if (is
1c90: 75 70 70 65 72 28 63 29 29 20 7b 0a 09 20 20 20  upper(c)) {..   
1ca0: 20 63 20 3d 20 74 6f 6c 6f 77 65 72 28 63 29 3b   c = tolower(c);
1cb0: 0a 09 7d 20 65 6c 73 65 20 69 66 20 28 63 20 3d  ..} else if (c =
1cc0: 3d 20 27 5c 5c 27 29 20 7b 0a 09 20 20 20 20 63  = '\\') {..    c
1cd0: 20 3d 20 27 2f 27 3b 0a 09 7d 0a 23 65 6e 64 69   = '/';..}.#endi
1ce0: 66 0a 09 69 66 20 28 63 20 3d 3d 20 27 2f 27 29  f..if (c == '/')
1cf0: 20 7b 0a 09 20 20 20 20 69 6e 74 20 63 32 20 3d   {..    int c2 =
1d00: 20 7a 50 61 74 68 5b 69 2b 31 5d 3b 0a 0a 09 20   zPath[i+1];... 
1d10: 20 20 20 69 66 20 28 63 32 20 3d 3d 20 27 2f 27     if (c2 == '/'
1d20: 29 20 7b 0a 09 09 63 6f 6e 74 69 6e 75 65 3b 0a  ) {...continue;.
1d30: 09 20 20 20 20 7d 0a 09 20 20 20 20 69 66 20 28  .    }..    if (
1d40: 63 32 20 3d 3d 20 27 2e 27 29 20 7b 0a 09 09 69  c2 == '.') {...i
1d50: 6e 74 20 63 33 20 3d 20 7a 50 61 74 68 5b 69 2b  nt c3 = zPath[i+
1d60: 32 5d 3b 0a 0a 09 09 69 66 20 28 63 33 20 3d 3d  2];....if (c3 ==
1d70: 20 27 2f 27 20 7c 7c 20 63 33 20 3d 3d 20 30 29   '/' || c3 == 0)
1d80: 20 7b 0a 09 09 20 20 20 20 69 2b 2b 3b 0a 09 09   {...    i++;...
1d90: 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 09 09      continue;...
1da0: 7d 0a 09 09 69 66 20 28 63 33 20 3d 3d 20 27 2e  }...if (c3 == '.
1db0: 27 20 26 26 20 28 7a 50 61 74 68 5b 69 2b 33 5d  ' && (zPath[i+3]
1dc0: 20 3d 3d 20 27 2e 27 20 7c 7c 20 7a 50 61 74 68   == '.' || zPath
1dd0: 5b 69 2b 33 5d 20 3d 3d 20 30 29 29 20 7b 0a 09  [i+3] == 0)) {..
1de0: 09 20 20 20 20 69 20 2b 3d 20 32 3b 0a 09 09 20  .    i += 2;... 
1df0: 20 20 20 77 68 69 6c 65 20 28 6a 20 3e 20 30 20     while (j > 0 
1e00: 26 26 20 7a 50 61 74 68 5b 6a 2d 31 5d 20 21 3d  && zPath[j-1] !=
1e10: 20 27 2f 27 29 20 7b 0a 09 09 09 6a 2d 2d 3b 0a   '/') {....j--;.
1e20: 09 09 20 20 20 20 7d 0a 09 09 20 20 20 20 63 6f  ..    }...    co
1e30: 6e 74 69 6e 75 65 3b 0a 09 09 7d 0a 09 20 20 20  ntinue;...}..   
1e40: 20 7d 0a 09 7d 0a 09 7a 50 61 74 68 5b 6a 2b 2b   }..}..zPath[j++
1e50: 5d 20 3d 20 63 3b 0a 20 20 20 20 7d 0a 20 20 20  ] = c;.    }.   
1e60: 20 69 66 20 28 6a 20 3d 3d 20 30 29 20 7b 0a 09   if (j == 0) {..
1e70: 7a 50 61 74 68 5b 6a 2b 2b 5d 20 3d 20 27 2f 27  zPath[j++] = '/'
1e80: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20 69  ;.    }.    /* i
1e90: 66 20 28 6a 3e 31 20 26 26 20 7a 50 61 74 68 5b  f (j>1 && zPath[
1ea0: 6a 2d 31 5d 20 3d 3d 20 27 2f 27 29 20 6a 2d 2d  j-1] == '/') j--
1eb0: 3b 20 2a 2f 0a 20 20 20 20 7a 50 61 74 68 5b 6a  ; */.    zPath[j
1ec0: 5d 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75 72  ] = 0;.    retur
1ed0: 6e 20 7a 50 61 74 68 3b 0a 7d 0a 2f 2a 0a 20 2a  n zPath;.}./*. *
1ee0: 20 43 6f 6e 73 74 72 75 63 74 20 61 6e 20 61 62   Construct an ab
1ef0: 73 6f 6c 75 74 65 20 70 61 74 68 6e 61 6d 65 20  solute pathname 
1f00: 77 68 65 72 65 20 6d 65 6d 6f 72 79 20 69 73 20  where memory is 
1f10: 6f 62 74 61 69 6e 65 64 20 66 72 6f 6d 20 54 63  obtained from Tc
1f20: 6c 5f 41 6c 6c 6f 63 20 74 68 61 74 0a 20 2a 20  l_Alloc that. * 
1f30: 6d 65 61 6e 73 20 74 68 65 20 73 61 6d 65 20 66  means the same f
1f40: 69 6c 65 20 61 73 20 74 68 65 20 70 61 74 68 6e  ile as the pathn
1f50: 61 6d 65 20 67 69 76 65 6e 2e 0a 20 2a 2f 0a 73  ame given.. */.s
1f60: 74 61 74 69 63 20 63 68 61 72 20 2a 0a 41 62 73  tatic char *.Abs
1f70: 6f 6c 75 74 65 50 61 74 68 28 0a 20 20 20 20 63  olutePath(.    c
1f80: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 52 65 6c 61  onst char *zRela
1f90: 74 69 76 65 29 0a 7b 0a 20 20 20 20 54 63 6c 5f  tive).{.    Tcl_
1fa0: 44 53 74 72 69 6e 67 20 70 77 64 3b 0a 20 20 20  DString pwd;.   
1fb0: 20 63 68 61 72 20 2a 7a 52 65 73 75 6c 74 3b 0a   char *zResult;.
1fc0: 20 20 20 20 69 6e 74 20 6c 65 6e 3b 0a 0a 20 20      int len;..  
1fd0: 20 20 54 63 6c 5f 44 53 74 72 69 6e 67 49 6e 69    Tcl_DStringIni
1fe0: 74 28 26 70 77 64 29 3b 0a 20 20 20 20 69 66 20  t(&pwd);.    if 
1ff0: 28 7a 52 65 6c 61 74 69 76 65 5b 30 5d 20 3d 3d  (zRelative[0] ==
2000: 20 27 7e 27 20 26 26 20 7a 52 65 6c 61 74 69 76   '~' && zRelativ
2010: 65 5b 31 5d 20 3d 3d 20 27 2f 27 29 20 7b 0a 09  e[1] == '/') {..
2020: 2f 2a 20 54 4f 44 4f 3a 20 64 6f 20 74 68 69 73  /* TODO: do this
2030: 20 66 6f 72 20 61 6c 6c 20 70 61 74 68 73 3f 3f   for all paths??
2040: 3f 20 2a 2f 0a 09 69 66 20 28 54 63 6c 5f 54 72  ? */..if (Tcl_Tr
2050: 61 6e 73 6c 61 74 65 46 69 6c 65 4e 61 6d 65 28  anslateFileName(
2060: 30 2c 20 7a 52 65 6c 61 74 69 76 65 2c 20 26 70  0, zRelative, &p
2070: 77 64 29 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  wd) != NULL) {..
2080: 20 20 20 20 7a 52 65 73 75 6c 74 20 3d 20 43 61      zResult = Ca
2090: 6e 6f 6e 69 63 61 6c 50 61 74 68 28 22 22 2c 20  nonicalPath("", 
20a0: 54 63 6c 5f 44 53 74 72 69 6e 67 56 61 6c 75 65  Tcl_DStringValue
20b0: 28 26 70 77 64 29 29 3b 0a 09 20 20 20 20 67 6f  (&pwd));..    go
20c0: 74 6f 20 64 6f 6e 65 3b 0a 09 7d 0a 20 20 20 20  to done;..}.    
20d0: 7d 20 65 6c 73 65 20 69 66 20 28 7a 52 65 6c 61  } else if (zRela
20e0: 74 69 76 65 5b 30 5d 20 21 3d 20 27 2f 27 29 20  tive[0] != '/') 
20f0: 7b 0a 23 69 66 64 65 66 20 5f 5f 57 49 4e 33 32  {.#ifdef __WIN32
2100: 5f 5f 0a 09 69 66 20 28 21 28 7a 52 65 6c 61 74  __..if (!(zRelat
2110: 69 76 65 5b 30 5d 3d 3d 27 5c 5c 27 20 7c 7c 20  ive[0]=='\\' || 
2120: 28 7a 52 65 6c 61 74 69 76 65 5b 30 5d 20 26 26  (zRelative[0] &&
2130: 20 7a 52 65 6c 61 74 69 76 65 5b 31 5d 20 3d 3d   zRelative[1] ==
2140: 20 27 3a 27 29 29 29 20 7b 0a 09 20 20 20 20 2f   ':'))) {..    /
2150: 2a 54 63 6c 5f 47 65 74 43 77 64 28 30 2c 20 26  *Tcl_GetCwd(0, &
2160: 70 77 64 29 3b 20 2a 2f 0a 09 7d 0a 23 65 6c 73  pwd); */..}.#els
2170: 65 0a 09 54 63 6c 5f 47 65 74 43 77 64 28 30 2c  e..Tcl_GetCwd(0,
2180: 20 26 70 77 64 29 3b 0a 23 65 6e 64 69 66 0a 20   &pwd);.#endif. 
2190: 20 20 20 7d 0a 0a 20 20 20 20 7a 52 65 73 75 6c     }..    zResul
21a0: 74 20 3d 20 43 61 6e 6f 6e 69 63 61 6c 50 61 74  t = CanonicalPat
21b0: 68 28 54 63 6c 5f 44 53 74 72 69 6e 67 56 61 6c  h(Tcl_DStringVal
21c0: 75 65 28 26 70 77 64 29 2c 20 7a 52 65 6c 61 74  ue(&pwd), zRelat
21d0: 69 76 65 29 3b 0a 20 20 64 6f 6e 65 3a 0a 20 20  ive);.  done:.  
21e0: 20 20 54 63 6c 5f 44 53 74 72 69 6e 67 46 72 65    Tcl_DStringFre
21f0: 65 28 26 70 77 64 29 3b 0a 20 20 20 20 6c 65 6e  e(&pwd);.    len
2200: 20 3d 20 73 74 72 6c 65 6e 28 7a 52 65 73 75 6c   = strlen(zResul
2210: 74 29 3b 0a 20 20 20 20 69 66 20 28 6c 65 6e 20  t);.    if (len 
2220: 3e 20 30 20 26 26 20 7a 52 65 73 75 6c 74 5b 6c  > 0 && zResult[l
2230: 65 6e 2d 31 5d 20 3d 3d 20 27 2f 27 29 20 7b 0a  en-1] == '/') {.
2240: 09 7a 52 65 73 75 6c 74 5b 6c 65 6e 2d 31 5d 20  .zResult[len-1] 
2250: 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72  = 0;.    }.    r
2260: 65 74 75 72 6e 20 7a 52 65 73 75 6c 74 3b 0a 7d  eturn zResult;.}
2270: 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 61 20 5a  ../*.** Read a Z
2280: 49 50 20 61 72 63 68 69 76 65 20 61 6e 64 20 6d  IP archive and m
2290: 61 6b 65 20 65 6e 74 72 69 65 73 20 69 6e 20 74  ake entries in t
22a0: 68 65 20 76 69 72 75 74 61 6c 20 66 69 6c 65 20  he virutal file 
22b0: 68 61 73 68 20 74 61 62 6c 65 20 66 6f 72 20 61  hash table for a
22c0: 6c 6c 0a 2a 2a 20 63 6f 6e 74 65 6e 74 20 66 69  ll.** content fi
22d0: 6c 65 73 20 6f 66 20 74 68 61 74 20 5a 49 50 20  les of that ZIP 
22e0: 61 72 63 68 69 76 65 2e 20 20 41 6c 73 6f 20 69  archive.  Also i
22f0: 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 5a 56  nitialize the ZV
2300: 46 53 20 69 66 20 74 68 69 73 0a 2a 2a 20 72 6f  FS if this.** ro
2310: 75 74 69 6e 65 20 68 61 73 20 6e 6f 74 20 62 65  utine has not be
2320: 65 6e 20 70 72 65 76 69 6f 75 73 6c 79 20 63 61  en previously ca
2330: 6c 6c 65 64 2e 0a 2a 2f 0a 69 6e 74 20 5a 76 66  lled..*/.int Zvf
2340: 73 5f 4d 6f 75 6e 74 28 0a 20 20 54 63 6c 5f 49  s_Mount(.  Tcl_I
2350: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 20  nterp *interp,  
2360: 20 20 2f 2a 20 4c 65 61 76 65 20 65 72 72 6f 72    /* Leave error
2370: 20 6d 65 73 73 61 67 65 73 20 69 6e 20 74 68 69   messages in thi
2380: 73 20 69 6e 74 65 72 70 72 65 74 65 72 20 2a 2f  s interpreter */
2390: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
23a0: 41 72 63 68 69 76 65 2c 20 20 20 20 20 20 20 20  Archive,        
23b0: 2f 2a 20 54 68 65 20 5a 49 50 20 61 72 63 68 69  /* The ZIP archi
23c0: 76 65 20 66 69 6c 65 20 2a 2f 0a 20 20 63 6f 6e  ve file */.  con
23d0: 73 74 20 63 68 61 72 20 2a 7a 4d 6f 75 6e 74 50  st char *zMountP
23e0: 6f 69 6e 74 20 20 20 20 20 20 2f 2a 20 4d 6f 75  oint      /* Mou
23f0: 6e 74 20 63 6f 6e 74 65 6e 74 73 20 61 74 20 74  nt contents at t
2400: 68 69 73 20 64 69 72 65 63 74 6f 72 79 20 2a 2f  his directory */
2410: 0a 29 20 7b 0a 20 20 20 20 54 63 6c 5f 43 68 61  .) {.    Tcl_Cha
2420: 6e 6e 65 6c 20 63 68 61 6e 3b 09 09 2f 2a 20 55  nnel chan;../* U
2430: 73 65 64 20 66 6f 72 20 72 65 61 64 69 6e 67 20  sed for reading 
2440: 74 68 65 20 5a 49 50 20 61 72 63 68 69 76 65 20  the ZIP archive 
2450: 66 69 6c 65 20 2a 2f 0a 20 20 20 20 63 68 61 72  file */.    char
2460: 20 2a 7a 41 72 63 68 69 76 65 4e 61 6d 65 20 3d   *zArchiveName =
2470: 20 30 3b 09 2f 2a 20 41 20 63 6f 70 79 20 6f 66   0;./* A copy of
2480: 20 7a 41 72 63 68 69 76 65 20 2a 2f 0a 20 20 20   zArchive */.   
2490: 20 63 68 61 72 20 2a 7a 54 72 75 65 4e 61 6d 65   char *zTrueName
24a0: 20 3d 20 30 3b 09 2f 2a 20 41 20 63 6f 70 79 20   = 0;./* A copy 
24b0: 6f 66 20 7a 4d 6f 75 6e 74 50 6f 69 6e 74 20 2a  of zMountPoint *
24c0: 2f 0a 20 20 20 20 69 6e 74 20 6e 46 69 6c 65 3b  /.    int nFile;
24d0: 09 09 09 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20  .../* Number of 
24e0: 66 69 6c 65 73 20 69 6e 20 74 68 65 20 61 72 63  files in the arc
24f0: 68 69 76 65 20 2a 2f 0a 20 20 20 20 69 6e 74 20  hive */.    int 
2500: 69 50 6f 73 3b 09 09 09 2f 2a 20 43 75 72 72 65  iPos;.../* Curre
2510: 6e 74 20 70 6f 73 69 74 69 6f 6e 20 69 6e 20 74  nt position in t
2520: 68 65 20 61 72 63 68 69 76 65 20 66 69 6c 65 20  he archive file 
2530: 2a 2f 0a 20 20 20 20 5a 76 66 73 41 72 63 68 69  */.    ZvfsArchi
2540: 76 65 20 2a 70 41 72 63 68 69 76 65 3b 09 2f 2a  ve *pArchive;./*
2550: 20 54 68 65 20 5a 49 50 20 61 72 63 68 69 76 65   The ZIP archive
2560: 20 62 65 69 6e 67 20 6d 6f 75 6e 74 65 64 20 2a   being mounted *
2570: 2f 0a 20 20 20 20 54 63 6c 5f 48 61 73 68 45 6e  /.    Tcl_HashEn
2580: 74 72 79 20 2a 70 45 6e 74 72 79 3b 09 2f 2a 20  try *pEntry;./* 
2590: 48 61 73 68 20 74 61 62 6c 65 20 65 6e 74 72 79  Hash table entry
25a0: 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 73 4e 65   */.    int isNe
25b0: 77 3b 09 09 09 2f 2a 20 46 6c 61 67 20 74 6f 20  w;.../* Flag to 
25c0: 74 65 6c 6c 20 75 73 65 20 77 68 65 6e 20 61 20  tell use when a 
25d0: 68 61 73 68 20 65 6e 74 72 79 20 69 73 0a 09 09  hash entry is...
25e0: 09 09 20 2a 20 6e 65 77 20 2a 2f 0a 20 20 20 20  .. * new */.    
25f0: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 7a 42  unsigned char zB
2600: 75 66 5b 31 30 30 5d 3b 09 2f 2a 20 53 70 61 63  uf[100];./* Spac
2610: 65 20 69 6e 74 6f 20 77 68 69 63 68 20 74 6f 20  e into which to 
2620: 72 65 61 64 20 66 72 6f 6d 20 74 68 65 20 5a 49  read from the ZI
2630: 50 0a 09 09 09 09 20 2a 20 61 72 63 68 69 76 65  P..... * archive
2640: 20 2a 2f 0a 20 20 20 20 54 63 6c 5f 48 61 73 68   */.    Tcl_Hash
2650: 53 65 61 72 63 68 20 7a 53 65 61 72 63 68 3b 09  Search zSearch;.
2660: 2f 2a 20 53 65 61 72 63 68 20 61 6c 6c 20 6d 6f  /* Search all mo
2670: 75 6e 74 20 70 6f 69 6e 74 73 20 2a 2f 0a 20 20  unt points */.  
2680: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 73    unsigned int s
2690: 74 61 72 74 5a 69 70 3b 0a 0a 20 20 20 20 69 66  tartZip;..    if
26a0: 20 28 21 6c 6f 63 61 6c 2e 69 73 49 6e 69 74 29   (!local.isInit)
26b0: 20 7b 0a 09 72 65 74 75 72 6e 20 54 43 4c 5f 45   {..return TCL_E
26c0: 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  RROR;.    }..   
26d0: 20 2f 2a 0a 20 20 20 20 20 2a 20 49 66 20 6e 75   /*.     * If nu
26e0: 6c 6c 20 61 72 63 68 69 76 65 20 6e 61 6d 65 2c  ll archive name,
26f0: 20 72 65 74 75 72 6e 20 61 6c 6c 20 63 75 72 72   return all curr
2700: 65 6e 74 20 6d 6f 75 6e 74 73 2e 0a 20 20 20 20  ent mounts..    
2710: 20 2a 2f 0a 0a 20 20 20 20 69 66 20 28 21 7a 41   */..    if (!zA
2720: 72 63 68 69 76 65 29 20 7b 0a 09 54 63 6c 5f 44  rchive) {..Tcl_D
2730: 53 74 72 69 6e 67 20 64 53 74 72 3b 0a 0a 09 54  String dStr;...T
2740: 63 6c 5f 44 53 74 72 69 6e 67 49 6e 69 74 28 26  cl_DStringInit(&
2750: 64 53 74 72 29 3b 0a 09 70 45 6e 74 72 79 20 3d  dStr);..pEntry =
2760: 20 54 63 6c 5f 46 69 72 73 74 48 61 73 68 45 6e   Tcl_FirstHashEn
2770: 74 72 79 28 26 6c 6f 63 61 6c 2e 61 72 63 68 69  try(&local.archi
2780: 76 65 48 61 73 68 2c 26 7a 53 65 61 72 63 68 29  veHash,&zSearch)
2790: 3b 0a 09 77 68 69 6c 65 20 28 70 45 6e 74 72 79  ;..while (pEntry
27a0: 29 20 7b 0a 09 20 20 20 20 70 41 72 63 68 69 76  ) {..    pArchiv
27b0: 65 20 3d 20 54 63 6c 5f 47 65 74 48 61 73 68 56  e = Tcl_GetHashV
27c0: 61 6c 75 65 28 70 45 6e 74 72 79 29 3b 0a 09 20  alue(pEntry);.. 
27d0: 20 20 20 69 66 20 28 70 41 72 63 68 69 76 65 29     if (pArchive)
27e0: 20 7b 0a 09 09 54 63 6c 5f 44 53 74 72 69 6e 67   {...Tcl_DString
27f0: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 26 64  AppendElement(&d
2800: 53 74 72 2c 20 70 41 72 63 68 69 76 65 2d 3e 7a  Str, pArchive->z
2810: 4e 61 6d 65 29 3b 0a 09 09 54 63 6c 5f 44 53 74  Name);...Tcl_DSt
2820: 72 69 6e 67 41 70 70 65 6e 64 45 6c 65 6d 65 6e  ringAppendElemen
2830: 74 28 26 64 53 74 72 2c 20 70 41 72 63 68 69 76  t(&dStr, pArchiv
2840: 65 2d 3e 7a 4d 6f 75 6e 74 50 6f 69 6e 74 29 3b  e->zMountPoint);
2850: 0a 09 20 20 20 20 7d 0a 09 20 20 20 20 70 45 6e  ..    }..    pEn
2860: 74 72 79 20 3d 20 54 63 6c 5f 4e 65 78 74 48 61  try = Tcl_NextHa
2870: 73 68 45 6e 74 72 79 28 26 7a 53 65 61 72 63 68  shEntry(&zSearch
2880: 29 3b 0a 09 7d 0a 09 54 63 6c 5f 44 53 74 72 69  );..}..Tcl_DStri
2890: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  ngResult(interp,
28a0: 20 26 64 53 74 72 29 3b 0a 09 72 65 74 75 72 6e   &dStr);..return
28b0: 20 54 43 4c 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 0a   TCL_OK;.    }..
28c0: 20 20 20 20 2f 2a 0a 20 20 20 20 20 2a 20 49 66      /*.     * If
28d0: 20 6e 75 6c 6c 20 6d 6f 75 6e 74 2c 20 72 65 74   null mount, ret
28e0: 75 72 6e 20 6d 6f 75 6e 74 20 70 6f 69 6e 74 2e  urn mount point.
28f0: 0a 20 20 20 20 20 2a 2f 0a 0a 20 20 20 20 2f 2a  .     */..    /*
2900: 54 4f 44 4f 3a 20 63 6c 65 61 6e 75 70 20 61 6c  TODO: cleanup al
2910: 6c 6f 63 61 74 69 6f 6e 73 20 6f 66 20 41 62 73  locations of Abs
2920: 6f 6c 75 74 65 28 29 20 70 61 74 68 2e 2a 2f 0a  olute() path.*/.
2930: 20 20 20 20 69 66 20 28 21 7a 4d 6f 75 6e 74 50      if (!zMountP
2940: 6f 69 6e 74 29 20 7b 0a 09 7a 54 72 75 65 4e 61  oint) {..zTrueNa
2950: 6d 65 20 3d 20 41 62 73 6f 6c 75 74 65 50 61 74  me = AbsolutePat
2960: 68 28 7a 41 72 63 68 69 76 65 29 3b 0a 09 70 45  h(zArchive);..pE
2970: 6e 74 72 79 20 3d 20 54 63 6c 5f 46 69 6e 64 48  ntry = Tcl_FindH
2980: 61 73 68 45 6e 74 72 79 28 26 6c 6f 63 61 6c 2e  ashEntry(&local.
2990: 61 72 63 68 69 76 65 48 61 73 68 2c 20 7a 54 72  archiveHash, zTr
29a0: 75 65 4e 61 6d 65 29 3b 0a 09 69 66 20 28 70 45  ueName);..if (pE
29b0: 6e 74 72 79 29 20 7b 0a 09 20 20 20 20 70 41 72  ntry) {..    pAr
29c0: 63 68 69 76 65 20 3d 20 54 63 6c 5f 47 65 74 48  chive = Tcl_GetH
29d0: 61 73 68 56 61 6c 75 65 28 70 45 6e 74 72 79 29  ashValue(pEntry)
29e0: 3b 0a 09 20 20 20 20 69 66 20 28 70 41 72 63 68  ;..    if (pArch
29f0: 69 76 65 20 26 26 20 69 6e 74 65 72 70 29 20 7b  ive && interp) {
2a00: 0a 09 09 54 63 6c 5f 41 70 70 65 6e 64 52 65 73  ...Tcl_AppendRes
2a10: 75 6c 74 28 69 6e 74 65 72 70 2c 20 70 41 72 63  ult(interp, pArc
2a20: 68 69 76 65 2d 3e 7a 4d 6f 75 6e 74 50 6f 69 6e  hive->zMountPoin
2a30: 74 2c 20 30 29 3b 0a 09 20 20 20 20 7d 0a 09 7d  t, 0);..    }..}
2a40: 0a 09 54 63 6c 5f 46 72 65 65 28 28 63 68 61 72  ..Tcl_Free((char
2a50: 20 2a 29 7a 54 72 75 65 4e 61 6d 65 29 3b 0a 09   *)zTrueName);..
2a60: 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 20  return TCL_OK;. 
2a70: 20 20 20 7d 0a 20 20 20 20 54 63 6c 5f 4d 75 74     }.    Tcl_Mut
2a80: 65 78 4c 6f 63 6b 28 26 41 72 63 68 69 76 65 46  exLock(&ArchiveF
2a90: 69 6c 65 41 63 63 65 73 73 29 3b 0a 20 20 20 20  ileAccess);.    
2aa0: 63 68 61 6e 20 3d 20 54 63 6c 5f 4f 70 65 6e 46  chan = Tcl_OpenF
2ab0: 69 6c 65 43 68 61 6e 6e 65 6c 28 69 6e 74 65 72  ileChannel(inter
2ac0: 70 2c 20 7a 41 72 63 68 69 76 65 2c 20 22 72 22  p, zArchive, "r"
2ad0: 2c 20 30 29 3b 0a 20 20 20 20 69 66 20 28 21 63  , 0);.    if (!c
2ae0: 68 61 6e 29 20 7b 0a 20 20 20 20 20 20 20 20 54  han) {.        T
2af0: 63 6c 5f 4d 75 74 65 78 55 6e 6c 6f 63 6b 28 26  cl_MutexUnlock(&
2b00: 41 72 63 68 69 76 65 46 69 6c 65 41 63 63 65 73  ArchiveFileAcces
2b10: 73 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75  s);.        retu
2b20: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
2b30: 20 20 7d 0a 20 20 20 20 69 66 20 28 54 63 6c 5f    }.    if (Tcl_
2b40: 53 65 74 43 68 61 6e 6e 65 6c 4f 70 74 69 6f 6e  SetChannelOption
2b50: 28 69 6e 74 65 72 70 2c 20 63 68 61 6e 2c 20 22  (interp, chan, "
2b60: 2d 74 72 61 6e 73 6c 61 74 69 6f 6e 22 2c 20 22  -translation", "
2b70: 62 69 6e 61 72 79 22 29 20 21 3d 20 54 43 4c 5f  binary") != TCL_
2b80: 4f 4b 29 7b 0a 09 67 6f 74 6f 20 63 6c 6f 73 65  OK){..goto close
2b90: 52 65 6c 65 61 73 65 44 69 65 3b 0a 20 20 20 20  ReleaseDie;.    
2ba0: 7d 0a 20 20 20 20 69 66 20 28 54 63 6c 5f 53 65  }.    if (Tcl_Se
2bb0: 74 43 68 61 6e 6e 65 6c 4f 70 74 69 6f 6e 28 69  tChannelOption(i
2bc0: 6e 74 65 72 70 2c 20 63 68 61 6e 2c 20 22 2d 65  nterp, chan, "-e
2bd0: 6e 63 6f 64 69 6e 67 22 2c 20 22 62 69 6e 61 72  ncoding", "binar
2be0: 79 22 29 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  y") != TCL_OK) {
2bf0: 0a 09 67 6f 74 6f 20 63 6c 6f 73 65 52 65 6c 65  ..goto closeRele
2c00: 61 73 65 44 69 65 3b 0a 20 20 20 20 7d 0a 0a 20  aseDie;.    }.. 
2c10: 20 20 20 2f 2a 0a 20 20 20 20 20 2a 20 52 65 61     /*.     * Rea
2c20: 64 20 74 68 65 20 22 45 6e 64 20 4f 66 20 43 65  d the "End Of Ce
2c30: 6e 74 72 61 6c 20 44 69 72 65 63 74 6f 72 79 22  ntral Directory"
2c40: 20 72 65 63 6f 72 64 20 66 72 6f 6d 20 74 68 65   record from the
2c50: 20 65 6e 64 20 6f 66 20 74 68 65 20 5a 49 50 0a   end of the ZIP.
2c60: 20 20 20 20 20 2a 20 61 72 63 68 69 76 65 2e 0a       * archive..
2c70: 20 20 20 20 20 2a 2f 0a 0a 20 20 20 20 69 50 6f       */..    iPo
2c80: 73 20 3d 20 54 63 6c 5f 53 65 65 6b 28 63 68 61  s = Tcl_Seek(cha
2c90: 6e 2c 20 2d 32 32 2c 20 53 45 45 4b 5f 45 4e 44  n, -22, SEEK_END
2ca0: 29 3b 0a 20 20 20 20 54 63 6c 5f 52 65 61 64 28  );.    Tcl_Read(
2cb0: 63 68 61 6e 2c 20 28 63 68 61 72 20 2a 29 20 7a  chan, (char *) z
2cc0: 42 75 66 2c 20 32 32 29 3b 0a 20 20 20 20 69 66  Buf, 22);.    if
2cd0: 20 28 6d 65 6d 63 6d 70 28 7a 42 75 66 2c 20 22   (memcmp(zBuf, "
2ce0: 5c 31 32 30 5c 31 31 33 5c 30 35 5c 30 36 22 2c  \120\113\05\06",
2cf0: 20 34 29 29 20 7b 0a 09 69 66 28 69 6e 74 65 72   4)) {..if(inter
2d00: 70 29 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73  p) Tcl_AppendRes
2d10: 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 6e 6f 74  ult(interp, "not
2d20: 20 61 20 5a 49 50 20 61 72 63 68 69 76 65 22 2c   a ZIP archive",
2d30: 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 20 20 20 20   NULL);.        
2d40: 67 6f 74 6f 20 63 6c 6f 73 65 52 65 6c 65 61 73  goto closeReleas
2d50: 65 44 69 65 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  eDie;.    }..   
2d60: 20 2f 2a 0a 20 20 20 20 20 2a 20 43 6f 6e 73 74   /*.     * Const
2d70: 72 75 63 74 20 74 68 65 20 61 72 63 68 69 76 65  ruct the archive
2d80: 20 72 65 63 6f 72 64 2e 0a 20 20 20 20 20 2a 2f   record..     */
2d90: 0a 0a 20 20 20 20 7a 41 72 63 68 69 76 65 4e 61  ..    zArchiveNa
2da0: 6d 65 20 3d 20 41 62 73 6f 6c 75 74 65 50 61 74  me = AbsolutePat
2db0: 68 28 7a 41 72 63 68 69 76 65 29 3b 0a 20 20 20  h(zArchive);.   
2dc0: 20 70 45 6e 74 72 79 20 3d 20 54 63 6c 5f 43 72   pEntry = Tcl_Cr
2dd0: 65 61 74 65 48 61 73 68 45 6e 74 72 79 28 26 6c  eateHashEntry(&l
2de0: 6f 63 61 6c 2e 61 72 63 68 69 76 65 48 61 73 68  ocal.archiveHash
2df0: 2c 20 7a 41 72 63 68 69 76 65 4e 61 6d 65 2c 20  , zArchiveName, 
2e00: 26 69 73 4e 65 77 29 3b 0a 20 20 20 20 69 66 20  &isNew);.    if 
2e10: 28 21 69 73 4e 65 77 29 20 7b 0a 09 70 41 72 63  (!isNew) {..pArc
2e20: 68 69 76 65 20 3d 20 54 63 6c 5f 47 65 74 48 61  hive = Tcl_GetHa
2e30: 73 68 56 61 6c 75 65 28 70 45 6e 74 72 79 29 3b  shValue(pEntry);
2e40: 0a 09 69 66 20 28 69 6e 74 65 72 70 29 20 7b 0a  ..if (interp) {.
2e50: 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 41 70            Tcl_Ap
2e60: 70 65 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72  pendResult(inter
2e70: 70 2c 20 22 61 6c 72 65 61 64 79 20 6d 6f 75 6e  p, "already moun
2e80: 74 65 64 20 61 74 20 22 2c 20 70 41 72 63 68 69  ted at ", pArchi
2e90: 76 65 2d 3e 7a 4d 6f 75 6e 74 50 6f 69 6e 74 2c  ve->zMountPoint,
2ea0: 30 29 3b 0a 09 7d 0a 20 20 20 20 20 20 20 20 67  0);..}.        g
2eb0: 6f 74 6f 20 63 6c 6f 73 65 52 65 6c 65 61 73 65  oto closeRelease
2ec0: 44 69 65 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  Die;.    }..    
2ed0: 2f 2a 0a 20 20 20 20 20 2a 20 45 6d 70 74 79 20  /*.     * Empty 
2ee0: 73 74 72 69 6e 67 20 69 73 20 74 68 65 20 73 70  string is the sp
2ef0: 65 63 69 61 6c 20 63 61 73 65 20 6f 66 20 6d 6f  ecial case of mo
2f00: 75 6e 74 69 6e 67 20 6f 6e 20 69 74 73 65 6c 66  unting on itself
2f10: 2e 0a 20 20 20 20 20 2a 2f 0a 0a 20 20 20 20 69  ..     */..    i
2f20: 66 20 28 21 2a 7a 4d 6f 75 6e 74 50 6f 69 6e 74  f (!*zMountPoint
2f30: 29 20 7b 0a 09 7a 4d 6f 75 6e 74 50 6f 69 6e 74  ) {..zMountPoint
2f40: 20 3d 20 7a 54 72 75 65 4e 61 6d 65 20 3d 20 41   = zTrueName = A
2f50: 62 73 6f 6c 75 74 65 50 61 74 68 28 7a 41 72 63  bsolutePath(zArc
2f60: 68 69 76 65 29 3b 0a 20 20 20 20 7d 0a 0a 20 20  hive);.    }..  
2f70: 20 20 70 41 72 63 68 69 76 65 20 3d 20 28 76 6f    pArchive = (vo
2f80: 69 64 20 2a 29 20 54 63 6c 5f 41 6c 6c 6f 63 28  id *) Tcl_Alloc(
2f90: 73 69 7a 65 6f 66 28 2a 70 41 72 63 68 69 76 65  sizeof(*pArchive
2fa0: 29 20 2b 20 73 74 72 6c 65 6e 28 7a 4d 6f 75 6e  ) + strlen(zMoun
2fb0: 74 50 6f 69 6e 74 29 2b 31 29 3b 0a 20 20 20 20  tPoint)+1);.    
2fc0: 70 41 72 63 68 69 76 65 2d 3e 7a 4e 61 6d 65 20  pArchive->zName 
2fd0: 3d 20 7a 41 72 63 68 69 76 65 4e 61 6d 65 3b 0a  = zArchiveName;.
2fe0: 20 20 20 20 70 41 72 63 68 69 76 65 2d 3e 7a 4d      pArchive->zM
2ff0: 6f 75 6e 74 50 6f 69 6e 74 20 3d 20 28 63 68 61  ountPoint = (cha
3000: 72 20 2a 29 20 26 70 41 72 63 68 69 76 65 5b 31  r *) &pArchive[1
3010: 5d 3b 0a 20 20 20 20 73 74 72 63 70 79 28 70 41  ];.    strcpy(pA
3020: 72 63 68 69 76 65 2d 3e 7a 4d 6f 75 6e 74 50 6f  rchive->zMountPo
3030: 69 6e 74 2c 20 7a 4d 6f 75 6e 74 50 6f 69 6e 74  int, zMountPoint
3040: 29 3b 0a 20 20 20 20 70 41 72 63 68 69 76 65 2d  );.    pArchive-
3050: 3e 70 46 69 6c 65 73 20 3d 20 30 3b 0a 20 20 20  >pFiles = 0;.   
3060: 20 54 63 6c 5f 53 65 74 48 61 73 68 56 61 6c 75   Tcl_SetHashValu
3070: 65 28 70 45 6e 74 72 79 2c 20 70 41 72 63 68 69  e(pEntry, pArchi
3080: 76 65 29 3b 0a 0a 20 20 20 20 2f 2a 0a 20 20 20  ve);..    /*.   
3090: 20 20 2a 20 43 6f 6d 70 75 74 65 20 74 68 65 20    * Compute the 
30a0: 73 74 61 72 74 69 6e 67 20 6c 6f 63 61 74 69 6f  starting locatio
30b0: 6e 20 6f 66 20 74 68 65 20 64 69 72 65 63 74 6f  n of the directo
30c0: 72 79 20 66 6f 72 20 74 68 65 20 5a 49 50 20 61  ry for the ZIP a
30d0: 72 63 68 69 76 65 20 69 6e 0a 20 20 20 20 20 2a  rchive in.     *
30e0: 20 69 50 6f 73 20 74 68 65 6e 20 73 65 65 6b 20   iPos then seek 
30f0: 74 6f 20 74 68 61 74 20 6c 6f 63 61 74 69 6f 6e  to that location
3100: 2e 0a 20 20 20 20 20 2a 2f 0a 0a 20 20 20 20 6e  ..     */..    n
3110: 46 69 6c 65 20 3d 20 49 4e 54 31 36 28 7a 42 75  File = INT16(zBu
3120: 66 2c 20 38 29 3b 0a 20 20 20 20 69 50 6f 73 20  f, 8);.    iPos 
3130: 2d 3d 20 49 4e 54 33 32 28 7a 42 75 66 2c 20 31  -= INT32(zBuf, 1
3140: 32 29 3b 0a 20 20 20 20 54 63 6c 5f 53 65 65 6b  2);.    Tcl_Seek
3150: 28 63 68 61 6e 2c 20 69 50 6f 73 2c 20 53 45 45  (chan, iPos, SEE
3160: 4b 5f 53 45 54 29 3b 0a 20 20 20 20 73 74 61 72  K_SET);.    star
3170: 74 5a 69 70 20 3d 20 69 50 6f 73 3b 0a 0a 20 20  tZip = iPos;..  
3180: 20 20 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 69    while (1) {..i
3190: 6e 74 20 6c 65 6e 4e 61 6d 65 3b 09 09 2f 2a 20  nt lenName;../* 
31a0: 4c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 6e 65  Length of the ne
31b0: 78 74 20 66 69 6c 65 6e 61 6d 65 20 2a 2f 0a 09  xt filename */..
31c0: 69 6e 74 20 6c 65 6e 45 78 74 72 61 3d 30 3b 09  int lenExtra=0;.
31d0: 09 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 22 65  ./* Length of "e
31e0: 78 74 72 61 22 20 64 61 74 61 20 66 6f 72 20 6e  xtra" data for n
31f0: 65 78 74 20 66 69 6c 65 20 2a 2f 0a 09 69 6e 74  ext file */..int
3200: 20 69 44 61 74 61 3b 09 09 2f 2a 20 4f 66 66 73   iData;../* Offs
3210: 65 74 20 74 6f 20 73 74 61 72 74 20 6f 66 20 66  et to start of f
3220: 69 6c 65 20 64 61 74 61 20 2a 2f 0a 09 69 6e 74  ile data */..int
3230: 20 64 6f 73 54 69 6d 65 3b 0a 09 69 6e 74 20 64   dosTime;..int d
3240: 6f 73 44 61 74 65 3b 0a 09 69 6e 74 20 69 73 64  osDate;..int isd
3250: 69 72 3b 0a 09 5a 76 66 73 46 69 6c 65 20 2a 70  ir;..ZvfsFile *p
3260: 5a 76 66 73 3b 09 2f 2a 20 41 20 6e 65 77 20 76  Zvfs;./* A new v
3270: 69 72 74 75 61 6c 20 66 69 6c 65 20 2a 2f 0a 09  irtual file */..
3280: 63 68 61 72 20 2a 7a 46 75 6c 6c 50 61 74 68 3b  char *zFullPath;
3290: 09 2f 2a 20 46 75 6c 6c 20 70 61 74 68 6e 61 6d  ./* Full pathnam
32a0: 65 20 6f 66 20 74 68 65 20 76 69 72 74 75 61 6c  e of the virtual
32b0: 20 66 69 6c 65 20 2a 2f 0a 09 63 68 61 72 20 7a   file */..char z
32c0: 4e 61 6d 65 5b 31 30 32 34 5d 3b 09 2f 2a 20 53  Name[1024];./* S
32d0: 70 61 63 65 20 74 6f 20 68 6f 6c 64 20 74 68 65  pace to hold the
32e0: 20 66 69 6c 65 6e 61 6d 65 20 2a 2f 0a 0a 09 69   filename */...i
32f0: 66 20 28 6e 46 69 6c 65 2d 2d 20 3c 3d 20 30 29  f (nFile-- <= 0)
3300: 20 7b 0a 09 20 20 20 20 69 73 64 69 72 20 3d 20   {..    isdir = 
3310: 31 3b 0a 09 20 20 20 20 7a 46 75 6c 6c 50 61 74  1;..    zFullPat
3320: 68 20 3d 20 43 61 6e 6f 6e 69 63 61 6c 50 61 74  h = CanonicalPat
3330: 68 28 7a 4d 6f 75 6e 74 50 6f 69 6e 74 2c 20 22  h(zMountPoint, "
3340: 22 29 3b 0a 09 20 20 20 20 69 44 61 74 61 20 3d  ");..    iData =
3350: 20 73 74 61 72 74 5a 69 70 3b 0a 09 20 20 20 20   startZip;..    
3360: 67 6f 74 6f 20 61 64 64 65 6e 74 72 79 3b 0a 09  goto addentry;..
3370: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 61 64 20  }.../*.. * Read 
3380: 74 68 65 20 6e 65 78 74 20 64 69 72 65 63 74 6f  the next directo
3390: 72 79 20 65 6e 74 72 79 2e 20 20 45 78 74 72 61  ry entry.  Extra
33a0: 63 74 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74  ct the size of t
33b0: 68 65 20 66 69 6c 65 6e 61 6d 65 2c 0a 09 20 2a  he filename,.. *
33c0: 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65   the size of the
33d0: 20 22 65 78 74 72 61 22 20 69 6e 66 6f 72 6d 61   "extra" informa
33e0: 74 69 6f 6e 2c 20 61 6e 64 20 74 68 65 20 6f 66  tion, and the of
33f0: 66 73 65 74 20 69 6e 74 6f 20 74 68 65 0a 09 20  fset into the.. 
3400: 2a 20 61 72 63 68 69 76 65 20 66 69 6c 65 20 6f  * archive file o
3410: 66 20 74 68 65 20 66 69 6c 65 20 64 61 74 61 2e  f the file data.
3420: 0a 09 20 2a 2f 0a 0a 09 54 63 6c 5f 52 65 61 64  .. */...Tcl_Read
3430: 28 63 68 61 6e 2c 20 28 63 68 61 72 20 2a 29 20  (chan, (char *) 
3440: 7a 42 75 66 2c 20 34 36 29 3b 0a 09 69 66 20 28  zBuf, 46);..if (
3450: 6d 65 6d 63 6d 70 28 7a 42 75 66 2c 20 22 5c 31  memcmp(zBuf, "\1
3460: 32 30 5c 31 31 33 5c 30 31 5c 30 32 22 2c 20 34  20\113\01\02", 4
3470: 29 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 69  )) {.          i
3480: 66 28 69 6e 74 65 72 70 29 20 7b 0a 09 20 20 20  f(interp) {..   
3490: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
34a0: 74 28 69 6e 74 65 72 70 2c 20 22 69 6c 6c 2d 66  t(interp, "ill-f
34b0: 6f 72 6d 65 64 20 63 65 6e 74 72 61 6c 20 64 69  ormed central di
34c0: 72 65 63 74 6f 72 79 20 65 6e 74 72 79 22 2c 4e  rectory entry",N
34d0: 55 4c 4c 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ULL);.          
34e0: 7d 0a 20 20 20 20 20 20 20 20 20 20 69 66 20 28  }.          if (
34f0: 7a 54 72 75 65 4e 61 6d 65 29 20 7b 0a 20 20 20  zTrueName) {.   
3500: 20 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 46             Tcl_F
3510: 72 65 65 28 7a 54 72 75 65 4e 61 6d 65 29 3b 0a  ree(zTrueName);.
3520: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
3530: 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c        return TCL
3540: 5f 45 52 52 4f 52 3b 0a 09 7d 0a 09 6c 65 6e 4e  _ERROR;..}..lenN
3550: 61 6d 65 20 3d 20 49 4e 54 31 36 28 7a 42 75 66  ame = INT16(zBuf
3560: 2c 20 32 38 29 3b 0a 09 6c 65 6e 45 78 74 72 61  , 28);..lenExtra
3570: 20 3d 20 49 4e 54 31 36 28 7a 42 75 66 2c 20 33   = INT16(zBuf, 3
3580: 30 29 20 2b 20 49 4e 54 31 36 28 7a 42 75 66 2c  0) + INT16(zBuf,
3590: 20 33 32 29 3b 0a 09 69 44 61 74 61 20 3d 20 49   32);..iData = I
35a0: 4e 54 33 32 28 7a 42 75 66 2c 20 34 32 29 3b 0a  NT32(zBuf, 42);.
35b0: 0a 09 2f 2a 0a 09 20 2a 20 49 66 20 74 68 65 20  ../*.. * If the 
35c0: 76 69 72 74 75 61 6c 20 66 69 6c 65 6e 61 6d 65  virtual filename
35d0: 20 69 73 20 74 6f 6f 20 62 69 67 20 74 6f 20 66   is too big to f
35e0: 69 74 20 69 6e 20 7a 4e 61 6d 65 5b 5d 2c 20 74  it in zName[], t
35f0: 68 65 6e 20 73 6b 69 70 0a 09 20 2a 20 74 68 69  hen skip.. * thi
3600: 73 20 66 69 6c 65 0a 09 20 2a 2f 0a 0a 09 69 66  s file.. */...if
3610: 20 28 6c 65 6e 4e 61 6d 65 20 3e 3d 20 73 69 7a   (lenName >= siz
3620: 65 6f 66 28 7a 4e 61 6d 65 29 29 20 7b 0a 09 20  eof(zName)) {.. 
3630: 20 20 20 54 63 6c 5f 53 65 65 6b 28 63 68 61 6e     Tcl_Seek(chan
3640: 2c 20 6c 65 6e 4e 61 6d 65 20 2b 20 6c 65 6e 45  , lenName + lenE
3650: 78 74 72 61 2c 20 53 45 45 4b 5f 43 55 52 29 3b  xtra, SEEK_CUR);
3660: 0a 09 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a  ..    continue;.
3670: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 6f 6e 73  .}.../*.. * Cons
3680: 74 72 75 63 74 20 61 6e 20 65 6e 74 72 79 20 69  truct an entry i
3690: 6e 20 6c 6f 63 61 6c 2e 66 69 6c 65 48 61 73 68  n local.fileHash
36a0: 20 66 6f 72 20 74 68 69 73 20 76 69 72 74 75 61   for this virtua
36b0: 6c 20 66 69 6c 65 2e 0a 09 20 2a 2f 0a 0a 09 54  l file... */...T
36c0: 63 6c 5f 52 65 61 64 28 63 68 61 6e 2c 20 7a 4e  cl_Read(chan, zN
36d0: 61 6d 65 2c 20 6c 65 6e 4e 61 6d 65 29 3b 0a 09  ame, lenName);..
36e0: 69 73 64 69 72 20 3d 20 30 3b 0a 09 69 66 20 28  isdir = 0;..if (
36f0: 6c 65 6e 4e 61 6d 65 20 3e 20 30 20 26 26 20 7a  lenName > 0 && z
3700: 4e 61 6d 65 5b 6c 65 6e 4e 61 6d 65 2d 31 5d 20  Name[lenName-1] 
3710: 3d 3d 20 27 2f 27 29 20 7b 0a 09 20 20 20 20 6c  == '/') {..    l
3720: 65 6e 4e 61 6d 65 2d 2d 3b 0a 09 20 20 20 20 69  enName--;..    i
3730: 73 64 69 72 20 3d 20 32 3b 0a 09 7d 0a 09 7a 4e  sdir = 2;..}..zN
3740: 61 6d 65 5b 6c 65 6e 4e 61 6d 65 5d 20 3d 20 30  ame[lenName] = 0
3750: 3b 0a 09 7a 46 75 6c 6c 50 61 74 68 20 3d 20 43  ;..zFullPath = C
3760: 61 6e 6f 6e 69 63 61 6c 50 61 74 68 28 7a 4d 6f  anonicalPath(zMo
3770: 75 6e 74 50 6f 69 6e 74 2c 20 7a 4e 61 6d 65 29  untPoint, zName)
3780: 3b 0a 20 20 20 20 61 64 64 65 6e 74 72 79 3a 0a  ;.    addentry:.
3790: 09 70 5a 76 66 73 20 3d 20 28 76 6f 69 64 20 2a  .pZvfs = (void *
37a0: 29 20 54 63 6c 5f 41 6c 6c 6f 63 28 73 69 7a 65  ) Tcl_Alloc(size
37b0: 6f 66 28 2a 70 5a 76 66 73 29 29 3b 0a 09 70 5a  of(*pZvfs));..pZ
37c0: 76 66 73 2d 3e 7a 4e 61 6d 65 20 3d 20 7a 46 75  vfs->zName = zFu
37d0: 6c 6c 50 61 74 68 3b 0a 09 70 5a 76 66 73 2d 3e  llPath;..pZvfs->
37e0: 70 41 72 63 68 69 76 65 20 3d 20 70 41 72 63 68  pArchive = pArch
37f0: 69 76 65 3b 0a 09 70 5a 76 66 73 2d 3e 69 73 64  ive;..pZvfs->isd
3800: 69 72 20 3d 20 69 73 64 69 72 3b 0a 09 70 5a 76  ir = isdir;..pZv
3810: 66 73 2d 3e 64 65 70 74 68 20 3d 20 73 74 72 63  fs->depth = strc
3820: 68 72 63 6e 74 28 7a 46 75 6c 6c 50 61 74 68 2c  hrcnt(zFullPath,
3830: 20 27 2f 27 29 3b 0a 09 70 5a 76 66 73 2d 3e 69   '/');..pZvfs->i
3840: 4f 66 66 73 65 74 20 3d 20 69 44 61 74 61 3b 0a  Offset = iData;.
3850: 09 69 66 20 28 69 44 61 74 61 20 3c 20 73 74 61  .if (iData < sta
3860: 72 74 5a 69 70 29 20 7b 0a 09 20 20 20 20 73 74  rtZip) {..    st
3870: 61 72 74 5a 69 70 20 3d 20 69 44 61 74 61 3b 0a  artZip = iData;.
3880: 09 7d 0a 09 64 6f 73 44 61 74 65 20 3d 20 49 4e  .}..dosDate = IN
3890: 54 31 36 28 7a 42 75 66 2c 20 31 34 29 3b 0a 09  T16(zBuf, 14);..
38a0: 64 6f 73 54 69 6d 65 20 3d 20 49 4e 54 31 36 28  dosTime = INT16(
38b0: 7a 42 75 66 2c 20 31 32 29 3b 0a 09 70 5a 76 66  zBuf, 12);..pZvf
38c0: 73 2d 3e 74 69 6d 65 73 74 61 6d 70 20 3d 20 44  s->timestamp = D
38d0: 6f 73 54 69 6d 65 44 61 74 65 28 64 6f 73 44 61  osTimeDate(dosDa
38e0: 74 65 2c 20 64 6f 73 54 69 6d 65 29 3b 0a 09 70  te, dosTime);..p
38f0: 5a 76 66 73 2d 3e 6e 42 79 74 65 20 3d 20 49 4e  Zvfs->nByte = IN
3900: 54 33 32 28 7a 42 75 66 2c 20 32 34 29 3b 0a 09  T32(zBuf, 24);..
3910: 70 5a 76 66 73 2d 3e 6e 42 79 74 65 43 6f 6d 70  pZvfs->nByteComp
3920: 72 20 3d 20 49 4e 54 33 32 28 7a 42 75 66 2c 20  r = INT32(zBuf, 
3930: 32 30 29 3b 0a 09 70 5a 76 66 73 2d 3e 70 4e 65  20);..pZvfs->pNe
3940: 78 74 20 3d 20 70 41 72 63 68 69 76 65 2d 3e 70  xt = pArchive->p
3950: 46 69 6c 65 73 3b 0a 09 70 5a 76 66 73 2d 3e 70  Files;..pZvfs->p
3960: 65 72 6d 69 73 73 69 6f 6e 73 20 3d 20 30 78 66  ermissions = 0xf
3970: 66 66 66 20 26 20 28 49 4e 54 33 32 28 7a 42 75  fff & (INT32(zBu
3980: 66 2c 20 33 38 29 20 3e 3e 20 31 36 29 3b 0a 09  f, 38) >> 16);..
3990: 70 41 72 63 68 69 76 65 2d 3e 70 46 69 6c 65 73  pArchive->pFiles
39a0: 20 3d 20 70 5a 76 66 73 3b 0a 09 70 45 6e 74 72   = pZvfs;..pEntr
39b0: 79 20 3d 20 54 63 6c 5f 43 72 65 61 74 65 48 61  y = Tcl_CreateHa
39c0: 73 68 45 6e 74 72 79 28 26 6c 6f 63 61 6c 2e 66  shEntry(&local.f
39d0: 69 6c 65 48 61 73 68 2c 20 7a 46 75 6c 6c 50 61  ileHash, zFullPa
39e0: 74 68 2c 20 26 69 73 4e 65 77 29 3b 0a 09 69 66  th, &isNew);..if
39f0: 20 28 69 73 4e 65 77 29 20 7b 0a 09 20 20 20 20   (isNew) {..    
3a00: 70 5a 76 66 73 2d 3e 70 4e 65 78 74 4e 61 6d 65  pZvfs->pNextName
3a10: 20 3d 20 30 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a   = 0;..} else {.
3a20: 09 20 20 20 20 5a 76 66 73 46 69 6c 65 20 2a 70  .    ZvfsFile *p
3a30: 4f 6c 64 20 3d 20 54 63 6c 5f 47 65 74 48 61 73  Old = Tcl_GetHas
3a40: 68 56 61 6c 75 65 28 70 45 6e 74 72 79 29 3b 0a  hValue(pEntry);.
3a50: 09 20 20 20 20 70 4f 6c 64 2d 3e 70 50 72 65 76  .    pOld->pPrev
3a60: 4e 61 6d 65 20 3d 20 70 5a 76 66 73 3b 0a 09 20  Name = pZvfs;.. 
3a70: 20 20 20 70 5a 76 66 73 2d 3e 70 4e 65 78 74 4e     pZvfs->pNextN
3a80: 61 6d 65 20 3d 20 70 4f 6c 64 3b 0a 09 7d 0a 09  ame = pOld;..}..
3a90: 70 5a 76 66 73 2d 3e 70 50 72 65 76 4e 61 6d 65  pZvfs->pPrevName
3aa0: 20 3d 20 30 3b 0a 09 54 63 6c 5f 53 65 74 48 61   = 0;..Tcl_SetHa
3ab0: 73 68 56 61 6c 75 65 28 70 45 6e 74 72 79 2c 20  shValue(pEntry, 
3ac0: 70 5a 76 66 73 29 3b 0a 0a 09 69 66 20 28 6e 46  pZvfs);...if (nF
3ad0: 69 6c 65 20 3c 20 30 29 20 7b 0a 09 20 20 20 20  ile < 0) {..    
3ae0: 62 72 65 61 6b 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  break;..}.../*..
3af0: 20 2a 20 53 6b 69 70 20 6f 76 65 72 20 74 68 65   * Skip over the
3b00: 20 65 78 74 72 61 20 69 6e 66 6f 72 6d 61 74 69   extra informati
3b10: 6f 6e 20 73 6f 20 74 68 61 74 20 74 68 65 20 6e  on so that the n
3b20: 65 78 74 20 72 65 61 64 20 77 69 6c 6c 20 62 65  ext read will be
3b30: 20 66 72 6f 6d 0a 09 20 2a 20 74 68 65 20 62 65   from.. * the be
3b40: 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68 65 20 6e  ginning of the n
3b50: 65 78 74 20 64 69 72 65 63 74 6f 72 79 20 65 6e  ext directory en
3b60: 74 72 79 2e 0a 09 20 2a 2f 0a 0a 09 54 63 6c 5f  try... */...Tcl_
3b70: 53 65 65 6b 28 63 68 61 6e 2c 20 6c 65 6e 45 78  Seek(chan, lenEx
3b80: 74 72 61 2c 20 53 45 45 4b 5f 43 55 52 29 3b 0a  tra, SEEK_CUR);.
3b90: 20 20 20 20 7d 0a 20 20 20 20 54 63 6c 5f 43 6c      }.    Tcl_Cl
3ba0: 6f 73 65 28 69 6e 74 65 72 70 2c 20 63 68 61 6e  ose(interp, chan
3bb0: 29 3b 0a 20 20 20 20 69 66 20 28 7a 54 72 75 65  );.    if (zTrue
3bc0: 4e 61 6d 65 29 20 7b 0a 09 54 63 6c 5f 46 72 65  Name) {..Tcl_Fre
3bd0: 65 28 7a 54 72 75 65 4e 61 6d 65 29 3b 0a 20 20  e(zTrueName);.  
3be0: 20 20 7d 0a 20 20 20 20 54 63 6c 5f 4d 75 74 65    }.    Tcl_Mute
3bf0: 78 55 6e 6c 6f 63 6b 28 26 41 72 63 68 69 76 65  xUnlock(&Archive
3c00: 46 69 6c 65 41 63 63 65 73 73 29 3b 0a 20 20 20  FileAccess);.   
3c10: 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a   return TCL_OK;.
3c20: 0a 63 6c 6f 73 65 52 65 6c 65 61 73 65 44 69 65  .closeReleaseDie
3c30: 3a 0a 20 20 54 63 6c 5f 43 6c 6f 73 65 28 69 6e  :.  Tcl_Close(in
3c40: 74 65 72 70 2c 20 63 68 61 6e 29 3b 0a 20 20 54  terp, chan);.  T
3c50: 63 6c 5f 4d 75 74 65 78 55 6e 6c 6f 63 6b 28 26  cl_MutexUnlock(&
3c60: 41 72 63 68 69 76 65 46 69 6c 65 41 63 63 65 73  ArchiveFileAcces
3c70: 73 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  s);.  return TCL
3c80: 5f 45 52 52 4f 52 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  _ERROR;.}../*.**
3c90: 20 4c 6f 63 61 74 65 20 74 68 65 20 5a 76 66 73   Locate the Zvfs
3ca0: 46 69 6c 65 20 73 74 72 75 63 74 75 72 65 20 74  File structure t
3cb0: 68 61 74 20 63 6f 72 72 65 73 70 6f 6e 64 73 20  hat corresponds 
3cc0: 74 6f 20 74 68 65 20 66 69 6c 65 20 6e 61 6d 65  to the file name
3cd0: 64 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 4e 55 4c  d..** Return NUL
3ce0: 4c 20 69 66 20 74 68 65 72 65 20 69 73 20 6e 6f  L if there is no
3cf0: 20 73 75 63 68 20 5a 76 66 73 46 69 6c 65 2e 0a   such ZvfsFile..
3d00: 2a 2f 0a 73 74 61 74 69 63 20 5a 76 66 73 46 69  */.static ZvfsFi
3d10: 6c 65 20 2a 5a 76 66 73 4c 6f 6f 6b 75 70 28 63  le *ZvfsLookup(c
3d20: 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b  har *zFilename){
3d30: 0a 20 20 63 68 61 72 20 2a 7a 54 72 75 65 4e 61  .  char *zTrueNa
3d40: 6d 65 3b 0a 20 20 54 63 6c 5f 48 61 73 68 45 6e  me;.  Tcl_HashEn
3d50: 74 72 79 20 2a 70 45 6e 74 72 79 3b 0a 20 20 5a  try *pEntry;.  Z
3d60: 76 66 73 46 69 6c 65 20 2a 70 46 69 6c 65 3b 0a  vfsFile *pFile;.
3d70: 0a 20 20 69 66 28 20 6c 6f 63 61 6c 2e 69 73 49  .  if( local.isI
3d80: 6e 69 74 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  nit==0 ) return 
3d90: 30 3b 0a 20 20 7a 54 72 75 65 4e 61 6d 65 20 3d  0;.  zTrueName =
3da0: 20 41 62 73 6f 6c 75 74 65 50 61 74 68 28 7a 46   AbsolutePath(zF
3db0: 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 70 45 6e 74  ilename);.  pEnt
3dc0: 72 79 20 3d 20 54 63 6c 5f 46 69 6e 64 48 61 73  ry = Tcl_FindHas
3dd0: 68 45 6e 74 72 79 28 26 6c 6f 63 61 6c 2e 66 69  hEntry(&local.fi
3de0: 6c 65 48 61 73 68 2c 20 7a 54 72 75 65 4e 61 6d  leHash, zTrueNam
3df0: 65 29 3b 0a 20 20 70 46 69 6c 65 20 3d 20 70 45  e);.  pFile = pE
3e00: 6e 74 72 79 20 3f 20 54 63 6c 5f 47 65 74 48 61  ntry ? Tcl_GetHa
3e10: 73 68 56 61 6c 75 65 28 70 45 6e 74 72 79 29 20  shValue(pEntry) 
3e20: 3a 20 30 3b 0a 20 20 54 63 6c 5f 46 72 65 65 28  : 0;.  Tcl_Free(
3e30: 7a 54 72 75 65 4e 61 6d 65 29 3b 0a 20 20 72 65  zTrueName);.  re
3e40: 74 75 72 6e 20 70 46 69 6c 65 3b 0a 7d 0a 0a 2f  turn pFile;.}../
3e50: 2a 0a 2a 2a 20 55 6e 6d 6f 75 6e 74 20 61 6c 6c  *.** Unmount all
3e60: 20 74 68 65 20 66 69 6c 65 73 20 69 6e 20 74 68   the files in th
3e70: 65 20 67 69 76 65 6e 20 5a 49 50 20 61 72 63 68  e given ZIP arch
3e80: 69 76 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ive..*/.static i
3e90: 6e 74 20 5a 76 66 73 5f 55 6e 6d 6f 75 6e 74 28  nt Zvfs_Unmount(
3ea0: 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20  .    const char 
3eb0: 2a 7a 41 72 63 68 69 76 65 0a 29 20 7b 0a 20 20  *zArchive.) {.  
3ec0: 20 20 63 68 61 72 20 2a 7a 41 72 63 68 69 76 65    char *zArchive
3ed0: 4e 61 6d 65 3b 0a 20 20 20 20 5a 76 66 73 41 72  Name;.    ZvfsAr
3ee0: 63 68 69 76 65 20 2a 70 41 72 63 68 69 76 65 3b  chive *pArchive;
3ef0: 0a 20 20 20 20 5a 76 66 73 46 69 6c 65 20 2a 70  .    ZvfsFile *p
3f00: 46 69 6c 65 2c 20 2a 70 4e 65 78 74 46 69 6c 65  File, *pNextFile
3f10: 3b 0a 20 20 20 20 54 63 6c 5f 48 61 73 68 45 6e  ;.    Tcl_HashEn
3f20: 74 72 79 20 2a 70 45 6e 74 72 79 3b 0a 0a 20 20  try *pEntry;..  
3f30: 20 20 7a 41 72 63 68 69 76 65 4e 61 6d 65 20 3d    zArchiveName =
3f40: 20 41 62 73 6f 6c 75 74 65 50 61 74 68 28 7a 41   AbsolutePath(zA
3f50: 72 63 68 69 76 65 29 3b 0a 20 20 20 20 70 45 6e  rchive);.    pEn
3f60: 74 72 79 20 3d 20 54 63 6c 5f 46 69 6e 64 48 61  try = Tcl_FindHa
3f70: 73 68 45 6e 74 72 79 28 26 6c 6f 63 61 6c 2e 61  shEntry(&local.a
3f80: 72 63 68 69 76 65 48 61 73 68 2c 20 7a 41 72 63  rchiveHash, zArc
3f90: 68 69 76 65 4e 61 6d 65 29 3b 0a 20 20 20 20 54  hiveName);.    T
3fa0: 63 6c 5f 46 72 65 65 28 7a 41 72 63 68 69 76 65  cl_Free(zArchive
3fb0: 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 20 28 70  Name);.    if (p
3fc0: 45 6e 74 72 79 20 3d 3d 20 30 29 20 7b 0a 09 72  Entry == 0) {..r
3fd0: 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20  eturn 0;.    }. 
3fe0: 20 20 20 54 63 6c 5f 4d 75 74 65 78 4c 6f 63 6b     Tcl_MutexLock
3ff0: 28 26 41 72 63 68 69 76 65 46 69 6c 65 41 63 63  (&ArchiveFileAcc
4000: 65 73 73 29 3b 0a 20 20 20 20 70 41 72 63 68 69  ess);.    pArchi
4010: 76 65 20 3d 20 54 63 6c 5f 47 65 74 48 61 73 68  ve = Tcl_GetHash
4020: 56 61 6c 75 65 28 70 45 6e 74 72 79 29 3b 0a 20  Value(pEntry);. 
4030: 20 20 20 54 63 6c 5f 44 65 6c 65 74 65 48 61 73     Tcl_DeleteHas
4040: 68 45 6e 74 72 79 28 70 45 6e 74 72 79 29 3b 0a  hEntry(pEntry);.
4050: 20 20 20 20 54 63 6c 5f 46 72 65 65 28 70 41 72      Tcl_Free(pAr
4060: 63 68 69 76 65 2d 3e 7a 4e 61 6d 65 29 3b 0a 20  chive->zName);. 
4070: 20 20 20 66 6f 72 28 70 46 69 6c 65 3d 70 41 72     for(pFile=pAr
4080: 63 68 69 76 65 2d 3e 70 46 69 6c 65 73 20 3b 20  chive->pFiles ; 
4090: 70 46 69 6c 65 3b 20 70 46 69 6c 65 3d 70 4e 65  pFile; pFile=pNe
40a0: 78 74 46 69 6c 65 29 20 7b 0a 09 70 4e 65 78 74  xtFile) {..pNext
40b0: 46 69 6c 65 20 3d 20 70 46 69 6c 65 2d 3e 70 4e  File = pFile->pN
40c0: 65 78 74 3b 0a 09 69 66 20 28 70 46 69 6c 65 2d  ext;..if (pFile-
40d0: 3e 70 4e 65 78 74 4e 61 6d 65 29 20 7b 0a 09 20  >pNextName) {.. 
40e0: 20 20 20 70 46 69 6c 65 2d 3e 70 4e 65 78 74 4e     pFile->pNextN
40f0: 61 6d 65 2d 3e 70 50 72 65 76 4e 61 6d 65 20 3d  ame->pPrevName =
4100: 20 70 46 69 6c 65 2d 3e 70 50 72 65 76 4e 61 6d   pFile->pPrevNam
4110: 65 3b 0a 09 7d 0a 09 69 66 20 28 70 46 69 6c 65  e;..}..if (pFile
4120: 2d 3e 70 50 72 65 76 4e 61 6d 65 29 20 7b 0a 09  ->pPrevName) {..
4130: 20 20 20 20 70 46 69 6c 65 2d 3e 70 50 72 65 76      pFile->pPrev
4140: 4e 61 6d 65 2d 3e 70 4e 65 78 74 4e 61 6d 65 20  Name->pNextName 
4150: 3d 20 70 46 69 6c 65 2d 3e 70 4e 65 78 74 4e 61  = pFile->pNextNa
4160: 6d 65 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 20  me;..} else {.. 
4170: 20 20 20 70 45 6e 74 72 79 20 3d 20 54 63 6c 5f     pEntry = Tcl_
4180: 46 69 6e 64 48 61 73 68 45 6e 74 72 79 28 26 6c  FindHashEntry(&l
4190: 6f 63 61 6c 2e 66 69 6c 65 48 61 73 68 2c 20 70  ocal.fileHash, p
41a0: 46 69 6c 65 2d 3e 7a 4e 61 6d 65 29 3b 0a 09 20  File->zName);.. 
41b0: 20 20 20 69 66 20 28 70 45 6e 74 72 79 20 3d 3d     if (pEntry ==
41c0: 20 30 29 20 7b 0a 09 09 54 63 6c 5f 50 61 6e 69   0) {...Tcl_Pani
41d0: 63 28 22 54 68 69 73 20 73 68 6f 75 6c 64 20 6e  c("This should n
41e0: 65 76 65 72 20 68 61 70 70 65 6e 22 29 3b 0a 09  ever happen");..
41f0: 20 20 20 20 7d 20 65 6c 73 65 20 69 66 20 28 70      } else if (p
4200: 46 69 6c 65 2d 3e 70 4e 65 78 74 4e 61 6d 65 29  File->pNextName)
4210: 20 7b 0a 09 09 54 63 6c 5f 53 65 74 48 61 73 68   {...Tcl_SetHash
4220: 56 61 6c 75 65 28 70 45 6e 74 72 79 2c 20 70 46  Value(pEntry, pF
4230: 69 6c 65 2d 3e 70 4e 65 78 74 4e 61 6d 65 29 3b  ile->pNextName);
4240: 0a 09 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 09  ..    } else {..
4250: 09 54 63 6c 5f 44 65 6c 65 74 65 48 61 73 68 45  .Tcl_DeleteHashE
4260: 6e 74 72 79 28 70 45 6e 74 72 79 29 3b 0a 09 20  ntry(pEntry);.. 
4270: 20 20 20 7d 0a 09 7d 0a 09 54 63 6c 5f 46 72 65     }..}..Tcl_Fre
4280: 65 28 70 46 69 6c 65 2d 3e 7a 4e 61 6d 65 29 3b  e(pFile->zName);
4290: 0a 09 54 63 6c 5f 46 72 65 65 28 28 76 6f 69 64  ..Tcl_Free((void
42a0: 20 2a 29 20 70 46 69 6c 65 29 3b 0a 20 20 20 20   *) pFile);.    
42b0: 7d 0a 20 20 20 20 54 63 6c 5f 4d 75 74 65 78 55  }.    Tcl_MutexU
42c0: 6e 6c 6f 63 6b 28 26 41 72 63 68 69 76 65 46 69  nlock(&ArchiveFi
42d0: 6c 65 41 63 63 65 73 73 29 3b 0a 20 20 20 20 72  leAccess);.    r
42e0: 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 20  eturn 1;.}../*. 
42f0: 2a 20 7a 76 66 73 3a 3a 6d 6f 75 6e 74 20 20 5a  * zvfs::mount  Z
4300: 69 70 2d 61 72 63 68 69 76 65 2d 6e 61 6d 65 20  ip-archive-name 
4310: 20 6d 6f 75 6e 74 2d 70 6f 69 6e 74 0a 20 2a 0a   mount-point. *.
4320: 20 2a 20 43 72 65 61 74 65 20 61 20 6e 65 77 20   * Create a new 
4330: 6d 6f 75 6e 74 20 70 6f 69 6e 74 20 6f 6e 20 74  mount point on t
4340: 68 65 20 67 69 76 65 6e 20 5a 49 50 20 61 72 63  he given ZIP arc
4350: 68 69 76 65 2e 20 41 66 74 65 72 20 74 68 69 73  hive. After this
4360: 20 63 6f 6d 6d 61 6e 64 0a 20 2a 20 65 78 65 63   command. * exec
4370: 75 74 65 73 2c 20 66 69 6c 65 73 20 63 6f 6e 74  utes, files cont
4380: 61 69 6e 65 64 20 69 6e 20 74 68 65 20 5a 49 50  ained in the ZIP
4390: 20 61 72 63 68 69 76 65 20 77 69 6c 6c 20 61 70   archive will ap
43a0: 70 65 61 72 20 74 6f 20 54 63 6c 20 74 6f 20 62  pear to Tcl to b
43b0: 65 0a 20 2a 20 72 65 67 75 6c 61 72 20 66 69 6c  e. * regular fil
43c0: 65 73 20 61 74 20 74 68 65 20 6d 6f 75 6e 74 20  es at the mount 
43d0: 70 6f 69 6e 74 2e 0a 20 2a 0a 20 2a 20 57 69 74  point.. *. * Wit
43e0: 68 20 6e 6f 20 6d 6f 75 6e 74 2d 70 6f 69 6e 74  h no mount-point
43f0: 2c 20 72 65 74 75 72 6e 20 6d 6f 75 6e 74 20 70  , return mount p
4400: 6f 69 6e 74 20 66 6f 72 20 61 72 63 68 69 76 65  oint for archive
4410: 2e 20 57 69 74 68 20 6e 6f 20 61 72 63 68 69 76  . With no archiv
4420: 65 2c 0a 20 2a 20 72 65 74 75 72 6e 20 61 6c 6c  e,. * return all
4430: 20 61 72 63 68 69 76 65 2f 6d 6f 75 6e 74 20 70   archive/mount p
4440: 61 69 72 73 2e 20 49 66 20 6d 6f 75 6e 74 2d 70  airs. If mount-p
4450: 6f 69 6e 74 20 69 73 20 73 70 65 63 69 66 69 65  oint is specifie
4460: 64 20 61 73 20 61 6e 20 65 6d 70 74 79 0a 20 2a  d as an empty. *
4470: 20 73 74 72 69 6e 67 2c 20 6d 6f 75 6e 74 20 6f   string, mount o
4480: 6e 20 66 69 6c 65 20 70 61 74 68 2e 0a 20 2a 2f  n file path.. */
4490: 0a 73 74 61 74 69 63 20 69 6e 74 0a 5a 76 66 73  .static int.Zvfs
44a0: 4d 6f 75 6e 74 4f 62 6a 43 6d 64 28 0a 20 20 20  MountObjCmd(.   
44b0: 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69 65   ClientData clie
44c0: 6e 74 44 61 74 61 2c 09 2f 2a 20 43 6c 69 65 6e  ntData,./* Clien
44d0: 74 20 64 61 74 61 20 66 6f 72 20 74 68 69 73 20  t data for this 
44e0: 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 20 20 54  command */.    T
44f0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
4500: 70 2c 09 09 2f 2a 20 54 68 65 20 69 6e 74 65 72  p,../* The inter
4510: 70 72 65 74 65 72 20 75 73 65 64 20 74 6f 20 72  preter used to r
4520: 65 70 6f 72 74 20 65 72 72 6f 72 73 20 2a 2f 0a  eport errors */.
4530: 20 20 20 20 69 6e 74 20 6f 62 6a 63 2c 09 09 09      int objc,...
4540: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72 67  /* Number of arg
4550: 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 20 20 54 63  uments */.    Tc
4560: 6c 5f 4f 62 6a 20 2a 63 6f 6e 73 74 2a 20 6f 62  l_Obj *const* ob
4570: 6a 76 29 09 09 2f 2a 20 56 61 6c 75 65 73 20 6f  jv)../* Values o
4580: 66 20 61 6c 6c 20 61 72 67 75 6d 65 6e 74 73 20  f all arguments 
4590: 2a 2f 0a 7b 0a 20 20 20 20 2f 2a 54 4f 44 4f 3a  */.{.    /*TODO:
45a0: 20 43 6f 6e 76 65 72 74 20 74 6f 20 54 63 6c 5f   Convert to Tcl_
45b0: 4f 62 6a 20 41 50 49 21 2a 2f 0a 20 20 20 20 69  Obj API!*/.    i
45c0: 66 20 28 6f 62 6a 63 20 3e 20 33 29 20 7b 0a 09  f (objc > 3) {..
45d0: 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74  Tcl_AppendResult
45e0: 28 69 6e 74 65 72 70 2c 20 22 77 72 6f 6e 67 20  (interp, "wrong 
45f0: 23 20 61 72 67 73 3a 20 73 68 6f 75 6c 64 20 62  # args: should b
4600: 65 20 5c 22 22 2c 20 54 63 6c 5f 47 65 74 53 74  e \"", Tcl_GetSt
4610: 72 69 6e 67 28 6f 62 6a 76 5b 30 5d 29 2c 0a 09  ring(objv[0]),..
4620: 09 22 20 3f 20 5a 49 50 2d 46 49 4c 45 20 3f 20  ." ? ZIP-FILE ? 
4630: 4d 4f 55 4e 54 2d 50 4f 49 4e 54 20 3f 20 3f 5c  MOUNT-POINT ? ?\
4640: 22 22 2c 20 30 29 3b 0a 09 72 65 74 75 72 6e 20  "", 0);..return 
4650: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d  TCL_ERROR;.    }
4660: 0a 20 20 20 20 72 65 74 75 72 6e 20 5a 76 66 73  .    return Zvfs
4670: 5f 4d 6f 75 6e 74 28 69 6e 74 65 72 70 2c 20 6f  _Mount(interp, o
4680: 62 6a 63 3e 31 3f 54 63 6c 5f 47 65 74 53 74 72  bjc>1?Tcl_GetStr
4690: 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 3a 4e 55 4c  ing(objv[1]):NUL
46a0: 4c 2c 20 6f 62 6a 63 3e 32 3f 54 63 6c 5f 47 65  L, objc>2?Tcl_Ge
46b0: 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29  tString(objv[2])
46c0: 3a 4e 55 4c 4c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  :NULL);.}../*. *
46d0: 20 7a 76 66 73 3a 3a 75 6e 6d 6f 75 6e 74 20 20   zvfs::unmount  
46e0: 5a 69 70 2d 61 72 63 68 69 76 65 2d 6e 61 6d 65  Zip-archive-name
46f0: 0a 20 2a 0a 20 2a 20 55 6e 64 6f 20 74 68 65 20  . *. * Undo the 
4700: 65 66 66 65 63 74 73 20 6f 66 20 7a 76 66 73 3a  effects of zvfs:
4710: 3a 6d 6f 75 6e 74 2e 0a 20 2a 2f 0a 73 74 61 74  :mount.. */.stat
4720: 69 63 20 69 6e 74 0a 5a 76 66 73 55 6e 6d 6f 75  ic int.ZvfsUnmou
4730: 6e 74 4f 62 6a 43 6d 64 28 0a 20 20 20 20 43 6c  ntObjCmd(.    Cl
4740: 69 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44  ientData clientD
4750: 61 74 61 2c 09 2f 2a 20 43 6c 69 65 6e 74 20 64  ata,./* Client d
4760: 61 74 61 20 66 6f 72 20 74 68 69 73 20 63 6f 6d  ata for this com
4770: 6d 61 6e 64 20 2a 2f 0a 20 20 20 20 54 63 6c 5f  mand */.    Tcl_
4780: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 09  Interp *interp,.
4790: 09 2f 2a 20 54 68 65 20 69 6e 74 65 72 70 72 65  ./* The interpre
47a0: 74 65 72 20 75 73 65 64 20 74 6f 20 72 65 70 6f  ter used to repo
47b0: 72 74 20 65 72 72 6f 72 73 20 2a 2f 0a 20 20 20  rt errors */.   
47c0: 20 69 6e 74 20 6f 62 6a 63 2c 09 09 09 2f 2a 20   int objc,.../* 
47d0: 4e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65  Number of argume
47e0: 6e 74 73 20 2a 2f 0a 20 20 20 20 54 63 6c 5f 4f  nts */.    Tcl_O
47f0: 62 6a 20 2a 63 6f 6e 73 74 2a 20 6f 62 6a 76 29  bj *const* objv)
4800: 09 09 2f 2a 20 56 61 6c 75 65 73 20 6f 66 20 61  ../* Values of a
4810: 6c 6c 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  ll arguments */.
4820: 7b 0a 20 20 20 20 5a 76 66 73 41 72 63 68 69 76  {.    ZvfsArchiv
4830: 65 20 2a 70 41 72 63 68 69 76 65 3b 09 2f 2a 20  e *pArchive;./* 
4840: 54 68 65 20 5a 49 50 20 61 72 63 68 69 76 65 20  The ZIP archive 
4850: 62 65 69 6e 67 20 6d 6f 75 6e 74 65 64 20 2a 2f  being mounted */
4860: 0a 20 20 20 20 54 63 6c 5f 48 61 73 68 45 6e 74  .    Tcl_HashEnt
4870: 72 79 20 2a 70 45 6e 74 72 79 3b 09 2f 2a 20 48  ry *pEntry;./* H
4880: 61 73 68 20 74 61 62 6c 65 20 65 6e 74 72 79 20  ash table entry 
4890: 2a 2f 0a 20 20 20 20 54 63 6c 5f 48 61 73 68 53  */.    Tcl_HashS
48a0: 65 61 72 63 68 20 7a 53 65 61 72 63 68 3b 09 2f  earch zSearch;./
48b0: 2a 20 53 65 61 72 63 68 20 61 6c 6c 20 6d 6f 75  * Search all mou
48c0: 6e 74 20 70 6f 69 6e 74 73 20 2a 2f 0a 20 20 20  nt points */.   
48d0: 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65   char *zFilename
48e0: 3b 0a 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21  ;.    if (objc !
48f0: 3d 20 32 29 20 7b 0a 09 54 63 6c 5f 41 70 70 65  = 2) {..Tcl_Appe
4900: 6e 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  ndResult(interp,
4910: 20 22 77 72 6f 6e 67 20 23 20 61 72 67 73 3a 20   "wrong # args: 
4920: 73 68 6f 75 6c 64 20 62 65 20 5c 22 22 2c 20 54  should be \"", T
4930: 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a  cl_GetString(obj
4940: 76 5b 30 5d 29 2c 0a 09 09 22 20 5a 49 50 2d 46  v[0]),..." ZIP-F
4950: 49 4c 45 5c 22 22 2c 20 30 29 3b 0a 09 72 65 74  ILE\"", 0);..ret
4960: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
4970: 20 20 20 7d 0a 20 20 20 20 69 66 20 28 21 6c 6f     }.    if (!lo
4980: 63 61 6c 2e 69 73 49 6e 69 74 29 20 7b 0a 09 72  cal.isInit) {..r
4990: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
49a0: 0a 20 20 20 20 7d 0a 20 20 20 20 7a 46 69 6c 65  .    }.    zFile
49b0: 6e 61 6d 65 3d 54 63 6c 5f 47 65 74 53 74 72 69  name=Tcl_GetStri
49c0: 6e 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a 20 20 20  ng(objv[1]);.   
49d0: 20 69 66 20 28 5a 76 66 73 5f 55 6e 6d 6f 75 6e   if (Zvfs_Unmoun
49e0: 74 28 7a 46 69 6c 65 6e 61 6d 65 29 29 20 7b 0a  t(zFilename)) {.
49f0: 09 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a  .return TCL_OK;.
4a00: 20 20 20 20 7d 0a 20 20 20 20 70 45 6e 74 72 79      }.    pEntry
4a10: 20 3d 20 54 63 6c 5f 46 69 72 73 74 48 61 73 68   = Tcl_FirstHash
4a20: 45 6e 74 72 79 28 26 6c 6f 63 61 6c 2e 61 72 63  Entry(&local.arc
4a30: 68 69 76 65 48 61 73 68 2c 26 7a 53 65 61 72 63  hiveHash,&zSearc
4a40: 68 29 3b 0a 20 20 20 20 77 68 69 6c 65 20 28 70  h);.    while (p
4a50: 45 6e 74 72 79 29 20 7b 0a 09 70 41 72 63 68 69  Entry) {..pArchi
4a60: 76 65 20 3d 20 54 63 6c 5f 47 65 74 48 61 73 68  ve = Tcl_GetHash
4a70: 56 61 6c 75 65 28 70 45 6e 74 72 79 29 3b 0a 09  Value(pEntry);..
4a80: 69 66 20 28 70 41 72 63 68 69 76 65 20 26 26 20  if (pArchive && 
4a90: 70 41 72 63 68 69 76 65 2d 3e 7a 4d 6f 75 6e 74  pArchive->zMount
4aa0: 50 6f 69 6e 74 5b 30 5d 0a 09 09 26 26 20 28 73  Point[0]...&& (s
4ab0: 74 72 63 6d 70 28 70 41 72 63 68 69 76 65 2d 3e  trcmp(pArchive->
4ac0: 7a 4d 6f 75 6e 74 50 6f 69 6e 74 2c 20 7a 46 69  zMountPoint, zFi
4ad0: 6c 65 6e 61 6d 65 29 20 3d 3d 20 30 29 29 20 7b  lename) == 0)) {
4ae0: 0a 09 20 20 20 20 69 66 20 28 5a 76 66 73 5f 55  ..    if (Zvfs_U
4af0: 6e 6d 6f 75 6e 74 28 70 41 72 63 68 69 76 65 2d  nmount(pArchive-
4b00: 3e 7a 4e 61 6d 65 29 29 20 7b 0a 09 09 72 65 74  >zName)) {...ret
4b10: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 09 20 20 20  urn TCL_OK;..   
4b20: 20 7d 0a 09 20 20 20 20 62 72 65 61 6b 3b 0a 09   }..    break;..
4b30: 7d 0a 09 70 45 6e 74 72 79 20 3d 20 54 63 6c 5f  }..pEntry = Tcl_
4b40: 4e 65 78 74 48 61 73 68 45 6e 74 72 79 28 26 7a  NextHashEntry(&z
4b50: 53 65 61 72 63 68 29 3b 0a 20 20 20 20 7d 0a 0a  Search);.    }..
4b60: 20 20 20 20 54 63 6c 5f 41 70 70 65 6e 64 52 65      Tcl_AppendRe
4b70: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 22 75 6e  sult(interp, "un
4b80: 6b 6e 6f 77 6e 20 7a 76 66 73 20 6d 6f 75 6e 74  known zvfs mount
4b90: 20 70 6f 69 6e 74 20 6f 72 20 66 69 6c 65 3a 20   point or file: 
4ba0: 22 2c 20 7a 46 69 6c 65 6e 61 6d 65 2c 0a 09 20  ", zFilename,.. 
4bb0: 20 20 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 72 65     NULL);.    re
4bc0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
4bd0: 7d 0a 0a 2f 2a 0a 20 2a 20 7a 76 66 73 3a 3a 65  }../*. * zvfs::e
4be0: 78 69 73 74 73 20 20 66 69 6c 65 6e 61 6d 65 0a  xists  filename.
4bf0: 20 2a 0a 20 2a 20 52 65 74 75 72 6e 20 54 52 55   *. * Return TRU
4c00: 45 20 69 66 20 74 68 65 20 67 69 76 65 6e 20 66  E if the given f
4c10: 69 6c 65 6e 61 6d 65 20 65 78 69 73 74 73 20 69  ilename exists i
4c20: 6e 20 74 68 65 20 5a 56 46 53 20 61 6e 64 20 46  n the ZVFS and F
4c30: 41 4c 53 45 20 69 66 20 69 74 20 64 6f 65 73 0a  ALSE if it does.
4c40: 20 2a 20 6e 6f 74 2e 0a 20 2a 2f 0a 73 74 61 74   * not.. */.stat
4c50: 69 63 20 69 6e 74 0a 5a 76 66 73 45 78 69 73 74  ic int.ZvfsExist
4c60: 73 4f 62 6a 43 6d 64 28 0a 20 20 20 20 43 6c 69  sObjCmd(.    Cli
4c70: 65 6e 74 44 61 74 61 20 63 6c 69 65 6e 74 44 61  entData clientDa
4c80: 74 61 2c 09 2f 2a 20 43 6c 69 65 6e 74 20 64 61  ta,./* Client da
4c90: 74 61 20 66 6f 72 20 74 68 69 73 20 63 6f 6d 6d  ta for this comm
4ca0: 61 6e 64 20 2a 2f 0a 20 20 20 20 54 63 6c 5f 49  and */.    Tcl_I
4cb0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 09 09  nterp *interp,..
4cc0: 2f 2a 20 54 68 65 20 69 6e 74 65 72 70 72 65 74  /* The interpret
4cd0: 65 72 20 75 73 65 64 20 74 6f 20 72 65 70 6f 72  er used to repor
4ce0: 74 20 65 72 72 6f 72 73 20 2a 2f 0a 20 20 20 20  t errors */.    
4cf0: 69 6e 74 20 6f 62 6a 63 2c 09 09 09 2f 2a 20 4e  int objc,.../* N
4d00: 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e  umber of argumen
4d10: 74 73 20 2a 2f 0a 20 20 20 20 54 63 6c 5f 4f 62  ts */.    Tcl_Ob
4d20: 6a 20 2a 63 6f 6e 73 74 2a 20 6f 62 6a 76 29 09  j *const* objv).
4d30: 2f 2a 20 56 61 6c 75 65 73 20 6f 66 20 61 6c 6c  /* Values of all
4d40: 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 7b 0a   arguments */.{.
4d50: 20 20 20 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e      char *zFilen
4d60: 61 6d 65 3b 0a 0a 20 20 20 20 69 66 20 28 6f 62  ame;..    if (ob
4d70: 6a 63 20 21 3d 20 32 29 20 7b 0a 09 54 63 6c 5f  jc != 2) {..Tcl_
4d80: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
4d90: 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 46  erp, 1, objv, "F
4da0: 49 4c 45 4e 41 4d 45 22 29 3b 0a 09 72 65 74 75  ILENAME");..retu
4db0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
4dc0: 20 20 7d 0a 20 20 20 20 7a 46 69 6c 65 6e 61 6d    }.    zFilenam
4dd0: 65 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  e = Tcl_GetStrin
4de0: 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a 20 20 20 20  g(objv[1]);.    
4df0: 54 63 6c 5f 53 65 74 42 6f 6f 6c 65 61 6e 4f 62  Tcl_SetBooleanOb
4e00: 6a 28 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75  j(Tcl_GetObjResu
4e10: 6c 74 28 69 6e 74 65 72 70 29 2c 20 5a 76 66 73  lt(interp), Zvfs
4e20: 4c 6f 6f 6b 75 70 28 7a 46 69 6c 65 6e 61 6d 65  Lookup(zFilename
4e30: 29 21 3d 30 29 3b 0a 20 20 20 20 72 65 74 75 72  )!=0);.    retur
4e40: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  n TCL_OK;.}../*.
4e50: 20 2a 20 7a 76 66 73 3a 3a 69 6e 66 6f 20 20 66   * zvfs::info  f
4e60: 69 6c 65 6e 61 6d 65 0a 20 2a 0a 20 2a 20 52 65  ilename. *. * Re
4e70: 74 75 72 6e 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  turn information
4e80: 20 61 62 6f 75 74 20 74 68 65 20 67 69 76 65 6e   about the given
4e90: 20 66 69 6c 65 20 69 6e 20 74 68 65 20 5a 56 46   file in the ZVF
4ea0: 53 2e 20 20 54 68 65 20 69 6e 66 6f 72 6d 61 74  S.  The informat
4eb0: 69 6f 6e 0a 20 2a 20 63 6f 6e 73 69 73 74 73 20  ion. * consists 
4ec0: 6f 66 20 28 31 29 20 74 68 65 20 6e 61 6d 65 20  of (1) the name 
4ed0: 6f 66 20 74 68 65 20 5a 49 50 20 61 72 63 68 69  of the ZIP archi
4ee0: 76 65 20 74 68 61 74 20 63 6f 6e 74 61 69 6e 73  ve that contains
4ef0: 20 74 68 65 20 66 69 6c 65 2c 20 28 32 29 20 74   the file, (2) t
4f00: 68 65 0a 20 2a 20 73 69 7a 65 20 6f 66 20 74 68  he. * size of th
4f10: 65 20 66 69 6c 65 20 61 66 74 65 72 20 64 65 63  e file after dec
4f20: 6f 6d 70 72 65 73 73 69 6f 6e 73 2c 20 28 33 29  ompressions, (3)
4f30: 20 74 68 65 20 63 6f 6d 70 72 65 73 73 65 64 20   the compressed 
4f40: 73 69 7a 65 20 6f 66 20 74 68 65 20 66 69 6c 65  size of the file
4f50: 2c 0a 20 2a 20 61 6e 64 20 28 34 29 20 74 68 65  ,. * and (4) the
4f60: 20 6f 66 66 73 65 74 20 6f 66 20 74 68 65 20 63   offset of the c
4f70: 6f 6d 70 72 65 73 73 65 64 20 64 61 74 61 20 69  ompressed data i
4f80: 6e 20 74 68 65 20 61 72 63 68 69 76 65 2e 0a 20  n the archive.. 
4f90: 2a 0a 20 2a 20 4e 6f 74 65 3a 20 71 75 65 72 79  *. * Note: query
4fa0: 69 6e 67 20 74 68 65 20 6d 6f 75 6e 74 20 70 6f  ing the mount po
4fb0: 69 6e 74 20 67 69 76 65 73 20 74 68 65 20 73 74  int gives the st
4fc0: 61 72 74 20 6f 66 20 7a 69 70 20 64 61 74 61 20  art of zip data 
4fd0: 6f 66 66 73 65 74 20 69 6e 20 28 34 29 2c 0a 20  offset in (4),. 
4fe0: 2a 20 77 68 69 63 68 20 63 61 6e 20 62 65 20 75  * which can be u
4ff0: 73 65 64 20 74 6f 20 74 72 75 6e 63 61 74 65 20  sed to truncate 
5000: 74 68 65 20 7a 69 70 20 69 6e 66 6f 20 6f 66 66  the zip info off
5010: 20 61 6e 20 65 78 65 63 75 74 61 62 6c 65 2e 0a   an executable..
5020: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 0a 5a   */.static int.Z
5030: 76 66 73 49 6e 66 6f 4f 62 6a 43 6d 64 28 0a 20  vfsInfoObjCmd(. 
5040: 20 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c     ClientData cl
5050: 69 65 6e 74 44 61 74 61 2c 09 2f 2a 20 43 6c 69  ientData,./* Cli
5060: 65 6e 74 20 64 61 74 61 20 66 6f 72 20 74 68 69  ent data for thi
5070: 73 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 20  s command */.   
5080: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
5090: 65 72 70 2c 09 09 2f 2a 20 54 68 65 20 69 6e 74  erp,../* The int
50a0: 65 72 70 72 65 74 65 72 20 75 73 65 64 20 74 6f  erpreter used to
50b0: 20 72 65 70 6f 72 74 20 65 72 72 6f 72 73 20 2a   report errors *
50c0: 2f 0a 20 20 20 20 69 6e 74 20 6f 62 6a 63 2c 09  /.    int objc,.
50d0: 09 09 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61  ../* Number of a
50e0: 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 20 20  rguments */.    
50f0: 54 63 6c 5f 4f 62 6a 20 2a 63 6f 6e 73 74 2a 20  Tcl_Obj *const* 
5100: 6f 62 6a 76 29 09 2f 2a 20 56 61 6c 75 65 73 20  objv)./* Values 
5110: 6f 66 20 61 6c 6c 20 61 72 67 75 6d 65 6e 74 73  of all arguments
5120: 20 2a 2f 0a 7b 0a 20 20 20 20 63 68 61 72 20 2a   */.{.    char *
5130: 7a 46 69 6c 65 6e 61 6d 65 3b 0a 20 20 20 20 5a  zFilename;.    Z
5140: 76 66 73 46 69 6c 65 20 2a 70 46 69 6c 65 3b 0a  vfsFile *pFile;.
5150: 0a 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d  .    if (objc !=
5160: 20 32 29 20 7b 0a 09 54 63 6c 5f 57 72 6f 6e 67   2) {..Tcl_Wrong
5170: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
5180: 31 2c 20 6f 62 6a 76 2c 20 22 46 49 4c 45 4e 41  1, objv, "FILENA
5190: 4d 45 22 29 3b 0a 09 72 65 74 75 72 6e 20 54 43  ME");..return TC
51a0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 20  L_ERROR;.    }. 
51b0: 20 20 20 7a 46 69 6c 65 6e 61 6d 65 20 3d 20 54     zFilename = T
51c0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a  cl_GetString(obj
51d0: 76 5b 31 5d 29 3b 0a 20 20 20 20 70 46 69 6c 65  v[1]);.    pFile
51e0: 20 3d 20 5a 76 66 73 4c 6f 6f 6b 75 70 28 7a 46   = ZvfsLookup(zF
51f0: 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 20 20 69 66  ilename);.    if
5200: 20 28 70 46 69 6c 65 29 20 7b 0a 09 54 63 6c 5f   (pFile) {..Tcl_
5210: 4f 62 6a 20 2a 70 52 65 73 75 6c 74 20 3d 20 54  Obj *pResult = T
5220: 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_GetObjResult(
5230: 69 6e 74 65 72 70 29 3b 0a 0a 09 54 63 6c 5f 4c  interp);...Tcl_L
5240: 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d  istObjAppendElem
5250: 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 52 65 73  ent(interp, pRes
5260: 75 6c 74 2c 20 0a 09 09 54 63 6c 5f 4e 65 77 53  ult, ...Tcl_NewS
5270: 74 72 69 6e 67 4f 62 6a 28 70 46 69 6c 65 2d 3e  tringObj(pFile->
5280: 70 41 72 63 68 69 76 65 2d 3e 7a 4e 61 6d 65 2c  pArchive->zName,
5290: 20 2d 31 29 29 3b 0a 09 54 63 6c 5f 4c 69 73 74   -1));..Tcl_List
52a0: 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74  ObjAppendElement
52b0: 28 69 6e 74 65 72 70 2c 20 70 52 65 73 75 6c 74  (interp, pResult
52c0: 2c 0a 09 09 54 63 6c 5f 4e 65 77 49 6e 74 4f 62  ,...Tcl_NewIntOb
52d0: 6a 28 70 46 69 6c 65 2d 3e 6e 42 79 74 65 29 29  j(pFile->nByte))
52e0: 3b 0a 09 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70  ;..Tcl_ListObjAp
52f0: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65  pendElement(inte
5300: 72 70 2c 20 70 52 65 73 75 6c 74 2c 0a 09 09 54  rp, pResult,...T
5310: 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 70 46 69  cl_NewIntObj(pFi
5320: 6c 65 2d 3e 6e 42 79 74 65 43 6f 6d 70 72 29 29  le->nByteCompr))
5330: 3b 0a 09 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70  ;..Tcl_ListObjAp
5340: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65  pendElement(inte
5350: 72 70 2c 20 70 52 65 73 75 6c 74 2c 0a 09 09 54  rp, pResult,...T
5360: 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 70 46 69  cl_NewIntObj(pFi
5370: 6c 65 2d 3e 69 4f 66 66 73 65 74 29 29 3b 0a 20  le->iOffset));. 
5380: 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e 20     }.    return 
5390: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  TCL_OK;.}../*. *
53a0: 20 7a 76 66 73 3a 3a 6c 69 73 74 0a 20 2a 0a 20   zvfs::list. *. 
53b0: 2a 20 52 65 74 75 72 6e 20 61 20 6c 69 73 74 20  * Return a list 
53c0: 6f 66 20 61 6c 6c 20 66 69 6c 65 73 20 69 6e 20  of all files in 
53d0: 74 68 65 20 5a 56 46 53 2e 20 20 54 68 65 20 6f  the ZVFS.  The o
53e0: 72 64 65 72 20 6f 66 20 74 68 65 20 6e 61 6d 65  rder of the name
53f0: 73 20 69 6e 20 74 68 65 20 6c 69 73 74 0a 20 2a  s in the list. *
5400: 20 69 73 20 61 72 62 69 74 72 61 72 79 2e 0a 20   is arbitrary.. 
5410: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 0a 5a 76  */.static int.Zv
5420: 66 73 4c 69 73 74 4f 62 6a 43 6d 64 28 0a 20 20  fsListObjCmd(.  
5430: 20 20 43 6c 69 65 6e 74 44 61 74 61 20 63 6c 69    ClientData cli
5440: 65 6e 74 44 61 74 61 2c 09 2f 2a 20 43 6c 69 65  entData,./* Clie
5450: 6e 74 20 64 61 74 61 20 66 6f 72 20 74 68 69 73  nt data for this
5460: 20 63 6f 6d 6d 61 6e 64 20 2a 2f 0a 20 20 20 20   command */.    
5470: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
5480: 72 70 2c 09 09 2f 2a 20 54 68 65 20 69 6e 74 65  rp,../* The inte
5490: 72 70 72 65 74 65 72 20 75 73 65 64 20 74 6f 20  rpreter used to 
54a0: 72 65 70 6f 72 74 20 65 72 72 6f 72 73 20 2a 2f  report errors */
54b0: 0a 20 20 20 20 69 6e 74 20 6f 62 6a 63 2c 09 09  .    int objc,..
54c0: 09 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 61 72  ./* Number of ar
54d0: 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 20 20 54  guments */.    T
54e0: 63 6c 5f 4f 62 6a 20 2a 63 6f 6e 73 74 2a 20 6f  cl_Obj *const* o
54f0: 62 6a 76 29 09 2f 2a 20 56 61 6c 75 65 73 20 6f  bjv)./* Values o
5500: 66 20 61 6c 6c 20 61 72 67 75 6d 65 6e 74 73 20  f all arguments 
5510: 2a 2f 0a 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  */.{.    char *z
5520: 50 61 74 74 65 72 6e 20 3d 20 30 3b 0a 20 20 20  Pattern = 0;.   
5530: 20 54 63 6c 5f 52 65 67 45 78 70 20 70 52 65 67   Tcl_RegExp pReg
5540: 65 78 70 20 3d 20 30 3b 0a 20 20 20 20 54 63 6c  exp = 0;.    Tcl
5550: 5f 48 61 73 68 45 6e 74 72 79 20 2a 70 45 6e 74  _HashEntry *pEnt
5560: 72 79 3b 0a 20 20 20 20 54 63 6c 5f 48 61 73 68  ry;.    Tcl_Hash
5570: 53 65 61 72 63 68 20 73 53 65 61 72 63 68 3b 0a  Search sSearch;.
5580: 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 52 65      Tcl_Obj *pRe
5590: 73 75 6c 74 20 3d 20 54 63 6c 5f 47 65 74 4f 62  sult = Tcl_GetOb
55a0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  jResult(interp);
55b0: 0a 0a 20 20 20 20 69 66 20 28 6f 62 6a 63 20 3e  ..    if (objc >
55c0: 20 33 29 20 7b 0a 09 54 63 6c 5f 57 72 6f 6e 67   3) {..Tcl_Wrong
55d0: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
55e0: 31 2c 20 6f 62 6a 76 2c 20 22 3f 28 2d 67 6c 6f  1, objv, "?(-glo
55f0: 62 7c 2d 72 65 67 65 78 70 29 3f 20 3f 50 41 54  b|-regexp)? ?PAT
5600: 54 45 52 4e 3f 22 29 3b 0a 09 72 65 74 75 72 6e  TERN?");..return
5610: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 20 20   TCL_ERROR;.    
5620: 7d 0a 20 20 20 20 69 66 20 28 6c 6f 63 61 6c 2e  }.    if (local.
5630: 69 73 49 6e 69 74 20 3d 3d 20 30 29 20 7b 0a 09  isInit == 0) {..
5640: 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 20  return TCL_OK;. 
5650: 20 20 20 7d 0a 20 20 20 20 69 66 20 28 6f 62 6a     }.    if (obj
5660: 63 20 3d 3d 20 33 29 20 7b 0a 09 69 6e 74 20 6e  c == 3) {..int n
5670: 3b 0a 09 63 68 61 72 20 2a 7a 53 77 69 74 63 68  ;..char *zSwitch
5680: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
5690: 46 72 6f 6d 4f 62 6a 28 6f 62 6a 76 5b 31 5d 2c  FromObj(objv[1],
56a0: 20 26 6e 29 3b 0a 0a 09 69 66 20 28 6e 20 3e 3d   &n);...if (n >=
56b0: 20 32 20 26 26 20 73 74 72 6e 63 6d 70 28 7a 53   2 && strncmp(zS
56c0: 77 69 74 63 68 2c 22 2d 67 6c 6f 62 22 2c 6e 29  witch,"-glob",n)
56d0: 20 3d 3d 20 30 29 20 7b 0a 09 20 20 20 20 7a 50   == 0) {..    zP
56e0: 61 74 74 65 72 6e 20 3d 20 54 63 6c 5f 47 65 74  attern = Tcl_Get
56f0: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d 29 3b  String(objv[2]);
5700: 0a 09 7d 20 65 6c 73 65 20 69 66 20 28 6e 20 3e  ..} else if (n >
5710: 3d 20 32 20 26 26 20 73 74 72 6e 63 6d 70 28 7a  = 2 && strncmp(z
5720: 53 77 69 74 63 68 2c 22 2d 72 65 67 65 78 70 22  Switch,"-regexp"
5730: 2c 6e 29 20 3d 3d 20 30 29 20 7b 0a 09 20 20 20  ,n) == 0) {..   
5740: 20 70 52 65 67 65 78 70 20 3d 20 54 63 6c 5f 52   pRegexp = Tcl_R
5750: 65 67 45 78 70 43 6f 6d 70 69 6c 65 28 69 6e 74  egExpCompile(int
5760: 65 72 70 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  erp, Tcl_GetStri
5770: 6e 67 28 6f 62 6a 76 5b 32 5d 29 29 3b 0a 09 20  ng(objv[2]));.. 
5780: 20 20 20 69 66 20 28 70 52 65 67 65 78 70 20 3d     if (pRegexp =
5790: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 20  = 0) {...return 
57a0: 54 43 4c 5f 45 52 52 4f 52 3b 0a 09 20 20 20 20  TCL_ERROR;..    
57b0: 7d 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 20 20 20  }..} else {..   
57c0: 20 54 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c   Tcl_AppendResul
57d0: 74 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b 6e 6f  t(interp, "unkno
57e0: 77 6e 20 6f 70 74 69 6f 6e 3a 20 22 2c 20 7a 53  wn option: ", zS
57f0: 77 69 74 63 68 2c 20 30 29 3b 0a 09 20 20 20 20  witch, 0);..    
5800: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
5810: 3b 0a 09 7d 0a 20 20 20 20 7d 20 65 6c 73 65 20  ;..}.    } else 
5820: 69 66 20 28 6f 62 6a 63 20 3d 3d 20 32 29 20 7b  if (objc == 2) {
5830: 0a 09 7a 50 61 74 74 65 72 6e 20 3d 20 54 63 6c  ..zPattern = Tcl
5840: 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b  _GetString(objv[
5850: 31 5d 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  1]);.    }..    
5860: 2f 2a 0a 20 20 20 20 20 2a 20 44 6f 20 74 68 65  /*.     * Do the
5870: 20 6c 69 73 74 69 6e 67 2e 0a 20 20 20 20 20 2a   listing..     *
5880: 2f 0a 0a 20 20 20 20 69 66 20 28 7a 50 61 74 74  /..    if (zPatt
5890: 65 72 6e 29 20 7b 0a 09 66 6f 72 20 28 70 45 6e  ern) {..for (pEn
58a0: 74 72 79 20 3d 20 54 63 6c 5f 46 69 72 73 74 48  try = Tcl_FirstH
58b0: 61 73 68 45 6e 74 72 79 28 26 6c 6f 63 61 6c 2e  ashEntry(&local.
58c0: 66 69 6c 65 48 61 73 68 2c 20 26 73 53 65 61 72  fileHash, &sSear
58d0: 63 68 29 3b 0a 09 09 70 45 6e 74 72 79 3b 20 70  ch);...pEntry; p
58e0: 45 6e 74 72 79 20 3d 20 54 63 6c 5f 4e 65 78 74  Entry = Tcl_Next
58f0: 48 61 73 68 45 6e 74 72 79 28 26 73 53 65 61 72  HashEntry(&sSear
5900: 63 68 29 29 7b 0a 09 20 20 20 20 5a 76 66 73 46  ch)){..    ZvfsF
5910: 69 6c 65 20 2a 70 46 69 6c 65 20 3d 20 54 63 6c  ile *pFile = Tcl
5920: 5f 47 65 74 48 61 73 68 56 61 6c 75 65 28 70 45  _GetHashValue(pE
5930: 6e 74 72 79 29 3b 0a 09 20 20 20 20 63 68 61 72  ntry);..    char
5940: 20 2a 7a 20 3d 20 70 46 69 6c 65 2d 3e 7a 4e 61   *z = pFile->zNa
5950: 6d 65 3b 0a 0a 09 20 20 20 20 69 66 20 28 54 63  me;...    if (Tc
5960: 6c 5f 53 74 72 69 6e 67 43 61 73 65 4d 61 74 63  l_StringCaseMatc
5970: 68 28 7a 2c 20 7a 50 61 74 74 65 72 6e 2c 20 31  h(z, zPattern, 1
5980: 29 29 20 7b 0a 09 09 54 63 6c 5f 4c 69 73 74 4f  )) {...Tcl_ListO
5990: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
59a0: 69 6e 74 65 72 70 2c 20 70 52 65 73 75 6c 74 2c  interp, pResult,
59b0: 0a 09 09 09 54 63 6c 5f 4e 65 77 53 74 72 69 6e  ....Tcl_NewStrin
59c0: 67 4f 62 6a 28 7a 2c 20 2d 31 29 29 3b 0a 09 20  gObj(z, -1));.. 
59d0: 20 20 20 7d 0a 09 7d 0a 20 20 20 20 7d 20 65 6c     }..}.    } el
59e0: 73 65 20 69 66 20 28 70 52 65 67 65 78 70 29 20  se if (pRegexp) 
59f0: 7b 0a 09 66 6f 72 28 70 45 6e 74 72 79 20 3d 20  {..for(pEntry = 
5a00: 54 63 6c 5f 46 69 72 73 74 48 61 73 68 45 6e 74  Tcl_FirstHashEnt
5a10: 72 79 28 26 6c 6f 63 61 6c 2e 66 69 6c 65 48 61  ry(&local.fileHa
5a20: 73 68 2c 20 26 73 53 65 61 72 63 68 29 3b 0a 09  sh, &sSearch);..
5a30: 09 70 45 6e 74 72 79 3b 20 70 45 6e 74 72 79 20  .pEntry; pEntry 
5a40: 3d 20 54 63 6c 5f 4e 65 78 74 48 61 73 68 45 6e  = Tcl_NextHashEn
5a50: 74 72 79 28 26 73 53 65 61 72 63 68 29 29 7b 0a  try(&sSearch)){.
5a60: 09 20 20 20 20 5a 76 66 73 46 69 6c 65 20 2a 70  .    ZvfsFile *p
5a70: 46 69 6c 65 20 3d 20 54 63 6c 5f 47 65 74 48 61  File = Tcl_GetHa
5a80: 73 68 56 61 6c 75 65 28 70 45 6e 74 72 79 29 3b  shValue(pEntry);
5a90: 0a 09 20 20 20 20 63 68 61 72 20 2a 7a 20 3d 20  ..    char *z = 
5aa0: 70 46 69 6c 65 2d 3e 7a 4e 61 6d 65 3b 0a 0a 09  pFile->zName;...
5ab0: 20 20 20 20 69 66 20 28 54 63 6c 5f 52 65 67 45      if (Tcl_RegE
5ac0: 78 70 45 78 65 63 28 69 6e 74 65 72 70 2c 20 70  xpExec(interp, p
5ad0: 52 65 67 65 78 70 2c 20 7a 2c 20 7a 29 29 20 7b  Regexp, z, z)) {
5ae0: 0a 09 09 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70  ...Tcl_ListObjAp
5af0: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65  pendElement(inte
5b00: 72 70 2c 20 70 52 65 73 75 6c 74 2c 0a 09 09 09  rp, pResult,....
5b10: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
5b20: 28 7a 2c 20 2d 31 29 29 3b 0a 09 20 20 20 20 7d  (z, -1));..    }
5b30: 0a 09 7d 0a 20 20 20 20 7d 20 65 6c 73 65 20 7b  ..}.    } else {
5b40: 0a 09 66 6f 72 20 28 70 45 6e 74 72 79 20 3d 20  ..for (pEntry = 
5b50: 54 63 6c 5f 46 69 72 73 74 48 61 73 68 45 6e 74  Tcl_FirstHashEnt
5b60: 72 79 28 26 6c 6f 63 61 6c 2e 66 69 6c 65 48 61  ry(&local.fileHa
5b70: 73 68 2c 20 26 73 53 65 61 72 63 68 29 3b 0a 09  sh, &sSearch);..
5b80: 09 70 45 6e 74 72 79 3b 20 70 45 6e 74 72 79 20  .pEntry; pEntry 
5b90: 3d 20 54 63 6c 5f 4e 65 78 74 48 61 73 68 45 6e  = Tcl_NextHashEn
5ba0: 74 72 79 28 26 73 53 65 61 72 63 68 29 29 7b 0a  try(&sSearch)){.
5bb0: 09 20 20 20 20 5a 76 66 73 46 69 6c 65 20 2a 70  .    ZvfsFile *p
5bc0: 46 69 6c 65 20 3d 20 54 63 6c 5f 47 65 74 48 61  File = Tcl_GetHa
5bd0: 73 68 56 61 6c 75 65 28 70 45 6e 74 72 79 29 3b  shValue(pEntry);
5be0: 0a 09 20 20 20 20 63 68 61 72 20 2a 7a 20 3d 20  ..    char *z = 
5bf0: 70 46 69 6c 65 2d 3e 7a 4e 61 6d 65 3b 0a 0a 09  pFile->zName;...
5c00: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
5c10: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74  ppendElement(int
5c20: 65 72 70 2c 20 70 52 65 73 75 6c 74 2c 0a 09 09  erp, pResult,...
5c30: 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e      Tcl_NewStrin
5c40: 67 4f 62 6a 28 7a 2c 20 2d 31 29 29 3b 0a 09 7d  gObj(z, -1));..}
5c50: 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75 72  .    }.    retur
5c60: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  n TCL_OK;.}../*.
5c70: 2a 2a 20 57 68 65 6e 65 76 65 72 20 61 20 5a 56  ** Whenever a ZV
5c80: 46 53 20 66 69 6c 65 20 69 73 20 6f 70 65 6e 65  FS file is opene
5c90: 64 2c 20 61 6e 20 69 6e 73 74 61 6e 63 65 20 6f  d, an instance o
5ca0: 66 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65  f this structure
5cb0: 20 69 73 0a 2a 2a 20 61 74 74 61 63 68 65 64 20   is.** attached 
5cc0: 74 6f 20 74 68 65 20 6f 70 65 6e 20 63 68 61 6e  to the open chan
5cd0: 6e 65 6c 20 77 68 65 72 65 20 69 74 20 77 69 6c  nel where it wil
5ce0: 6c 20 62 65 20 61 76 61 69 6c 61 62 6c 65 20 74  l be available t
5cf0: 6f 20 74 68 65 0a 2a 2a 20 5a 56 46 53 20 49 2f  o the.** ZVFS I/
5d00: 4f 20 72 6f 75 74 69 6e 65 73 20 62 65 6c 6f 77  O routines below
5d10: 2e 20 20 41 6c 6c 20 73 74 61 74 65 20 69 6e 66  .  All state inf
5d20: 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 61  ormation about a
5d30: 6e 20 6f 70 65 6e 0a 2a 2a 20 5a 56 46 53 20 66  n open.** ZVFS f
5d40: 69 6c 65 20 69 73 20 68 65 6c 64 20 69 6e 20 74  ile is held in t
5d50: 68 69 73 20 73 74 72 75 63 74 75 72 65 2e 0a 2a  his structure..*
5d60: 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
5d70: 20 5a 76 66 73 43 68 61 6e 6e 65 6c 49 6e 66 6f   ZvfsChannelInfo
5d80: 20 7b 0a 20 20 75 6e 73 69 67 6e 65 64 20 6c 6f   {.  unsigned lo
5d90: 6e 67 20 6e 42 79 74 65 3b 20 20 20 20 20 20 2f  ng nByte;      /
5da0: 2a 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * number of byte
5db0: 73 20 6f 66 20 75 6e 63 6f 6d 70 72 65 73 73 65  s of uncompresse
5dc0: 64 20 64 61 74 61 20 2a 2f 0a 20 20 75 6e 73 69  d data */.  unsi
5dd0: 67 6e 65 64 20 6c 6f 6e 67 20 6e 42 79 74 65 43  gned long nByteC
5de0: 6f 6d 70 72 3b 20 2f 2a 20 6e 75 6d 62 65 72 20  ompr; /* number 
5df0: 6f 66 20 62 79 74 65 73 20 6f 66 20 75 6e 72 65  of bytes of unre
5e00: 61 64 20 63 6f 6d 70 72 65 73 73 65 64 20 64 61  ad compressed da
5e10: 74 61 20 2a 2f 0a 20 20 75 6e 73 69 67 6e 65 64  ta */.  unsigned
5e20: 20 6c 6f 6e 67 20 6e 44 61 74 61 3b 20 20 20 20   long nData;    
5e30: 20 20 2f 2a 20 74 6f 74 61 6c 20 6e 75 6d 62 65    /* total numbe
5e40: 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 63 6f  r of bytes of co
5e50: 6d 70 72 65 73 73 65 64 20 64 61 74 61 20 2a 2f  mpressed data */
5e60: 0a 20 20 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  .  unsigned long
5e70: 20 72 65 61 64 53 6f 46 61 72 3b 20 20 2f 2a 20   readSoFar;  /* 
5e80: 70 6f 73 69 74 69 6f 6e 20 6f 66 20 6e 65 78 74  position of next
5e90: 20 62 79 74 65 20 74 6f 20 62 65 20 72 65 61 64   byte to be read
5ea0: 20 66 72 6f 6d 20 74 68 65 20 63 68 61 6e 6e 65   from the channe
5eb0: 6c 20 2a 2f 0a 20 20 6c 6f 6e 67 20 73 74 61 72  l */.  long star
5ec0: 74 4f 66 44 61 74 61 3b 20 20 20 20 20 20 20 20  tOfData;        
5ed0: 20 2f 2a 20 46 69 6c 65 20 70 6f 73 69 74 69 6f   /* File positio
5ee0: 6e 20 6f 66 20 73 74 61 72 74 20 6f 66 20 64 61  n of start of da
5ef0: 74 61 20 69 6e 20 5a 49 50 20 61 72 63 68 69 76  ta in ZIP archiv
5f00: 65 20 2a 2f 0a 20 20 54 63 6c 5f 43 68 61 6e 6e  e */.  Tcl_Chann
5f10: 65 6c 20 63 68 61 6e 3b 20 20 20 20 20 20 20 20  el chan;        
5f20: 20 2f 2a 20 4f 70 65 6e 20 66 69 6c 65 20 68 61   /* Open file ha
5f30: 6e 64 6c 65 20 74 6f 20 74 68 65 20 61 72 63 68  ndle to the arch
5f40: 69 76 65 20 66 69 6c 65 20 2a 2f 0a 20 20 75 6e  ive file */.  un
5f50: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 7a 42 75  signed char *zBu
5f60: 66 3b 20 20 20 20 20 20 2f 2a 20 62 75 66 66 65  f;      /* buffe
5f70: 72 20 75 73 65 64 20 62 79 20 74 68 65 20 64 65  r used by the de
5f80: 63 6f 6d 70 72 65 73 73 6f 72 20 2a 2f 0a 20 20  compressor */.  
5f90: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 75  unsigned char *u
5fa0: 42 75 66 3b 09 20 20 20 20 2f 2a 20 70 6f 69 6e  Buf;.    /* poin
5fb0: 74 65 72 20 74 6f 20 74 68 65 20 75 6e 63 6f 6d  ter to the uncom
5fc0: 70 72 65 73 73 65 64 2c 20 75 6e 65 6e 63 72 79  pressed, unencry
5fd0: 70 74 65 64 20 64 61 74 61 20 2a 2f 0a 20 20 7a  pted data */.  z
5fe0: 5f 73 74 72 65 61 6d 20 73 74 72 65 61 6d 3b 20  _stream stream; 
5ff0: 20 20 20 20 20 20 20 20 20 2f 2a 20 73 74 61 74           /* stat
6000: 65 20 6f 66 20 74 68 65 20 64 65 63 6f 6d 70 72  e of the decompr
6010: 65 73 73 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 69  essor */.  int i
6020: 73 45 6e 63 72 79 70 74 65 64 3b 20 20 20 20 20  sEncrypted;     
6030: 20 20 20 20 20 2f 2a 20 66 69 6c 65 20 69 73 20       /* file is 
6040: 65 6e 63 72 79 70 74 65 64 20 2a 2f 0a 20 20 69  encrypted */.  i
6050: 6e 74 20 69 73 43 6f 6d 70 72 65 73 73 65 64 3b  nt isCompressed;
6060: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
6070: 20 64 61 74 61 20 69 73 20 63 6f 6d 70 72 65 73   data is compres
6080: 73 65 64 20 2a 2f 0a 7d 20 5a 76 66 73 43 68 61  sed */.} ZvfsCha
6090: 6e 6e 65 6c 49 6e 66 6f 3b 0a 0a 2f 2a 0a 2a 2a  nnelInfo;../*.**
60a0: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73   This routine is
60b0: 20 63 61 6c 6c 65 64 20 61 73 20 61 6e 20 65 78   called as an ex
60c0: 69 74 20 68 61 6e 64 6c 65 72 2e 20 20 49 66 20  it handler.  If 
60d0: 77 65 20 64 6f 20 6e 6f 74 20 73 65 74 0a 2a 2a  we do not set.**
60e0: 20 5a 76 66 73 43 68 61 6e 6e 65 6c 49 6e 66 6f   ZvfsChannelInfo
60f0: 2e 63 68 61 6e 20 74 6f 20 4e 55 4c 4c 2c 20 74  .chan to NULL, t
6100: 68 65 6e 20 54 63 6c 5f 43 6c 6f 73 65 28 29 20  hen Tcl_Close() 
6110: 77 69 6c 6c 20 62 65 20 63 61 6c 6c 65 64 20 6f  will be called o
6120: 6e 0a 2a 2a 20 74 68 61 74 20 63 68 61 6e 6e 65  n.** that channe
6130: 6c 20 61 20 73 65 63 6f 6e 64 20 74 69 6d 65 20  l a second time 
6140: 77 68 65 6e 20 54 63 6c 5f 45 78 69 74 20 72 75  when Tcl_Exit ru
6150: 6e 73 2e 20 20 54 68 69 73 20 77 69 6c 6c 20 6c  ns.  This will l
6160: 65 61 64 20 74 6f 20 61 20 0a 2a 2a 20 63 6f 72  ead to a .** cor
6170: 65 20 64 75 6d 70 2e 0a 2a 2f 0a 73 74 61 74 69  e dump..*/.stati
6180: 63 20 76 6f 69 64 20 76 66 73 45 78 69 74 28 76  c void vfsExit(v
6190: 6f 69 64 20 2a 70 41 72 67 29 7b 0a 20 20 5a 76  oid *pArg){.  Zv
61a0: 66 73 43 68 61 6e 6e 65 6c 49 6e 66 6f 20 2a 70  fsChannelInfo *p
61b0: 49 6e 66 6f 20 3d 20 28 5a 76 66 73 43 68 61 6e  Info = (ZvfsChan
61c0: 6e 65 6c 49 6e 66 6f 2a 29 70 41 72 67 3b 0a 20  nelInfo*)pArg;. 
61d0: 20 70 49 6e 66 6f 2d 3e 63 68 61 6e 20 3d 20 30   pInfo->chan = 0
61e0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
61f0: 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65  routine is calle
6200: 64 20 77 68 65 6e 20 74 68 65 20 5a 56 46 53 20  d when the ZVFS 
6210: 63 68 61 6e 6e 65 6c 20 69 73 20 63 6c 6f 73 65  channel is close
6220: 64 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  d.*/.static int 
6230: 76 66 73 43 6c 6f 73 65 28 0a 20 20 43 6c 69 65  vfsClose(.  Clie
6240: 6e 74 44 61 74 61 20 20 69 6e 73 74 61 6e 63 65  ntData  instance
6250: 44 61 74 61 2c 20 20 20 20 2f 2a 20 41 20 5a 76  Data,    /* A Zv
6260: 66 73 43 68 61 6e 6e 65 6c 49 6e 66 6f 20 73 74  fsChannelInfo st
6270: 72 75 63 74 75 72 65 20 2a 2f 0a 20 20 54 63 6c  ructure */.  Tcl
6280: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 20  _Interp *interp 
6290: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65            /* The
62a0: 20 54 43 4c 20 69 6e 74 65 72 70 72 65 74 65 72   TCL interpreter
62b0: 20 2a 2f 0a 29 7b 0a 20 20 5a 76 66 73 43 68 61   */.){.  ZvfsCha
62c0: 6e 6e 65 6c 49 6e 66 6f 2a 20 70 49 6e 66 6f 20  nnelInfo* pInfo 
62d0: 3d 20 28 5a 76 66 73 43 68 61 6e 6e 65 6c 49 6e  = (ZvfsChannelIn
62e0: 66 6f 2a 29 69 6e 73 74 61 6e 63 65 44 61 74 61  fo*)instanceData
62f0: 3b 0a 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e  ;..  if( pInfo->
6300: 7a 42 75 66 20 29 7b 0a 20 20 20 20 54 63 6c 5f  zBuf ){.    Tcl_
6310: 46 72 65 65 28 28 63 68 61 72 20 2a 29 70 49 6e  Free((char *)pIn
6320: 66 6f 2d 3e 7a 42 75 66 29 3b 0a 20 20 20 20 54  fo->zBuf);.    T
6330: 63 6c 5f 46 72 65 65 28 28 63 68 61 72 20 2a 29  cl_Free((char *)
6340: 70 49 6e 66 6f 2d 3e 75 42 75 66 29 3b 0a 20 20  pInfo->uBuf);.  
6350: 20 20 69 6e 66 6c 61 74 65 45 6e 64 28 26 70 49    inflateEnd(&pI
6360: 6e 66 6f 2d 3e 73 74 72 65 61 6d 29 3b 0a 20 20  nfo->stream);.  
6370: 7d 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 63  }.  if( pInfo->c
6380: 68 61 6e 20 29 7b 0a 20 20 20 20 54 63 6c 5f 43  han ){.    Tcl_C
6390: 6c 6f 73 65 28 69 6e 74 65 72 70 2c 20 70 49 6e  lose(interp, pIn
63a0: 66 6f 2d 3e 63 68 61 6e 29 3b 0a 20 20 20 20 54  fo->chan);.    T
63b0: 63 6c 5f 44 65 6c 65 74 65 45 78 69 74 48 61 6e  cl_DeleteExitHan
63c0: 64 6c 65 72 28 76 66 73 45 78 69 74 2c 20 70 49  dler(vfsExit, pI
63d0: 6e 66 6f 29 3b 0a 20 20 7d 0a 20 20 54 63 6c 5f  nfo);.  }.  Tcl_
63e0: 4d 75 74 65 78 55 6e 6c 6f 63 6b 28 26 41 72 63  MutexUnlock(&Arc
63f0: 68 69 76 65 46 69 6c 65 41 63 63 65 73 73 29 3b  hiveFileAccess);
6400: 0a 20 20 54 63 6c 5f 46 72 65 65 28 28 63 68 61  .  Tcl_Free((cha
6410: 72 2a 29 70 49 6e 66 6f 29 3b 0a 20 20 72 65 74  r*)pInfo);.  ret
6420: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 73  urn TCL_OK;.}..s
6430: 74 61 74 69 63 20 69 6e 74 20 76 66 73 49 6e 70  tatic int vfsInp
6440: 75 74 20 28 0a 20 20 43 6c 69 65 6e 74 44 61 74  ut (.  ClientDat
6450: 61 20 69 6e 73 74 61 6e 63 65 44 61 74 61 2c 20  a instanceData, 
6460: 2f 2a 20 54 68 65 20 63 68 61 6e 6e 65 6c 20 74  /* The channel t
6470: 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20  o read from */. 
6480: 20 63 68 61 72 20 2a 62 75 66 2c 20 20 20 20 20   char *buf,     
6490: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 75 66            /* Buf
64a0: 66 65 72 20 74 6f 20 66 69 6c 6c 20 2a 2f 0a 20  fer to fill */. 
64b0: 20 69 6e 74 20 74 6f 52 65 61 64 2c 20 20 20 20   int toRead,    
64c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 71            /* Req
64d0: 75 65 73 74 65 64 20 6e 75 6d 62 65 72 20 6f 66  uested number of
64e0: 20 62 79 74 65 73 20 2a 2f 0a 20 20 69 6e 74 20   bytes */.  int 
64f0: 2a 70 45 72 72 6f 72 43 6f 64 65 20 20 20 20 20  *pErrorCode     
6500: 20 20 20 20 20 2f 2a 20 4c 6f 63 61 74 69 6f 6e       /* Location
6510: 20 6f 66 20 65 72 72 6f 72 20 66 6c 61 67 20 2a   of error flag *
6520: 2f 0a 29 7b 20 2f 2a 20 54 68 65 20 54 43 4c 20  /.){ /* The TCL 
6530: 49 2f 4f 20 73 79 73 74 65 6d 20 63 61 6c 6c 73  I/O system calls
6540: 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 74   this function t
6550: 6f 20 61 63 74 75 61 6c 6c 79 20 72 65 61 64 20  o actually read 
6560: 69 6e 66 6f 72 6d 61 74 69 6f 6e 0a 20 20 20 20  information.    
6570: 2a 20 66 72 6f 6d 20 61 20 5a 56 46 53 20 66 69  * from a ZVFS fi
6580: 6c 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 5a 76 66  le..    */.  Zvf
6590: 73 43 68 61 6e 6e 65 6c 49 6e 66 6f 2a 20 70 49  sChannelInfo* pI
65a0: 6e 66 6f 20 3d 20 28 5a 76 66 73 43 68 61 6e 6e  nfo = (ZvfsChann
65b0: 65 6c 49 6e 66 6f 2a 29 20 69 6e 73 74 61 6e 63  elInfo*) instanc
65c0: 65 44 61 74 61 3b 0a 20 20 75 6e 73 69 67 6e 65  eData;.  unsigne
65d0: 64 20 6c 6f 6e 67 20 6e 65 78 74 70 6f 73 3b 0a  d long nextpos;.
65e0: 0a 20 20 6e 65 78 74 70 6f 73 20 3d 20 70 49 6e  .  nextpos = pIn
65f0: 66 6f 2d 3e 72 65 61 64 53 6f 46 61 72 20 2b 20  fo->readSoFar + 
6600: 74 6f 52 65 61 64 3b 0a 20 20 69 66 20 28 6e 65  toRead;.  if (ne
6610: 78 74 70 6f 73 20 3e 20 70 49 6e 66 6f 2d 3e 6e  xtpos > pInfo->n
6620: 42 79 74 65 29 20 7b 0a 09 20 20 74 6f 52 65 61  Byte) {..  toRea
6630: 64 20 3d 20 70 49 6e 66 6f 2d 3e 6e 42 79 74 65  d = pInfo->nByte
6640: 20 2d 20 70 49 6e 66 6f 2d 3e 72 65 61 64 53 6f   - pInfo->readSo
6650: 46 61 72 3b 0a 09 20 20 6e 65 78 74 70 6f 73 20  Far;..  nextpos 
6660: 3d 20 70 49 6e 66 6f 2d 3e 6e 42 79 74 65 3b 0a  = pInfo->nByte;.
6670: 20 20 7d 0a 20 20 69 66 28 20 74 6f 52 65 61 64    }.  if( toRead
6680: 20 3d 3d 20 30 20 29 0a 20 20 20 20 72 65 74 75   == 0 ).    retu
6690: 72 6e 20 30 3b 0a 0a 20 20 6d 65 6d 63 70 79 28  rn 0;..  memcpy(
66a0: 62 75 66 2c 20 70 49 6e 66 6f 2d 3e 75 42 75 66  buf, pInfo->uBuf
66b0: 20 2b 20 70 49 6e 66 6f 2d 3e 72 65 61 64 53 6f   + pInfo->readSo
66c0: 46 61 72 2c 20 74 6f 52 65 61 64 29 3b 0a 0a 20  Far, toRead);.. 
66d0: 20 70 49 6e 66 6f 2d 3e 72 65 61 64 53 6f 46 61   pInfo->readSoFa
66e0: 72 20 3d 20 6e 65 78 74 70 6f 73 3b 0a 20 20 2a  r = nextpos;.  *
66f0: 70 45 72 72 6f 72 43 6f 64 65 20 3d 20 30 3b 0a  pErrorCode = 0;.
6700: 20 20 0a 20 20 72 65 74 75 72 6e 20 74 6f 52 65    .  return toRe
6710: 61 64 3b 0a 7d 0a 0a 0a 73 74 61 74 69 63 20 69  ad;.}...static i
6720: 6e 74 20 76 66 73 52 65 61 64 20 28 0a 20 20 43  nt vfsRead (.  C
6730: 6c 69 65 6e 74 44 61 74 61 20 69 6e 73 74 61 6e  lientData instan
6740: 63 65 44 61 74 61 2c 20 2f 2a 20 54 68 65 20 63  ceData, /* The c
6750: 68 61 6e 6e 65 6c 20 74 6f 20 72 65 61 64 20 66  hannel to read f
6760: 72 6f 6d 20 2a 2f 0a 20 20 63 68 61 72 20 2a 62  rom */.  char *b
6770: 75 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  uf,             
6780: 20 20 2f 2a 20 42 75 66 66 65 72 20 74 6f 20 66    /* Buffer to f
6790: 69 6c 6c 20 2a 2f 0a 20 20 69 6e 74 20 74 6f 52  ill */.  int toR
67a0: 65 61 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  ead,            
67b0: 20 20 2f 2a 20 52 65 71 75 65 73 74 65 64 20 6e    /* Requested n
67c0: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 2a  umber of bytes *
67d0: 2f 0a 20 20 69 6e 74 20 2a 70 45 72 72 6f 72 43  /.  int *pErrorC
67e0: 6f 64 65 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ode          /* 
67f0: 4c 6f 63 61 74 69 6f 6e 20 6f 66 20 65 72 72 6f  Location of erro
6800: 72 20 66 6c 61 67 20 2a 2f 0a 20 20 29 7b 20 2f  r flag */.  ){ /
6810: 2a 20 52 65 61 64 20 61 6e 64 20 64 65 63 6f 6d  * Read and decom
6820: 70 72 65 73 73 20 61 6c 6c 20 64 61 74 61 20 66  press all data f
6830: 6f 72 20 74 68 65 20 61 73 73 6f 63 69 61 74 65  or the associate
6840: 64 20 66 69 6c 65 20 69 6e 74 6f 20 74 68 65 20  d file into the 
6850: 73 70 65 63 69 66 69 65 64 20 62 75 66 66 65 72  specified buffer
6860: 20 2a 2f 0a 20 20 5a 76 66 73 43 68 61 6e 6e 65   */.  ZvfsChanne
6870: 6c 49 6e 66 6f 2a 20 70 49 6e 66 6f 20 3d 20 28  lInfo* pInfo = (
6880: 5a 76 66 73 43 68 61 6e 6e 65 6c 49 6e 66 6f 2a  ZvfsChannelInfo*
6890: 29 20 69 6e 73 74 61 6e 63 65 44 61 74 61 3b 0a  ) instanceData;.
68a0: 20 20 69 6e 74 20 6c 65 6e 3b 0a 23 69 66 64 65    int len;.#ifde
68b0: 66 20 5a 49 50 56 46 53 43 52 59 50 54 0a 20 20  f ZIPVFSCRYPT.  
68c0: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 65 6e  unsigned char en
68d0: 63 72 79 70 74 48 64 72 5b 31 32 5d 3b 0a 20 20  cryptHdr[12];.  
68e0: 69 6e 74 20 43 3b 0a 20 20 69 6e 74 20 74 65 6d  int C;.  int tem
68f0: 70 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 68  p;.  int i;.  ch
6900: 61 72 20 70 77 64 62 75 66 5b 32 30 5d 3b 0a 23  ar pwdbuf[20];.#
6910: 65 6e 64 69 66 0a 0a 20 20 69 66 28 20 28 75 6e  endif..  if( (un
6920: 73 69 67 6e 65 64 20 6c 6f 6e 67 29 74 6f 52 65  signed long)toRe
6930: 61 64 20 3e 20 70 49 6e 66 6f 2d 3e 6e 42 79 74  ad > pInfo->nByt
6940: 65 20 29 7b 0a 20 20 20 20 74 6f 52 65 61 64 20  e ){.    toRead 
6950: 3d 20 70 49 6e 66 6f 2d 3e 6e 42 79 74 65 3b 0a  = pInfo->nByte;.
6960: 20 20 7d 0a 20 20 69 66 28 20 74 6f 52 65 61 64    }.  if( toRead
6970: 20 3d 3d 20 30 20 29 7b 0a 20 20 20 20 72 65 74   == 0 ){.    ret
6980: 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 69 66 20  urn 0;.  }.  if 
6990: 28 70 49 6e 66 6f 2d 3e 69 73 45 6e 63 72 79 70  (pInfo->isEncryp
69a0: 74 65 64 29 20 7b 0a 23 69 66 64 65 66 20 5a 49  ted) {.#ifdef ZI
69b0: 50 56 46 53 43 52 59 50 54 0a 0a 20 20 20 20 20  PVFSCRYPT..     
69c0: 20 2f 2a 20 4d 61 6b 65 20 70 72 65 70 61 72 61   /* Make prepara
69d0: 74 69 6f 6e 73 20 74 6f 20 64 65 63 72 79 70 74  tions to decrypt
69e0: 20 74 68 65 20 64 61 74 61 2e 20 2a 2f 0a 0a 09   the data. */...
69f0: 20 20 2f 2a 20 52 65 61 64 20 61 6e 64 20 64 65    /* Read and de
6a00: 63 72 79 70 74 20 74 68 65 20 65 6e 63 72 79 70  crypt the encryp
6a10: 74 69 6f 6e 20 68 65 61 64 65 72 2e 20 2a 2f 0a  tion header. */.
6a20: 20 20 20 20 20 20 63 72 63 5f 33 32 5f 74 61 62        crc_32_tab
6a30: 20 3d 20 67 65 74 5f 63 72 63 5f 74 61 62 6c 65   = get_crc_table
6a40: 28 29 3b 0a 09 20 20 69 6e 69 74 5f 6b 65 79 73  ();..  init_keys
6a50: 28 67 65 74 50 77 64 4b 65 79 28 70 77 64 62 75  (getPwdKey(pwdbu
6a60: 66 29 29 3b 0a 20 20 20 20 20 20 6c 65 6e 20 3d  f));.      len =
6a70: 20 54 63 6c 5f 52 65 61 64 28 70 49 6e 66 6f 2d   Tcl_Read(pInfo-
6a80: 3e 63 68 61 6e 2c 20 65 6e 63 72 79 70 74 48 64  >chan, encryptHd
6a90: 72 2c 20 73 69 7a 65 6f 66 28 65 6e 63 72 79 70  r, sizeof(encryp
6aa0: 74 48 64 72 29 29 3b 0a 20 20 20 20 20 20 69 66  tHdr));.      if
6ab0: 20 28 6c 65 6e 20 3d 3d 20 73 69 7a 65 6f 66 28   (len == sizeof(
6ac0: 65 6e 63 72 79 70 74 48 64 72 29 29 20 7b 0a 09  encryptHdr)) {..
6ad0: 09 20 20 66 6f 72 20 28 69 20 3d 20 30 3b 20 69  .  for (i = 0; i
6ae0: 20 3c 20 73 69 7a 65 6f 66 28 65 6e 63 72 79 70   < sizeof(encryp
6af0: 74 48 64 72 29 3b 20 2b 2b 69 29 20 7b 0a 09 09  tHdr); ++i) {...
6b00: 09 09 43 20 3d 20 65 6e 63 72 79 70 74 48 64 72  ..C = encryptHdr
6b10: 5b 69 5d 20 5e 20 64 65 63 72 79 70 74 5f 62 79  [i] ^ decrypt_by
6b20: 74 65 28 29 3b 0a 09 09 09 09 75 70 64 61 74 65  te();.....update
6b30: 5f 6b 65 79 73 28 43 29 3b 0a 09 09 20 20 7d 0a  _keys(C);...  }.
6b40: 0a 09 20 20 7d 0a 23 65 6e 64 69 66 0a 0a 09 7d  ..  }.#endif...}
6b50: 0a 20 20 69 66 28 20 70 49 6e 66 6f 2d 3e 69 73  .  if( pInfo->is
6b60: 43 6f 6d 70 72 65 73 73 65 64 20 29 7b 0a 20 20  Compressed ){.  
6b70: 20 20 69 6e 74 20 65 72 72 20 3d 20 5a 5f 4f 4b    int err = Z_OK
6b80: 3b 0a 20 20 20 20 7a 5f 73 74 72 65 61 6d 20 2a  ;.    z_stream *
6b90: 73 74 72 65 61 6d 20 3d 20 26 70 49 6e 66 6f 2d  stream = &pInfo-
6ba0: 3e 73 74 72 65 61 6d 3b 0a 20 20 20 20 73 74 72  >stream;.    str
6bb0: 65 61 6d 2d 3e 6e 65 78 74 5f 6f 75 74 20 3d 20  eam->next_out = 
6bc0: 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a  (unsigned char *
6bd0: 29 62 75 66 3b 0a 20 20 20 20 73 74 72 65 61 6d  )buf;.    stream
6be0: 2d 3e 61 76 61 69 6c 5f 6f 75 74 20 3d 20 74 6f  ->avail_out = to
6bf0: 52 65 61 64 3b 0a 20 20 20 20 77 68 69 6c 65 20  Read;.    while 
6c00: 28 73 74 72 65 61 6d 2d 3e 61 76 61 69 6c 5f 6f  (stream->avail_o
6c10: 75 74 29 20 7b 0a 20 20 20 20 20 20 69 66 20 28  ut) {.      if (
6c20: 21 73 74 72 65 61 6d 2d 3e 61 76 61 69 6c 5f 69  !stream->avail_i
6c30: 6e 29 20 7b 0a 20 20 20 20 20 20 20 20 6c 65 6e  n) {.        len
6c40: 20 3d 20 70 49 6e 66 6f 2d 3e 6e 42 79 74 65 43   = pInfo->nByteC
6c50: 6f 6d 70 72 3b 0a 20 20 20 20 20 20 20 20 69 66  ompr;.        if
6c60: 20 28 6c 65 6e 20 3e 20 43 4f 4d 50 52 5f 42 55   (len > COMPR_BU
6c70: 46 5f 53 49 5a 45 29 20 7b 0a 20 20 20 20 20 20  F_SIZE) {.      
6c80: 20 20 20 20 6c 65 6e 20 3d 20 43 4f 4d 50 52 5f      len = COMPR_
6c90: 42 55 46 5f 53 49 5a 45 3b 0a 20 20 20 20 20 20  BUF_SIZE;.      
6ca0: 20 20 7d 0a 20 20 20 20 20 20 20 20 6c 65 6e 20    }.        len 
6cb0: 3d 20 54 63 6c 5f 52 65 61 64 28 70 49 6e 66 6f  = Tcl_Read(pInfo
6cc0: 2d 3e 63 68 61 6e 2c 20 28 63 68 61 72 20 2a 29  ->chan, (char *)
6cd0: 70 49 6e 66 6f 2d 3e 7a 42 75 66 2c 20 6c 65 6e  pInfo->zBuf, len
6ce0: 29 3b 0a 23 69 66 64 65 66 20 5a 49 50 56 46 53  );.#ifdef ZIPVFS
6cf0: 43 52 59 50 54 0a 0a 09 09 69 66 20 28 70 49 6e  CRYPT....if (pIn
6d00: 66 6f 2d 3e 69 73 45 6e 63 72 79 70 74 65 64 29  fo->isEncrypted)
6d10: 20 7b 0a 09 09 09 2f 2a 20 44 65 63 72 79 70 74   {..../* Decrypt
6d20: 20 74 68 65 20 62 79 74 65 73 20 77 65 20 68 61   the bytes we ha
6d30: 76 65 20 6a 75 73 74 20 72 65 61 64 2e 20 2a 2f  ve just read. */
6d40: 0a 09 09 09 66 6f 72 20 28 69 20 3d 20 30 3b 20  ....for (i = 0; 
6d50: 69 20 3c 20 6c 65 6e 3b 20 2b 2b 69 29 20 7b 0a  i < len; ++i) {.
6d60: 09 09 09 09 43 20 3d 20 70 49 6e 66 6f 2d 3e 7a  ....C = pInfo->z
6d70: 42 75 66 5b 69 5d 3b 0a 09 09 09 20 20 20 20 74  Buf[i];....    t
6d80: 65 6d 70 20 3d 20 43 20 5e 20 64 65 63 72 79 70  emp = C ^ decryp
6d90: 74 5f 62 79 74 65 28 29 3b 0a 09 09 09 09 75 70  t_byte();.....up
6da0: 64 61 74 65 5f 6b 65 79 73 28 74 65 6d 70 29 3b  date_keys(temp);
6db0: 0a 09 09 09 09 70 49 6e 66 6f 2d 3e 7a 42 75 66  .....pInfo->zBuf
6dc0: 5b 69 5d 20 3d 20 74 65 6d 70 3b 0a 09 09 09 7d  [i] = temp;....}
6dd0: 0a 09 09 7d 0a 23 65 6e 64 69 66 0a 20 20 20 20  ...}.#endif.    
6de0: 20 20 20 20 70 49 6e 66 6f 2d 3e 6e 42 79 74 65      pInfo->nByte
6df0: 43 6f 6d 70 72 20 2d 3d 20 6c 65 6e 3b 0a 20 20  Compr -= len;.  
6e00: 20 20 20 20 20 20 73 74 72 65 61 6d 2d 3e 6e 65        stream->ne
6e10: 78 74 5f 69 6e 20 3d 20 70 49 6e 66 6f 2d 3e 7a  xt_in = pInfo->z
6e20: 42 75 66 3b 0a 20 20 20 20 20 20 20 20 73 74 72  Buf;.        str
6e30: 65 61 6d 2d 3e 61 76 61 69 6c 5f 69 6e 20 3d 20  eam->avail_in = 
6e40: 6c 65 6e 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  len;.      }.   
6e50: 20 20 20 65 72 72 20 3d 20 69 6e 66 6c 61 74 65     err = inflate
6e60: 28 73 74 72 65 61 6d 2c 20 5a 5f 4e 4f 5f 46 4c  (stream, Z_NO_FL
6e70: 55 53 48 29 3b 0a 20 20 20 20 20 20 69 66 20 28  USH);.      if (
6e80: 65 72 72 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  err) break;.    
6e90: 7d 0a 20 20 20 20 69 66 20 28 65 72 72 20 3d 3d  }.    if (err ==
6ea0: 20 5a 5f 53 54 52 45 41 4d 5f 45 4e 44 29 20 7b   Z_STREAM_END) {
6eb0: 0a 20 20 20 20 20 20 69 66 20 28 28 73 74 72 65  .      if ((stre
6ec0: 61 6d 2d 3e 61 76 61 69 6c 5f 6f 75 74 20 21 3d  am->avail_out !=
6ed0: 20 30 29 29 20 7b 0a 20 20 20 20 20 20 20 20 2a   0)) {.        *
6ee0: 70 45 72 72 6f 72 43 6f 64 65 20 3d 20 65 72 72  pErrorCode = err
6ef0: 3b 20 2f 2a 20 70 72 65 6d 61 74 75 72 65 20 65  ; /* premature e
6f00: 6e 64 20 2a 2f 0a 20 20 20 20 20 20 20 20 72 65  nd */.        re
6f10: 74 75 72 6e 20 2d 31 3b 0a 20 20 20 20 20 20 7d  turn -1;.      }
6f20: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 65  .    }else if( e
6f30: 72 72 20 29 7b 0a 20 20 20 20 20 20 2a 70 45 72  rr ){.      *pEr
6f40: 72 6f 72 43 6f 64 65 20 3d 20 65 72 72 3b 20 2f  rorCode = err; /
6f50: 2a 20 73 6f 6d 65 20 6f 74 68 65 72 20 7a 6c 69  * some other zli
6f60: 62 20 65 72 72 6f 72 20 2a 2f 0a 20 20 20 20 20  b error */.     
6f70: 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 20 20   return -1;.    
6f80: 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 74  }.  }else{.    t
6f90: 6f 52 65 61 64 20 3d 20 54 63 6c 5f 52 65 61 64  oRead = Tcl_Read
6fa0: 28 70 49 6e 66 6f 2d 3e 63 68 61 6e 2c 20 62 75  (pInfo->chan, bu
6fb0: 66 2c 20 74 6f 52 65 61 64 29 3b 0a 23 69 66 64  f, toRead);.#ifd
6fc0: 65 66 20 5a 49 50 56 46 53 43 52 59 50 54 0a 09  ef ZIPVFSCRYPT..
6fd0: 69 66 20 28 70 49 6e 66 6f 2d 3e 69 73 45 6e 63  if (pInfo->isEnc
6fe0: 72 79 70 74 65 64 29 20 7b 0a 09 09 2f 2a 20 44  rypted) {.../* D
6ff0: 65 63 72 79 70 74 20 74 68 65 20 62 79 74 65 73  ecrypt the bytes
7000: 20 77 65 20 68 61 76 65 20 6a 75 73 74 20 72 65   we have just re
7010: 61 64 2e 20 2a 2f 0a 09 09 66 6f 72 20 28 69 20  ad. */...for (i 
7020: 3d 20 30 3b 20 69 20 3c 20 74 6f 52 65 61 64 3b  = 0; i < toRead;
7030: 20 2b 2b 69 29 20 7b 0a 09 09 09 43 20 3d 20 62   ++i) {....C = b
7040: 75 66 5b 69 5d 3b 0a 09 09 20 20 20 20 74 65 6d  uf[i];...    tem
7050: 70 20 3d 20 43 20 5e 20 64 65 63 72 79 70 74 5f  p = C ^ decrypt_
7060: 62 79 74 65 28 29 3b 0a 09 09 09 75 70 64 61 74  byte();....updat
7070: 65 5f 6b 65 79 73 28 74 65 6d 70 29 3b 0a 09 09  e_keys(temp);...
7080: 09 62 75 66 5b 69 5d 20 3d 20 74 65 6d 70 3b 0a  .buf[i] = temp;.
7090: 09 09 7d 0a 09 7d 0a 23 65 6e 64 69 66 0a 20 20  ..}..}.#endif.  
70a0: 7d 0a 20 20 70 49 6e 66 6f 2d 3e 6e 42 79 74 65  }.  pInfo->nByte
70b0: 20 3d 20 74 6f 52 65 61 64 3b 0a 20 20 70 49 6e   = toRead;.  pIn
70c0: 66 6f 2d 3e 72 65 61 64 53 6f 46 61 72 20 3d 20  fo->readSoFar = 
70d0: 30 3b 0a 20 20 2a 70 45 72 72 6f 72 43 6f 64 65  0;.  *pErrorCode
70e0: 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 74   = 0;.  return t
70f0: 6f 52 65 61 64 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  oRead;.}../*.** 
7100: 57 72 69 74 65 20 74 6f 20 61 20 5a 56 46 53 20  Write to a ZVFS 
7110: 66 69 6c 65 2e 20 20 5a 56 46 53 20 66 69 6c 65  file.  ZVFS file
7120: 73 20 61 72 65 20 61 6c 77 61 79 73 20 72 65 61  s are always rea
7130: 64 2d 6f 6e 6c 79 2c 20 73 6f 20 74 68 69 73 20  d-only, so this 
7140: 72 6f 75 74 69 6e 65 0a 2a 2a 20 61 6c 77 61 79  routine.** alway
7150: 73 20 72 65 74 75 72 6e 73 20 61 6e 20 65 72 72  s returns an err
7160: 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  or..*/.static in
7170: 74 20 76 66 73 4f 75 74 70 75 74 28 0a 20 20 43  t vfsOutput(.  C
7180: 6c 69 65 6e 74 44 61 74 61 20 69 6e 73 74 61 6e  lientData instan
7190: 63 65 44 61 74 61 2c 20 20 20 2f 2a 20 54 68 65  ceData,   /* The
71a0: 20 63 68 61 6e 6e 65 6c 20 74 6f 20 77 72 69 74   channel to writ
71b0: 65 20 74 6f 20 2a 2f 0a 20 20 43 4f 4e 53 54 20  e to */.  CONST 
71c0: 63 68 61 72 20 2a 62 75 66 2c 20 20 20 20 20 20  char *buf,      
71d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61             /* Da
71e0: 74 61 20 74 6f 20 62 65 20 73 74 6f 72 65 64 2e  ta to be stored.
71f0: 20 2a 2f 0a 20 20 69 6e 74 20 74 6f 57 72 69 74   */.  int toWrit
7200: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
7210: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
7220: 74 65 73 20 74 6f 20 77 72 69 74 65 2e 20 2a 2f  tes to write. */
7230: 0a 20 20 69 6e 74 20 2a 70 45 72 72 6f 72 43 6f  .  int *pErrorCo
7240: 64 65 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  de            /*
7250: 20 4c 6f 63 61 74 69 6f 6e 20 6f 66 20 65 72 72   Location of err
7260: 6f 72 20 66 6c 61 67 2e 20 2a 2f 0a 29 7b 0a 20  or flag. */.){. 
7270: 20 2a 70 45 72 72 6f 72 43 6f 64 65 20 3d 20 45   *pErrorCode = E
7280: 49 4e 56 41 4c 3b 0a 20 20 72 65 74 75 72 6e 20  INVAL;.  return 
7290: 2d 31 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  -1;.}..static in
72a0: 74 20 76 66 73 53 65 65 6b 28 0a 20 20 43 6c 69  t vfsSeek(.  Cli
72b0: 65 6e 74 44 61 74 61 20 69 6e 73 74 61 6e 63 65  entData instance
72c0: 44 61 74 61 2c 20 20 20 20 2f 2a 20 54 68 65 20  Data,    /* The 
72d0: 66 69 6c 65 20 73 74 72 75 63 74 75 72 65 20 2a  file structure *
72e0: 2f 0a 20 20 6c 6f 6e 67 20 6f 66 66 73 65 74 2c  /.  long offset,
72f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7300: 2f 2a 20 4f 66 66 73 65 74 20 74 6f 20 73 65 65  /* Offset to see
7310: 6b 20 74 6f 20 2a 2f 0a 20 20 69 6e 74 20 6d 6f  k to */.  int mo
7320: 64 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  de,             
7330: 20 20 20 20 20 20 2f 2a 20 4f 6e 65 20 6f 66 20        /* One of 
7340: 53 45 45 4b 5f 43 55 52 2c 20 53 45 45 4b 5f 53  SEEK_CUR, SEEK_S
7350: 45 54 20 6f 72 20 53 45 45 4b 5f 45 4e 44 20 2a  ET or SEEK_END *
7360: 2f 0a 20 20 69 6e 74 20 2a 70 45 72 72 6f 72 43  /.  int *pErrorC
7370: 6f 64 65 20 20 20 20 20 20 20 20 20 20 20 20 20  ode             
7380: 2f 2a 20 57 72 69 74 65 20 74 68 65 20 65 72 72  /* Write the err
7390: 6f 72 20 63 6f 64 65 20 68 65 72 65 20 2a 2f 0a  or code here */.
73a0: 29 7b 20 2f 2a 20 4d 6f 76 65 20 74 68 65 20 66  ){ /* Move the f
73b0: 69 6c 65 20 70 6f 69 6e 74 65 72 20 73 6f 20 74  ile pointer so t
73c0: 68 61 74 20 74 68 65 20 6e 65 78 74 20 62 79 74  hat the next byt
73d0: 65 20 72 65 61 64 20 77 69 6c 6c 20 62 65 20 22  e read will be "
73e0: 6f 66 66 73 65 74 22 2e 20 2a 2f 0a 0a 20 20 5a  offset". */..  Z
73f0: 76 66 73 43 68 61 6e 6e 65 6c 49 6e 66 6f 2a 20  vfsChannelInfo* 
7400: 70 49 6e 66 6f 20 3d 20 28 5a 76 66 73 43 68 61  pInfo = (ZvfsCha
7410: 6e 6e 65 6c 49 6e 66 6f 2a 29 20 69 6e 73 74 61  nnelInfo*) insta
7420: 6e 63 65 44 61 74 61 3b 0a 0a 20 20 73 77 69 74  nceData;..  swit
7430: 63 68 28 20 6d 6f 64 65 20 29 7b 0a 20 20 20 20  ch( mode ){.    
7440: 63 61 73 65 20 53 45 45 4b 5f 43 55 52 3a 20 7b  case SEEK_CUR: {
7450: 0a 20 20 20 20 20 20 6f 66 66 73 65 74 20 2b 3d  .      offset +=
7460: 20 70 49 6e 66 6f 2d 3e 72 65 61 64 53 6f 46 61   pInfo->readSoFa
7470: 72 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  r;.      break;.
7480: 20 20 20 20 7d 0a 20 20 20 20 63 61 73 65 20 53      }.    case S
7490: 45 45 4b 5f 45 4e 44 3a 20 7b 0a 20 20 20 20 20  EEK_END: {.     
74a0: 20 6f 66 66 73 65 74 20 2b 3d 20 70 49 6e 66 6f   offset += pInfo
74b0: 2d 3e 6e 42 79 74 65 20 2d 20 31 3b 0a 20 20 20  ->nByte - 1;.   
74c0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
74d0: 20 20 20 20 64 65 66 61 75 6c 74 3a 20 7b 0a 20      default: {. 
74e0: 20 20 20 20 20 2f 2a 20 44 6f 20 6e 6f 74 68 69       /* Do nothi
74f0: 6e 67 20 2a 2f 0a 20 20 20 20 20 20 62 72 65 61  ng */.      brea
7500: 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 2f 2a 20  k;.    }.  }./* 
7510: 44 6f 6e 27 74 20 73 65 65 6b 20 70 61 73 74 20  Don't seek past 
7520: 65 6e 64 20 6f 66 20 64 61 74 61 20 2a 2f 0a 69  end of data */.i
7530: 66 20 28 70 49 6e 66 6f 2d 3e 6e 42 79 74 65 20  f (pInfo->nByte 
7540: 3c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  < (unsigned long
7550: 29 6f 66 66 73 65 74 29 0a 20 20 20 20 72 65 74  )offset).    ret
7560: 75 72 6e 20 2d 31 3b 0a 0a 2f 2a 20 44 6f 6e 27  urn -1;../* Don'
7570: 74 20 73 65 65 6b 20 62 65 66 6f 72 65 20 74 68  t seek before th
7580: 65 20 73 74 61 72 74 20 6f 66 20 64 61 74 61 20  e start of data 
7590: 2a 2f 0a 69 66 20 28 6f 66 66 73 65 74 20 3c 20  */.if (offset < 
75a0: 30 29 0a 20 20 20 20 72 65 74 75 72 6e 20 2d 31  0).    return -1
75b0: 3b 0a 0a 70 49 6e 66 6f 2d 3e 72 65 61 64 53 6f  ;..pInfo->readSo
75c0: 46 61 72 20 3d 20 28 75 6e 73 69 67 6e 65 64 20  Far = (unsigned 
75d0: 6c 6f 6e 67 29 6f 66 66 73 65 74 3b 0a 72 65 74  long)offset;.ret
75e0: 75 72 6e 20 70 49 6e 66 6f 2d 3e 72 65 61 64 53  urn pInfo->readS
75f0: 6f 46 61 72 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 48  oFar;.}../*.** H
7600: 61 6e 64 6c 65 20 65 76 65 6e 74 73 20 6f 6e 20  andle events on 
7610: 74 68 65 20 63 68 61 6e 6e 65 6c 2e 20 20 5a 56  the channel.  ZV
7620: 46 53 20 66 69 6c 65 73 20 64 6f 20 6e 6f 74 20  FS files do not 
7630: 67 65 6e 65 72 61 74 65 20 65 76 65 6e 74 73 2c  generate events,
7640: 0a 2a 2a 20 73 6f 20 74 68 69 73 20 69 73 20 61  .** so this is a
7650: 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a 73 74 61 74 69   no-op..*/.stati
7660: 63 20 76 6f 69 64 20 76 66 73 57 61 74 63 68 43  c void vfsWatchC
7670: 68 61 6e 6e 65 6c 28 0a 20 20 43 6c 69 65 6e 74  hannel(.  Client
7680: 44 61 74 61 20 69 6e 73 74 61 6e 63 65 44 61 74  Data instanceDat
7690: 61 2c 20 20 20 2f 2a 20 43 68 61 6e 6e 65 6c 20  a,   /* Channel 
76a0: 74 6f 20 77 61 74 63 68 20 2a 2f 0a 20 20 69 6e  to watch */.  in
76b0: 74 20 6d 61 73 6b 20 20 20 20 20 20 20 20 20 20  t mask          
76c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 45 76 65 6e           /* Even
76d0: 74 73 20 6f 66 20 69 6e 74 65 72 65 73 74 20 2a  ts of interest *
76e0: 2f 0a 29 7b 0a 20 20 72 65 74 75 72 6e 3b 0a 7d  /.){.  return;.}
76f0: 0a 0a 2f 2a 0a 2a 2a 20 43 61 6c 6c 65 64 20 74  ../*.** Called t
7700: 6f 20 72 65 74 72 69 65 76 65 20 74 68 65 20 75  o retrieve the u
7710: 6e 64 65 72 6c 79 69 6e 67 20 66 69 6c 65 20 68  nderlying file h
7720: 61 6e 64 6c 65 20 66 6f 72 20 74 68 69 73 20 5a  andle for this Z
7730: 56 46 53 20 66 69 6c 65 2e 0a 2a 2a 20 41 73 20  VFS file..** As 
7740: 74 68 65 20 5a 56 46 53 20 66 69 6c 65 20 68 61  the ZVFS file ha
7750: 73 20 6e 6f 20 75 6e 64 65 72 6c 79 69 6e 67 20  s no underlying 
7760: 66 69 6c 65 20 68 61 6e 64 6c 65 2c 20 74 68 69  file handle, thi
7770: 73 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f  s is a no-op..*/
7780: 0a 73 74 61 74 69 63 20 69 6e 74 20 76 66 73 47  .static int vfsG
7790: 65 74 46 69 6c 65 28 0a 20 20 43 6c 69 65 6e 74  etFile(.  Client
77a0: 44 61 74 61 20 20 69 6e 73 74 61 6e 63 65 44 61  Data  instanceDa
77b0: 74 61 2c 20 20 20 2f 2a 20 43 68 61 6e 6e 65 6c  ta,   /* Channel
77c0: 20 74 6f 20 71 75 65 72 79 20 2a 2f 0a 20 20 69   to query */.  i
77d0: 6e 74 20 64 69 72 65 63 74 69 6f 6e 2c 20 20 20  nt direction,   
77e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 69             /* Di
77f0: 72 65 63 74 69 6f 6e 20 6f 66 20 69 6e 74 65 72  rection of inter
7800: 65 73 74 20 2a 2f 0a 20 20 43 6c 69 65 6e 74 44  est */.  ClientD
7810: 61 74 61 2a 20 68 61 6e 64 6c 65 50 74 72 20 20  ata* handlePtr  
7820: 20 20 20 20 20 2f 2a 20 53 70 61 63 65 20 74 6f       /* Space to
7830: 20 74 68 65 20 68 61 6e 64 6c 65 20 69 6e 74 6f   the handle into
7840: 20 2a 2f 0a 29 7b 0a 20 20 72 65 74 75 72 6e 20   */.){.  return 
7850: 54 43 4c 5f 45 52 52 4f 52 3b 0a 7d 0a 0a 2f 2a  TCL_ERROR;.}../*
7860: 0a 2a 2a 20 54 68 69 73 20 73 74 72 75 63 74 75  .** This structu
7870: 72 65 20 64 65 73 63 72 69 62 65 73 20 74 68 65  re describes the
7880: 20 63 68 61 6e 6e 65 6c 20 74 79 70 65 20 73 74   channel type st
7890: 72 75 63 74 75 72 65 20 66 6f 72 20 0a 2a 2a 20  ructure for .** 
78a0: 61 63 63 65 73 73 20 74 6f 20 74 68 65 20 5a 56  access to the ZV
78b0: 46 53 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 54 63  FS..*/.static Tc
78c0: 6c 5f 43 68 61 6e 6e 65 6c 54 79 70 65 20 76 66  l_ChannelType vf
78d0: 73 43 68 61 6e 6e 65 6c 54 79 70 65 20 3d 20 7b  sChannelType = {
78e0: 0a 20 20 22 76 66 73 22 2c 09 09 2f 2a 20 54 79  .  "vfs",../* Ty
78f0: 70 65 20 6e 61 6d 65 2e 20 20 20 20 20 20 20 20  pe name.        
7900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7910: 20 20 20 20 20 20 20 20 20 20 20 20 2a 2f 0a 20              */. 
7920: 20 4e 55 4c 4c 2c 09 09 09 2f 2a 20 53 65 74 20   NULL,.../* Set 
7930: 62 6c 6f 63 6b 69 6e 67 2f 6e 6f 6e 62 6c 6f 63  blocking/nonbloc
7940: 6b 69 6e 67 20 62 65 68 61 76 69 6f 75 72 2e 20  king behaviour. 
7950: 4e 55 4c 4c 27 61 62 6c 65 20 2a 2f 0a 20 20 76  NULL'able */.  v
7960: 66 73 43 6c 6f 73 65 2c 09 09 2f 2a 20 43 6c 6f  fsClose,../* Clo
7970: 73 65 20 63 68 61 6e 6e 65 6c 2c 20 63 6c 65 61  se channel, clea
7980: 6e 20 69 6e 73 74 61 6e 63 65 20 64 61 74 61 20  n instance data 
7990: 20 20 20 20 20 20 20 20 20 20 20 2a 2f 0a 20 20             */.  
79a0: 76 66 73 49 6e 70 75 74 2c 09 09 2f 2a 20 48 61  vfsInput,../* Ha
79b0: 6e 64 6c 65 20 72 65 61 64 20 72 65 71 75 65 73  ndle read reques
79c0: 74 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t               
79d0: 20 20 20 20 20 20 20 20 20 20 20 20 2a 2f 0a 20              */. 
79e0: 20 76 66 73 4f 75 74 70 75 74 2c 09 09 2f 2a 20   vfsOutput,../* 
79f0: 48 61 6e 64 6c 65 20 77 72 69 74 65 20 72 65 71  Handle write req
7a00: 75 65 73 74 20 20 20 20 20 20 20 20 20 20 20 20  uest            
7a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 2f                */
7a20: 0a 20 20 76 66 73 53 65 65 6b 2c 09 09 2f 2a 20  .  vfsSeek,../* 
7a30: 4d 6f 76 65 20 6c 6f 63 61 74 69 6f 6e 20 6f 66  Move location of
7a40: 20 61 63 63 65 73 73 20 70 6f 69 6e 74 2e 20 20   access point.  
7a50: 20 20 20 20 4e 55 4c 4c 27 61 62 6c 65 20 2a 2f      NULL'able */
7a60: 0a 20 20 4e 55 4c 4c 2c 09 09 09 2f 2a 20 53 65  .  NULL,.../* Se
7a70: 74 20 6f 70 74 69 6f 6e 73 2e 20 20 20 20 20 20  t options.      
7a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7a90: 20 20 4e 55 4c 4c 27 61 62 6c 65 20 2a 2f 0a 20    NULL'able */. 
7aa0: 20 4e 55 4c 4c 2c 09 09 09 2f 2a 20 47 65 74 20   NULL,.../* Get 
7ab0: 6f 70 74 69 6f 6e 73 2e 20 20 20 20 20 20 20 20  options.        
7ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7ad0: 4e 55 4c 4c 27 61 62 6c 65 20 2a 2f 0a 20 20 76  NULL'able */.  v
7ae0: 66 73 57 61 74 63 68 43 68 61 6e 6e 65 6c 2c 09  fsWatchChannel,.
7af0: 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 6e 6f  /* Initialize no
7b00: 74 69 66 69 65 72 20 20 20 20 20 20 20 20 20 20  tifier          
7b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7b20: 20 2a 2f 0a 20 20 76 66 73 47 65 74 46 69 6c 65   */.  vfsGetFile
7b30: 09 09 2f 2a 20 47 65 74 20 4f 53 20 68 61 6e 64  ../* Get OS hand
7b40: 6c 65 20 66 72 6f 6d 20 74 68 65 20 63 68 61 6e  le from the chan
7b50: 6e 65 6c 2e 20 20 20 20 20 20 20 20 20 20 20 20  nel.            
7b60: 20 20 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20     */.};../*.** 
7b70: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 61 74 74  This routine att
7b80: 65 6d 70 74 73 20 74 6f 20 64 6f 20 61 6e 20 6f  empts to do an o
7b90: 70 65 6e 20 6f 66 20 61 20 66 69 6c 65 2e 20 20  pen of a file.  
7ba0: 43 68 65 63 6b 20 74 6f 20 73 65 65 0a 2a 2a 20  Check to see.** 
7bb0: 69 66 20 74 68 65 20 66 69 6c 65 20 69 73 20 6c  if the file is l
7bc0: 6f 63 61 74 65 64 20 69 6e 20 74 68 65 20 5a 56  ocated in the ZV
7bd0: 46 53 2e 20 20 49 66 20 73 6f 2c 20 74 68 65 6e  FS.  If so, then
7be0: 20 6f 70 65 6e 20 61 20 63 68 61 6e 6e 65 6c 0a   open a channel.
7bf0: 2a 2a 20 66 6f 72 20 72 65 61 64 69 6e 67 20 74  ** for reading t
7c00: 68 65 20 66 69 6c 65 2e 20 20 49 66 20 6e 6f 74  he file.  If not
7c10: 2c 20 72 65 74 75 72 6e 20 4e 55 4c 4c 2e 0a 2a  , return NULL..*
7c20: 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f 43 68 61  /.static Tcl_Cha
7c30: 6e 6e 65 6c 20 5a 76 66 73 46 69 6c 65 4f 70 65  nnel ZvfsFileOpe
7c40: 6e 28 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20  n(.  Tcl_Interp 
7c50: 2a 69 6e 74 65 72 70 2c 20 20 20 20 20 2f 2a 20  *interp,     /* 
7c60: 54 68 65 20 54 43 4c 20 69 6e 74 65 72 70 72 65  The TCL interpre
7c70: 74 65 72 20 64 6f 69 6e 67 20 74 68 65 20 6f 70  ter doing the op
7c80: 65 6e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 46  en */.  char *zF
7c90: 69 6c 65 6e 61 6d 65 2c 20 20 20 20 20 20 20 20  ilename,        
7ca0: 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 66  /* Name of the f
7cb0: 69 6c 65 20 74 6f 20 6f 70 65 6e 20 2a 2f 0a 20  ile to open */. 
7cc0: 20 63 68 61 72 20 2a 6d 6f 64 65 53 74 72 69 6e   char *modeStrin
7cd0: 67 2c 20 20 20 20 20 20 20 2f 2a 20 4d 6f 64 65  g,       /* Mode
7ce0: 20 73 74 72 69 6e 67 20 66 6f 72 20 74 68 65 20   string for the 
7cf0: 6f 70 65 6e 20 28 69 67 6e 6f 72 65 64 29 20 2a  open (ignored) *
7d00: 2f 0a 20 20 69 6e 74 20 70 65 72 6d 69 73 73 69  /.  int permissi
7d10: 6f 6e 73 20 20 20 20 20 20 20 20 20 2f 2a 20 50  ons         /* P
7d20: 65 72 6d 69 73 73 69 6f 6e 73 20 66 6f 72 20 61  ermissions for a
7d30: 20 6e 65 77 6c 79 20 63 72 65 61 74 65 64 20 66   newly created f
7d40: 69 6c 65 20 28 69 67 6e 6f 72 65 64 29 20 2a 2f  ile (ignored) */
7d50: 0a 29 7b 0a 20 20 5a 76 66 73 46 69 6c 65 20 2a  .){.  ZvfsFile *
7d60: 70 46 69 6c 65 3b 0a 20 20 5a 76 66 73 43 68 61  pFile;.  ZvfsCha
7d70: 6e 6e 65 6c 49 6e 66 6f 20 2a 70 49 6e 66 6f 3b  nnelInfo *pInfo;
7d80: 0a 20 20 54 63 6c 5f 43 68 61 6e 6e 65 6c 20 63  .  Tcl_Channel c
7d90: 68 61 6e 3b 0a 20 20 73 74 61 74 69 63 20 69 6e  han;.  static in
7da0: 74 20 63 6f 75 6e 74 20 3d 20 31 3b 0a 20 20 63  t count = 1;.  c
7db0: 68 61 72 20 7a 4e 61 6d 65 5b 35 30 5d 3b 0a 20  har zName[50];. 
7dc0: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 7a   unsigned char z
7dd0: 42 75 66 5b 35 30 5d 3b 0a 20 20 69 6e 74 20 65  Buf[50];.  int e
7de0: 72 72 43 6f 64 65 3b 0a 0a 20 20 70 46 69 6c 65  rrCode;..  pFile
7df0: 20 3d 20 5a 76 66 73 4c 6f 6f 6b 75 70 28 7a 46   = ZvfsLookup(zF
7e00: 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 69 66 28 20  ilename);.  if( 
7e10: 70 46 69 6c 65 3d 3d 30 20 29 20 7b 0a 20 20 20  pFile==0 ) {.   
7e20: 20 72 65 74 75 72 6e 20 4e 55 4c 4c 3b 0a 20 20   return NULL;.  
7e30: 7d 0a 20 20 6f 70 65 6e 61 72 63 68 20 3d 20 31  }.  openarch = 1
7e40: 3b 0a 20 20 0a 20 20 54 63 6c 5f 4d 75 74 65 78  ;.  .  Tcl_Mutex
7e50: 4c 6f 63 6b 28 26 41 72 63 68 69 76 65 46 69 6c  Lock(&ArchiveFil
7e60: 65 41 63 63 65 73 73 29 3b 0a 20 20 63 68 61 6e  eAccess);.  chan
7e70: 20 3d 20 54 63 6c 5f 4f 70 65 6e 46 69 6c 65 43   = Tcl_OpenFileC
7e80: 68 61 6e 6e 65 6c 28 69 6e 74 65 72 70 2c 20 70  hannel(interp, p
7e90: 46 69 6c 65 2d 3e 70 41 72 63 68 69 76 65 2d 3e  File->pArchive->
7ea0: 7a 4e 61 6d 65 2c 20 22 72 22 2c 20 30 29 3b 0a  zName, "r", 0);.
7eb0: 20 20 6f 70 65 6e 61 72 63 68 20 3d 20 30 3b 0a    openarch = 0;.
7ec0: 20 20 0a 20 20 69 66 20 28 6c 6f 63 61 6c 2e 66    .  if (local.f
7ed0: 69 72 73 74 4d 6f 75 6e 74 20 3d 3d 20 4e 55 4c  irstMount == NUL
7ee0: 4c 29 20 7b 0a 09 6c 6f 63 61 6c 2e 66 69 72 73  L) {..local.firs
7ef0: 74 4d 6f 75 6e 74 20 3d 20 70 46 69 6c 65 2d 3e  tMount = pFile->
7f00: 70 41 72 63 68 69 76 65 2d 3e 7a 4e 61 6d 65 3b  pArchive->zName;
7f10: 0a 20 20 7d 0a 20 20 69 66 28 20 63 68 61 6e 3d  .  }.  if( chan=
7f20: 3d 30 20 29 7b 0a 20 20 20 20 54 63 6c 5f 4d 75  =0 ){.    Tcl_Mu
7f30: 74 65 78 55 6e 6c 6f 63 6b 28 26 41 72 63 68 69  texUnlock(&Archi
7f40: 76 65 46 69 6c 65 41 63 63 65 73 73 29 3b 0a 20  veFileAccess);. 
7f50: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d     return 0;.  }
7f60: 0a 20 20 69 66 28 20 20 54 63 6c 5f 53 65 74 43  .  if(  Tcl_SetC
7f70: 68 61 6e 6e 65 6c 4f 70 74 69 6f 6e 28 69 6e 74  hannelOption(int
7f80: 65 72 70 2c 20 63 68 61 6e 2c 20 22 2d 74 72 61  erp, chan, "-tra
7f90: 6e 73 6c 61 74 69 6f 6e 22 2c 20 22 62 69 6e 61  nslation", "bina
7fa0: 72 79 22 29 0a 20 20 20 20 7c 7c 20 54 63 6c 5f  ry").    || Tcl_
7fb0: 53 65 74 43 68 61 6e 6e 65 6c 4f 70 74 69 6f 6e  SetChannelOption
7fc0: 28 69 6e 74 65 72 70 2c 20 63 68 61 6e 2c 20 22  (interp, chan, "
7fd0: 2d 65 6e 63 6f 64 69 6e 67 22 2c 20 22 62 69 6e  -encoding", "bin
7fe0: 61 72 79 22 29 0a 20 20 29 7b 0a 20 20 20 20 2f  ary").  ){.    /
7ff0: 2a 20 74 68 69 73 20 73 68 6f 75 6c 64 20 6e 65  * this should ne
8000: 76 65 72 20 68 61 70 70 65 6e 20 2a 2f 0a 20 20  ver happen */.  
8010: 20 20 67 6f 74 6f 20 63 6c 6f 73 65 52 65 6c 65    goto closeRele
8020: 61 73 65 44 69 65 3b 0a 20 20 7d 0a 20 20 54 63  aseDie;.  }.  Tc
8030: 6c 5f 53 65 65 6b 28 63 68 61 6e 2c 20 70 46 69  l_Seek(chan, pFi
8040: 6c 65 2d 3e 69 4f 66 66 73 65 74 2c 20 53 45 45  le->iOffset, SEE
8050: 4b 5f 53 45 54 29 3b 0a 20 20 54 63 6c 5f 52 65  K_SET);.  Tcl_Re
8060: 61 64 28 63 68 61 6e 2c 20 28 63 68 61 72 20 2a  ad(chan, (char *
8070: 29 7a 42 75 66 2c 20 33 30 29 3b 0a 20 20 69 66  )zBuf, 30);.  if
8080: 28 20 6d 65 6d 63 6d 70 28 7a 42 75 66 2c 20 22  ( memcmp(zBuf, "
8090: 5c 31 32 30 5c 31 31 33 5c 30 33 5c 30 34 22 2c  \120\113\03\04",
80a0: 20 34 29 20 29 7b 0a 20 20 20 20 69 66 28 20 69   4) ){.    if( i
80b0: 6e 74 65 72 70 20 29 7b 0a 20 20 20 20 20 20 54  nterp ){.      T
80c0: 63 6c 5f 41 70 70 65 6e 64 52 65 73 75 6c 74 28  cl_AppendResult(
80d0: 69 6e 74 65 72 70 2c 20 22 6c 6f 63 61 6c 20 68  interp, "local h
80e0: 65 61 64 65 72 20 6d 69 73 6d 61 74 63 68 3a 20  eader mismatch: 
80f0: 22 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 7d 0a  ", NULL);.    }.
8100: 20 20 20 20 67 6f 74 6f 20 63 6c 6f 73 65 52 65      goto closeRe
8110: 6c 65 61 73 65 44 69 65 3b 0a 20 20 7d 0a 20 20  leaseDie;.  }.  
8120: 70 49 6e 66 6f 20 3d 20 28 5a 76 66 73 43 68 61  pInfo = (ZvfsCha
8130: 6e 6e 65 6c 49 6e 66 6f 2a 29 54 63 6c 5f 41 6c  nnelInfo*)Tcl_Al
8140: 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70 49 6e  loc( sizeof(*pIn
8150: 66 6f 29 20 29 3b 0a 20 20 70 49 6e 66 6f 2d 3e  fo) );.  pInfo->
8160: 63 68 61 6e 20 3d 20 63 68 61 6e 3b 0a 20 20 54  chan = chan;.  T
8170: 63 6c 5f 43 72 65 61 74 65 45 78 69 74 48 61 6e  cl_CreateExitHan
8180: 64 6c 65 72 28 76 66 73 45 78 69 74 2c 20 70 49  dler(vfsExit, pI
8190: 6e 66 6f 29 3b 0a 23 69 66 64 65 66 20 5a 49 50  nfo);.#ifdef ZIP
81a0: 56 46 53 43 52 59 50 54 0a 20 20 70 49 6e 66 6f  VFSCRYPT.  pInfo
81b0: 2d 3e 69 73 45 6e 63 72 79 70 74 65 64 20 3d 20  ->isEncrypted = 
81c0: 7a 42 75 66 5b 36 5d 20 26 20 31 3b 0a 20 20 69  zBuf[6] & 1;.  i
81d0: 66 20 28 70 46 69 6c 65 2d 3e 70 41 72 63 68 69  f (pFile->pArchi
81e0: 76 65 2d 3e 7a 4e 61 6d 65 20 3d 3d 20 6c 6f 63  ve->zName == loc
81f0: 61 6c 2e 66 69 72 73 74 4d 6f 75 6e 74 29 20 7b  al.firstMount) {
8200: 0a 09 2f 2a 20 46 72 65 65 57 72 61 70 20 73 70  ../* FreeWrap sp
8210: 65 63 69 66 69 63 2e 0a 09 20 20 20 57 65 20 61  ecific...   We a
8220: 72 65 20 6f 70 65 6e 69 6e 67 20 61 20 66 69 6c  re opening a fil
8230: 65 20 66 72 6f 6d 20 74 68 65 20 65 78 65 63 75  e from the execu
8240: 74 61 62 6c 65 2e 0a 09 20 20 20 41 6c 6c 20 73  table...   All s
8250: 75 63 68 20 66 69 6c 65 73 20 6d 75 73 74 20 62  uch files must b
8260: 65 20 65 6e 63 72 79 70 74 65 64 2e 0a 20 20 20  e encrypted..   
8270: 20 20 20 2a 2f 0a 09 69 66 20 28 21 70 49 6e 66     */..if (!pInf
8280: 6f 2d 3e 69 73 45 6e 63 72 79 70 74 65 64 29 20  o->isEncrypted) 
8290: 7b 0a 09 20 20 20 20 2f 2a 20 54 68 65 20 66 69  {..    /* The fi
82a0: 6c 65 20 69 73 20 6e 6f 74 20 65 6e 63 72 79 70  le is not encryp
82b0: 74 65 64 2e 0a 09 09 20 53 6f 6d 65 6f 6e 65 20  ted.... Someone 
82c0: 6d 75 73 74 20 68 61 76 65 20 74 61 6d 70 65 72  must have tamper
82d0: 65 64 20 77 69 74 68 20 74 68 65 20 61 70 70 6c  ed with the appl
82e0: 69 63 61 74 69 6f 6e 2e 0a 09 09 20 4c 65 74 27  ication.... Let'
82f0: 73 20 65 78 69 74 20 74 68 65 20 70 72 6f 67 72  s exit the progr
8300: 61 6d 2e 0a 09 20 20 20 20 2a 2f 0a 09 09 20 70  am...    */... p
8310: 72 69 6e 74 66 28 22 54 68 69 73 20 61 70 70 6c  rintf("This appl
8320: 69 63 61 74 69 6f 6e 20 68 61 73 20 61 6e 20 75  ication has an u
8330: 6e 61 75 74 68 6f 72 69 7a 65 64 20 6d 6f 64 69  nauthorized modi
8340: 66 69 63 61 74 69 6f 6e 2e 20 45 78 69 74 69 6e  fication. Exitin
8350: 67 20 69 6d 6d 65 64 69 61 74 65 6c 79 5c 6e 22  g immediately\n"
8360: 29 3b 0a 09 09 20 65 78 69 74 28 2d 31 30 29 3b  );... exit(-10);
8370: 0a 09 20 20 20 7d 0a 20 20 20 20 20 7d 0a 23 65  ..   }.     }.#e
8380: 6e 64 69 66 0a 20 20 70 49 6e 66 6f 2d 3e 69 73  ndif.  pInfo->is
8390: 43 6f 6d 70 72 65 73 73 65 64 20 3d 20 49 4e 54  Compressed = INT
83a0: 31 36 28 7a 42 75 66 2c 20 38 29 3b 0a 20 20 69  16(zBuf, 8);.  i
83b0: 66 20 28 70 49 6e 66 6f 2d 3e 69 73 43 6f 6d 70  f (pInfo->isComp
83c0: 72 65 73 73 65 64 20 29 7b 0a 20 20 20 20 20 20  ressed ){.      
83d0: 7a 5f 73 74 72 65 61 6d 20 2a 73 74 72 65 61 6d  z_stream *stream
83e0: 20 3d 20 26 70 49 6e 66 6f 2d 3e 73 74 72 65 61   = &pInfo->strea
83f0: 6d 3b 0a 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e  m;.      pInfo->
8400: 7a 42 75 66 20 3d 20 28 76 6f 69 64 20 2a 29 54  zBuf = (void *)T
8410: 63 6c 5f 41 6c 6c 6f 63 28 43 4f 4d 50 52 5f 42  cl_Alloc(COMPR_B
8420: 55 46 5f 53 49 5a 45 29 3b 0a 20 20 20 20 20 20  UF_SIZE);.      
8430: 73 74 72 65 61 6d 2d 3e 7a 61 6c 6c 6f 63 20 3d  stream->zalloc =
8440: 20 28 61 6c 6c 6f 63 5f 66 75 6e 63 29 30 3b 0a   (alloc_func)0;.
8450: 20 20 20 20 20 20 73 74 72 65 61 6d 2d 3e 7a 66        stream->zf
8460: 72 65 65 20 3d 20 28 66 72 65 65 5f 66 75 6e 63  ree = (free_func
8470: 29 30 3b 0a 20 20 20 20 20 20 73 74 72 65 61 6d  )0;.      stream
8480: 2d 3e 6f 70 61 71 75 65 20 3d 20 28 76 6f 69 64  ->opaque = (void
8490: 70 66 29 30 3b 0a 20 20 20 20 20 20 73 74 72 65  pf)0;.      stre
84a0: 61 6d 2d 3e 61 76 61 69 6c 5f 69 6e 20 3d 20 32  am->avail_in = 2
84b0: 3b 0a 20 20 20 20 20 20 73 74 72 65 61 6d 2d 3e  ;.      stream->
84c0: 6e 65 78 74 5f 69 6e 20 3d 20 70 49 6e 66 6f 2d  next_in = pInfo-
84d0: 3e 7a 42 75 66 3b 0a 20 20 20 20 20 20 70 49 6e  >zBuf;.      pIn
84e0: 66 6f 2d 3e 7a 42 75 66 5b 30 5d 20 3d 20 30 78  fo->zBuf[0] = 0x
84f0: 37 38 3b 0a 20 20 20 20 20 20 70 49 6e 66 6f 2d  78;.      pInfo-
8500: 3e 7a 42 75 66 5b 31 5d 20 3d 20 30 78 30 31 3b  >zBuf[1] = 0x01;
8510: 0a 20 20 20 20 20 20 69 6e 66 6c 61 74 65 49 6e  .      inflateIn
8520: 69 74 28 26 70 49 6e 66 6f 2d 3e 73 74 72 65 61  it(&pInfo->strea
8530: 6d 29 3b 0a 20 20 7d 20 65 6c 73 65 20 7b 0a 20  m);.  } else {. 
8540: 20 20 20 20 20 20 20 70 49 6e 66 6f 2d 3e 7a 42         pInfo->zB
8550: 75 66 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 70 49  uf = 0;.  }.  pI
8560: 6e 66 6f 2d 3e 6e 42 79 74 65 20 3d 20 49 4e 54  nfo->nByte = INT
8570: 33 32 28 7a 42 75 66 2c 32 32 29 3b 0a 20 20 70  32(zBuf,22);.  p
8580: 49 6e 66 6f 2d 3e 6e 42 79 74 65 43 6f 6d 70 72  Info->nByteCompr
8590: 20 3d 20 70 49 6e 66 6f 2d 3e 6e 44 61 74 61 20   = pInfo->nData 
85a0: 3d 20 49 4e 54 33 32 28 7a 42 75 66 2c 31 38 29  = INT32(zBuf,18)
85b0: 3b 0a 20 20 70 49 6e 66 6f 2d 3e 72 65 61 64 53  ;.  pInfo->readS
85c0: 6f 46 61 72 20 3d 20 30 3b 0a 20 20 54 63 6c 5f  oFar = 0;.  Tcl_
85d0: 53 65 65 6b 28 63 68 61 6e 2c 20 49 4e 54 31 36  Seek(chan, INT16
85e0: 28 7a 42 75 66 2c 32 36 29 2b 49 4e 54 31 36 28  (zBuf,26)+INT16(
85f0: 7a 42 75 66 2c 32 38 29 2c 20 53 45 45 4b 5f 43  zBuf,28), SEEK_C
8600: 55 52 29 3b 0a 20 20 70 49 6e 66 6f 2d 3e 73 74  UR);.  pInfo->st
8610: 61 72 74 4f 66 44 61 74 61 20 3d 20 54 63 6c 5f  artOfData = Tcl_
8620: 54 65 6c 6c 28 63 68 61 6e 29 3b 0a 20 20 73 70  Tell(chan);.  sp
8630: 72 69 6e 74 66 28 7a 4e 61 6d 65 2c 22 76 66 73  rintf(zName,"vfs
8640: 5f 25 78 5f 25 78 22 2c 28 28 69 6e 74 29 70 46  _%x_%x",((int)pF
8650: 69 6c 65 29 3e 3e 31 32 2c 63 6f 75 6e 74 2b 2b  ile)>>12,count++
8660: 29 3b 0a 20 20 63 68 61 6e 20 3d 20 54 63 6c 5f  );.  chan = Tcl_
8670: 43 72 65 61 74 65 43 68 61 6e 6e 65 6c 28 26 76  CreateChannel(&v
8680: 66 73 43 68 61 6e 6e 65 6c 54 79 70 65 2c 20 7a  fsChannelType, z
8690: 4e 61 6d 65 2c 20 0a 20 20 20 20 20 20 20 20 20  Name, .         
86a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
86b0: 20 20 28 43 6c 69 65 6e 74 44 61 74 61 29 70 49    (ClientData)pI
86c0: 6e 66 6f 2c 20 54 43 4c 5f 52 45 41 44 41 42 4c  nfo, TCL_READABL
86d0: 45 29 3b 0a 0a 20 20 70 49 6e 66 6f 2d 3e 75 42  E);..  pInfo->uB
86e0: 75 66 20 3d 20 28 76 6f 69 64 20 2a 29 54 63 6c  uf = (void *)Tcl
86f0: 5f 41 6c 6c 6f 63 28 70 49 6e 66 6f 2d 3e 6e 42  _Alloc(pInfo->nB
8700: 79 74 65 29 3b 0a 20 20 2f 2a 20 52 65 61 64 20  yte);.  /* Read 
8710: 61 6e 64 20 64 65 63 6f 6d 70 72 65 73 73 20 74  and decompress t
8720: 68 65 20 66 69 6c 65 20 63 6f 6e 74 65 6e 74 73  he file contents
8730: 20 2a 2f 0a 20 20 69 66 20 28 70 49 6e 66 6f 2d   */.  if (pInfo-
8740: 3e 75 42 75 66 29 20 7b 0a 20 20 20 20 70 49 6e  >uBuf) {.    pIn
8750: 66 6f 2d 3e 75 42 75 66 5b 30 5d 20 3d 20 30 3b  fo->uBuf[0] = 0;
8760: 0a 20 20 20 20 76 66 73 52 65 61 64 28 70 49 6e  .    vfsRead(pIn
8770: 66 6f 2c 20 28 63 68 61 72 20 2a 29 70 49 6e 66  fo, (char *)pInf
8780: 6f 2d 3e 75 42 75 66 2c 20 70 49 6e 66 6f 2d 3e  o->uBuf, pInfo->
8790: 6e 42 79 74 65 2c 20 26 65 72 72 43 6f 64 65 29  nByte, &errCode)
87a0: 3b 0a 20 20 20 20 70 49 6e 66 6f 2d 3e 72 65 61  ;.    pInfo->rea
87b0: 64 53 6f 46 61 72 20 3d 20 30 3b 0a 20 20 7d 0a  dSoFar = 0;.  }.
87c0: 0a 20 20 72 65 74 75 72 6e 20 63 68 61 6e 3b 0a  .  return chan;.
87d0: 0a 63 6c 6f 73 65 52 65 6c 65 61 73 65 44 69 65  .closeReleaseDie
87e0: 3a 0a 20 20 54 63 6c 5f 43 6c 6f 73 65 28 69 6e  :.  Tcl_Close(in
87f0: 74 65 72 70 2c 20 63 68 61 6e 29 3b 0a 20 20 54  terp, chan);.  T
8800: 63 6c 5f 4d 75 74 65 78 55 6e 6c 6f 63 6b 28 26  cl_MutexUnlock(&
8810: 41 72 63 68 69 76 65 46 69 6c 65 41 63 63 65 73  ArchiveFileAcces
8820: 73 29 3b 0a 20 20 72 65 74 75 72 6e 20 4e 55 4c  s);.  return NUL
8830: 4c 3b 0a 0a 7d 0a 0a 54 63 6c 5f 43 68 61 6e 6e  L;..}..Tcl_Chann
8840: 65 6c 20 54 6f 62 65 5f 46 53 4f 70 65 6e 46 69  el Tobe_FSOpenFi
8850: 6c 65 43 68 61 6e 6e 65 6c 50 72 6f 63 20 28 0a  leChannelProc (.
8860: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
8870: 74 65 72 70 2c 20 0a 20 20 54 63 6c 5f 4f 62 6a  terp, .  Tcl_Obj
8880: 20 2a 70 61 74 68 50 74 72 2c 0a 20 20 69 6e 74   *pathPtr,.  int
8890: 20 6d 6f 64 65 2c 20 0a 20 20 69 6e 74 20 70 65   mode, .  int pe
88a0: 72 6d 69 73 73 69 6f 6e 73 0a 29 20 7b 0a 20 20  rmissions.) {.  
88b0: 69 6e 74 20 6c 65 6e 3b 0a 20 20 2f 2a 20 69 66  int len;.  /* if
88c0: 20 28 6d 6f 64 65 20 21 3d 20 4f 5f 52 44 4f 4e   (mode != O_RDON
88d0: 4c 59 29 20 72 65 74 75 72 6e 20 4e 55 4c 4c 3b  LY) return NULL;
88e0: 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20 5a 76 66   */.  return Zvf
88f0: 73 46 69 6c 65 4f 70 65 6e 28 69 6e 74 65 72 70  sFileOpen(interp
8900: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 46  , Tcl_GetStringF
8910: 72 6f 6d 4f 62 6a 28 70 61 74 68 50 74 72 2c 26  romObj(pathPtr,&
8920: 6c 65 6e 29 2c 20 30 2c 0a 20 20 20 20 70 65 72  len), 0,.    per
8930: 6d 69 73 73 69 6f 6e 73 29 3b 0a 7d 0a 0a 2f 2a  missions);.}../*
8940: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
8950: 20 64 6f 65 73 20 61 20 73 74 61 74 28 29 20 73   does a stat() s
8960: 79 73 74 65 6d 20 63 61 6c 6c 20 66 6f 72 20 61  ystem call for a
8970: 20 5a 56 46 53 20 66 69 6c 65 2e 0a 2a 2f 0a 69   ZVFS file..*/.i
8980: 6e 74 20 54 6f 62 65 5f 46 53 53 74 61 74 50 72  nt Tobe_FSStatPr
8990: 6f 63 20 28 0a 20 20 20 54 63 6c 5f 4f 62 6a 20  oc (.   Tcl_Obj 
89a0: 2a 70 61 74 68 50 74 72 2c 20 0a 20 20 20 54 63  *pathPtr, .   Tc
89b0: 6c 5f 53 74 61 74 42 75 66 20 2a 62 75 66 0a 29  l_StatBuf *buf.)
89c0: 20 7b 0a 20 20 20 20 63 68 61 72 20 2a 70 61 74   {.    char *pat
89d0: 68 3d 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  h=Tcl_GetString(
89e0: 70 61 74 68 50 74 72 29 3b 0a 20 20 20 20 5a 76  pathPtr);.    Zv
89f0: 66 73 46 69 6c 65 20 2a 70 46 69 6c 65 3b 0a 0a  fsFile *pFile;..
8a00: 20 20 20 20 70 46 69 6c 65 20 3d 20 5a 76 66 73      pFile = Zvfs
8a10: 4c 6f 6f 6b 75 70 28 70 61 74 68 29 3b 0a 20 20  Lookup(path);.  
8a20: 20 20 69 66 20 28 70 46 69 6c 65 20 3d 3d 20 30    if (pFile == 0
8a30: 29 20 7b 0a 09 72 65 74 75 72 6e 20 2d 31 3b 0a  ) {..return -1;.
8a40: 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74      }.    memset
8a50: 28 62 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28  (buf, 0, sizeof(
8a60: 2a 62 75 66 29 29 3b 0a 20 20 20 20 69 66 20 28  *buf));.    if (
8a70: 70 46 69 6c 65 2d 3e 69 73 64 69 72 29 20 7b 0a  pFile->isdir) {.
8a80: 09 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20  .buf->st_mode = 
8a90: 30 34 30 35 35 35 3b 0a 20 20 20 20 7d 20 65 6c  040555;.    } el
8aa0: 73 65 20 7b 0a 09 62 75 66 2d 3e 73 74 5f 6d 6f  se {..buf->st_mo
8ab0: 64 65 20 3d 20 28 30 31 30 30 30 30 30 7c 70 46  de = (0100000|pF
8ac0: 69 6c 65 2d 3e 70 65 72 6d 69 73 73 69 6f 6e 73  ile->permissions
8ad0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 62 75 66  );.    }.    buf
8ae0: 2d 3e 73 74 5f 69 6e 6f 20 3d 20 30 3b 0a 20 20  ->st_ino = 0;.  
8af0: 20 20 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d    buf->st_size =
8b00: 20 70 46 69 6c 65 2d 3e 6e 42 79 74 65 3b 0a 20   pFile->nByte;. 
8b10: 20 20 20 62 75 66 2d 3e 73 74 5f 6d 74 69 6d 65     buf->st_mtime
8b20: 20 3d 20 70 46 69 6c 65 2d 3e 74 69 6d 65 73 74   = pFile->timest
8b30: 61 6d 70 3b 0a 20 20 20 20 62 75 66 2d 3e 73 74  amp;.    buf->st
8b40: 5f 63 74 69 6d 65 20 3d 20 70 46 69 6c 65 2d 3e  _ctime = pFile->
8b50: 74 69 6d 65 73 74 61 6d 70 3b 0a 20 20 20 20 62  timestamp;.    b
8b60: 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20 3d 20 70  uf->st_atime = p
8b70: 46 69 6c 65 2d 3e 74 69 6d 65 73 74 61 6d 70 3b  File->timestamp;
8b80: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d  .    return 0;.}
8b90: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ../*.** This rou
8ba0: 74 69 6e 65 20 64 6f 65 73 20 61 6e 20 61 63 63  tine does an acc
8bb0: 65 73 73 28 29 20 73 79 73 74 65 6d 20 63 61 6c  ess() system cal
8bc0: 6c 20 66 6f 72 20 61 20 5a 56 46 53 20 66 69 6c  l for a ZVFS fil
8bd0: 65 2e 0a 2a 2f 0a 69 6e 74 20 54 6f 62 65 5f 46  e..*/.int Tobe_F
8be0: 53 41 63 63 65 73 73 50 72 6f 63 20 28 54 63 6c  SAccessProc (Tcl
8bf0: 5f 4f 62 6a 20 2a 70 61 74 68 50 74 72 2c 20 69  _Obj *pathPtr, i
8c00: 6e 74 20 6d 6f 64 65 29 20 7b 0a 20 20 20 20 63  nt mode) {.    c
8c10: 68 61 72 20 2a 70 61 74 68 3d 54 63 6c 5f 47 65  har *path=Tcl_Ge
8c20: 74 53 74 72 69 6e 67 28 70 61 74 68 50 74 72 29  tString(pathPtr)
8c30: 3b 0a 20 20 20 20 5a 76 66 73 46 69 6c 65 20 2a  ;.    ZvfsFile *
8c40: 70 46 69 6c 65 3b 0a 0a 20 20 20 20 69 66 20 28  pFile;..    if (
8c50: 6d 6f 64 65 20 26 20 33 29 20 7b 0a 09 72 65 74  mode & 3) {..ret
8c60: 75 72 6e 20 2d 31 3b 0a 20 20 20 20 7d 0a 20 20  urn -1;.    }.  
8c70: 20 20 70 46 69 6c 65 20 3d 20 5a 76 66 73 4c 6f    pFile = ZvfsLo
8c80: 6f 6b 75 70 28 70 61 74 68 29 3b 0a 20 20 20 20  okup(path);.    
8c90: 69 66 20 28 70 46 69 6c 65 20 3d 3d 20 30 29 20  if (pFile == 0) 
8ca0: 7b 0a 09 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20  {..return -1;.  
8cb0: 20 20 7d 0a 20 20 20 20 72 65 74 75 72 6e 20 30    }.    return 0
8cc0: 3b 0a 7d 0a 0a 54 63 6c 5f 4f 62 6a 2a 20 54 6f  ;.}..Tcl_Obj* To
8cd0: 62 65 5f 46 53 46 69 6c 65 73 79 73 74 65 6d 53  be_FSFilesystemS
8ce0: 65 70 61 72 61 74 6f 72 50 72 6f 63 28 54 63 6c  eparatorProc(Tcl
8cf0: 5f 4f 62 6a 20 2a 70 61 74 68 50 74 72 29 20 7b  _Obj *pathPtr) {
8d00: 20 0a 20 20 72 65 74 75 72 6e 20 54 63 6c 5f 4e   .  return Tcl_N
8d10: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 2f 22 2c  ewStringObj("/",
8d20: 2d 31 29 3b 3b 0a 7d 0a 0a 2f 2a 20 46 75 6e 63  -1);;.}../* Func
8d30: 74 69 6f 6e 20 74 6f 20 70 72 6f 63 65 73 73 20  tion to process 
8d40: 61 20 0a 2a 20 27 54 6f 62 65 5f 46 53 4d 61 74  a .* 'Tobe_FSMat
8d50: 63 68 49 6e 44 69 72 65 63 74 6f 72 79 28 29 27  chInDirectory()'
8d60: 2e 20 20 49 66 20 6e 6f 74 0a 2a 20 69 6d 70 6c  .  If not.* impl
8d70: 65 6d 65 6e 74 65 64 2c 20 74 68 65 6e 20 67 6c  emented, then gl
8d80: 6f 62 20 61 6e 64 20 72 65 63 75 72 73 69 76 65  ob and recursive
8d90: 0a 2a 20 63 6f 70 79 20 66 75 6e 63 74 69 6f 6e  .* copy function
8da0: 61 6c 69 74 79 20 77 69 6c 6c 20 62 65 20 6c 61  ality will be la
8db0: 63 6b 69 6e 67 20 69 6e 0a 2a 20 74 68 65 20 66  cking in.* the f
8dc0: 69 6c 65 73 79 73 74 65 6d 2e 20 2a 2f 0a 69 6e  ilesystem. */.in
8dd0: 74 20 54 6f 62 65 5f 46 53 4d 61 74 63 68 49 6e  t Tobe_FSMatchIn
8de0: 44 69 72 65 63 74 6f 72 79 50 72 6f 63 20 28 0a  DirectoryProc (.
8df0: 20 20 20 20 54 63 6c 5f 49 6e 74 65 72 70 2a 20      Tcl_Interp* 
8e00: 69 6e 74 65 72 70 2c 0a 20 20 20 20 54 63 6c 5f  interp,.    Tcl_
8e10: 4f 62 6a 20 2a 72 65 73 75 6c 74 2c 0a 20 20 20  Obj *result,.   
8e20: 20 54 63 6c 5f 4f 62 6a 20 2a 70 61 74 68 50 74   Tcl_Obj *pathPt
8e30: 72 2c 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61  r,.    const cha
8e40: 72 20 2a 70 61 74 74 65 72 6e 2c 0a 20 20 20 20  r *pattern,.    
8e50: 54 63 6c 5f 47 6c 6f 62 54 79 70 65 44 61 74 61  Tcl_GlobTypeData
8e60: 20 2a 20 74 79 70 65 73 0a 29 20 7b 0a 20 20 20   * types.) {.   
8e70: 20 54 63 6c 5f 48 61 73 68 45 6e 74 72 79 20 2a   Tcl_HashEntry *
8e80: 70 45 6e 74 72 79 3b 0a 20 20 20 20 54 63 6c 5f  pEntry;.    Tcl_
8e90: 48 61 73 68 53 65 61 72 63 68 20 73 53 65 61 72  HashSearch sSear
8ea0: 63 68 3b 0a 20 20 20 20 69 6e 74 20 73 63 6e 74  ch;.    int scnt
8eb0: 3d 30 2c 20 70 61 74 68 6c 65 6e 3d 30 2c 20 70  =0, pathlen=0, p
8ec0: 61 74 74 65 72 6e 6c 65 6e 3d 30 2c 20 64 69 72  atternlen=0, dir
8ed0: 67 6c 6f 62 3d 30 2c 20 66 69 6c 65 67 6c 6f 62  glob=0, fileglob
8ee0: 3d 30 2c 20 6d 6e 74 67 6c 6f 62 3d 30 3b 0a 20  =0, mntglob=0;. 
8ef0: 20 20 20 69 6e 74 20 6e 75 6c 6c 70 61 74 74 65     int nullpatte
8f00: 72 6e 3d 28 70 61 74 74 65 72 6e 20 3d 3d 20 4e  rn=(pattern == N
8f10: 55 4c 4c 20 7c 7c 20 28 2a 70 61 74 74 65 72 6e  ULL || (*pattern
8f20: 3d 3d 27 5c 30 27 29 29 3b 0a 20 20 20 20 63 68  =='\0'));.    ch
8f30: 61 72 20 2a 7a 50 61 74 74 65 72 6e 20 3d 20 4e  ar *zPattern = N
8f40: 55 4c 4c 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a  ULL;.    char *z
8f50: 70 3d 4e 55 4c 4c 3b 0a 20 20 20 20 0a 20 20 20  p=NULL;.    .   
8f60: 20 69 66 28 74 79 70 65 73 20 26 26 20 74 79 70   if(types && typ
8f70: 65 73 2d 3e 74 79 70 65 29 20 7b 0a 20 20 20 20  es->type) {.    
8f80: 20 20 64 69 72 67 6c 6f 62 20 3d 20 28 74 79 70    dirglob = (typ
8f90: 65 73 2d 3e 74 79 70 65 26 54 43 4c 5f 47 4c 4f  es->type&TCL_GLO
8fa0: 42 5f 54 59 50 45 5f 44 49 52 29 3b 0a 20 20 20  B_TYPE_DIR);.   
8fb0: 20 20 20 66 69 6c 65 67 6c 6f 62 20 3d 20 28 74     fileglob = (t
8fc0: 79 70 65 73 2d 3e 74 79 70 65 20 26 20 54 43 4c  ypes->type & TCL
8fd0: 5f 47 4c 4f 42 5f 54 59 50 45 5f 46 49 4c 45 29  _GLOB_TYPE_FILE)
8fe0: 3b 0a 20 20 20 20 20 20 6d 6e 74 67 6c 6f 62 20  ;.      mntglob 
8ff0: 3d 20 28 74 79 70 65 73 2d 3e 74 79 70 65 26 54  = (types->type&T
9000: 43 4c 5f 47 4c 4f 42 5f 54 59 50 45 5f 4d 4f 55  CL_GLOB_TYPE_MOU
9010: 4e 54 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  NT);.    }.    i
9020: 66 28 21 6e 75 6c 6c 70 61 74 74 65 72 6e 29 20  f(!nullpattern) 
9030: 7b 0a 20 20 20 20 20 20 70 61 74 74 65 72 6e 6c  {.      patternl
9040: 65 6e 3d 73 74 72 6c 65 6e 28 70 61 74 74 65 72  en=strlen(patter
9050: 6e 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66  n);.    }.    if
9060: 28 70 61 74 68 50 74 72 29 20 7b 0a 20 20 20 20  (pathPtr) {.    
9070: 20 20 7a 70 3d 54 63 6c 5f 47 65 74 53 74 72 69    zp=Tcl_GetStri
9080: 6e 67 46 72 6f 6d 4f 62 6a 28 70 61 74 68 50 74  ngFromObj(pathPt
9090: 72 2c 26 70 61 74 68 6c 65 6e 29 3b 0a 23 69 66  r,&pathlen);.#if
90a0: 64 65 66 20 5f 5f 57 49 4e 33 32 5f 5f 0a 20 20  def __WIN32__.  
90b0: 20 20 20 20 69 66 20 28 69 73 61 6c 70 68 61 28      if (isalpha(
90c0: 7a 70 5b 30 5d 29 20 26 26 20 7a 70 5b 31 5d 3d  zp[0]) && zp[1]=
90d0: 3d 27 3a 27 29 20 7b 0a 09 7a 70 2b 3d 32 3b 0a  =':') {..zp+=2;.
90e0: 20 20 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20        }.#endif. 
90f0: 20 20 20 7d 0a 20 20 20 20 69 66 28 6d 6e 74 67     }.    if(mntg
9100: 6c 6f 62 29 20 7b 20 72 65 74 75 72 6e 20 54 43  lob) { return TC
9110: 4c 5f 4f 4b 3b 20 7d 0a 20 20 20 20 69 66 20 28  L_OK; }.    if (
9120: 6d 6e 74 67 6c 6f 62 29 20 7b 0a 20 20 20 20 20  mntglob) {.     
9130: 20 2f 2a 20 4c 6f 6f 6b 20 66 6f 72 20 61 20 64   /* Look for a d
9140: 69 72 65 63 74 6f 72 79 20 6d 6f 75 6e 74 20 2a  irectory mount *
9150: 2f 0a 20 20 20 20 20 20 54 63 6c 5f 48 61 73 68  /.      Tcl_Hash
9160: 45 6e 74 72 79 20 2a 70 45 6e 74 72 79 3b 20 20  Entry *pEntry;  
9170: 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62 6c 65     /* Hash table
9180: 20 65 6e 74 72 79 20 2a 2f 0a 20 20 20 20 20 20   entry */.      
9190: 54 63 6c 5f 48 61 73 68 53 65 61 72 63 68 20 7a  Tcl_HashSearch z
91a0: 53 65 61 72 63 68 3b 20 20 20 2f 2a 20 53 65 61  Search;   /* Sea
91b0: 72 63 68 20 61 6c 6c 20 6d 6f 75 6e 74 20 70 6f  rch all mount po
91c0: 69 6e 74 73 20 2a 2f 0a 20 20 20 20 20 20 5a 76  ints */.      Zv
91d0: 66 73 41 72 63 68 69 76 65 20 2a 70 41 72 63 68  fsArchive *pArch
91e0: 69 76 65 3b 20 20 20 20 20 2f 2a 20 54 68 65 20  ive;     /* The 
91f0: 5a 49 50 20 61 72 63 68 69 76 65 20 62 65 69 6e  ZIP archive bein
9200: 67 20 6d 6f 75 6e 74 65 64 20 2a 2f 0a 20 20 20  g mounted */.   
9210: 20 20 20 63 68 61 72 20 6d 6f 75 6e 74 70 74 5b     char mountpt[
9220: 32 30 30 5d 3b 0a 20 20 20 20 20 20 69 6e 74 20  200];.      int 
9230: 69 3d 31 3b 0a 20 20 20 20 20 20 6d 6f 75 6e 74  i=1;.      mount
9240: 70 74 5b 30 5d 3d 27 2f 27 3b 0a 20 20 20 20 20  pt[0]='/';.     
9250: 20 69 66 28 70 61 74 68 50 74 72 29 20 7b 0a 20   if(pathPtr) {. 
9260: 20 20 20 20 20 20 20 66 6f 72 28 69 3d 31 3b 69         for(i=1;i
9270: 3c 70 61 74 68 6c 65 6e 20 26 26 20 69 3c 32 30  <pathlen && i<20
9280: 30 3b 69 2b 2b 29 20 7b 0a 20 20 20 20 20 20 20  0;i++) {.       
9290: 20 20 20 69 66 28 7a 70 5b 69 5d 3d 3d 27 2f 27     if(zp[i]=='/'
92a0: 20 7c 7c 20 7a 70 5b 69 5d 3d 3d 27 5c 30 27 29   || zp[i]=='\0')
92b0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20   break;.        
92c0: 20 20 6d 6f 75 6e 74 70 74 5b 69 5d 3d 7a 70 5b    mountpt[i]=zp[
92d0: 69 5d 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  i];.        }.  
92e0: 20 20 20 20 7d 0a 20 20 20 20 20 20 6d 6f 75 6e      }.      moun
92f0: 74 70 74 5b 69 5d 3d 27 5c 30 27 3b 0a 20 20 20  tpt[i]='\0';.   
9300: 20 20 20 66 6f 72 28 0a 20 20 20 20 20 20 20 20     for(.        
9310: 70 45 6e 74 72 79 3d 54 63 6c 5f 46 69 72 73 74  pEntry=Tcl_First
9320: 48 61 73 68 45 6e 74 72 79 28 26 6c 6f 63 61 6c  HashEntry(&local
9330: 2e 61 72 63 68 69 76 65 48 61 73 68 2c 26 7a 53  .archiveHash,&zS
9340: 65 61 72 63 68 29 3b 0a 20 20 20 20 20 20 20 20  earch);.        
9350: 70 45 6e 74 72 79 3b 0a 20 20 20 20 20 20 20 20  pEntry;.        
9360: 70 45 6e 74 72 79 3d 54 63 6c 5f 4e 65 78 74 48  pEntry=Tcl_NextH
9370: 61 73 68 45 6e 74 72 79 28 26 7a 53 65 61 72 63  ashEntry(&zSearc
9380: 68 29 0a 20 20 20 20 20 20 29 20 7b 0a 20 20 20  h).      ) {.   
9390: 20 20 20 20 20 70 41 72 63 68 69 76 65 20 3d 20       pArchive = 
93a0: 54 63 6c 5f 47 65 74 48 61 73 68 56 61 6c 75 65  Tcl_GetHashValue
93b0: 28 70 45 6e 74 72 79 29 3b 0a 20 20 20 20 20 20  (pEntry);.      
93c0: 20 20 69 66 20 28 70 41 72 63 68 69 76 65 29 20    if (pArchive) 
93d0: 7b 0a 20 20 20 20 20 20 20 20 20 20 63 68 61 72  {.          char
93e0: 20 2a 7a 20 3d 20 70 41 72 63 68 69 76 65 2d 3e   *z = pArchive->
93f0: 7a 4d 6f 75 6e 74 50 6f 69 6e 74 3b 0a 20 20 20  zMountPoint;.   
9400: 20 20 20 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a         Tcl_Obj *
9410: 70 54 61 69 6c 3d 4e 55 4c 4c 3b 0a 20 20 20 20  pTail=NULL;.    
9420: 20 20 20 20 20 20 69 6e 74 20 6d 61 74 63 68 3d        int match=
9430: 30 3b 0a 20 20 20 20 20 20 20 20 20 20 6d 61 74  0;.          mat
9440: 63 68 3d 28 73 74 72 63 6d 70 28 6d 6f 75 6e 74  ch=(strcmp(mount
9450: 70 74 2c 20 7a 29 3d 3d 30 29 3b 0a 20 20 20 20  pt, z)==0);.    
9460: 20 20 20 20 20 20 69 66 28 21 6d 61 74 63 68 29        if(!match)
9470: 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20   continue;.     
9480: 20 20 20 20 20 70 54 61 69 6c 3d 54 63 6c 5f 4e       pTail=Tcl_N
9490: 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 2c 20 2d  ewStringObj(z, -
94a0: 31 29 3b 0a 20 20 20 20 20 20 20 20 20 20 54 63  1);.          Tc
94b0: 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45  l_ListObjAppendE
94c0: 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 72  lement(interp, r
94d0: 65 73 75 6c 74 2c 20 70 54 61 69 6c 29 3b 0a 20  esult, pTail);. 
94e0: 20 20 20 20 20 20 20 20 20 2f 2f 54 63 6c 5f 44           //Tcl_D
94f0: 65 63 72 52 65 66 43 6f 75 6e 74 28 70 54 61 69  ecrRefCount(pTai
9500: 6c 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  l);.        }.  
9510: 20 20 20 20 7d 0a 20 20 20 20 7d 20 65 6c 73 65      }.    } else
9520: 20 7b 0a 20 20 20 20 20 20 69 6e 74 20 69 64 78   {.      int idx
9530: 3d 30 3b 0a 20 20 20 20 20 20 69 66 28 21 7a 70  =0;.      if(!zp
9540: 20 26 26 20 6e 75 6c 6c 70 61 74 74 65 72 6e 29   && nullpattern)
9550: 20 7b 0a 20 20 20 20 20 20 20 20 7a 50 61 74 74   {.        zPatt
9560: 65 72 6e 3d 4e 55 4c 4c 3b 0a 20 20 20 20 20 20  ern=NULL;.      
9570: 7d 20 65 6c 73 65 20 7b 0a 09 54 63 6c 5f 44 53  } else {..Tcl_DS
9580: 74 72 69 6e 67 20 64 54 65 6d 70 50 61 74 68 3b  tring dTempPath;
9590: 0a 09 54 63 6c 5f 44 53 74 72 69 6e 67 49 6e 69  ..Tcl_DStringIni
95a0: 74 28 26 64 54 65 6d 70 50 61 74 68 29 3b 0a 20  t(&dTempPath);. 
95b0: 20 20 20 20 20 20 20 7a 50 61 74 74 65 72 6e 3d         zPattern=
95c0: 28 63 68 61 72 2a 29 54 63 6c 5f 41 6c 6c 6f 63  (char*)Tcl_Alloc
95d0: 28 70 61 74 68 6c 65 6e 2b 70 61 74 74 65 72 6e  (pathlen+pattern
95e0: 6c 65 6e 2b 33 29 3b 0a 20 20 20 20 20 20 20 20  len+3);.        
95f0: 6d 65 6d 73 65 74 28 7a 50 61 74 74 65 72 6e 2c  memset(zPattern,
9600: 30 2c 70 61 74 68 6c 65 6e 2b 70 61 74 74 65 72  0,pathlen+patter
9610: 6e 6c 65 6e 2b 33 29 3b 0a 20 20 20 20 20 20 20  nlen+3);.       
9620: 20 69 66 28 7a 70 29 20 7b 0a 09 20 20 54 63 6c   if(zp) {..  Tcl
9630: 5f 44 53 74 72 69 6e 67 41 70 70 65 6e 64 28 26  _DStringAppend(&
9640: 64 54 65 6d 70 50 61 74 68 2c 7a 70 2c 2d 31 29  dTempPath,zp,-1)
9650: 3b 20 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  ; .        }.   
9660: 20 20 20 20 20 69 66 20 28 7a 70 20 26 26 20 21       if (zp && !
9670: 6e 75 6c 6c 70 61 74 74 65 72 6e 29 20 7b 0a 20  nullpattern) {. 
9680: 20 20 20 20 20 20 20 20 20 69 66 20 28 70 61 74           if (pat
9690: 68 6c 65 6e 20 3e 20 31 20 7c 7c 20 7a 50 61 74  hlen > 1 || zPat
96a0: 74 65 72 6e 5b 30 5d 20 21 3d 20 27 2f 27 29 20  tern[0] != '/') 
96b0: 7b 0a 09 20 20 20 20 54 63 6c 5f 44 53 74 72 69  {..    Tcl_DStri
96c0: 6e 67 41 70 70 65 6e 64 28 26 64 54 65 6d 70 50  ngAppend(&dTempP
96d0: 61 74 68 2c 22 2f 22 2c 2d 31 29 3b 20 0a 20 20  ath,"/",-1); .  
96e0: 20 20 20 20 20 20 20 20 20 20 69 64 78 2b 2b 3b            idx++;
96f0: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
9700: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69       }.        i
9710: 66 20 28 21 6e 75 6c 6c 70 61 74 74 65 72 6e 29  f (!nullpattern)
9720: 20 7b 0a 09 20 20 54 63 6c 5f 44 53 74 72 69 6e   {..  Tcl_DStrin
9730: 67 41 70 70 65 6e 64 28 26 64 54 65 6d 70 50 61  gAppend(&dTempPa
9740: 74 68 2c 70 61 74 74 65 72 6e 2c 70 61 74 74 65  th,pattern,patte
9750: 72 6e 6c 65 6e 29 3b 20 0a 20 20 20 20 20 20 20  rnlen); .       
9760: 20 7d 0a 09 7a 50 61 74 74 65 72 6e 3d 73 74 72   }..zPattern=str
9770: 64 75 70 28 54 63 6c 5f 44 53 74 72 69 6e 67 56  dup(Tcl_DStringV
9780: 61 6c 75 65 28 26 64 54 65 6d 70 50 61 74 68 29  alue(&dTempPath)
9790: 29 3b 0a 20 20 20 20 20 20 20 20 54 63 6c 5f 44  );.        Tcl_D
97a0: 53 74 72 69 6e 67 46 72 65 65 28 26 64 54 65 6d  StringFree(&dTem
97b0: 70 50 61 74 68 29 3b 0a 20 20 20 20 20 20 20 20  pPath);.        
97c0: 73 63 6e 74 20 3d 20 73 74 72 63 68 72 63 6e 74  scnt = strchrcnt
97d0: 28 7a 50 61 74 74 65 72 6e 2c 20 27 2f 27 29 3b  (zPattern, '/');
97e0: 0a 20 20 20 20 20 20 7d 20 20 20 20 20 20 0a 20  .      }      . 
97f0: 20 20 20 20 20 66 6f 72 20 28 0a 20 20 20 20 20       for (.     
9800: 20 20 20 70 45 6e 74 72 79 20 3d 20 54 63 6c 5f     pEntry = Tcl_
9810: 46 69 72 73 74 48 61 73 68 45 6e 74 72 79 28 26  FirstHashEntry(&
9820: 6c 6f 63 61 6c 2e 66 69 6c 65 48 61 73 68 2c 20  local.fileHash, 
9830: 26 73 53 65 61 72 63 68 29 3b 0a 20 20 20 20 20  &sSearch);.     
9840: 20 20 20 70 45 6e 74 72 79 3b 0a 20 20 20 20 20     pEntry;.     
9850: 20 20 20 70 45 6e 74 72 79 20 3d 20 54 63 6c 5f     pEntry = Tcl_
9860: 4e 65 78 74 48 61 73 68 45 6e 74 72 79 28 26 73  NextHashEntry(&s
9870: 53 65 61 72 63 68 29 0a 20 20 20 20 20 20 29 7b  Search).      ){
9880: 0a 20 20 20 20 20 20 20 20 20 20 5a 76 66 73 46  .          ZvfsF
9890: 69 6c 65 20 2a 70 46 69 6c 65 20 3d 20 54 63 6c  ile *pFile = Tcl
98a0: 5f 47 65 74 48 61 73 68 56 61 6c 75 65 28 70 45  _GetHashValue(pE
98b0: 6e 74 72 79 29 3b 0a 20 20 20 20 20 20 20 20 20  ntry);.         
98c0: 20 69 66 28 70 46 69 6c 65 29 20 7b 0a 20 20 20   if(pFile) {.   
98d0: 20 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a           char *z
98e0: 20 3d 20 70 46 69 6c 65 2d 3e 7a 4e 61 6d 65 3b   = pFile->zName;
98f0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 54 63 6c  .            Tcl
9900: 5f 4f 62 6a 20 2a 70 54 61 69 6c 3d 4e 55 4c 4c  _Obj *pTail=NULL
9910: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 6e  ;.            in
9920: 74 20 6d 61 74 63 68 3d 30 3b 0a 20 20 20 20 20  t match=0;.     
9930: 20 20 20 20 20 20 20 69 66 20 28 64 69 72 67 6c         if (dirgl
9940: 6f 62 20 26 26 20 21 70 46 69 6c 65 2d 3e 69 73  ob && !pFile->is
9950: 64 69 72 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20  dir) continue;. 
9960: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 28 66             if (f
9970: 69 6c 65 67 6c 6f 62 20 26 26 20 70 46 69 6c 65  ileglob && pFile
9980: 2d 3e 69 73 64 69 72 29 20 63 6f 6e 74 69 6e 75  ->isdir) continu
9990: 65 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69  e;.            i
99a0: 66 28 73 63 6e 74 20 21 3d 20 70 46 69 6c 65 2d  f(scnt != pFile-
99b0: 3e 64 65 70 74 68 29 20 63 6f 6e 74 69 6e 75 65  >depth) continue
99c0: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 6d 61  ;.            ma
99d0: 74 63 68 3d 54 63 6c 5f 53 74 72 69 6e 67 43 61  tch=Tcl_StringCa
99e0: 73 65 4d 61 74 63 68 28 7a 2c 20 7a 50 61 74 74  seMatch(z, zPatt
99f0: 65 72 6e 2c 20 30 29 3b 0a 20 20 20 20 20 20 20  ern, 0);.       
9a00: 20 20 20 20 20 69 66 28 21 6d 61 74 63 68 29 20       if(!match) 
9a10: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
9a20: 20 20 20 20 20 20 70 54 61 69 6c 3d 54 63 6c 5f        pTail=Tcl_
9a30: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 7a 2c 20  NewStringObj(z, 
9a40: 2d 31 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  -1);.           
9a50: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
9a60: 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70  ndElement(interp
9a70: 2c 20 72 65 73 75 6c 74 2c 20 70 54 61 69 6c 29  , result, pTail)
9a80: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
9a90: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20      }.    }..   
9aa0: 20 69 66 20 28 7a 50 61 74 74 65 72 6e 29 20 7b   if (zPattern) {
9ab0: 0a 09 66 72 65 65 28 7a 50 61 74 74 65 72 6e 29  ..free(zPattern)
9ac0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75  ;.    }.    retu
9ad0: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  rn TCL_OK;.}../*
9ae0: 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63 68 65   Function to che
9af0: 63 6b 20 77 68 65 74 68 65 72 20 61 20 70 61 74  ck whether a pat
9b00: 68 20 69 73 20 69 6e 20 0a 2a 20 74 68 69 73 20  h is in .* this 
9b10: 66 69 6c 65 73 79 73 74 65 6d 2e 20 20 54 68 69  filesystem.  Thi
9b20: 73 20 69 73 20 74 68 65 20 6d 6f 73 74 0a 2a 20  s is the most.* 
9b30: 69 6d 70 6f 72 74 61 6e 74 20 66 69 6c 65 73 79  important filesy
9b40: 73 74 65 6d 20 70 72 6f 63 65 64 75 72 65 2e 20  stem procedure. 
9b50: 2a 2f 0a 69 6e 74 20 54 6f 62 65 5f 46 53 50 61  */.int Tobe_FSPa
9b60: 74 68 49 6e 46 69 6c 65 73 79 73 74 65 6d 50 72  thInFilesystemPr
9b70: 6f 63 20 28 0a 20 20 20 20 54 63 6c 5f 4f 62 6a  oc (.    Tcl_Obj
9b80: 20 2a 70 61 74 68 50 74 72 2c 0a 20 20 20 20 43   *pathPtr,.    C
9b90: 6c 69 65 6e 74 44 61 74 61 20 2a 63 6c 69 65 6e  lientData *clien
9ba0: 74 44 61 74 61 50 74 72 0a 29 20 7b 0a 20 20 20  tDataPtr.) {.   
9bb0: 20 5a 76 66 73 46 69 6c 65 20 2a 7a 46 69 6c 65   ZvfsFile *zFile
9bc0: 3b 0a 20 20 20 20 63 68 61 72 20 2a 70 61 74 68  ;.    char *path
9bd0: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
9be0: 28 70 61 74 68 50 74 72 29 3b 0a 20 20 20 20 0a  (pathPtr);.    .
9bf0: 20 20 20 20 69 66 20 28 6f 70 65 6e 61 72 63 68      if (openarch
9c00: 29 20 7b 0a 09 72 65 74 75 72 6e 20 2d 31 3b 0a  ) {..return -1;.
9c10: 20 20 20 20 7d 0a 20 20 20 20 7a 46 69 6c 65 20      }.    zFile 
9c20: 3d 20 5a 76 66 73 4c 6f 6f 6b 75 70 28 70 61 74  = ZvfsLookup(pat
9c30: 68 29 3b 0a 20 20 20 20 69 66 20 28 7a 46 69 6c  h);.    if (zFil
9c40: 65 20 21 3d 20 4e 55 4c 4c 20 26 26 20 73 74 72  e != NULL && str
9c50: 63 6d 70 28 70 61 74 68 2c 20 7a 46 69 6c 65 2d  cmp(path, zFile-
9c60: 3e 70 41 72 63 68 69 76 65 2d 3e 7a 4e 61 6d 65  >pArchive->zName
9c70: 29 29 20 7b 0a 09 72 65 74 75 72 6e 20 54 43 4c  )) {..return TCL
9c80: 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72  _OK;.    }.    r
9c90: 65 74 75 72 6e 20 2d 31 3b 0a 7d 0a 0a 54 63 6c  eturn -1;.}..Tcl
9ca0: 5f 4f 62 6a 20 2a 54 6f 62 65 5f 46 53 4c 69 73  _Obj *Tobe_FSLis
9cb0: 74 56 6f 6c 75 6d 65 73 50 72 6f 63 20 28 76 6f  tVolumesProc (vo
9cc0: 69 64 29 20 7b 0a 20 20 20 20 54 63 6c 5f 48 61  id) {.    Tcl_Ha
9cd0: 73 68 45 6e 74 72 79 20 2a 70 45 6e 74 72 79 3b  shEntry *pEntry;
9ce0: 20 20 20 20 20 2f 2a 20 48 61 73 68 20 74 61 62       /* Hash tab
9cf0: 6c 65 20 65 6e 74 72 79 20 2a 2f 0a 20 20 20 20  le entry */.    
9d00: 54 63 6c 5f 48 61 73 68 53 65 61 72 63 68 20 7a  Tcl_HashSearch z
9d10: 53 65 61 72 63 68 3b 20 20 20 2f 2a 20 53 65 61  Search;   /* Sea
9d20: 72 63 68 20 61 6c 6c 20 6d 6f 75 6e 74 20 70 6f  rch all mount po
9d30: 69 6e 74 73 20 2a 2f 0a 20 20 20 20 5a 76 66 73  ints */.    Zvfs
9d40: 41 72 63 68 69 76 65 20 2a 70 41 72 63 68 69 76  Archive *pArchiv
9d50: 65 3b 20 20 20 20 20 2f 2a 20 54 68 65 20 5a 49  e;     /* The ZI
9d60: 50 20 61 72 63 68 69 76 65 20 62 65 69 6e 67 20  P archive being 
9d70: 6d 6f 75 6e 74 65 64 20 2a 2f 0a 20 20 20 20 54  mounted */.    T
9d80: 63 6c 5f 4f 62 6a 20 2a 70 56 6f 6c 73 3d 30 2c  cl_Obj *pVols=0,
9d90: 20 2a 70 56 6f 6c 3b 0a 20 20 20 20 63 68 61 72   *pVol;.    char
9da0: 20 6d 6f 75 6e 74 70 74 5b 32 30 30 5d 3b 0a 20   mountpt[200];. 
9db0: 20 20 20 0a 20 20 20 20 70 45 6e 74 72 79 3d 54     .    pEntry=T
9dc0: 63 6c 5f 46 69 72 73 74 48 61 73 68 45 6e 74 72  cl_FirstHashEntr
9dd0: 79 28 26 6c 6f 63 61 6c 2e 61 72 63 68 69 76 65  y(&local.archive
9de0: 48 61 73 68 2c 26 7a 53 65 61 72 63 68 29 3b 0a  Hash,&zSearch);.
9df0: 20 20 20 20 77 68 69 6c 65 20 28 70 45 6e 74 72      while (pEntr
9e00: 79 29 20 7b 0a 09 70 41 72 63 68 69 76 65 20 3d  y) {..pArchive =
9e10: 20 54 63 6c 5f 47 65 74 48 61 73 68 56 61 6c 75   Tcl_GetHashValu
9e20: 65 28 70 45 6e 74 72 79 29 3b 0a 09 69 66 20 28  e(pEntry);..if (
9e30: 70 41 72 63 68 69 76 65 29 20 7b 0a 09 20 20 20  pArchive) {..   
9e40: 20 69 66 20 28 21 70 56 6f 6c 73 29 20 7b 0a 09   if (!pVols) {..
9e50: 09 70 56 6f 6c 73 3d 54 63 6c 5f 4e 65 77 4c 69  .pVols=Tcl_NewLi
9e60: 73 74 4f 62 6a 28 30 2c 30 29 3b 0a 09 09 54 63  stObj(0,0);...Tc
9e70: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70  l_IncrRefCount(p
9e80: 56 6f 6c 73 29 3b 0a 09 20 20 20 20 7d 0a 09 20  Vols);..    }.. 
9e90: 20 20 20 73 70 72 69 6e 74 66 28 6d 6f 75 6e 74     sprintf(mount
9ea0: 70 74 2c 20 22 7a 76 66 73 3a 25 73 22 2c 20 70  pt, "zvfs:%s", p
9eb0: 41 72 63 68 69 76 65 2d 3e 7a 4d 6f 75 6e 74 50  Archive->zMountP
9ec0: 6f 69 6e 74 29 3b 0a 09 20 20 20 20 70 56 6f 6c  oint);..    pVol
9ed0: 3d 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62  =Tcl_NewStringOb
9ee0: 6a 28 6d 6f 75 6e 74 70 74 2c 2d 31 29 3b 0a 09  j(mountpt,-1);..
9ef0: 20 20 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43      Tcl_IncrRefC
9f00: 6f 75 6e 74 28 70 56 6f 6c 29 3b 0a 09 20 20 20  ount(pVol);..   
9f10: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
9f20: 6e 64 45 6c 65 6d 65 6e 74 28 4e 55 4c 4c 2c 20  ndElement(NULL, 
9f30: 70 56 6f 6c 73 2c 70 56 6f 6c 29 3b 0a 09 20 20  pVols,pVol);..  
9f40: 20 20 2f 2a 20 54 63 6c 5f 41 70 70 65 6e 64 52    /* Tcl_AppendR
9f50: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 70 41 72  esult(interp,pAr
9f60: 63 68 69 76 65 2d 3e 7a 4d 6f 75 6e 74 50 6f 69  chive->zMountPoi
9f70: 6e 74 2c 22 20 22 2c 70 41 72 63 68 69 76 65 2d  nt," ",pArchive-
9f80: 3e 7a 4e 61 6d 65 2c 22 20 22 2c 30 29 3b 2a 2f  >zName," ",0);*/
9f90: 0a 09 7d 0a 09 70 45 6e 74 72 79 3d 54 63 6c 5f  ..}..pEntry=Tcl_
9fa0: 4e 65 78 74 48 61 73 68 45 6e 74 72 79 28 26 7a  NextHashEntry(&z
9fb0: 53 65 61 72 63 68 29 3b 0a 20 20 20 20 7d 0a 20  Search);.    }. 
9fc0: 20 20 20 72 65 74 75 72 6e 20 70 56 6f 6c 73 3b     return pVols;
9fd0: 0a 7d 0a 0a 69 6e 74 20 54 6f 62 65 5f 46 53 43  .}..int Tobe_FSC
9fe0: 68 64 69 72 50 72 6f 63 20 28 54 63 6c 5f 4f 62  hdirProc (Tcl_Ob
9ff0: 6a 20 2a 70 61 74 68 50 74 72 29 20 7b 0a 20 20  j *pathPtr) {.  
a000: 20 2f 2a 20 53 6f 6d 65 64 61 79 2c 20 77 65 20   /* Someday, we 
a010: 73 68 6f 75 6c 64 20 61 63 74 75 61 6c 6c 79 20  should actually 
a020: 63 68 65 63 6b 20 69 66 20 74 68 69 73 20 69 73  check if this is
a030: 20 61 20 76 61 6c 69 64 20 70 61 74 68 2e 20 2a   a valid path. *
a040: 2f 0a 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  /.   return TCL_
a050: 4f 4b 3b 0a 7d 0a 0a 63 6f 6e 73 74 20 63 68 61  OK;.}..const cha
a060: 72 20 2a 20 63 6f 6e 73 74 2a 0a 54 6f 62 65 5f  r * const*.Tobe_
a070: 46 53 46 69 6c 65 41 74 74 72 53 74 72 69 6e 67  FSFileAttrString
a080: 73 50 72 6f 63 28 0a 20 20 20 20 54 63 6c 5f 4f  sProc(.    Tcl_O
a090: 62 6a 20 2a 70 61 74 68 50 74 72 2c 0a 20 20 20  bj *pathPtr,.   
a0a0: 20 54 63 6c 5f 4f 62 6a 2a 2a 20 6f 62 6a 50 74   Tcl_Obj** objPt
a0b0: 72 52 65 66 29 0a 7b 0a 20 20 20 20 63 68 61 72  rRef).{.    char
a0c0: 20 2a 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74   *path = Tcl_Get
a0d0: 53 74 72 69 6e 67 28 70 61 74 68 50 74 72 29 3b  String(pathPtr);
a0e0: 0a 23 69 66 64 65 66 20 5f 5f 57 49 4e 33 32 5f  .#ifdef __WIN32_
a0f0: 5f 0a 20 20 20 20 73 74 61 74 69 63 20 63 6f 6e  _.    static con
a100: 73 74 20 63 68 61 72 20 2a 61 74 74 72 73 5b 5d  st char *attrs[]
a110: 20 3d 20 7b 0a 09 22 75 6e 63 6f 6d 70 73 69 7a   = {.."uncompsiz
a120: 65 22 2c 20 22 63 6f 6d 70 73 69 7a 65 22 2c 20  e", "compsize", 
a130: 22 6f 66 66 73 65 74 22 2c 20 22 6d 6f 75 6e 74  "offset", "mount
a140: 22 2c 20 22 61 72 63 68 69 76 65 22 2c 22 2d 61  ", "archive","-a
a150: 72 63 68 69 76 65 22 2c 20 22 2d 68 69 64 64 65  rchive", "-hidde
a160: 6e 22 2c 20 22 2d 72 65 61 64 6f 6e 6c 79 22 2c  n", "-readonly",
a170: 20 22 2d 73 79 73 74 65 6d 22 2c 20 22 2d 73 68   "-system", "-sh
a180: 6f 72 74 6e 61 6d 65 22 2c 20 30 0a 20 20 20 20  ortname", 0.    
a190: 7d 3b 0a 23 65 6c 73 65 0a 20 20 20 20 73 74 61  };.#else.    sta
a1a0: 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  tic const char *
a1b0: 61 74 74 72 73 5b 5d 20 3d 20 7b 0a 09 22 75 6e  attrs[] = {.."un
a1c0: 63 6f 6d 70 73 69 7a 65 22 2c 20 22 63 6f 6d 70  compsize", "comp
a1d0: 73 69 7a 65 22 2c 20 22 6f 66 66 73 65 74 22 2c  size", "offset",
a1e0: 20 22 6d 6f 75 6e 74 22 2c 20 22 61 72 63 68 69   "mount", "archi
a1f0: 76 65 22 2c 22 2d 67 72 6f 75 70 22 2c 20 22 2d  ve","-group", "-
a200: 6f 77 6e 65 72 22 2c 20 22 2d 70 65 72 6d 69 73  owner", "-permis
a210: 73 69 6f 6e 73 22 2c 20 30 0a 20 20 20 20 7d 3b  sions", 0.    };
a220: 0a 23 65 6e 64 69 66 0a 20 20 20 20 69 66 20 28  .#endif.    if (
a230: 5a 76 66 73 4c 6f 6f 6b 75 70 28 70 61 74 68 29  ZvfsLookup(path)
a240: 20 3d 3d 20 30 29 20 7b 0a 09 72 65 74 75 72 6e   == 0) {..return
a250: 20 4e 55 4c 4c 3b 0a 20 20 20 20 7d 0a 20 20 20   NULL;.    }.   
a260: 20 72 65 74 75 72 6e 20 61 74 74 72 73 3b 0a 7d   return attrs;.}
a270: 0a 0a 69 6e 74 20 54 6f 62 65 5f 46 53 46 69 6c  ..int Tobe_FSFil
a280: 65 41 74 74 72 73 47 65 74 50 72 6f 63 20 28 0a  eAttrsGetProc (.
a290: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
a2a0: 74 65 72 70 2c 0a 20 20 69 6e 74 20 69 6e 64 65  terp,.  int inde
a2b0: 78 2c 20 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70  x, .  Tcl_Obj *p
a2c0: 61 74 68 50 74 72 2c 0a 20 20 54 63 6c 5f 4f 62  athPtr,.  Tcl_Ob
a2d0: 6a 20 2a 2a 6f 62 6a 50 74 72 52 65 66 0a 29 20  j **objPtrRef.) 
a2e0: 7b 0a 20 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e  {.  char *zFilen
a2f0: 61 6d 65 3b 0a 20 20 5a 76 66 73 46 69 6c 65 20  ame;.  ZvfsFile 
a300: 2a 70 46 69 6c 65 3b 0a 20 20 7a 46 69 6c 65 6e  *pFile;.  zFilen
a310: 61 6d 65 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  ame = Tcl_GetStr
a320: 69 6e 67 28 70 61 74 68 50 74 72 29 3b 0a 20 20  ing(pathPtr);.  
a330: 70 46 69 6c 65 20 3d 20 5a 76 66 73 4c 6f 6f 6b  pFile = ZvfsLook
a340: 75 70 28 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20  up(zFilename);. 
a350: 20 69 66 28 21 70 46 69 6c 65 29 0a 09 72 65 74   if(!pFile)..ret
a360: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
a370: 20 73 77 69 74 63 68 20 28 69 6e 64 65 78 29 20   switch (index) 
a380: 7b 0a 20 20 20 20 20 63 61 73 65 20 30 3a 0a 09  {.     case 0:..
a390: 2a 6f 62 6a 50 74 72 52 65 66 3d 54 63 6c 5f 4e  *objPtrRef=Tcl_N
a3a0: 65 77 49 6e 74 4f 62 6a 28 70 46 69 6c 65 2d 3e  ewIntObj(pFile->
a3b0: 6e 42 79 74 65 43 6f 6d 70 72 29 3b 0a 09 72 65  nByteCompr);..re
a3c0: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 20 20 20  turn TCL_OK;.   
a3d0: 20 20 63 61 73 65 20 31 3a 0a 09 2a 6f 62 6a 50    case 1:..*objP
a3e0: 74 72 52 65 66 3d 20 54 63 6c 5f 4e 65 77 49 6e  trRef= Tcl_NewIn
a3f0: 74 4f 62 6a 28 70 46 69 6c 65 2d 3e 6e 42 79 74  tObj(pFile->nByt
a400: 65 29 3b 0a 09 72 65 74 75 72 6e 20 54 43 4c 5f  e);..return TCL_
a410: 4f 4b 3b 0a 20 20 20 20 20 63 61 73 65 20 32 3a  OK;.     case 2:
a420: 0a 09 2a 6f 62 6a 50 74 72 52 65 66 3d 20 54 63  ..*objPtrRef= Tc
a430: 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 70 46 69 6c  l_NewIntObj(pFil
a440: 65 2d 3e 6e 42 79 74 65 29 3b 0a 09 72 65 74 75  e->nByte);..retu
a450: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 20 20 20 20 20  rn TCL_OK;.     
a460: 63 61 73 65 20 33 3a 0a 09 2a 6f 62 6a 50 74 72  case 3:..*objPtr
a470: 52 65 66 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69  Ref= Tcl_NewStri
a480: 6e 67 4f 62 6a 28 70 46 69 6c 65 2d 3e 70 41 72  ngObj(pFile->pAr
a490: 63 68 69 76 65 2d 3e 7a 4d 6f 75 6e 74 50 6f 69  chive->zMountPoi
a4a0: 6e 74 2c 2d 31 29 3b 0a 09 72 65 74 75 72 6e 20  nt,-1);..return 
a4b0: 54 43 4c 5f 4f 4b 3b 0a 20 20 20 20 20 63 61 73  TCL_OK;.     cas
a4c0: 65 20 34 3a 0a 09 2a 6f 62 6a 50 74 72 52 65 66  e 4:..*objPtrRef
a4d0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
a4e0: 62 6a 28 70 46 69 6c 65 2d 3e 70 41 72 63 68 69  bj(pFile->pArchi
a4f0: 76 65 2d 3e 7a 4e 61 6d 65 2c 2d 31 29 3b 0a 09  ve->zName,-1);..
a500: 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 23  return TCL_OK;.#
a510: 69 66 64 65 66 20 5f 5f 57 49 4e 33 32 5f 5f 0a  ifdef __WIN32__.
a520: 20 20 20 20 63 61 73 65 20 35 3a 20 2f 2a 20 2d      case 5: /* -
a530: 61 72 63 68 69 76 65 20 2a 2f 0a 09 2a 6f 62 6a  archive */..*obj
a540: 50 74 72 52 65 66 20 3d 20 54 63 6c 5f 4e 65 77  PtrRef = Tcl_New
a550: 53 74 72 69 6e 67 4f 62 6a 28 22 30 22 2c 20 2d  StringObj("0", -
a560: 31 29 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 63  1); break;.    c
a570: 61 73 65 20 36 3a 20 2f 2a 20 2d 68 69 64 64 65  ase 6: /* -hidde
a580: 6e 20 2a 2f 0a 09 2a 6f 62 6a 50 74 72 52 65 66  n */..*objPtrRef
a590: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
a5a0: 4f 62 6a 28 22 30 22 2c 20 2d 31 29 3b 20 62 72  Obj("0", -1); br
a5b0: 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 37 3a  eak;.    case 7:
a5c0: 20 2f 2a 20 2d 72 65 61 64 6f 6e 6c 79 20 2a 2f   /* -readonly */
a5d0: 0a 09 2a 6f 62 6a 50 74 72 52 65 66 20 3d 20 54  ..*objPtrRef = T
a5e0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
a5f0: 22 22 2c 20 2d 31 29 3b 20 62 72 65 61 6b 3b 0a  "", -1); break;.
a600: 20 20 20 20 63 61 73 65 20 38 3a 20 2f 2a 20 2d      case 8: /* -
a610: 73 79 73 74 65 6d 20 2a 2f 0a 09 2a 6f 62 6a 50  system */..*objP
a620: 74 72 52 65 66 20 3d 20 54 63 6c 5f 4e 65 77 53  trRef = Tcl_NewS
a630: 74 72 69 6e 67 4f 62 6a 28 22 22 2c 20 2d 31 29  tringObj("", -1)
a640: 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73  ; break;.    cas
a650: 65 20 39 3a 20 2f 2a 20 2d 73 68 6f 72 74 6e 61  e 9: /* -shortna
a660: 6d 65 20 2a 2f 0a 09 2a 6f 62 6a 50 74 72 52 65  me */..*objPtrRe
a670: 66 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  f = Tcl_NewStrin
a680: 67 4f 62 6a 28 22 22 2c 20 2d 31 29 3b 0a 23 65  gObj("", -1);.#e
a690: 6c 73 65 0a 20 20 20 20 63 61 73 65 20 35 3a 20  lse.    case 5: 
a6a0: 2f 2a 20 2d 67 72 6f 75 70 20 2a 2f 0a 09 2a 6f  /* -group */..*o
a6b0: 62 6a 50 74 72 52 65 66 20 3d 20 54 63 6c 5f 4e  bjPtrRef = Tcl_N
a6c0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 22 2c 20  ewStringObj("", 
a6d0: 2d 31 29 3b 20 62 72 65 61 6b 3b 0a 20 20 20 20  -1); break;.    
a6e0: 63 61 73 65 20 36 3a 20 2f 2a 20 2d 6f 77 6e 65  case 6: /* -owne
a6f0: 72 20 2a 2f 0a 09 2a 6f 62 6a 50 74 72 52 65 66  r */..*objPtrRef
a700: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
a710: 4f 62 6a 28 22 22 2c 20 2d 31 29 3b 20 62 72 65  Obj("", -1); bre
a720: 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 37 3a 20  ak;.    case 7: 
a730: 2f 2a 20 2d 70 65 72 6d 69 73 73 69 6f 6e 73 20  /* -permissions 
a740: 2a 2f 20 7b 0a 20 20 20 20 20 20 63 68 61 72 20  */ {.      char 
a750: 62 75 66 5b 33 32 5d 3b 0a 20 20 20 20 20 20 73  buf[32];.      s
a760: 70 72 69 6e 74 66 28 62 75 66 2c 20 22 25 30 33  printf(buf, "%03
a770: 6f 22 2c 20 70 46 69 6c 65 2d 3e 70 65 72 6d 69  o", pFile->permi
a780: 73 73 69 6f 6e 73 29 3b 0a 20 20 20 20 20 20 2a  ssions);.      *
a790: 6f 62 6a 50 74 72 52 65 66 20 3d 20 54 63 6c 5f  objPtrRef = Tcl_
a7a0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 62 75 66  NewStringObj(buf
a7b0: 2c 20 2d 31 29 3b 20 62 72 65 61 6b 3b 0a 20 20  , -1); break;.  
a7c0: 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 20 20 20    }.#endif.     
a7d0: 64 65 66 61 75 6c 74 3a 0a 20 20 20 20 20 20 20  default:.       
a7e0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
a7f0: 52 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  R;.  }.  return 
a800: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 69 6e 74 20 54 6f  TCL_OK;.}.int To
a810: 62 65 5f 46 53 46 69 6c 65 41 74 74 72 73 53 65  be_FSFileAttrsSe
a820: 74 50 72 6f 63 20 28 0a 20 20 54 63 6c 5f 49 6e  tProc (.  Tcl_In
a830: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20  terp *interp,.  
a840: 69 6e 74 20 69 6e 64 65 78 2c 0a 20 20 54 63 6c  int index,.  Tcl
a850: 5f 4f 62 6a 20 2a 70 61 74 68 50 74 72 2c 0a 20  _Obj *pathPtr,. 
a860: 20 54 63 6c 5f 4f 62 6a 20 2a 6f 62 6a 50 74 72   Tcl_Obj *objPtr
a870: 29 20 7b 20 72 65 74 75 72 6e 20 54 43 4c 5f 45  ) { return TCL_E
a880: 52 52 4f 52 3b 20 7d 0a 0a 54 63 6c 5f 4f 62 6a  RROR; }..Tcl_Obj
a890: 2a 20 54 6f 62 65 5f 46 53 46 69 6c 65 73 79 73  * Tobe_FSFilesys
a8a0: 74 65 6d 50 61 74 68 54 79 70 65 50 72 6f 63 20  temPathTypeProc 
a8b0: 28 54 63 6c 5f 4f 62 6a 20 2a 70 61 74 68 50 74  (Tcl_Obj *pathPt
a8c0: 72 29 20 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  r) {.    return 
a8d0: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
a8e0: 28 22 7a 69 70 22 2c 2d 31 29 3b 0a 7d 0a 0a 2f  ("zip",-1);.}../
a8f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
a900: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
a910: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
a920: 2a 2a 2a 2a 2f 0a 0a 73 74 61 74 69 63 20 54 63  ****/..static Tc
a930: 6c 5f 46 69 6c 65 73 79 73 74 65 6d 20 54 6f 62  l_Filesystem Tob
a940: 65 5f 46 69 6c 65 73 79 73 74 65 6d 20 3d 20 7b  e_Filesystem = {
a950: 0a 20 20 20 20 22 7a 76 66 73 22 2c 09 09 20 20  .    "zvfs",..  
a960: 20 20 20 2f 2a 20 54 68 65 20 6e 61 6d 65 20 6f     /* The name o
a970: 66 20 74 68 65 20 66 69 6c 65 73 79 73 74 65 6d  f the filesystem
a980: 2e 20 2a 2f 0a 20 20 20 20 73 69 7a 65 6f 66 28  . */.    sizeof(
a990: 54 63 6c 5f 46 69 6c 65 73 79 73 74 65 6d 29 2c  Tcl_Filesystem),
a9a0: 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 74    /* Length of t
a9b0: 68 69 73 20 73 74 72 75 63 74 75 72 65 2c 20 73  his structure, s
a9c0: 6f 20 66 75 74 75 72 65 0a 20 20 20 20 20 20 20  o future.       
a9d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a9e0: 20 20 20 20 20 20 2a 20 62 69 6e 61 72 79 20 63        * binary c
a9f0: 6f 6d 70 61 74 69 62 69 6c 69 74 79 20 63 61 6e  ompatibility can
aa00: 20 62 65 20 61 73 73 75 72 65 64 2e 20 2a 2f 0a   be assured. */.
aa10: 20 20 20 20 54 43 4c 5f 46 49 4c 45 53 59 53 54      TCL_FILESYST
aa20: 45 4d 5f 56 45 52 53 49 4f 4e 5f 31 2c 0a 20 20  EM_VERSION_1,.  
aa30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aa40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 65 72            /* Ver
aa50: 73 69 6f 6e 20 6f 66 20 74 68 65 20 66 69 6c 65  sion of the file
aa60: 73 79 73 74 65 6d 20 74 79 70 65 2e 20 2a 2f 0a  system type. */.
aa70: 20 20 20 20 54 6f 62 65 5f 46 53 50 61 74 68 49      Tobe_FSPathI
aa80: 6e 46 69 6c 65 73 79 73 74 65 6d 50 72 6f 63 2c  nFilesystemProc,
aa90: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
aaa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
aab0: 46 75 6e 63 74 69 6f 6e 20 74 6f 20 63 68 65 63  Function to chec
aac0: 6b 20 77 68 65 74 68 65 72 20 61 20 70 61 74 68  k whether a path
aad0: 20 69 73 20 69 6e 20 0a 20 20 20 20 20 20 20 20   is in .        
aae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aaf0: 20 20 20 20 20 2a 20 74 68 69 73 20 66 69 6c 65       * this file
ab00: 73 79 73 74 65 6d 2e 20 20 54 68 69 73 20 69 73  system.  This is
ab10: 20 74 68 65 20 6d 6f 73 74 0a 20 20 20 20 20 20   the most.      
ab20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ab30: 20 20 20 20 20 20 20 2a 20 69 6d 70 6f 72 74 61         * importa
ab40: 6e 74 20 66 69 6c 65 73 79 73 74 65 6d 20 70 72  nt filesystem pr
ab50: 6f 63 65 64 75 72 65 2e 20 2a 2f 0a 20 20 20 20  ocedure. */.    
ab60: 4e 55 4c 4c 2c 0a 20 20 20 20 20 20 20 20 20 20  NULL,.          
ab70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ab80: 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f    /* Function to
ab90: 20 64 75 70 6c 69 63 61 74 65 20 69 6e 74 65 72   duplicate inter
aba0: 6e 61 6c 20 66 73 20 72 65 70 2e 20 20 4d 61 79  nal fs rep.  May
abb0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
abc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20                * 
abd0: 62 65 20 4e 55 4c 4c 20 28 62 75 74 20 74 68 65  be NULL (but the
abe0: 6e 20 66 73 20 69 73 20 6c 65 73 73 20 65 66 66  n fs is less eff
abf0: 69 63 69 65 6e 74 29 2e 20 2a 2f 0a 20 20 20 20  icient). */.    
ac00: 4e 55 4c 4c 2c 0a 20 20 20 20 20 20 20 20 20 20  NULL,.          
ac10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ac20: 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f    /* Function to
ac30: 20 66 72 65 65 20 69 6e 74 65 72 6e 61 6c 20 66   free internal f
ac40: 73 20 72 65 70 2e 20 20 4d 75 73 74 0a 20 20 20  s rep.  Must.   
ac50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ac60: 20 20 20 20 20 20 20 20 20 20 2a 20 62 65 20 69            * be i
ac70: 6d 70 6c 65 6d 65 6e 74 65 64 2c 20 69 66 20 69  mplemented, if i
ac80: 6e 74 65 72 6e 61 6c 20 72 65 70 72 65 73 65 6e  nternal represen
ac90: 74 61 74 69 6f 6e 73 0a 20 20 20 20 20 20 20 20  tations.        
aca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
acb0: 20 20 20 20 20 2a 20 6e 65 65 64 20 66 72 65 65       * need free
acc0: 69 6e 67 2c 20 6f 74 68 65 72 77 69 73 65 20 69  ing, otherwise i
acd0: 74 20 63 61 6e 20 62 65 20 4e 55 4c 4c 2e 20 2a  t can be NULL. *
ace0: 2f 0a 20 20 20 20 4e 55 4c 4c 2c 0a 20 20 20 20  /.    NULL,.    
acf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad00: 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74          /* Funct
ad10: 69 6f 6e 20 74 6f 20 63 6f 6e 76 65 72 74 20 69  ion to convert i
ad20: 6e 74 65 72 6e 61 6c 20 72 65 70 72 65 73 65 6e  nternal represen
ad30: 74 61 74 69 6f 6e 0a 20 20 20 20 20 20 20 20 20  tation.         
ad40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad50: 20 20 20 20 2a 20 74 6f 20 61 20 6e 6f 72 6d 61      * to a norma
ad60: 6c 69 7a 65 64 20 70 61 74 68 2e 20 20 4f 6e 6c  lized path.  Onl
ad70: 79 20 72 65 71 75 69 72 65 64 20 69 66 0a 20 20  y required if.  
ad80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ad90: 20 20 20 20 20 20 20 20 20 20 20 2a 20 74 68 65             * the
ada0: 20 66 73 20 63 72 65 61 74 65 73 20 70 75 72 65   fs creates pure
adb0: 20 70 61 74 68 20 6f 62 6a 65 63 74 73 20 77 69   path objects wi
adc0: 74 68 20 6e 6f 0a 20 20 20 20 20 20 20 20 20 20  th no.          
add0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ade0: 20 20 20 2a 20 73 74 72 69 6e 67 2f 70 61 74 68     * string/path
adf0: 20 72 65 70 72 65 73 65 6e 74 61 74 69 6f 6e 2e   representation.
ae00: 20 2a 2f 0a 20 20 20 20 4e 55 4c 4c 2c 0a 20 20   */.    NULL,.  
ae10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ae20: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e            /* Fun
ae30: 63 74 69 6f 6e 20 74 6f 20 63 72 65 61 74 65 20  ction to create 
ae40: 61 20 66 69 6c 65 73 79 73 74 65 6d 2d 73 70 65  a filesystem-spe
ae50: 63 69 66 69 63 0a 20 20 20 20 20 20 20 20 20 20  cific.          
ae60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ae70: 20 20 20 2a 20 69 6e 74 65 72 6e 61 6c 20 72 65     * internal re
ae80: 70 72 65 73 65 6e 74 61 74 69 6f 6e 2e 20 20 4d  presentation.  M
ae90: 61 79 20 62 65 20 4e 55 4c 4c 0a 20 20 20 20 20  ay be NULL.     
aea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aeb0: 20 20 20 20 20 20 20 20 2a 20 69 66 20 70 61 74          * if pat
aec0: 68 73 20 68 61 76 65 20 6e 6f 20 69 6e 74 65 72  hs have no inter
aed0: 6e 61 6c 20 72 65 70 72 65 73 65 6e 74 61 74 69  nal representati
aee0: 6f 6e 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  on, .           
aef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
af00: 20 20 2a 20 6f 72 20 69 66 20 74 68 65 20 54 6f    * or if the To
af10: 62 65 5f 46 53 50 61 74 68 49 6e 46 69 6c 65 73  be_FSPathInFiles
af20: 79 73 74 65 6d 50 72 6f 63 0a 20 20 20 20 20 20  ystemProc.      
af30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
af40: 20 20 20 20 20 20 20 2a 20 66 6f 72 20 74 68 69         * for thi
af50: 73 20 66 69 6c 65 73 79 73 74 65 6d 20 61 6c 77  s filesystem alw
af60: 61 79 73 20 69 6d 6d 65 64 69 61 74 65 6c 79 20  ays immediately 
af70: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
af80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20                * 
af90: 63 72 65 61 74 65 73 20 61 6e 20 69 6e 74 65 72  creates an inter
afa0: 6e 61 6c 20 72 65 70 72 65 73 65 6e 74 61 74 69  nal representati
afb0: 6f 6e 20 66 6f 72 20 0a 20 20 20 20 20 20 20 20  on for .        
afc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
afd0: 20 20 20 20 20 2a 20 70 61 74 68 73 20 69 74 20       * paths it 
afe0: 61 63 63 65 70 74 73 2e 20 2a 2f 0a 20 20 20 20  accepts. */.    
aff0: 4e 55 4c 4c 2c 0a 20 20 20 20 20 20 20 20 20 20  NULL,.          
b000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b010: 20 20 2f 2a 20 54 6f 62 65 5f 46 53 4e 6f 72 6d    /* Tobe_FSNorm
b020: 61 6c 69 7a 65 50 61 74 68 50 72 6f 63 20 28 4e  alizePathProc (N
b030: 6f 74 20 6e 65 65 64 65 64 29 0a 09 09 09 20 20  ot needed)....  
b040: 20 20 20 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f     * Function to
b050: 20 6e 6f 72 6d 61 6c 69 7a 65 20 61 20 70 61 74   normalize a pat
b060: 68 2e 20 20 53 68 6f 75 6c 64 0a 20 20 20 20 20  h.  Should.     
b070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b080: 20 20 20 20 20 20 20 20 2a 20 62 65 20 69 6d 70          * be imp
b090: 6c 65 6d 65 6e 74 65 64 20 66 6f 72 20 61 6c 6c  lemented for all
b0a0: 20 66 69 6c 65 73 79 73 74 65 6d 73 0a 20 20 20   filesystems.   
b0b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b0c0: 20 20 20 20 20 20 20 20 20 20 2a 20 77 68 69 63            * whic
b0d0: 68 20 63 61 6e 20 68 61 76 65 20 6d 75 6c 74 69  h can have multi
b0e0: 70 6c 65 20 73 74 72 69 6e 67 20 0a 20 20 20 20  ple string .    
b0f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b100: 20 20 20 20 20 20 20 20 20 2a 20 72 65 70 72 65           * repre
b110: 73 65 6e 74 61 74 69 6f 6e 73 20 66 6f 72 20 74  sentations for t
b120: 68 65 20 73 61 6d 65 20 70 61 74 68 20 0a 20 20  he same path .  
b130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b140: 20 20 20 20 20 20 20 20 20 20 20 2a 20 6f 62 6a             * obj
b150: 65 63 74 2e 20 2a 2f 0a 20 20 20 20 54 6f 62 65  ect. */.    Tobe
b160: 5f 46 53 46 69 6c 65 73 79 73 74 65 6d 50 61 74  _FSFilesystemPat
b170: 68 54 79 70 65 50 72 6f 63 2c 0a 20 20 20 20 20  hTypeProc,.     
b180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b190: 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69         /* Functi
b1a0: 6f 6e 20 74 6f 20 64 65 74 65 72 6d 69 6e 65 20  on to determine 
b1b0: 74 68 65 20 74 79 70 65 20 6f 66 20 61 20 0a 20  the type of a . 
b1c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b1d0: 20 20 20 20 20 20 20 20 20 20 20 20 2a 20 70 61              * pa
b1e0: 74 68 20 69 6e 20 74 68 69 73 20 66 69 6c 65 73  th in this files
b1f0: 79 73 74 65 6d 2e 20 20 4d 61 79 20 62 65 20 4e  ystem.  May be N
b200: 55 4c 4c 2e 20 2a 2f 0a 20 20 20 20 54 6f 62 65  ULL. */.    Tobe
b210: 5f 46 53 46 69 6c 65 73 79 73 74 65 6d 53 65 70  _FSFilesystemSep
b220: 61 72 61 74 6f 72 50 72 6f 63 2c 0a 20 20 20 20  aratorProc,.    
b230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b240: 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74          /* Funct
b250: 69 6f 6e 20 74 6f 20 72 65 74 75 72 6e 20 74 68  ion to return th
b260: 65 20 73 65 70 61 72 61 74 6f 72 20 0a 20 20 20  e separator .   
b270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b280: 20 20 20 20 20 20 20 20 20 20 2a 20 63 68 61 72            * char
b290: 61 63 74 65 72 28 73 29 20 66 6f 72 20 74 68 69  acter(s) for thi
b2a0: 73 20 66 69 6c 65 73 79 73 74 65 6d 2e 20 20 4d  s filesystem.  M
b2b0: 75 73 74 0a 20 20 20 20 20 20 20 20 20 20 20 20  ust.            
b2c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b2d0: 20 2a 20 62 65 20 69 6d 70 6c 65 6d 65 6e 74 65   * be implemente
b2e0: 64 2e 20 2a 2f 0a 20 20 20 20 54 6f 62 65 5f 46  d. */.    Tobe_F
b2f0: 53 53 74 61 74 50 72 6f 63 2c 0a 20 20 20 20 20  SStatProc,.     
b300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b310: 20 20 20 20 20 20 20 2f 2a 20 0a 20 20 20 20 20         /* .     
b320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b330: 20 20 20 20 20 20 20 20 2a 20 46 75 6e 63 74 69          * Functi
b340: 6f 6e 20 74 6f 20 70 72 6f 63 65 73 73 20 61 20  on to process a 
b350: 27 54 6f 62 65 5f 46 53 53 74 61 74 28 29 27 0a  'Tobe_FSStat()'.
b360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b370: 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20 63               * c
b380: 61 6c 6c 2e 20 20 4d 75 73 74 20 62 65 20 69 6d  all.  Must be im
b390: 70 6c 65 6d 65 6e 74 65 64 20 66 6f 72 20 61 6e  plemented for an
b3a0: 79 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y.              
b3b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
b3c0: 20 72 65 61 73 6f 6e 61 62 6c 65 20 66 69 6c 65   reasonable file
b3d0: 73 79 73 74 65 6d 2e 0a 20 20 20 20 20 20 20 20  system..        
b3e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b3f0: 20 20 20 20 20 2a 2f 0a 20 20 20 20 54 6f 62 65       */.    Tobe
b400: 5f 46 53 41 63 63 65 73 73 50 72 6f 63 2c 0a 20  _FSAccessProc,. 
b410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b420: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 0a 20             /* . 
b430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b440: 20 20 20 20 20 20 20 20 20 20 20 20 2a 20 46 75              * Fu
b450: 6e 63 74 69 6f 6e 20 74 6f 20 70 72 6f 63 65 73  nction to proces
b460: 73 20 61 20 27 54 6f 62 65 5f 46 53 41 63 63 65  s a 'Tobe_FSAcce
b470: 73 73 28 29 27 0a 20 20 20 20 20 20 20 20 20 20  ss()'.          
b480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b490: 20 20 20 2a 20 63 61 6c 6c 2e 20 20 4d 75 73 74     * call.  Must
b4a0: 20 62 65 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20   be implemented 
b4b0: 66 6f 72 20 61 6e 79 0a 20 20 20 20 20 20 20 20  for any.        
b4c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b4d0: 20 20 20 20 20 2a 20 72 65 61 73 6f 6e 61 62 6c       * reasonabl
b4e0: 65 20 66 69 6c 65 73 79 73 74 65 6d 2e 0a 20 20  e filesystem..  
b4f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b500: 20 20 20 20 20 20 20 20 20 20 20 2a 2f 0a 20 20             */.  
b510: 20 20 54 6f 62 65 5f 46 53 4f 70 65 6e 46 69 6c    Tobe_FSOpenFil
b520: 65 43 68 61 6e 6e 65 6c 50 72 6f 63 2c 0a 20 20  eChannelProc,.  
b530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b540: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 0a 20 20            /* .  
b550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b560: 20 20 20 20 20 20 20 20 20 20 20 2a 20 46 75 6e             * Fun
b570: 63 74 69 6f 6e 20 74 6f 20 70 72 6f 63 65 73 73  ction to process
b580: 20 61 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   a.             
b590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b5a0: 2a 20 27 54 6f 62 65 5f 46 53 4f 70 65 6e 46 69  * 'Tobe_FSOpenFi
b5b0: 6c 65 43 68 61 6e 6e 65 6c 28 29 27 20 63 61 6c  leChannel()' cal
b5c0: 6c 2e 20 20 4d 75 73 74 20 62 65 0a 20 20 20 20  l.  Must be.    
b5d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b5e0: 20 20 20 20 20 20 20 20 20 2a 20 69 6d 70 6c 65           * imple
b5f0: 6d 65 6e 74 65 64 20 66 6f 72 20 61 6e 79 20 72  mented for any r
b600: 65 61 73 6f 6e 61 62 6c 65 0a 20 20 20 20 20 20  easonable.      
b610: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b620: 20 20 20 20 20 20 20 2a 20 66 69 6c 65 73 79 73         * filesys
b630: 74 65 6d 2e 0a 20 20 20 20 20 20 20 20 20 20 20  tem..           
b640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b650: 20 20 2a 2f 0a 20 20 20 20 54 6f 62 65 5f 46 53    */.    Tobe_FS
b660: 4d 61 74 63 68 49 6e 44 69 72 65 63 74 6f 72 79  MatchInDirectory
b670: 50 72 6f 63 2c 0a 20 20 20 20 20 20 20 20 20 20  Proc,.          
b680: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b690: 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f    /* Function to
b6a0: 20 70 72 6f 63 65 73 73 20 61 20 0a 20 20 20 20   process a .    
b6b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b6c0: 20 20 20 20 20 20 20 20 20 2a 20 27 54 6f 62 65           * 'Tobe
b6d0: 5f 46 53 4d 61 74 63 68 49 6e 44 69 72 65 63 74  _FSMatchInDirect
b6e0: 6f 72 79 28 29 27 2e 20 20 49 66 20 6e 6f 74 0a  ory()'.  If not.
b6f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b700: 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20 69               * i
b710: 6d 70 6c 65 6d 65 6e 74 65 64 2c 20 74 68 65 6e  mplemented, then
b720: 20 67 6c 6f 62 20 61 6e 64 20 72 65 63 75 72 73   glob and recurs
b730: 69 76 65 0a 20 20 20 20 20 20 20 20 20 20 20 20  ive.            
b740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b750: 20 2a 20 63 6f 70 79 20 66 75 6e 63 74 69 6f 6e   * copy function
b760: 61 6c 69 74 79 20 77 69 6c 6c 20 62 65 20 6c 61  ality will be la
b770: 63 6b 69 6e 67 20 69 6e 0a 20 20 20 20 20 20 20  cking in.       
b780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b790: 20 20 20 20 20 20 2a 20 74 68 65 20 66 69 6c 65        * the file
b7a0: 73 79 73 74 65 6d 2e 20 2a 2f 0a 20 20 20 20 4e  system. */.    N
b7b0: 55 4c 4c 2c 0a 20 20 20 20 20 20 20 20 20 20 20  ULL,.           
b7c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b7d0: 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20   /* Function to 
b7e0: 70 72 6f 63 65 73 73 20 61 20 0a 20 20 20 20 20  process a .     
b7f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b800: 20 20 20 20 20 20 20 20 2a 20 27 54 6f 62 65 5f          * 'Tobe_
b810: 46 53 55 74 69 6d 65 28 29 27 20 63 61 6c 6c 2e  FSUtime()' call.
b820: 20 20 52 65 71 75 69 72 65 64 20 74 6f 0a 20 20    Required to.  
b830: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b840: 20 20 20 20 20 20 20 20 20 20 20 2a 20 61 6c 6c             * all
b850: 6f 77 20 73 65 74 74 69 6e 67 20 28 6e 6f 74 20  ow setting (not 
b860: 72 65 61 64 69 6e 67 29 20 6f 66 20 74 69 6d 65  reading) of time
b870: 73 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  s .             
b880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b890: 2a 20 77 69 74 68 20 27 66 69 6c 65 20 6d 74 69  * with 'file mti
b8a0: 6d 65 27 2c 20 27 66 69 6c 65 20 61 74 69 6d 65  me', 'file atime
b8b0: 27 20 61 6e 64 0a 20 20 20 20 20 20 20 20 20 20  ' and.          
b8c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b8d0: 20 20 20 2a 20 74 68 65 20 6f 70 65 6e 2d 72 2f     * the open-r/
b8e0: 6f 70 65 6e 2d 77 2f 66 63 6f 70 79 20 69 6d 70  open-w/fcopy imp
b8f0: 6c 65 6d 65 6e 74 61 74 69 6f 6e 0a 20 20 20 20  lementation.    
b900: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b910: 20 20 20 20 20 20 20 20 20 2a 20 6f 66 20 27 66           * of 'f
b920: 69 6c 65 20 63 6f 70 79 27 2e 20 2a 2f 0a 20 20  ile copy'. */.  
b930: 20 20 4e 55 4c 4c 2c 0a 20 20 20 20 20 20 20 20    NULL,.        
b940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b950: 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20      /* Function 
b960: 74 6f 20 70 72 6f 63 65 73 73 20 61 20 0a 20 20  to process a .  
b970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b980: 20 20 20 20 20 20 20 20 20 20 20 2a 20 27 54 6f             * 'To
b990: 62 65 5f 46 53 4c 69 6e 6b 28 29 27 20 63 61 6c  be_FSLink()' cal
b9a0: 6c 2e 20 20 53 68 6f 75 6c 64 20 62 65 0a 20 20  l.  Should be.  
b9b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b9c0: 20 20 20 20 20 20 20 20 20 20 20 2a 20 69 6d 70             * imp
b9d0: 6c 65 6d 65 6e 74 65 64 20 6f 6e 6c 79 20 69 66  lemented only if
b9e0: 20 74 68 65 20 66 69 6c 65 73 79 73 74 65 6d 20   the filesystem 
b9f0: 73 75 70 70 6f 72 74 73 0a 20 20 20 20 20 20 20  supports.       
ba00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ba10: 20 20 20 20 20 20 2a 20 6c 69 6e 6b 73 2e 20 2a        * links. *
ba20: 2f 0a 20 20 20 20 54 6f 62 65 5f 46 53 4c 69 73  /.    Tobe_FSLis
ba30: 74 56 6f 6c 75 6d 65 73 50 72 6f 63 2c 0a 20 20  tVolumesProc,.  
ba40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ba50: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e            /* Fun
ba60: 63 74 69 6f 6e 20 74 6f 20 6c 69 73 74 20 61 6e  ction to list an
ba70: 79 20 66 69 6c 65 73 79 73 74 65 6d 20 76 6f 6c  y filesystem vol
ba80: 75 6d 65 73 20 0a 20 20 20 20 20 20 20 20 20 20  umes .          
ba90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
baa0: 20 20 20 2a 20 61 64 64 65 64 20 62 79 20 74 68     * added by th
bab0: 69 73 20 66 69 6c 65 73 79 73 74 65 6d 2e 20 20  is filesystem.  
bac0: 53 68 6f 75 6c 64 20 62 65 0a 20 20 20 20 20 20  Should be.      
bad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bae0: 20 20 20 20 20 20 20 2a 20 69 6d 70 6c 65 6d 65         * impleme
baf0: 6e 74 65 64 20 6f 6e 6c 79 20 69 66 20 74 68 65  nted only if the
bb00: 20 66 69 6c 65 73 79 73 74 65 6d 20 61 64 64 73   filesystem adds
bb10: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
bb20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20                * 
bb30: 76 6f 6c 75 6d 65 73 20 61 74 20 74 68 65 20 68  volumes at the h
bb40: 65 61 64 20 6f 66 20 74 68 65 20 66 69 6c 65 73  ead of the files
bb50: 79 73 74 65 6d 2e 20 2a 2f 0a 20 20 20 20 54 6f  ystem. */.    To
bb60: 62 65 5f 46 53 46 69 6c 65 41 74 74 72 53 74 72  be_FSFileAttrStr
bb70: 69 6e 67 73 50 72 6f 63 2c 0a 20 20 20 20 20 20  ingsProc,.      
bb80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bb90: 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f        /* Functio
bba0: 6e 20 74 6f 20 6c 69 73 74 20 61 6c 6c 20 61 74  n to list all at
bbb0: 74 72 69 62 75 74 65 73 20 73 74 72 69 6e 67 73  tributes strings
bbc0: 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
bbd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
bbe0: 20 77 68 69 63 68 20 61 72 65 20 76 61 6c 69 64   which are valid
bbf0: 20 66 6f 72 20 74 68 69 73 20 66 69 6c 65 73 79   for this filesy
bc00: 73 74 65 6d 2e 20 20 0a 20 20 20 20 20 20 20 20  stem.  .        
bc10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bc20: 20 20 20 20 20 2a 20 49 66 20 6e 6f 74 20 69 6d       * If not im
bc30: 70 6c 65 6d 65 6e 74 65 64 20 74 68 65 20 66 69  plemented the fi
bc40: 6c 65 73 79 73 74 65 6d 20 77 69 6c 6c 0a 20 20  lesystem will.  
bc50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bc60: 20 20 20 20 20 20 20 20 20 20 20 2a 20 6e 6f 74             * not
bc70: 20 73 75 70 70 6f 72 74 20 74 68 65 20 27 66 69   support the 'fi
bc80: 6c 65 20 61 74 74 72 69 62 75 74 65 73 27 20 63  le attributes' c
bc90: 6f 6d 6d 61 6e 64 2e 0a 20 20 20 20 20 20 20 20  ommand..        
bca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bcb0: 20 20 20 20 20 2a 20 54 68 69 73 20 61 6c 6c 6f       * This allo
bcc0: 77 73 20 61 72 62 69 74 72 61 72 79 20 61 64 64  ws arbitrary add
bcd0: 69 74 69 6f 6e 61 6c 20 69 6e 66 6f 72 6d 61 74  itional informat
bce0: 69 6f 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20  ion.            
bcf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bd00: 20 2a 20 74 6f 20 62 65 20 61 74 74 61 63 68 65   * to be attache
bd10: 64 20 74 6f 20 66 69 6c 65 73 20 69 6e 20 74 68  d to files in th
bd20: 65 20 66 69 6c 65 73 79 73 74 65 6d 2e 20 2a 2f  e filesystem. */
bd30: 0a 20 20 20 20 54 6f 62 65 5f 46 53 46 69 6c 65  .    Tobe_FSFile
bd40: 41 74 74 72 73 47 65 74 50 72 6f 63 2c 0a 20 20  AttrsGetProc,.  
bd50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bd60: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e            /* Fun
bd70: 63 74 69 6f 6e 20 74 6f 20 70 72 6f 63 65 73 73  ction to process
bd80: 20 61 20 0a 20 20 20 20 20 20 20 20 20 20 20 20   a .            
bd90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bda0: 20 2a 20 27 54 6f 62 65 5f 46 53 46 69 6c 65 41   * 'Tobe_FSFileA
bdb0: 74 74 72 73 47 65 74 28 29 27 20 63 61 6c 6c 2c  ttrsGet()' call,
bdc0: 20 75 73 65 64 20 62 79 0a 20 20 20 20 20 20 20   used by.       
bdd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bde0: 20 20 20 20 20 20 2a 20 27 66 69 6c 65 20 61 74        * 'file at
bdf0: 74 72 69 62 75 74 65 73 27 2e 20 2a 2f 0a 20 20  tributes'. */.  
be00: 20 20 54 6f 62 65 5f 46 53 46 69 6c 65 41 74 74    Tobe_FSFileAtt
be10: 72 73 53 65 74 50 72 6f 63 2c 0a 20 20 20 20 20  rsSetProc,.     
be20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
be30: 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69         /* Functi
be40: 6f 6e 20 74 6f 20 70 72 6f 63 65 73 73 20 61 20  on to process a 
be50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
be60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20                * 
be70: 27 54 6f 62 65 5f 46 53 46 69 6c 65 41 74 74 72  'Tobe_FSFileAttr
be80: 73 53 65 74 28 29 27 20 63 61 6c 6c 2c 20 75 73  sSet()' call, us
be90: 65 64 20 62 79 0a 20 20 20 20 20 20 20 20 20 20  ed by.          
bea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
beb0: 20 20 20 2a 20 27 66 69 6c 65 20 61 74 74 72 69     * 'file attri
bec0: 62 75 74 65 73 27 2e 20 20 2a 2f 0a 20 20 20 20  butes'.  */.    
bed0: 4e 55 4c 4c 2c 0a 20 20 20 20 20 20 20 20 20 20  NULL,.          
bee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bef0: 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f    /* Function to
bf00: 20 70 72 6f 63 65 73 73 20 61 20 0a 20 20 20 20   process a .    
bf10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bf20: 20 20 20 20 20 20 20 20 20 2a 20 27 54 6f 62 65           * 'Tobe
bf30: 5f 46 53 43 72 65 61 74 65 44 69 72 65 63 74 6f  _FSCreateDirecto
bf40: 72 79 28 29 27 20 63 61 6c 6c 2e 20 53 68 6f 75  ry()' call. Shou
bf50: 6c 64 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ld.             
bf60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bf70: 2a 20 62 65 20 69 6d 70 6c 65 6d 65 6e 74 65 64  * be implemented
bf80: 20 75 6e 6c 65 73 73 20 74 68 65 20 46 53 20 69   unless the FS i
bf90: 73 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s.              
bfa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
bfb0: 20 72 65 61 64 2d 6f 6e 6c 79 2e 20 2a 2f 0a 20   read-only. */. 
bfc0: 20 20 20 4e 55 4c 4c 2c 0a 20 20 20 20 20 20 20     NULL,.       
bfd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bfe0: 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e       /* Function
bff0: 20 74 6f 20 70 72 6f 63 65 73 73 20 61 20 0a 20   to process a . 
c000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c010: 20 20 20 20 20 20 20 20 20 20 20 20 2a 20 27 54              * 'T
c020: 6f 62 65 5f 46 53 52 65 6d 6f 76 65 44 69 72 65  obe_FSRemoveDire
c030: 63 74 6f 72 79 28 29 27 20 63 61 6c 6c 2e 20 53  ctory()' call. S
c040: 68 6f 75 6c 64 0a 20 20 20 20 20 20 20 20 20 20  hould.          
c050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c060: 20 20 20 2a 20 62 65 20 69 6d 70 6c 65 6d 65 6e     * be implemen
c070: 74 65 64 20 75 6e 6c 65 73 73 20 74 68 65 20 46  ted unless the F
c080: 53 20 69 73 0a 20 20 20 20 20 20 20 20 20 20 20  S is.           
c090: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c0a0: 20 20 2a 20 72 65 61 64 2d 6f 6e 6c 79 2e 20 2a    * read-only. *
c0b0: 2f 0a 20 20 20 20 4e 55 4c 4c 2c 0a 20 20 20 20  /.    NULL,.    
c0c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c0d0: 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74          /* Funct
c0e0: 69 6f 6e 20 74 6f 20 70 72 6f 63 65 73 73 20 61  ion to process a
c0f0: 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20   .              
c100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
c110: 20 27 54 6f 62 65 5f 46 53 44 65 6c 65 74 65 46   'Tobe_FSDeleteF
c120: 69 6c 65 28 29 27 20 63 61 6c 6c 2e 20 20 53 68  ile()' call.  Sh
c130: 6f 75 6c 64 0a 20 20 20 20 20 20 20 20 20 20 20  ould.           
c140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c150: 20 20 2a 20 62 65 20 69 6d 70 6c 65 6d 65 6e 74    * be implement
c160: 65 64 20 75 6e 6c 65 73 73 20 74 68 65 20 46 53  ed unless the FS
c170: 20 69 73 0a 20 20 20 20 20 20 20 20 20 20 20 20   is.            
c180: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c190: 20 2a 20 72 65 61 64 2d 6f 6e 6c 79 2e 20 2a 2f   * read-only. */
c1a0: 0a 20 20 20 20 4e 55 4c 4c 2c 0a 20 20 20 20 20  .    NULL,.     
c1b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c1c0: 20 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69         /* Functi
c1d0: 6f 6e 20 74 6f 20 70 72 6f 63 65 73 73 20 61 20  on to process a 
c1e0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
c1f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20                * 
c200: 27 54 6f 62 65 5f 46 53 43 6f 70 79 46 69 6c 65  'Tobe_FSCopyFile
c210: 28 29 27 20 63 61 6c 6c 2e 20 20 49 66 20 6e 6f  ()' call.  If no
c220: 74 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t.              
c230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
c240: 20 69 6d 70 6c 65 6d 65 6e 74 65 64 20 54 63 6c   implemented Tcl
c250: 20 77 69 6c 6c 20 66 61 6c 6c 20 62 61 63 6b 0a   will fall back.
c260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c270: 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20 6f               * o
c280: 6e 20 6f 70 65 6e 2d 72 2c 20 6f 70 65 6e 2d 77  n open-r, open-w
c290: 20 61 6e 64 20 66 63 6f 70 79 20 61 73 0a 20 20   and fcopy as.  
c2a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c2b0: 20 20 20 20 20 20 20 20 20 20 20 2a 20 61 20 63             * a c
c2c0: 6f 70 79 69 6e 67 20 6d 65 63 68 61 6e 69 73 6d  opying mechanism
c2d0: 2e 20 2a 2f 0a 20 20 20 20 4e 55 4c 4c 2c 0a 20  . */.    NULL,. 
c2e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c2f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 75             /* Fu
c300: 6e 63 74 69 6f 6e 20 74 6f 20 70 72 6f 63 65 73  nction to proces
c310: 73 20 61 20 0a 20 20 20 20 20 20 20 20 20 20 20  s a .           
c320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c330: 20 20 2a 20 27 54 6f 62 65 5f 46 53 52 65 6e 61    * 'Tobe_FSRena
c340: 6d 65 46 69 6c 65 28 29 27 20 63 61 6c 6c 2e 20  meFile()' call. 
c350: 20 49 66 20 6e 6f 74 0a 20 20 20 20 20 20 20 20   If not.        
c360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c370: 20 20 20 20 20 2a 20 69 6d 70 6c 65 6d 65 6e 74       * implement
c380: 65 64 2c 20 54 63 6c 20 77 69 6c 6c 20 66 61 6c  ed, Tcl will fal
c390: 6c 20 62 61 63 6b 20 6f 6e 0a 20 20 20 20 20 20  l back on.      
c3a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c3b0: 20 20 20 20 20 20 20 2a 20 61 20 63 6f 70 79 20         * a copy 
c3c0: 61 6e 64 20 64 65 6c 65 74 65 20 6d 65 63 68 61  and delete mecha
c3d0: 6e 69 73 6d 2e 20 2a 2f 0a 20 20 20 20 4e 55 4c  nism. */.    NUL
c3e0: 4c 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  L,.             
c3f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c400: 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f 20 70 72  * Function to pr
c410: 6f 63 65 73 73 20 61 20 0a 20 20 20 20 20 20 20  ocess a .       
c420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c430: 20 20 20 20 20 20 2a 20 27 54 6f 62 65 5f 46 53        * 'Tobe_FS
c440: 43 6f 70 79 44 69 72 65 63 74 6f 72 79 28 29 27  CopyDirectory()'
c450: 20 63 61 6c 6c 2e 20 20 49 66 0a 20 20 20 20 20   call.  If.     
c460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c470: 20 20 20 20 20 20 20 20 2a 20 6e 6f 74 20 69 6d          * not im
c480: 70 6c 65 6d 65 6e 74 65 64 2c 20 54 63 6c 20 77  plemented, Tcl w
c490: 69 6c 6c 20 66 61 6c 6c 20 62 61 63 6b 0a 20 20  ill fall back.  
c4a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c4b0: 20 20 20 20 20 20 20 20 20 20 20 2a 20 6f 6e 20             * on 
c4c0: 61 20 72 65 63 75 72 73 69 76 65 20 63 72 65 61  a recursive crea
c4d0: 74 65 2d 64 69 72 2c 20 66 69 6c 65 20 63 6f 70  te-dir, file cop
c4e0: 79 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  y.              
c4f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
c500: 20 6d 65 63 68 61 6e 69 73 6d 2e 20 2a 2f 0a 20   mechanism. */. 
c510: 20 20 20 4e 55 4c 4c 2c 0a 20 20 20 20 20 20 20     NULL,.       
c520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c530: 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f 6e       /* Function
c540: 20 74 6f 20 70 72 6f 63 65 73 73 20 61 20 0a 20   to process a . 
c550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c560: 20 20 20 20 20 20 20 20 20 20 20 20 2a 20 27 54              * 'T
c570: 6f 62 65 5f 46 53 4c 6f 61 64 46 69 6c 65 28 29  obe_FSLoadFile()
c580: 27 20 63 61 6c 6c 2e 20 20 49 66 20 6e 6f 74 0a  ' call.  If not.
c590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c5a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20 69               * i
c5b0: 6d 70 6c 65 6d 65 6e 74 65 64 2c 20 54 63 6c 20  mplemented, Tcl 
c5c0: 77 69 6c 6c 20 66 61 6c 6c 20 62 61 63 6b 20 6f  will fall back o
c5d0: 6e 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n.              
c5e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
c5f0: 20 61 20 63 6f 70 79 20 74 6f 20 6e 61 74 69 76   a copy to nativ
c600: 65 2d 74 65 6d 70 20 66 6f 6c 6c 6f 77 65 64 20  e-temp followed 
c610: 62 79 20 61 20 0a 20 20 20 20 20 20 20 20 20 20  by a .          
c620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c630: 20 20 20 2a 20 54 6f 62 65 5f 46 53 4c 6f 61 64     * Tobe_FSLoad
c640: 46 69 6c 65 20 6f 6e 20 74 68 61 74 20 74 65 6d  File on that tem
c650: 70 6f 72 61 72 79 20 63 6f 70 79 2e 20 2a 2f 0a  porary copy. */.
c660: 20 20 20 20 4e 55 4c 4c 2c 0a 20 20 20 20 20 20      NULL,.      
c670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c680: 20 20 20 20 20 20 2f 2a 20 46 75 6e 63 74 69 6f        /* Functio
c690: 6e 20 74 6f 20 75 6e 6c 6f 61 64 20 61 20 70 72  n to unload a pr
c6a0: 65 76 69 6f 75 73 6c 79 20 0a 20 20 20 20 20 20  eviously .      
c6b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c6c0: 20 20 20 20 20 20 20 2a 20 73 75 63 63 65 73 73         * success
c6d0: 66 75 6c 6c 79 20 6c 6f 61 64 65 64 20 66 69 6c  fully loaded fil
c6e0: 65 2e 20 20 49 66 20 6c 6f 61 64 20 77 61 73 0a  e.  If load was.
c6f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c700: 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20 69               * i
c710: 6d 70 6c 65 6d 65 6e 74 65 64 2c 20 74 68 65 6e  mplemented, then
c720: 20 74 68 69 73 20 73 68 6f 75 6c 64 20 61 6c 73   this should als
c730: 6f 20 62 65 0a 20 20 20 20 20 20 20 20 20 20 20  o be.           
c740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c750: 20 20 2a 20 69 6d 70 6c 65 6d 65 6e 74 65 64 2c    * implemented,
c760: 20 69 66 20 74 68 65 72 65 20 69 73 20 61 6e 79   if there is any
c770: 20 63 6c 65 61 6e 75 70 0a 20 20 20 20 20 20 20   cleanup.       
c780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c790: 20 20 20 20 20 20 2a 20 61 63 74 69 6f 6e 20 72        * action r
c7a0: 65 71 75 69 72 65 64 2e 20 2a 2f 0a 20 20 20 20  equired. */.    
c7b0: 4e 55 4c 4c 2c 0a 20 20 20 20 20 20 20 20 20 20  NULL,.          
c7c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c7d0: 20 20 2f 2a 20 0a 20 20 20 20 20 20 20 20 20 20    /* .          
c7e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c7f0: 20 20 20 2a 20 46 75 6e 63 74 69 6f 6e 20 74 6f     * Function to
c800: 20 70 72 6f 63 65 73 73 20 61 20 27 54 6f 62 65   process a 'Tobe
c810: 5f 46 53 47 65 74 43 77 64 28 29 27 0a 20 20 20  _FSGetCwd()'.   
c820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c830: 20 20 20 20 20 20 20 20 20 20 2a 20 63 61 6c 6c            * call
c840: 2e 20 20 4d 6f 73 74 20 66 69 6c 65 73 79 73 74  .  Most filesyst
c850: 65 6d 73 20 6e 65 65 64 20 6e 6f 74 0a 20 20 20  ems need not.   
c860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c870: 20 20 20 20 20 20 20 20 20 20 2a 20 69 6d 70 6c            * impl
c880: 65 6d 65 6e 74 20 74 68 69 73 2e 20 20 49 74 20  ement this.  It 
c890: 77 69 6c 6c 20 75 73 75 61 6c 6c 79 20 6f 6e 6c  will usually onl
c8a0: 79 20 62 65 0a 20 20 20 20 20 20 20 20 20 20 20  y be.           
c8b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c8c0: 20 20 2a 20 63 61 6c 6c 65 64 20 6f 6e 63 65 2c    * called once,
c8d0: 20 69 66 20 27 67 65 74 63 77 64 27 20 69 73 20   if 'getcwd' is 
c8e0: 63 61 6c 6c 65 64 0a 20 20 20 20 20 20 20 20 20  called.         
c8f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c900: 20 20 20 20 2a 20 62 65 66 6f 72 65 20 27 63 68      * before 'ch
c910: 64 69 72 27 2e 20 20 4d 61 79 20 62 65 20 4e 55  dir'.  May be NU
c920: 4c 4c 2e 0a 20 20 20 20 20 20 20 20 20 20 20 20  LL..            
c930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c940: 20 2a 2f 0a 20 20 20 20 4e 55 4c 4c 2c 0a 20 20   */.    NULL,.  
c950: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c960: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 0a 20 20            /* .  
c970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c980: 20 20 20 20 20 20 20 20 20 20 20 2a 20 46 75 6e             * Fun
c990: 63 74 69 6f 6e 20 74 6f 20 70 72 6f 63 65 73 73  ction to process
c9a0: 20 61 20 27 54 6f 62 65 5f 46 53 43 68 64 69 72   a 'Tobe_FSChdir
c9b0: 28 29 27 0a 20 20 20 20 20 20 20 20 20 20 20 20  ()'.            
c9c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c9d0: 20 2a 20 63 61 6c 6c 2e 20 20 49 66 20 66 69 6c   * call.  If fil
c9e0: 65 73 79 73 74 65 6d 73 20 64 6f 20 6e 6f 74 20  esystems do not 
c9f0: 69 6d 70 6c 65 6d 65 6e 74 0a 20 20 20 20 20 20  implement.      
ca00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ca10: 20 20 20 20 20 20 20 2a 20 74 68 69 73 2c 20 69         * this, i
ca20: 74 20 77 69 6c 6c 20 62 65 20 65 6d 75 6c 61 74  t will be emulat
ca30: 65 64 20 62 79 20 61 20 73 65 72 69 65 73 20 6f  ed by a series o
ca40: 66 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f.              
ca50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
ca60: 20 64 69 72 65 63 74 6f 72 79 20 61 63 63 65 73   directory acces
ca70: 73 20 63 68 65 63 6b 73 2e 20 20 4f 74 68 65 72  s checks.  Other
ca80: 77 69 73 65 2c 0a 20 20 20 20 20 20 20 20 20 20  wise,.          
ca90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
caa0: 20 20 20 2a 20 76 69 72 74 75 61 6c 20 66 69 6c     * virtual fil
cab0: 65 73 79 73 74 65 6d 73 20 77 68 69 63 68 20 64  esystems which d
cac0: 6f 20 69 6d 70 6c 65 6d 65 6e 74 0a 20 20 20 20  o implement.    
cad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cae0: 20 20 20 20 20 20 20 20 20 2a 20 69 74 20 6e 65           * it ne
caf0: 65 64 20 6f 6e 6c 79 20 72 65 73 70 6f 6e 64 20  ed only respond 
cb00: 77 69 74 68 20 61 20 70 6f 73 69 74 69 76 65 0a  with a positive.
cb10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cb20: 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 20 72               * r
cb30: 65 74 75 72 6e 20 72 65 73 75 6c 74 20 69 66 20  eturn result if 
cb40: 74 68 65 20 64 69 72 4e 61 6d 65 20 69 73 20 61  the dirName is a
cb50: 20 76 61 6c 69 64 0a 20 20 20 20 20 20 20 20 20   valid.         
cb60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cb70: 20 20 20 20 2a 20 64 69 72 65 63 74 6f 72 79 20      * directory 
cb80: 69 6e 20 74 68 65 69 72 20 66 69 6c 65 73 79 73  in their filesys
cb90: 74 65 6d 2e 20 20 54 68 65 79 0a 20 20 20 20 20  tem.  They.     
cba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cbb0: 20 20 20 20 20 20 20 20 2a 20 6e 65 65 64 20 6e          * need n
cbc0: 6f 74 20 72 65 6d 65 6d 62 65 72 20 74 68 65 20  ot remember the 
cbd0: 72 65 73 75 6c 74 2c 20 73 69 6e 63 65 20 74 68  result, since th
cbe0: 61 74 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  at.             
cbf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cc00: 2a 20 77 69 6c 6c 20 62 65 20 61 75 74 6f 6d 61  * will be automa
cc10: 74 69 63 61 6c 6c 79 20 72 65 6d 65 6d 62 65 72  tically remember
cc20: 65 64 20 66 6f 72 20 75 73 65 0a 20 20 20 20 20  ed for use.     
cc30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cc40: 20 20 20 20 20 20 20 20 2a 20 62 79 20 47 65 74          * by Get
cc50: 43 77 64 2e 20 20 52 65 61 6c 20 66 69 6c 65 73  Cwd.  Real files
cc60: 79 73 74 65 6d 73 20 73 68 6f 75 6c 64 0a 20 20  ystems should.  
cc70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cc80: 20 20 20 20 20 20 20 20 20 20 20 2a 20 63 61 72             * car
cc90: 72 79 20 6f 75 74 20 74 68 65 20 63 6f 72 72 65  ry out the corre
cca0: 63 74 20 61 63 74 69 6f 6e 20 28 69 2e 65 2e 20  ct action (i.e. 
ccb0: 63 61 6c 6c 0a 20 20 20 20 20 20 20 20 20 20 20  call.           
ccc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
ccd0: 20 20 2a 20 74 68 65 20 63 6f 72 72 65 63 74 20    * the correct 
cce0: 73 79 73 74 65 6d 20 27 63 68 64 69 72 27 20 61  system 'chdir' a
ccf0: 70 69 29 2e 20 20 49 66 20 6e 6f 74 0a 20 20 20  pi).  If not.   
cd00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cd10: 20 20 20 20 20 20 20 20 20 20 2a 20 69 6d 70 6c            * impl
cd20: 65 6d 65 6e 74 65 64 2c 20 74 68 65 6e 20 27 63  emented, then 'c
cd30: 64 27 20 61 6e 64 20 27 70 77 64 27 20 77 69 6c  d' and 'pwd' wil
cd40: 6c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  l.              
cd50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2a                 *
cd60: 20 66 61 69 6c 20 69 6e 73 69 64 65 20 74 68 65   fail inside the
cd70: 20 66 69 6c 65 73 79 73 74 65 6d 2e 0a 20 20 20   filesystem..   
cd80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cd90: 20 20 20 20 20 20 20 20 20 20 2a 2f 0a 7d 3b 0a            */.};.
cda0: 0a 76 6f 69 64 20 28 2a 5a 76 66 73 5f 50 6f 73  .void (*Zvfs_Pos
cdb0: 74 49 6e 69 74 29 28 54 63 6c 5f 49 6e 74 65 72  tInit)(Tcl_Inter
cdc0: 70 20 2a 29 3d 30 3b 0a 0a 69 6e 74 20 5a 76 66  p *)=0;..int Zvf
cdd0: 73 5f 43 6f 6d 6d 6f 6e 5f 49 6e 69 74 28 54 63  s_Common_Init(Tc
cde0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
cdf0: 29 20 7b 0a 20 20 69 66 28 20 21 6c 6f 63 61 6c  ) {.  if( !local
ce00: 2e 69 73 49 6e 69 74 20 29 7b 0a 20 20 20 20 2f  .isInit ){.    /
ce10: 2a 20 4f 6e 65 2d 74 69 6d 65 20 69 6e 69 74 69  * One-time initi
ce20: 61 6c 69 7a 61 74 69 6f 6e 20 6f 66 20 74 68 65  alization of the
ce30: 20 5a 56 46 53 20 2a 2f 0a 20 20 20 20 54 63 6c   ZVFS */.    Tcl
ce40: 5f 46 53 52 65 67 69 73 74 65 72 28 30 2c 20 26  _FSRegister(0, &
ce50: 54 6f 62 65 5f 46 69 6c 65 73 79 73 74 65 6d 29  Tobe_Filesystem)
ce60: 3b 0a 20 20 20 20 54 63 6c 5f 49 6e 69 74 48 61  ;.    Tcl_InitHa
ce70: 73 68 54 61 62 6c 65 28 26 6c 6f 63 61 6c 2e 66  shTable(&local.f
ce80: 69 6c 65 48 61 73 68 2c 20 54 43 4c 5f 53 54 52  ileHash, TCL_STR
ce90: 49 4e 47 5f 4b 45 59 53 29 3b 0a 20 20 20 20 54  ING_KEYS);.    T
cea0: 63 6c 5f 49 6e 69 74 48 61 73 68 54 61 62 6c 65  cl_InitHashTable
ceb0: 28 26 6c 6f 63 61 6c 2e 61 72 63 68 69 76 65 48  (&local.archiveH
cec0: 61 73 68 2c 20 54 43 4c 5f 53 54 52 49 4e 47 5f  ash, TCL_STRING_
ced0: 4b 45 59 53 29 3b 0a 20 20 20 20 6c 6f 63 61 6c  KEYS);.    local
cee0: 2e 69 73 49 6e 69 74 20 3d 20 31 3b 0a 20 20 7d  .isInit = 1;.  }
cef0: 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b  .  return TCL_OK
cf00: 3b 0a 7d 0a 0a 69 6e 74 20 5a 76 66 73 5f 49 6e  ;.}..int Zvfs_In
cf10: 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  it(Tcl_Interp *i
cf20: 6e 74 65 72 70 29 7b 0a 23 69 66 64 65 66 20 55  nterp){.#ifdef U
cf30: 53 45 5f 54 43 4c 5f 53 54 55 42 53 0a 20 20 69  SE_TCL_STUBS.  i
cf40: 66 28 20 54 63 6c 5f 49 6e 69 74 53 74 75 62 73  f( Tcl_InitStubs
cf50: 28 69 6e 74 65 72 70 2c 22 38 2e 30 22 2c 30 29  (interp,"8.0",0)
cf60: 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72  ==0 ){.    retur
cf70: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
cf80: 0a 23 65 6e 64 69 66 0a 20 20 54 63 6c 5f 50 6b  .#endif.  Tcl_Pk
cf90: 67 50 72 6f 76 69 64 65 28 69 6e 74 65 72 70 2c  gProvide(interp,
cfa0: 20 22 7a 76 66 73 22 2c 20 22 31 2e 30 22 29 3b   "zvfs", "1.0");
cfb0: 0a 20 20 5a 76 66 73 5f 43 6f 6d 6d 6f 6e 5f 49  .  Zvfs_Common_I
cfc0: 6e 69 74 28 69 6e 74 65 72 70 29 3b 0a 20 20 54  nit(interp);.  T
cfd0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
cfe0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 7a 76 66  and(interp, "zvf
cff0: 73 3a 3a 6d 6f 75 6e 74 22 2c 20 5a 76 66 73 4d  s::mount", ZvfsM
d000: 6f 75 6e 74 4f 62 6a 43 6d 64 2c 20 30 2c 20 30  ountObjCmd, 0, 0
d010: 29 3b 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f  );.  Tcl_CreateO
d020: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
d030: 2c 20 22 7a 76 66 73 3a 3a 75 6e 6d 6f 75 6e 74  , "zvfs::unmount
d040: 22 2c 20 5a 76 66 73 55 6e 6d 6f 75 6e 74 4f 62  ", ZvfsUnmountOb
d050: 6a 43 6d 64 2c 20 30 2c 20 30 29 3b 0a 20 20 54  jCmd, 0, 0);.  T
d060: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
d070: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 7a 76 66  and(interp, "zvf
d080: 73 3a 3a 65 78 69 73 74 73 22 2c 20 5a 76 66 73  s::exists", Zvfs
d090: 45 78 69 73 74 73 4f 62 6a 43 6d 64 2c 20 30 2c  ExistsObjCmd, 0,
d0a0: 20 30 29 3b 0a 20 20 54 63 6c 5f 43 72 65 61 74   0);.  Tcl_Creat
d0b0: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
d0c0: 72 70 2c 20 22 7a 76 66 73 3a 3a 69 6e 66 6f 22  rp, "zvfs::info"
d0d0: 2c 20 5a 76 66 73 49 6e 66 6f 4f 62 6a 43 6d 64  , ZvfsInfoObjCmd
d0e0: 2c 20 30 2c 20 30 29 3b 0a 20 20 54 63 6c 5f 43  , 0, 0);.  Tcl_C
d0f0: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
d100: 69 6e 74 65 72 70 2c 20 22 7a 76 66 73 3a 3a 6c  interp, "zvfs::l
d110: 69 73 74 22 2c 20 5a 76 66 73 4c 69 73 74 4f 62  ist", ZvfsListOb
d120: 6a 43 6d 64 2c 20 30 2c 20 30 29 3b 0a 20 20 69  jCmd, 0, 0);.  i
d130: 66 20 28 5a 76 66 73 5f 50 6f 73 74 49 6e 69 74  f (Zvfs_PostInit
d140: 29 20 5a 76 66 73 5f 50 6f 73 74 49 6e 69 74 28  ) Zvfs_PostInit(
d150: 69 6e 74 65 72 70 29 3b 0a 20 20 72 65 74 75 72  interp);.  retur
d160: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 69 6e 74  n TCL_OK;.}..int
d170: 20 5a 76 66 73 5f 53 61 66 65 49 6e 69 74 28 54   Zvfs_SafeInit(T
d180: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
d190: 70 29 7b 0a 23 69 66 64 65 66 20 55 53 45 5f 54  p){.#ifdef USE_T
d1a0: 43 4c 5f 53 54 55 42 53 0a 20 20 69 66 28 20 54  CL_STUBS.  if( T
d1b0: 63 6c 5f 49 6e 69 74 53 74 75 62 73 28 69 6e 74  cl_InitStubs(int
d1c0: 65 72 70 2c 22 38 2e 30 22 2c 30 29 3d 3d 30 20  erp,"8.0",0)==0 
d1d0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  ){.    return TC
d1e0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 23 65 6e  L_ERROR;.  }.#en
d1f0: 64 69 66 0a 20 20 5a 76 66 73 5f 43 6f 6d 6d 6f  dif.  Zvfs_Commo
d200: 6e 5f 49 6e 69 74 28 69 6e 74 65 72 70 29 3b 0a  n_Init(interp);.
d210: 20 20 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65    Tcl_PkgProvide
d220: 28 69 6e 74 65 72 70 2c 20 22 7a 76 66 73 22 2c  (interp, "zvfs",
d230: 20 22 31 2e 30 22 29 3b 0a 20 20 54 63 6c 5f 43   "1.0");.  Tcl_C
d240: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
d250: 69 6e 74 65 72 70 2c 20 22 7a 76 66 73 3a 3a 65  interp, "zvfs::e
d260: 78 69 73 74 73 22 2c 20 5a 76 66 73 45 78 69 73  xists", ZvfsExis
d270: 74 73 4f 62 6a 43 6d 64 2c 20 30 2c 20 30 29 3b  tsObjCmd, 0, 0);
d280: 0a 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  .  Tcl_CreateObj
d290: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
d2a0: 22 7a 76 66 73 3a 3a 69 6e 66 6f 22 2c 20 5a 76  "zvfs::info", Zv
d2b0: 66 73 49 6e 66 6f 4f 62 6a 43 6d 64 2c 20 30 2c  fsInfoObjCmd, 0,
d2c0: 20 30 29 3b 0a 20 20 54 63 6c 5f 43 72 65 61 74   0);.  Tcl_Creat
d2d0: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
d2e0: 72 70 2c 20 22 7a 76 66 73 3a 3a 6c 69 73 74 22  rp, "zvfs::list"
d2f0: 2c 20 5a 76 66 73 4c 69 73 74 4f 62 6a 43 6d 64  , ZvfsListObjCmd
d300: 2c 20 30 2c 20 30 29 3b 0a 20 20 69 66 20 28 5a  , 0, 0);.  if (Z
d310: 76 66 73 5f 50 6f 73 74 49 6e 69 74 29 20 5a 76  vfs_PostInit) Zv
d320: 66 73 5f 50 6f 73 74 49 6e 69 74 28 69 6e 74 65  fs_PostInit(inte
d330: 72 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43  rp);.  return TC
d340: 4c 5f 4f 4b 3b 0a 7d 0a 0a                       L_OK;.}..