/ Hex Artifact Content
Login

Artifact df57128d9ad2a1e60097d7971e787b582fb66ce0926577cb6f5978f7af210b8c:


0000: 2f 2a 0a 2a 2a 20 32 30 31 37 2d 31 32 2d 32 36  /*.** 2017-12-26
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20  file implements 
0190: 61 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20  a virtual table 
01a0: 66 6f 72 20 72 65 61 64 69 6e 67 20 61 6e 64 20  for reading and 
01b0: 77 72 69 74 69 6e 67 20 5a 49 50 20 61 72 63 68  writing ZIP arch
01c0: 69 76 65 0a 2a 2a 20 66 69 6c 65 73 2e 0a 2a 2a  ive.** files..**
01d0: 0a 2a 2a 20 55 73 61 67 65 20 65 78 61 6d 70 6c  .** Usage exampl
01e0: 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 53 45 4c  e:.**.**     SEL
01f0: 45 43 54 20 6e 61 6d 65 2c 20 73 7a 2c 20 64 61  ECT name, sz, da
0200: 74 65 74 69 6d 65 28 6d 74 69 6d 65 2c 27 75 6e  tetime(mtime,'un
0210: 69 78 65 70 6f 63 68 27 29 20 46 52 4f 4d 20 7a  ixepoch') FROM z
0220: 69 70 66 69 6c 65 28 24 66 69 6c 65 6e 61 6d 65  ipfile($filename
0230: 29 3b 0a 2a 2a 0a 2a 2a 20 43 75 72 72 65 6e 74  );.**.** Current
0240: 20 6c 69 6d 69 74 61 74 69 6f 6e 73 3a 0a 2a 2a   limitations:.**
0250: 0a 2a 2a 20 20 20 20 2a 20 20 4e 6f 20 73 75 70  .**    *  No sup
0260: 70 6f 72 74 20 66 6f 72 20 65 6e 63 72 79 70 74  port for encrypt
0270: 69 6f 6e 0a 2a 2a 20 20 20 20 2a 20 20 4e 6f 20  ion.**    *  No 
0280: 73 75 70 70 6f 72 74 20 66 6f 72 20 5a 49 50 20  support for ZIP 
0290: 61 72 63 68 69 76 65 73 20 73 70 61 6e 6e 69 6e  archives spannin
02a0: 67 20 6d 75 6c 74 69 70 6c 65 20 66 69 6c 65 73  g multiple files
02b0: 0a 2a 2a 20 20 20 20 2a 20 20 4e 6f 20 73 75 70  .**    *  No sup
02c0: 70 6f 72 74 20 66 6f 72 20 7a 69 70 36 34 20 65  port for zip64 e
02d0: 78 74 65 6e 73 69 6f 6e 73 0a 2a 2a 20 20 20 20  xtensions.**    
02e0: 2a 20 20 4f 6e 6c 79 20 74 68 65 20 22 69 6e 66  *  Only the "inf
02f0: 6c 61 74 65 2f 64 65 66 6c 61 74 65 22 20 28 7a  late/deflate" (z
0300: 6c 69 62 29 20 63 6f 6d 70 72 65 73 73 69 6f 6e  lib) compression
0310: 20 6d 65 74 68 6f 64 20 69 73 20 73 75 70 70 6f   method is suppo
0320: 72 74 65 64 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  rted.*/.#include
0330: 20 22 73 71 6c 69 74 65 33 65 78 74 2e 68 22 0a   "sqlite3ext.h".
0340: 53 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e  SQLITE_EXTENSION
0350: 5f 49 4e 49 54 31 0a 23 69 6e 63 6c 75 64 65 20  _INIT1.#include 
0360: 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75  <stdio.h>.#inclu
0370: 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69  de <string.h>.#i
0380: 6e 63 6c 75 64 65 20 3c 61 73 73 65 72 74 2e 68  nclude <assert.h
0390: 3e 0a 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 73  >..#include <sys
03a0: 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c 75  /types.h>.#inclu
03b0: 64 65 20 3c 73 79 73 2f 73 74 61 74 2e 68 3e 0a  de <sys/stat.h>.
03c0: 23 69 6e 63 6c 75 64 65 20 3c 66 63 6e 74 6c 2e  #include <fcntl.
03d0: 68 3e 0a 23 69 66 20 21 64 65 66 69 6e 65 64 28  h>.#if !defined(
03e0: 5f 57 49 4e 33 32 29 20 26 26 20 21 64 65 66 69  _WIN32) && !defi
03f0: 6e 65 64 28 57 49 4e 33 32 29 0a 23 20 20 69 6e  ned(WIN32).#  in
0400: 63 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e 68 3e  clude <unistd.h>
0410: 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 64 69 72  .#  include <dir
0420: 65 6e 74 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64  ent.h>.#  includ
0430: 65 20 3c 75 74 69 6d 65 2e 68 3e 0a 23 65 6c 73  e <utime.h>.#els
0440: 65 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 69 6f  e.#  include <io
0450: 2e 68 3e 0a 23 65 6e 64 69 66 0a 23 69 6e 63 6c  .h>.#endif.#incl
0460: 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a 23 69 6e  ude <time.h>.#in
0470: 63 6c 75 64 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a  clude <errno.h>.
0480: 0a 23 69 6e 63 6c 75 64 65 20 3c 7a 6c 69 62 2e  .#include <zlib.
0490: 68 3e 0a 0a 23 69 66 6e 64 65 66 20 53 51 4c 49  h>..#ifndef SQLI
04a0: 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54  TE_OMIT_VIRTUALT
04b0: 41 42 4c 45 0a 0a 23 69 66 6e 64 65 66 20 53 51  ABLE..#ifndef SQ
04c0: 4c 49 54 45 5f 41 4d 41 4c 47 41 4d 41 54 49 4f  LITE_AMALGAMATIO
04d0: 4e 0a 74 79 70 65 64 65 66 20 73 71 6c 69 74 65  N.typedef sqlite
04e0: 33 5f 69 6e 74 36 34 20 69 36 34 3b 0a 74 79 70  3_int64 i64;.typ
04f0: 65 64 65 66 20 75 6e 73 69 67 6e 65 64 20 63 68  edef unsigned ch
0500: 61 72 20 75 38 3b 0a 74 79 70 65 64 65 66 20 75  ar u8;.typedef u
0510: 6e 73 69 67 6e 65 64 20 73 68 6f 72 74 20 75 31  nsigned short u1
0520: 36 3b 0a 74 79 70 65 64 65 66 20 75 6e 73 69 67  6;.typedef unsig
0530: 6e 65 64 20 6c 6f 6e 67 20 75 33 32 3b 0a 23 64  ned long u32;.#d
0540: 65 66 69 6e 65 20 4d 49 4e 28 61 2c 62 29 20 28  efine MIN(a,b) (
0550: 28 61 29 3c 28 62 29 20 3f 20 28 61 29 20 3a 20  (a)<(b) ? (a) : 
0560: 28 62 29 29 0a 23 65 6e 64 69 66 0a 0a 73 74 61  (b)).#endif..sta
0570: 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 5a  tic const char Z
0580: 49 50 46 49 4c 45 5f 53 43 48 45 4d 41 5b 5d 20  IPFILE_SCHEMA[] 
0590: 3d 20 0a 20 20 22 43 52 45 41 54 45 20 54 41 42  = .  "CREATE TAB
05a0: 4c 45 20 79 28 22 0a 20 20 20 20 22 6e 61 6d 65  LE y(".    "name
05b0: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 22 20 20   PRIMARY KEY,"  
05c0: 2f 2a 20 30 3a 20 4e 61 6d 65 20 6f 66 20 66 69  /* 0: Name of fi
05d0: 6c 65 20 69 6e 20 7a 69 70 20 61 72 63 68 69 76  le in zip archiv
05e0: 65 20 2a 2f 0a 20 20 20 20 22 6d 6f 64 65 2c 22  e */.    "mode,"
05f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0600: 20 31 3a 20 50 4f 53 49 58 20 6d 6f 64 65 20 66   1: POSIX mode f
0610: 6f 72 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 22  or file */.    "
0620: 6d 74 69 6d 65 2c 22 20 20 20 20 20 20 20 20 20  mtime,"         
0630: 20 20 20 20 2f 2a 20 32 3a 20 4c 61 73 74 20 6d      /* 2: Last m
0640: 6f 64 69 66 69 63 61 74 69 6f 6e 20 74 69 6d 65  odification time
0650: 20 28 73 65 63 73 20 73 69 6e 63 65 20 31 39 37   (secs since 197
0660: 30 29 2a 2f 0a 20 20 20 20 22 73 7a 2c 22 20 20  0)*/.    "sz,"  
0670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0680: 20 33 3a 20 53 69 7a 65 20 6f 66 20 6f 62 6a 65   3: Size of obje
0690: 63 74 20 2a 2f 0a 20 20 20 20 22 72 61 77 64 61  ct */.    "rawda
06a0: 74 61 2c 22 20 20 20 20 20 20 20 20 20 20 20 2f  ta,"           /
06b0: 2a 20 34 3a 20 52 61 77 20 64 61 74 61 20 2a 2f  * 4: Raw data */
06c0: 0a 20 20 20 20 22 64 61 74 61 2c 22 20 20 20 20  .    "data,"    
06d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 35 3a 20            /* 5: 
06e0: 55 6e 63 6f 6d 70 72 65 73 73 65 64 20 64 61 74  Uncompressed dat
06f0: 61 20 2a 2f 0a 20 20 20 20 22 6d 65 74 68 6f 64  a */.    "method
0700: 2c 22 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ,"            /*
0710: 20 36 3a 20 43 6f 6d 70 72 65 73 73 69 6f 6e 20   6: Compression 
0720: 6d 65 74 68 6f 64 20 28 69 6e 74 65 67 65 72 29  method (integer)
0730: 20 2a 2f 0a 20 20 20 20 22 7a 20 48 49 44 44 45   */.    "z HIDDE
0740: 4e 22 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  N"           /* 
0750: 37 3a 20 4e 61 6d 65 20 6f 66 20 7a 69 70 20 66  7: Name of zip f
0760: 69 6c 65 20 2a 2f 0a 20 20 22 29 20 57 49 54 48  ile */.  ") WITH
0770: 4f 55 54 20 52 4f 57 49 44 3b 22 3b 0a 0a 23 64  OUT ROWID;";..#d
0780: 65 66 69 6e 65 20 5a 49 50 46 49 4c 45 5f 46 5f  efine ZIPFILE_F_
0790: 43 4f 4c 55 4d 4e 5f 49 44 58 20 37 20 20 20 20  COLUMN_IDX 7    
07a0: 2f 2a 20 49 6e 64 65 78 20 6f 66 20 63 6f 6c 75  /* Index of colu
07b0: 6d 6e 20 22 66 69 6c 65 22 20 69 6e 20 74 68 65  mn "file" in the
07c0: 20 61 62 6f 76 65 20 2a 2f 0a 23 64 65 66 69 6e   above */.#defin
07d0: 65 20 5a 49 50 46 49 4c 45 5f 42 55 46 46 45 52  e ZIPFILE_BUFFER
07e0: 5f 53 49 5a 45 20 28 36 34 2a 31 30 32 34 29 0a  _SIZE (64*1024).
07f0: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 67 69 63 20 6e 75  ../*.** Magic nu
0800: 6d 62 65 72 73 20 75 73 65 64 20 74 6f 20 72 65  mbers used to re
0810: 61 64 20 61 6e 64 20 77 72 69 74 65 20 7a 69 70  ad and write zip
0820: 20 66 69 6c 65 73 2e 0a 2a 2a 0a 2a 2a 20 5a 49   files..**.** ZI
0830: 50 46 49 4c 45 5f 4e 45 57 45 4e 54 52 59 5f 4d  PFILE_NEWENTRY_M
0840: 41 44 45 42 59 3a 0a 2a 2a 20 20 20 55 73 65 20  ADEBY:.**   Use 
0850: 74 68 69 73 20 76 61 6c 75 65 20 66 6f 72 20 74  this value for t
0860: 68 65 20 22 76 65 72 73 69 6f 6e 2d 6d 61 64 65  he "version-made
0870: 2d 62 79 22 20 66 69 65 6c 64 20 69 6e 20 6e 65  -by" field in ne
0880: 77 20 7a 69 70 20 66 69 6c 65 0a 2a 2a 20 20 20  w zip file.**   
0890: 65 6e 74 72 69 65 73 2e 20 54 68 65 20 75 70 70  entries. The upp
08a0: 65 72 20 62 79 74 65 20 69 6e 64 69 63 61 74 65  er byte indicate
08b0: 73 20 22 75 6e 69 78 22 2c 20 61 6e 64 20 74 68  s "unix", and th
08c0: 65 20 6c 6f 77 65 72 20 62 79 74 65 20 0a 2a 2a  e lower byte .**
08d0: 20 20 20 69 6e 64 69 63 61 74 65 73 20 74 68 61     indicates tha
08e0: 74 20 74 68 65 20 7a 69 70 20 66 69 6c 65 20 6d  t the zip file m
08f0: 61 74 63 68 65 73 20 70 6b 7a 69 70 20 73 70 65  atches pkzip spe
0900: 63 69 66 69 63 61 74 69 6f 6e 20 33 2e 30 2e 20  cification 3.0. 
0910: 0a 2a 2a 20 20 20 54 68 69 73 20 69 73 20 77 68  .**   This is wh
0920: 61 74 20 69 6e 66 6f 2d 7a 69 70 20 73 65 65 6d  at info-zip seem
0930: 73 20 74 6f 20 64 6f 2e 0a 2a 2a 0a 2a 2a 20 5a  s to do..**.** Z
0940: 49 50 46 49 4c 45 5f 4e 45 57 45 4e 54 52 59 5f  IPFILE_NEWENTRY_
0950: 52 45 51 55 49 52 45 44 3a 0a 2a 2a 20 20 20 56  REQUIRED:.**   V
0960: 61 6c 75 65 20 66 6f 72 20 22 76 65 72 73 69 6f  alue for "versio
0970: 6e 2d 72 65 71 75 69 72 65 64 2d 74 6f 2d 65 78  n-required-to-ex
0980: 74 72 61 63 74 22 20 66 69 65 6c 64 20 6f 66 20  tract" field of 
0990: 6e 65 77 20 65 6e 74 72 69 65 73 2e 0a 2a 2a 20  new entries..** 
09a0: 20 20 56 65 72 73 69 6f 6e 20 32 2e 30 20 69 73    Version 2.0 is
09b0: 20 72 65 71 75 69 72 65 64 20 74 6f 20 73 75 70   required to sup
09c0: 70 6f 72 74 20 66 6f 6c 64 65 72 73 20 61 6e 64  port folders and
09d0: 20 64 65 66 6c 61 74 65 20 63 6f 6d 70 72 65 73   deflate compres
09e0: 73 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 5a 49 50 46  sion..**.** ZIPF
09f0: 49 4c 45 5f 4e 45 57 45 4e 54 52 59 5f 46 4c 41  ILE_NEWENTRY_FLA
0a00: 47 53 3a 0a 2a 2a 20 20 20 56 61 6c 75 65 20 66  GS:.**   Value f
0a10: 6f 72 20 22 67 65 6e 65 72 61 6c 2d 70 75 72 70  or "general-purp
0a20: 6f 73 65 2d 62 69 74 2d 66 6c 61 67 73 22 20 66  ose-bit-flags" f
0a30: 69 65 6c 64 20 6f 66 20 6e 65 77 20 65 6e 74 72  ield of new entr
0a40: 69 65 73 2e 20 42 69 74 0a 2a 2a 20 20 20 31 31  ies. Bit.**   11
0a50: 20 6d 65 61 6e 73 20 22 75 74 66 2d 38 20 66 69   means "utf-8 fi
0a60: 6c 65 6e 61 6d 65 20 61 6e 64 20 63 6f 6d 6d 65  lename and comme
0a70: 6e 74 22 2e 0a 2a 2a 0a 2a 2a 20 5a 49 50 46 49  nt"..**.** ZIPFI
0a80: 4c 45 5f 53 49 47 4e 41 54 55 52 45 5f 43 44 53  LE_SIGNATURE_CDS
0a90: 3a 0a 2a 2a 20 20 20 46 69 72 73 74 20 34 20 62  :.**   First 4 b
0aa0: 79 74 65 73 20 6f 66 20 61 20 76 61 6c 69 64 20  ytes of a valid 
0ab0: 43 44 53 20 72 65 63 6f 72 64 2e 0a 2a 2a 0a 2a  CDS record..**.*
0ac0: 2a 20 5a 49 50 46 49 4c 45 5f 53 49 47 4e 41 54  * ZIPFILE_SIGNAT
0ad0: 55 52 45 5f 4c 46 48 3a 0a 2a 2a 20 20 20 46 69  URE_LFH:.**   Fi
0ae0: 72 73 74 20 34 20 62 79 74 65 73 20 6f 66 20 61  rst 4 bytes of a
0af0: 20 76 61 6c 69 64 20 4c 46 48 20 72 65 63 6f 72   valid LFH recor
0b00: 64 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 5a 49  d..*/.#define ZI
0b10: 50 46 49 4c 45 5f 45 58 54 52 41 5f 54 49 4d 45  PFILE_EXTRA_TIME
0b20: 53 54 41 4d 50 20 20 20 30 78 35 34 35 35 0a 23  STAMP   0x5455.#
0b30: 64 65 66 69 6e 65 20 5a 49 50 46 49 4c 45 5f 4e  define ZIPFILE_N
0b40: 45 57 45 4e 54 52 59 5f 4d 41 44 45 42 59 20 20  EWENTRY_MADEBY  
0b50: 20 28 28 33 3c 3c 38 29 20 2b 20 33 30 29 0a 23   ((3<<8) + 30).#
0b60: 64 65 66 69 6e 65 20 5a 49 50 46 49 4c 45 5f 4e  define ZIPFILE_N
0b70: 45 57 45 4e 54 52 59 5f 52 45 51 55 49 52 45 44  EWENTRY_REQUIRED
0b80: 20 32 30 0a 23 64 65 66 69 6e 65 20 5a 49 50 46   20.#define ZIPF
0b90: 49 4c 45 5f 4e 45 57 45 4e 54 52 59 5f 46 4c 41  ILE_NEWENTRY_FLA
0ba0: 47 53 20 20 20 20 30 78 38 30 30 0a 23 64 65 66  GS    0x800.#def
0bb0: 69 6e 65 20 5a 49 50 46 49 4c 45 5f 53 49 47 4e  ine ZIPFILE_SIGN
0bc0: 41 54 55 52 45 5f 43 44 53 20 20 20 20 20 30 78  ATURE_CDS     0x
0bd0: 30 32 30 31 34 62 35 30 0a 23 64 65 66 69 6e 65  02014b50.#define
0be0: 20 5a 49 50 46 49 4c 45 5f 53 49 47 4e 41 54 55   ZIPFILE_SIGNATU
0bf0: 52 45 5f 4c 46 48 20 20 20 20 20 30 78 30 34 30  RE_LFH     0x040
0c00: 33 34 62 35 30 0a 23 64 65 66 69 6e 65 20 5a 49  34b50.#define ZI
0c10: 50 46 49 4c 45 5f 53 49 47 4e 41 54 55 52 45 5f  PFILE_SIGNATURE_
0c20: 45 4f 43 44 20 20 20 20 30 78 30 36 30 35 34 62  EOCD    0x06054b
0c30: 35 30 0a 23 64 65 66 69 6e 65 20 5a 49 50 46 49  50.#define ZIPFI
0c40: 4c 45 5f 4c 46 48 5f 46 49 58 45 44 5f 53 5a 20  LE_LFH_FIXED_SZ 
0c50: 20 20 20 20 20 33 30 0a 0a 23 64 65 66 69 6e 65       30..#define
0c60: 20 5a 49 50 46 49 4c 45 5f 45 4f 43 44 5f 46 49   ZIPFILE_EOCD_FI
0c70: 58 45 44 5f 53 5a 20 20 20 20 20 32 32 0a 0a 2f  XED_SZ     22../
0c80: 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 65 72 72  *.** Set the err
0c90: 6f 72 20 6d 65 73 73 61 67 65 20 63 6f 6e 74 61  or message conta
0ca0: 69 6e 65 64 20 69 6e 20 63 6f 6e 74 65 78 74 20  ined in context 
0cb0: 63 74 78 20 74 6f 20 74 68 65 20 72 65 73 75 6c  ctx to the resul
0cc0: 74 73 20 6f 66 0a 2a 2a 20 76 70 72 69 6e 74 66  ts of.** vprintf
0cd0: 28 7a 46 6d 74 2c 20 2e 2e 2e 29 2e 0a 2a 2f 0a  (zFmt, ...)..*/.
0ce0: 73 74 61 74 69 63 20 76 6f 69 64 20 7a 69 70 66  static void zipf
0cf0: 69 6c 65 43 74 78 45 72 72 6f 72 4d 73 67 28 73  ileCtxErrorMsg(s
0d00: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
0d10: 63 74 78 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  ctx, const char 
0d20: 2a 7a 46 6d 74 2c 20 2e 2e 2e 29 7b 0a 20 20 63  *zFmt, ...){.  c
0d30: 68 61 72 20 2a 7a 4d 73 67 20 3d 20 30 3b 0a 20  har *zMsg = 0;. 
0d40: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76   va_list ap;.  v
0d50: 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6d 74  a_start(ap, zFmt
0d60: 29 3b 0a 20 20 7a 4d 73 67 20 3d 20 73 71 6c 69  );.  zMsg = sqli
0d70: 74 65 33 5f 76 6d 70 72 69 6e 74 66 28 7a 46 6d  te3_vmprintf(zFm
0d80: 74 2c 20 61 70 29 3b 0a 20 20 73 71 6c 69 74 65  t, ap);.  sqlite
0d90: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 63  3_result_error(c
0da0: 74 78 2c 20 7a 4d 73 67 2c 20 2d 31 29 3b 0a 20  tx, zMsg, -1);. 
0db0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 4d   sqlite3_free(zM
0dc0: 73 67 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70  sg);.  va_end(ap
0dd0: 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 2a 20 34 2e  );.}.../*.*** 4.
0de0: 33 2e 31 36 20 20 45 6e 64 20 6f 66 20 63 65 6e  3.16  End of cen
0df0: 74 72 61 6c 20 64 69 72 65 63 74 6f 72 79 20 72  tral directory r
0e00: 65 63 6f 72 64 3a 0a 2a 2a 2a 0a 2a 2a 2a 20 20  ecord:.***.***  
0e10: 20 65 6e 64 20 6f 66 20 63 65 6e 74 72 61 6c 20   end of central 
0e20: 64 69 72 20 73 69 67 6e 61 74 75 72 65 20 20 20  dir signature   
0e30: 20 34 20 62 79 74 65 73 20 20 28 30 78 30 36 30   4 bytes  (0x060
0e40: 35 34 62 35 30 29 0a 2a 2a 2a 20 20 20 6e 75 6d  54b50).***   num
0e50: 62 65 72 20 6f 66 20 74 68 69 73 20 64 69 73 6b  ber of this disk
0e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 32 20 62               2 b
0e70: 79 74 65 73 0a 2a 2a 2a 20 20 20 6e 75 6d 62 65  ytes.***   numbe
0e80: 72 20 6f 66 20 74 68 65 20 64 69 73 6b 20 77 69  r of the disk wi
0e90: 74 68 20 74 68 65 0a 2a 2a 2a 20 20 20 73 74 61  th the.***   sta
0ea0: 72 74 20 6f 66 20 74 68 65 20 63 65 6e 74 72 61  rt of the centra
0eb0: 6c 20 64 69 72 65 63 74 6f 72 79 20 20 32 20 62  l directory  2 b
0ec0: 79 74 65 73 0a 2a 2a 2a 20 20 20 74 6f 74 61 6c  ytes.***   total
0ed0: 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69   number of entri
0ee0: 65 73 20 69 6e 20 74 68 65 0a 2a 2a 2a 20 20 20  es in the.***   
0ef0: 63 65 6e 74 72 61 6c 20 64 69 72 65 63 74 6f 72  central director
0f00: 79 20 6f 6e 20 74 68 69 73 20 64 69 73 6b 20 20  y on this disk  
0f10: 32 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20 74 6f  2 bytes.***   to
0f20: 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e  tal number of en
0f30: 74 72 69 65 73 20 69 6e 0a 2a 2a 2a 20 20 20 74  tries in.***   t
0f40: 68 65 20 63 65 6e 74 72 61 6c 20 64 69 72 65 63  he central direc
0f50: 74 6f 72 79 20 20 20 20 20 20 20 20 20 20 20 32  tory           2
0f60: 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20 73 69 7a   bytes.***   siz
0f70: 65 20 6f 66 20 74 68 65 20 63 65 6e 74 72 61 6c  e of the central
0f80: 20 64 69 72 65 63 74 6f 72 79 20 20 20 34 20 62   directory   4 b
0f90: 79 74 65 73 0a 2a 2a 2a 20 20 20 6f 66 66 73 65  ytes.***   offse
0fa0: 74 20 6f 66 20 73 74 61 72 74 20 6f 66 20 63 65  t of start of ce
0fb0: 6e 74 72 61 6c 0a 2a 2a 2a 20 20 20 64 69 72 65  ntral.***   dire
0fc0: 63 74 6f 72 79 20 77 69 74 68 20 72 65 73 70 65  ctory with respe
0fd0: 63 74 20 74 6f 0a 2a 2a 2a 20 20 20 74 68 65 20  ct to.***   the 
0fe0: 73 74 61 72 74 69 6e 67 20 64 69 73 6b 20 6e 75  starting disk nu
0ff0: 6d 62 65 72 20 20 20 20 20 20 20 20 34 20 62 79  mber        4 by
1000: 74 65 73 0a 2a 2a 2a 20 20 20 2e 5a 49 50 20 66  tes.***   .ZIP f
1010: 69 6c 65 20 63 6f 6d 6d 65 6e 74 20 6c 65 6e 67  ile comment leng
1020: 74 68 20 20 20 20 20 20 20 20 32 20 62 79 74 65  th        2 byte
1030: 73 0a 2a 2a 2a 20 20 20 2e 5a 49 50 20 66 69 6c  s.***   .ZIP fil
1040: 65 20 63 6f 6d 6d 65 6e 74 20 20 20 20 20 20 20  e comment       
1050: 28 76 61 72 69 61 62 6c 65 20 73 69 7a 65 29 0a  (variable size).
1060: 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  */.typedef struc
1070: 74 20 5a 69 70 66 69 6c 65 45 4f 43 44 20 5a 69  t ZipfileEOCD Zi
1080: 70 66 69 6c 65 45 4f 43 44 3b 0a 73 74 72 75 63  pfileEOCD;.struc
1090: 74 20 5a 69 70 66 69 6c 65 45 4f 43 44 20 7b 0a  t ZipfileEOCD {.
10a0: 20 20 75 31 36 20 69 44 69 73 6b 3b 0a 20 20 75    u16 iDisk;.  u
10b0: 31 36 20 69 46 69 72 73 74 44 69 73 6b 3b 0a 20  16 iFirstDisk;. 
10c0: 20 75 31 36 20 6e 45 6e 74 72 79 3b 0a 20 20 75   u16 nEntry;.  u
10d0: 31 36 20 6e 45 6e 74 72 79 54 6f 74 61 6c 3b 0a  16 nEntryTotal;.
10e0: 20 20 75 33 32 20 6e 53 69 7a 65 3b 0a 20 20 75    u32 nSize;.  u
10f0: 33 32 20 69 4f 66 66 73 65 74 3b 0a 7d 3b 0a 0a  32 iOffset;.};..
1100: 2f 2a 0a 2a 2a 2a 20 34 2e 33 2e 31 32 20 20 43  /*.*** 4.3.12  C
1110: 65 6e 74 72 61 6c 20 64 69 72 65 63 74 6f 72 79  entral directory
1120: 20 73 74 72 75 63 74 75 72 65 3a 0a 2a 2a 2a 0a   structure:.***.
1130: 2a 2a 2a 20 2e 2e 2e 0a 2a 2a 2a 0a 2a 2a 2a 20  *** ....***.*** 
1140: 20 20 63 65 6e 74 72 61 6c 20 66 69 6c 65 20 68    central file h
1150: 65 61 64 65 72 20 73 69 67 6e 61 74 75 72 65 20  eader signature 
1160: 20 20 34 20 62 79 74 65 73 20 20 28 30 78 30 32    4 bytes  (0x02
1170: 30 31 34 62 35 30 29 0a 2a 2a 2a 20 20 20 76 65  014b50).***   ve
1180: 72 73 69 6f 6e 20 6d 61 64 65 20 62 79 20 20 20  rsion made by   
1190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 32 20                2 
11a0: 62 79 74 65 73 0a 2a 2a 2a 20 20 20 76 65 72 73  bytes.***   vers
11b0: 69 6f 6e 20 6e 65 65 64 65 64 20 74 6f 20 65 78  ion needed to ex
11c0: 74 72 61 63 74 20 20 20 20 20 20 20 32 20 62 79  tract       2 by
11d0: 74 65 73 0a 2a 2a 2a 20 20 20 67 65 6e 65 72 61  tes.***   genera
11e0: 6c 20 70 75 72 70 6f 73 65 20 62 69 74 20 66 6c  l purpose bit fl
11f0: 61 67 20 20 20 20 20 20 20 20 32 20 62 79 74 65  ag        2 byte
1200: 73 0a 2a 2a 2a 20 20 20 63 6f 6d 70 72 65 73 73  s.***   compress
1210: 69 6f 6e 20 6d 65 74 68 6f 64 20 20 20 20 20 20  ion method      
1220: 20 20 20 20 20 20 20 20 32 20 62 79 74 65 73 0a          2 bytes.
1230: 2a 2a 2a 20 20 20 6c 61 73 74 20 6d 6f 64 20 66  ***   last mod f
1240: 69 6c 65 20 74 69 6d 65 20 20 20 20 20 20 20 20  ile time        
1250: 20 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a        2 bytes.**
1260: 2a 20 20 20 6c 61 73 74 20 6d 6f 64 20 66 69 6c  *   last mod fil
1270: 65 20 64 61 74 65 20 20 20 20 20 20 20 20 20 20  e date          
1280: 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a 2a 20      2 bytes.*** 
1290: 20 20 63 72 63 2d 33 32 20 20 20 20 20 20 20 20    crc-32        
12a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12b0: 20 20 34 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20    4 bytes.***   
12c0: 63 6f 6d 70 72 65 73 73 65 64 20 73 69 7a 65 20  compressed size 
12d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
12e0: 34 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20 75 6e  4 bytes.***   un
12f0: 63 6f 6d 70 72 65 73 73 65 64 20 73 69 7a 65 20  compressed size 
1300: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 34 20                4 
1310: 62 79 74 65 73 0a 2a 2a 2a 20 20 20 66 69 6c 65  bytes.***   file
1320: 20 6e 61 6d 65 20 6c 65 6e 67 74 68 20 20 20 20   name length    
1330: 20 20 20 20 20 20 20 20 20 20 20 20 32 20 62 79              2 by
1340: 74 65 73 0a 2a 2a 2a 20 20 20 65 78 74 72 61 20  tes.***   extra 
1350: 66 69 65 6c 64 20 6c 65 6e 67 74 68 20 20 20 20  field length    
1360: 20 20 20 20 20 20 20 20 20 20 32 20 62 79 74 65            2 byte
1370: 73 0a 2a 2a 2a 20 20 20 66 69 6c 65 20 63 6f 6d  s.***   file com
1380: 6d 65 6e 74 20 6c 65 6e 67 74 68 20 20 20 20 20  ment length     
1390: 20 20 20 20 20 20 20 20 32 20 62 79 74 65 73 0a          2 bytes.
13a0: 2a 2a 2a 20 20 20 64 69 73 6b 20 6e 75 6d 62 65  ***   disk numbe
13b0: 72 20 73 74 61 72 74 20 20 20 20 20 20 20 20 20  r start         
13c0: 20 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a        2 bytes.**
13d0: 2a 20 20 20 69 6e 74 65 72 6e 61 6c 20 66 69 6c  *   internal fil
13e0: 65 20 61 74 74 72 69 62 75 74 65 73 20 20 20 20  e attributes    
13f0: 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a 2a 20      2 bytes.*** 
1400: 20 20 65 78 74 65 72 6e 61 6c 20 66 69 6c 65 20    external file 
1410: 61 74 74 72 69 62 75 74 65 73 20 20 20 20 20 20  attributes      
1420: 20 20 34 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20    4 bytes.***   
1430: 72 65 6c 61 74 69 76 65 20 6f 66 66 73 65 74 20  relative offset 
1440: 6f 66 20 6c 6f 63 61 6c 20 68 65 61 64 65 72 20  of local header 
1450: 34 20 62 79 74 65 73 0a 2a 2f 0a 74 79 70 65 64  4 bytes.*/.typed
1460: 65 66 20 73 74 72 75 63 74 20 5a 69 70 66 69 6c  ef struct Zipfil
1470: 65 43 44 53 20 5a 69 70 66 69 6c 65 43 44 53 3b  eCDS ZipfileCDS;
1480: 0a 73 74 72 75 63 74 20 5a 69 70 66 69 6c 65 43  .struct ZipfileC
1490: 44 53 20 7b 0a 20 20 75 31 36 20 69 56 65 72 73  DS {.  u16 iVers
14a0: 69 6f 6e 4d 61 64 65 42 79 3b 0a 20 20 75 31 36  ionMadeBy;.  u16
14b0: 20 69 56 65 72 73 69 6f 6e 45 78 74 72 61 63 74   iVersionExtract
14c0: 3b 0a 20 20 75 31 36 20 66 6c 61 67 73 3b 0a 20  ;.  u16 flags;. 
14d0: 20 75 31 36 20 69 43 6f 6d 70 72 65 73 73 69 6f   u16 iCompressio
14e0: 6e 3b 0a 20 20 75 31 36 20 6d 54 69 6d 65 3b 0a  n;.  u16 mTime;.
14f0: 20 20 75 31 36 20 6d 44 61 74 65 3b 0a 20 20 75    u16 mDate;.  u
1500: 33 32 20 63 72 63 33 32 3b 0a 20 20 75 33 32 20  32 crc32;.  u32 
1510: 73 7a 43 6f 6d 70 72 65 73 73 65 64 3b 0a 20 20  szCompressed;.  
1520: 75 33 32 20 73 7a 55 6e 63 6f 6d 70 72 65 73 73  u32 szUncompress
1530: 65 64 3b 0a 20 20 75 31 36 20 6e 46 69 6c 65 3b  ed;.  u16 nFile;
1540: 0a 20 20 75 31 36 20 6e 45 78 74 72 61 3b 0a 20  .  u16 nExtra;. 
1550: 20 75 31 36 20 6e 43 6f 6d 6d 65 6e 74 3b 0a 20   u16 nComment;. 
1560: 20 75 31 36 20 69 44 69 73 6b 53 74 61 72 74 3b   u16 iDiskStart;
1570: 0a 20 20 75 31 36 20 69 49 6e 74 65 72 6e 61 6c  .  u16 iInternal
1580: 41 74 74 72 3b 0a 20 20 75 33 32 20 69 45 78 74  Attr;.  u32 iExt
1590: 65 72 6e 61 6c 41 74 74 72 3b 0a 20 20 75 33 32  ernalAttr;.  u32
15a0: 20 69 4f 66 66 73 65 74 3b 0a 20 20 63 68 61 72   iOffset;.  char
15b0: 20 2a 7a 46 69 6c 65 3b 20 20 20 20 20 20 20 20   *zFile;        
15c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
15d0: 69 6c 65 6e 61 6d 65 20 28 73 71 6c 69 74 65 33  ilename (sqlite3
15e0: 5f 6d 61 6c 6c 6f 63 28 29 29 20 2a 2f 0a 7d 3b  _malloc()) */.};
15f0: 0a 0a 2f 2a 0a 2a 2a 2a 20 34 2e 33 2e 37 20 20  ../*.*** 4.3.7  
1600: 4c 6f 63 61 6c 20 66 69 6c 65 20 68 65 61 64 65  Local file heade
1610: 72 3a 0a 2a 2a 2a 0a 2a 2a 2a 20 20 20 6c 6f 63  r:.***.***   loc
1620: 61 6c 20 66 69 6c 65 20 68 65 61 64 65 72 20 73  al file header s
1630: 69 67 6e 61 74 75 72 65 20 20 20 20 20 34 20 62  ignature     4 b
1640: 79 74 65 73 20 20 28 30 78 30 34 30 33 34 62 35  ytes  (0x04034b5
1650: 30 29 0a 2a 2a 2a 20 20 20 76 65 72 73 69 6f 6e  0).***   version
1660: 20 6e 65 65 64 65 64 20 74 6f 20 65 78 74 72 61   needed to extra
1670: 63 74 20 20 20 20 20 20 20 32 20 62 79 74 65 73  ct       2 bytes
1680: 0a 2a 2a 2a 20 20 20 67 65 6e 65 72 61 6c 20 70  .***   general p
1690: 75 72 70 6f 73 65 20 62 69 74 20 66 6c 61 67 20  urpose bit flag 
16a0: 20 20 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a         2 bytes.*
16b0: 2a 2a 20 20 20 63 6f 6d 70 72 65 73 73 69 6f 6e  **   compression
16c0: 20 6d 65 74 68 6f 64 20 20 20 20 20 20 20 20 20   method         
16d0: 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a 2a       2 bytes.***
16e0: 20 20 20 6c 61 73 74 20 6d 6f 64 20 66 69 6c 65     last mod file
16f0: 20 74 69 6d 65 20 20 20 20 20 20 20 20 20 20 20   time           
1700: 20 20 20 32 20 62 79 74 65 73 0a 2a 2a 2a 20 20     2 bytes.***  
1710: 20 6c 61 73 74 20 6d 6f 64 20 66 69 6c 65 20 64   last mod file d
1720: 61 74 65 20 20 20 20 20 20 20 20 20 20 20 20 20  ate             
1730: 20 32 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20 63   2 bytes.***   c
1740: 72 63 2d 33 32 20 20 20 20 20 20 20 20 20 20 20  rc-32           
1750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 34                 4
1760: 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20 63 6f 6d   bytes.***   com
1770: 70 72 65 73 73 65 64 20 73 69 7a 65 20 20 20 20  pressed size    
1780: 20 20 20 20 20 20 20 20 20 20 20 20 20 34 20 62               4 b
1790: 79 74 65 73 0a 2a 2a 2a 20 20 20 75 6e 63 6f 6d  ytes.***   uncom
17a0: 70 72 65 73 73 65 64 20 73 69 7a 65 20 20 20 20  pressed size    
17b0: 20 20 20 20 20 20 20 20 20 20 20 34 20 62 79 74             4 byt
17c0: 65 73 0a 2a 2a 2a 20 20 20 66 69 6c 65 20 6e 61  es.***   file na
17d0: 6d 65 20 6c 65 6e 67 74 68 20 20 20 20 20 20 20  me length       
17e0: 20 20 20 20 20 20 20 20 20 32 20 62 79 74 65 73           2 bytes
17f0: 0a 2a 2a 2a 20 20 20 65 78 74 72 61 20 66 69 65  .***   extra fie
1800: 6c 64 20 6c 65 6e 67 74 68 20 20 20 20 20 20 20  ld length       
1810: 20 20 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a         2 bytes.*
1820: 2a 2a 20 20 20 0a 2a 2f 0a 74 79 70 65 64 65 66  **   .*/.typedef
1830: 20 73 74 72 75 63 74 20 5a 69 70 66 69 6c 65 4c   struct ZipfileL
1840: 46 48 20 5a 69 70 66 69 6c 65 4c 46 48 3b 0a 73  FH ZipfileLFH;.s
1850: 74 72 75 63 74 20 5a 69 70 66 69 6c 65 4c 46 48  truct ZipfileLFH
1860: 20 7b 0a 20 20 75 31 36 20 69 56 65 72 73 69 6f   {.  u16 iVersio
1870: 6e 45 78 74 72 61 63 74 3b 0a 20 20 75 31 36 20  nExtract;.  u16 
1880: 66 6c 61 67 73 3b 0a 20 20 75 31 36 20 69 43 6f  flags;.  u16 iCo
1890: 6d 70 72 65 73 73 69 6f 6e 3b 0a 20 20 75 31 36  mpression;.  u16
18a0: 20 6d 54 69 6d 65 3b 0a 20 20 75 31 36 20 6d 44   mTime;.  u16 mD
18b0: 61 74 65 3b 0a 20 20 75 33 32 20 63 72 63 33 32  ate;.  u32 crc32
18c0: 3b 0a 20 20 75 33 32 20 73 7a 43 6f 6d 70 72 65  ;.  u32 szCompre
18d0: 73 73 65 64 3b 0a 20 20 75 33 32 20 73 7a 55 6e  ssed;.  u32 szUn
18e0: 63 6f 6d 70 72 65 73 73 65 64 3b 0a 20 20 75 31  compressed;.  u1
18f0: 36 20 6e 46 69 6c 65 3b 0a 20 20 75 31 36 20 6e  6 nFile;.  u16 n
1900: 45 78 74 72 61 3b 0a 7d 3b 0a 0a 74 79 70 65 64  Extra;.};..typed
1910: 65 66 20 73 74 72 75 63 74 20 5a 69 70 66 69 6c  ef struct Zipfil
1920: 65 45 6e 74 72 79 20 5a 69 70 66 69 6c 65 45 6e  eEntry ZipfileEn
1930: 74 72 79 3b 0a 73 74 72 75 63 74 20 5a 69 70 66  try;.struct Zipf
1940: 69 6c 65 45 6e 74 72 79 20 7b 0a 20 20 5a 69 70  ileEntry {.  Zip
1950: 66 69 6c 65 43 44 53 20 63 64 73 3b 20 20 20 20  fileCDS cds;    
1960: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 72 73 65          /* Parse
1970: 64 20 43 44 53 20 72 65 63 6f 72 64 20 2a 2f 0a  d CDS record */.
1980: 20 20 75 33 32 20 6d 55 6e 69 78 54 69 6d 65 3b    u32 mUnixTime;
1990: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
19a0: 4d 6f 64 69 66 69 63 61 74 69 6f 6e 20 74 69 6d  Modification tim
19b0: 65 2c 20 69 6e 20 55 4e 49 58 20 66 6f 72 6d 61  e, in UNIX forma
19c0: 74 20 2a 2f 0a 20 20 75 38 20 2a 61 45 78 74 72  t */.  u8 *aExtr
19d0: 61 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  a;              
19e0: 20 20 2f 2a 20 63 64 73 2e 6e 45 78 74 72 61 2b    /* cds.nExtra+
19f0: 63 64 73 2e 6e 43 6f 6d 6d 65 6e 74 20 62 79 74  cds.nComment byt
1a00: 65 73 20 6f 66 20 65 78 74 72 61 20 64 61 74 61  es of extra data
1a10: 20 2a 2f 0a 20 20 69 36 34 20 69 44 61 74 61 4f   */.  i64 iDataO
1a20: 66 66 3b 0a 20 20 75 38 20 2a 61 44 61 74 61 3b  ff;.  u8 *aData;
1a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a40: 20 2f 2a 20 63 64 73 2e 73 7a 43 6f 6d 70 72 65   /* cds.szCompre
1a50: 73 73 65 64 20 62 79 74 65 73 20 6f 66 20 63 6f  ssed bytes of co
1a60: 6d 70 72 65 73 73 65 64 20 64 61 74 61 20 2a 2f  mpressed data */
1a70: 0a 20 20 5a 69 70 66 69 6c 65 45 6e 74 72 79 20  .  ZipfileEntry 
1a80: 2a 70 4e 65 78 74 3b 20 20 20 20 20 20 20 2f 2a  *pNext;       /*
1a90: 20 4e 65 78 74 20 65 6c 65 6d 65 6e 74 20 69 6e   Next element in
1aa0: 20 69 6e 2d 6d 65 6d 6f 72 79 20 43 44 53 20 2a   in-memory CDS *
1ab0: 2f 0a 7d 3b 0a 0a 2f 2a 20 0a 2a 2a 20 43 75 72  /.};../* .** Cur
1ac0: 73 6f 72 20 74 79 70 65 20 66 6f 72 20 72 65 63  sor type for rec
1ad0: 75 72 73 69 76 65 6c 79 20 69 74 65 72 61 74 69  ursively iterati
1ae0: 6e 67 20 74 68 72 6f 75 67 68 20 61 20 64 69 72  ng through a dir
1af0: 65 63 74 6f 72 79 20 73 74 72 75 63 74 75 72 65  ectory structure
1b00: 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72  ..*/.typedef str
1b10: 75 63 74 20 5a 69 70 66 69 6c 65 43 73 72 20 5a  uct ZipfileCsr Z
1b20: 69 70 66 69 6c 65 43 73 72 3b 0a 73 74 72 75 63  ipfileCsr;.struc
1b30: 74 20 5a 69 70 66 69 6c 65 43 73 72 20 7b 0a 20  t ZipfileCsr {. 
1b40: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75   sqlite3_vtab_cu
1b50: 72 73 6f 72 20 62 61 73 65 3b 20 20 2f 2a 20 42  rsor base;  /* B
1b60: 61 73 65 20 63 6c 61 73 73 20 2d 20 6d 75 73 74  ase class - must
1b70: 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 20 20 69   be first */.  i
1b80: 36 34 20 69 49 64 3b 20 20 20 20 20 20 20 20 20  64 iId;         
1b90: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72            /* Cur
1ba0: 73 6f 72 20 49 44 20 2a 2f 0a 20 20 75 38 20 62  sor ID */.  u8 b
1bb0: 45 6f 66 3b 20 20 20 20 20 20 20 20 20 20 20 20  Eof;            
1bc0: 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 77         /* True w
1bd0: 68 65 6e 20 61 74 20 45 4f 46 20 2a 2f 0a 20 20  hen at EOF */.  
1be0: 75 38 20 62 4e 6f 6f 70 3b 20 20 20 20 20 20 20  u8 bNoop;       
1bf0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 66             /* If
1c00: 20 6e 65 78 74 20 78 4e 65 78 74 28 29 20 63 61   next xNext() ca
1c10: 6c 6c 20 69 73 20 6e 6f 2d 6f 70 20 2a 2f 0a 0a  ll is no-op */..
1c20: 20 20 2f 2a 20 55 73 65 64 20 6f 75 74 73 69 64    /* Used outsid
1c30: 65 20 6f 66 20 77 72 69 74 65 20 74 72 61 6e 73  e of write trans
1c40: 61 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 46 49 4c  actions */.  FIL
1c50: 45 20 2a 70 46 69 6c 65 3b 20 20 20 20 20 20 20  E *pFile;       
1c60: 20 20 20 20 20 20 20 20 2f 2a 20 5a 69 70 20 66          /* Zip f
1c70: 69 6c 65 20 2a 2f 0a 20 20 69 36 34 20 69 4e 65  ile */.  i64 iNe
1c80: 78 74 4f 66 66 3b 20 20 20 20 20 20 20 20 20 20  xtOff;          
1c90: 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66      /* Offset of
1ca0: 20 6e 65 78 74 20 72 65 63 6f 72 64 20 69 6e 20   next record in 
1cb0: 63 65 6e 74 72 61 6c 20 64 69 72 65 63 74 6f 72  central director
1cc0: 79 20 2a 2f 0a 20 20 5a 69 70 66 69 6c 65 45 4f  y */.  ZipfileEO
1cd0: 43 44 20 65 6f 63 64 3b 20 20 20 20 20 20 20 20  CD eocd;        
1ce0: 20 20 2f 2a 20 50 61 72 73 65 20 6f 66 20 63 65    /* Parse of ce
1cf0: 6e 74 72 61 6c 20 64 69 72 65 63 74 6f 72 79 20  ntral directory 
1d00: 72 65 63 6f 72 64 20 2a 2f 0a 0a 20 20 5a 69 70  record */..  Zip
1d10: 66 69 6c 65 45 6e 74 72 79 20 2a 70 46 72 65 65  fileEntry *pFree
1d20: 45 6e 74 72 79 3b 0a 0a 20 20 5a 69 70 66 69 6c  Entry;..  Zipfil
1d30: 65 45 6e 74 72 79 20 2a 70 43 75 72 72 65 6e 74  eEntry *pCurrent
1d40: 3b 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20  ;    /* Current 
1d50: 65 6e 74 72 79 20 2a 2f 0a 20 20 5a 69 70 66 69  entry */.  Zipfi
1d60: 6c 65 43 73 72 20 2a 70 43 73 72 4e 65 78 74 3b  leCsr *pCsrNext;
1d70: 20 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 63 75        /* Next cu
1d80: 72 73 6f 72 20 6f 6e 20 73 61 6d 65 20 76 69 72  rsor on same vir
1d90: 74 75 61 6c 20 74 61 62 6c 65 20 2a 2f 0a 7d 3b  tual table */.};
1da0: 0a 0a 2f 2a 0a 2a 2a 20 50 6f 73 73 69 62 6c 65  ../*.** Possible
1db0: 20 76 61 6c 75 65 73 20 66 6f 72 20 5a 69 70 66   values for Zipf
1dc0: 69 6c 65 43 73 72 2e 65 54 79 70 65 2e 20 53 65  ileCsr.eType. Se
1dd0: 74 20 69 6e 20 7a 69 70 66 69 6c 65 46 69 6c 74  t in zipfileFilt
1de0: 65 72 28 29 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  er()..*/.#define
1df0: 20 5a 49 50 46 49 4c 45 5f 43 53 52 5f 4c 49 53   ZIPFILE_CSR_LIS
1e00: 54 20 31 20 20 20 20 20 20 20 20 2f 2a 20 43 75  T 1        /* Cu
1e10: 72 73 6f 72 20 72 65 61 64 73 20 66 72 6f 6d 20  rsor reads from 
1e20: 5a 69 70 66 69 6c 65 54 61 62 2e 70 46 69 72 73  ZipfileTab.pFirs
1e30: 74 45 6e 74 72 79 20 2a 2f 0a 23 64 65 66 69 6e  tEntry */.#defin
1e40: 65 20 5a 49 50 46 49 4c 45 5f 43 53 52 5f 46 49  e ZIPFILE_CSR_FI
1e50: 4c 45 20 32 20 20 20 20 20 20 20 20 2f 2a 20 43  LE 2        /* C
1e60: 75 72 73 6f 72 20 72 65 61 64 73 20 66 72 6f 6d  ursor reads from
1e70: 20 66 69 6c 65 20 6f 6e 20 64 69 73 6b 20 2a 2f   file on disk */
1e80: 0a 0a 2f 2a 0a 2a 2a 20 56 61 6c 75 65 73 20 66  ../*.** Values f
1e90: 6f 72 20 5a 69 70 66 69 6c 65 43 73 72 2e 66 6c  or ZipfileCsr.fl
1ea0: 61 67 73 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  ags..*/.#define 
1eb0: 5a 49 50 46 49 4c 45 5f 4e 4f 4f 50 5f 4e 45 58  ZIPFILE_NOOP_NEX
1ec0: 54 20 20 20 30 78 30 30 30 32 20 20 20 20 20 2f  T   0x0002     /
1ed0: 2a 20 4e 65 78 74 20 78 4e 65 78 74 28 29 20 69  * Next xNext() i
1ee0: 73 20 61 20 6e 6f 2d 6f 70 20 2a 2f 0a 0a 74 79  s a no-op */..ty
1ef0: 70 65 64 65 66 20 73 74 72 75 63 74 20 5a 69 70  pedef struct Zip
1f00: 66 69 6c 65 54 61 62 20 5a 69 70 66 69 6c 65 54  fileTab ZipfileT
1f10: 61 62 3b 0a 73 74 72 75 63 74 20 5a 69 70 66 69  ab;.struct Zipfi
1f20: 6c 65 54 61 62 20 7b 0a 20 20 73 71 6c 69 74 65  leTab {.  sqlite
1f30: 33 5f 76 74 61 62 20 62 61 73 65 3b 20 20 20 20  3_vtab base;    
1f40: 20 20 20 20 20 2f 2a 20 42 61 73 65 20 63 6c 61       /* Base cla
1f50: 73 73 20 2d 20 6d 75 73 74 20 62 65 20 66 69 72  ss - must be fir
1f60: 73 74 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 46  st */.  char *zF
1f70: 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ile;            
1f80: 20 20 20 2f 2a 20 5a 69 70 20 66 69 6c 65 20 74     /* Zip file t
1f90: 68 69 73 20 74 61 62 6c 65 20 61 63 63 65 73 73  his table access
1fa0: 65 73 20 28 6d 61 79 20 62 65 20 4e 55 4c 4c 29  es (may be NULL)
1fb0: 20 2a 2f 0a 20 20 75 38 20 2a 61 42 75 66 66 65   */.  u8 *aBuffe
1fc0: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
1fd0: 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62 75   /* Temporary bu
1fe0: 66 66 65 72 20 75 73 65 64 20 66 6f 72 20 76 61  ffer used for va
1ff0: 72 69 6f 75 73 20 74 61 73 6b 73 20 2a 2f 0a 0a  rious tasks */..
2000: 20 20 5a 69 70 66 69 6c 65 43 73 72 20 2a 70 43    ZipfileCsr *pC
2010: 73 72 4c 69 73 74 3b 20 20 20 20 20 20 2f 2a 20  srList;      /* 
2020: 4c 69 73 74 20 6f 66 20 63 75 72 73 6f 72 73 20  List of cursors 
2030: 2a 2f 0a 20 20 69 36 34 20 69 4e 65 78 74 43 73  */.  i64 iNextCs
2040: 72 69 64 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 66  rid;..  /* The f
2050: 6f 6c 6c 6f 77 69 6e 67 20 61 72 65 20 75 73 65  ollowing are use
2060: 64 20 62 79 20 77 72 69 74 65 20 74 72 61 6e 73  d by write trans
2070: 61 63 74 69 6f 6e 73 20 6f 6e 6c 79 20 2a 2f 0a  actions only */.
2080: 20 20 5a 69 70 66 69 6c 65 45 6e 74 72 79 20 2a    ZipfileEntry *
2090: 70 46 69 72 73 74 45 6e 74 72 79 3b 20 2f 2a 20  pFirstEntry; /* 
20a0: 4c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 61  Linked list of a
20b0: 6c 6c 20 66 69 6c 65 73 20 28 69 66 20 70 57 72  ll files (if pWr
20c0: 69 74 65 46 64 21 3d 30 29 20 2a 2f 0a 20 20 5a  iteFd!=0) */.  Z
20d0: 69 70 66 69 6c 65 45 6e 74 72 79 20 2a 70 4c 61  ipfileEntry *pLa
20e0: 73 74 45 6e 74 72 79 3b 20 20 2f 2a 20 4c 61 73  stEntry;  /* Las
20f0: 74 20 65 6c 65 6d 65 6e 74 20 69 6e 20 70 46 69  t element in pFi
2100: 72 73 74 45 6e 74 72 79 20 6c 69 73 74 20 2a 2f  rstEntry list */
2110: 0a 20 20 46 49 4c 45 20 2a 70 57 72 69 74 65 46  .  FILE *pWriteF
2120: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  d;            /*
2130: 20 46 69 6c 65 20 68 61 6e 64 6c 65 20 6f 70 65   File handle ope
2140: 6e 20 6f 6e 20 7a 69 70 20 61 72 63 68 69 76 65  n on zip archive
2150: 20 2a 2f 0a 20 20 69 36 34 20 73 7a 43 75 72 72   */.  i64 szCurr
2160: 65 6e 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ent;            
2170: 20 2f 2a 20 43 75 72 72 65 6e 74 20 73 69 7a 65   /* Current size
2180: 20 6f 66 20 7a 69 70 20 61 72 63 68 69 76 65 20   of zip archive 
2190: 2a 2f 0a 20 20 69 36 34 20 73 7a 4f 72 69 67 3b  */.  i64 szOrig;
21a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
21b0: 2f 2a 20 53 69 7a 65 20 6f 66 20 61 72 63 68 69  /* Size of archi
21c0: 76 65 20 61 74 20 73 74 61 72 74 20 6f 66 20 74  ve at start of t
21d0: 72 61 6e 73 61 63 74 69 6f 6e 20 2a 2f 0a 7d 3b  ransaction */.};
21e0: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 7a 69  ..static void zi
21f0: 70 66 69 6c 65 44 65 71 75 6f 74 65 28 63 68 61  pfileDequote(cha
2200: 72 20 2a 7a 49 6e 29 7b 0a 20 20 63 68 61 72 20  r *zIn){.  char 
2210: 71 20 3d 20 7a 49 6e 5b 30 5d 3b 0a 20 20 69 66  q = zIn[0];.  if
2220: 28 20 71 3d 3d 27 22 27 20 7c 7c 20 71 3d 3d 27  ( q=='"' || q=='
2230: 5c 27 27 20 7c 7c 20 71 3d 3d 27 60 27 20 7c 7c  \'' || q=='`' ||
2240: 20 71 3d 3d 27 5b 27 20 29 7b 0a 20 20 20 20 63   q=='[' ){.    c
2250: 68 61 72 20 63 3b 0a 20 20 20 20 69 6e 74 20 69  har c;.    int i
2260: 49 6e 20 3d 20 31 3b 0a 20 20 20 20 69 6e 74 20  In = 1;.    int 
2270: 69 4f 75 74 20 3d 20 30 3b 0a 20 20 20 20 69 66  iOut = 0;.    if
2280: 28 20 71 3d 3d 27 5b 27 20 29 20 71 20 3d 20 27  ( q=='[' ) q = '
2290: 5d 27 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28  ]';.    while( (
22a0: 63 20 3d 20 7a 49 6e 5b 69 49 6e 2b 2b 5d 29 20  c = zIn[iIn++]) 
22b0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 63 3d 3d  ){.      if( c==
22c0: 71 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  q ){.        if(
22d0: 20 7a 49 6e 5b 69 49 6e 2b 2b 5d 21 3d 71 20 29   zIn[iIn++]!=q )
22e0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
22f0: 20 20 20 20 20 20 7a 49 6e 5b 69 4f 75 74 2b 2b        zIn[iOut++
2300: 5d 20 3d 20 63 3b 0a 20 20 20 20 7d 0a 20 20 20  ] = c;.    }.   
2310: 20 7a 49 6e 5b 69 4f 75 74 5d 20 3d 20 27 5c 30   zIn[iOut] = '\0
2320: 27 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  ';.  }.}../*.** 
2330: 43 6f 6e 73 74 72 75 63 74 20 61 20 6e 65 77 20  Construct a new 
2340: 5a 69 70 66 69 6c 65 54 61 62 20 76 69 72 74 75  ZipfileTab virtu
2350: 61 6c 20 74 61 62 6c 65 20 6f 62 6a 65 63 74 2e  al table object.
2360: 0a 2a 2a 20 0a 2a 2a 20 20 20 61 72 67 76 5b 30  .** .**   argv[0
2370: 5d 20 20 20 2d 3e 20 6d 6f 64 75 6c 65 20 6e 61  ]   -> module na
2380: 6d 65 20 20 28 22 7a 69 70 66 69 6c 65 22 29 0a  me  ("zipfile").
2390: 2a 2a 20 20 20 61 72 67 76 5b 31 5d 20 20 20 2d  **   argv[1]   -
23a0: 3e 20 64 61 74 61 62 61 73 65 20 6e 61 6d 65 0a  > database name.
23b0: 2a 2a 20 20 20 61 72 67 76 5b 32 5d 20 20 20 2d  **   argv[2]   -
23c0: 3e 20 74 61 62 6c 65 20 6e 61 6d 65 0a 2a 2a 20  > table name.** 
23d0: 20 20 61 72 67 76 5b 2e 2e 2e 5d 20 2d 3e 20 22    argv[...] -> "
23e0: 63 6f 6c 75 6d 6e 20 6e 61 6d 65 22 20 61 6e 64  column name" and
23f0: 20 6f 74 68 65 72 20 6d 6f 64 75 6c 65 20 61 72   other module ar
2400: 67 75 6d 65 6e 74 20 66 69 65 6c 64 73 2e 0a 2a  gument fields..*
2410: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70  /.static int zip
2420: 66 69 6c 65 43 6f 6e 6e 65 63 74 28 0a 20 20 73  fileConnect(.  s
2430: 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f  qlite3 *db,.  vo
2440: 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20  id *pAux,.  int 
2450: 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72  argc, const char
2460: 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20   *const*argv,.  
2470: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70  sqlite3_vtab **p
2480: 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a  pVtab,.  char **
2490: 70 7a 45 72 72 0a 29 7b 0a 20 20 69 6e 74 20 6e  pzErr.){.  int n
24a0: 42 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 5a 69  Byte = sizeof(Zi
24b0: 70 66 69 6c 65 54 61 62 29 20 2b 20 5a 49 50 46  pfileTab) + ZIPF
24c0: 49 4c 45 5f 42 55 46 46 45 52 5f 53 49 5a 45 3b  ILE_BUFFER_SIZE;
24d0: 0a 20 20 69 6e 74 20 6e 46 69 6c 65 20 3d 20 30  .  int nFile = 0
24e0: 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ;.  const char *
24f0: 7a 46 69 6c 65 20 3d 20 30 3b 0a 20 20 5a 69 70  zFile = 0;.  Zip
2500: 66 69 6c 65 54 61 62 20 2a 70 4e 65 77 20 3d 20  fileTab *pNew = 
2510: 30 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  0;.  int rc;..  
2520: 69 66 28 20 61 72 67 63 3e 33 20 29 7b 0a 20 20  if( argc>3 ){.  
2530: 20 20 7a 46 69 6c 65 20 3d 20 61 72 67 76 5b 33    zFile = argv[3
2540: 5d 3b 0a 20 20 20 20 6e 46 69 6c 65 20 3d 20 28  ];.    nFile = (
2550: 69 6e 74 29 73 74 72 6c 65 6e 28 7a 46 69 6c 65  int)strlen(zFile
2560: 29 2b 31 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d  )+1;.  }..  rc =
2570: 20 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65   sqlite3_declare
2580: 5f 76 74 61 62 28 64 62 2c 20 5a 49 50 46 49 4c  _vtab(db, ZIPFIL
2590: 45 5f 53 43 48 45 4d 41 29 3b 0a 20 20 69 66 28  E_SCHEMA);.  if(
25a0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
25b0: 7b 0a 20 20 20 20 70 4e 65 77 20 3d 20 28 5a 69  {.    pNew = (Zi
25c0: 70 66 69 6c 65 54 61 62 2a 29 73 71 6c 69 74 65  pfileTab*)sqlite
25d0: 33 5f 6d 61 6c 6c 6f 63 28 6e 42 79 74 65 2b 6e  3_malloc(nByte+n
25e0: 46 69 6c 65 29 3b 0a 20 20 20 20 69 66 28 20 70  File);.    if( p
25f0: 4e 65 77 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  New==0 ) return 
2600: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
2610: 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20 30    memset(pNew, 0
2620: 2c 20 6e 42 79 74 65 2b 6e 46 69 6c 65 29 3b 0a  , nByte+nFile);.
2630: 20 20 20 20 70 4e 65 77 2d 3e 61 42 75 66 66 65      pNew->aBuffe
2640: 72 20 3d 20 28 75 38 2a 29 26 70 4e 65 77 5b 31  r = (u8*)&pNew[1
2650: 5d 3b 0a 20 20 20 20 69 66 28 20 7a 46 69 6c 65  ];.    if( zFile
2660: 20 29 7b 0a 20 20 20 20 20 20 70 4e 65 77 2d 3e   ){.      pNew->
2670: 7a 46 69 6c 65 20 3d 20 28 63 68 61 72 2a 29 26  zFile = (char*)&
2680: 70 4e 65 77 2d 3e 61 42 75 66 66 65 72 5b 5a 49  pNew->aBuffer[ZI
2690: 50 46 49 4c 45 5f 42 55 46 46 45 52 5f 53 49 5a  PFILE_BUFFER_SIZ
26a0: 45 5d 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79  E];.      memcpy
26b0: 28 70 4e 65 77 2d 3e 7a 46 69 6c 65 2c 20 7a 46  (pNew->zFile, zF
26c0: 69 6c 65 2c 20 6e 46 69 6c 65 29 3b 0a 20 20 20  ile, nFile);.   
26d0: 20 20 20 7a 69 70 66 69 6c 65 44 65 71 75 6f 74     zipfileDequot
26e0: 65 28 70 4e 65 77 2d 3e 7a 46 69 6c 65 29 3b 0a  e(pNew->zFile);.
26f0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 70 56      }.  }.  *ppV
2700: 74 61 62 20 3d 20 28 73 71 6c 69 74 65 33 5f 76  tab = (sqlite3_v
2710: 74 61 62 2a 29 70 4e 65 77 3b 0a 20 20 72 65 74  tab*)pNew;.  ret
2720: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69  urn rc;.}..stati
2730: 63 20 76 6f 69 64 20 7a 69 70 66 69 6c 65 45 6e  c void zipfileEn
2740: 74 72 79 46 72 65 65 28 5a 69 70 66 69 6c 65 45  tryFree(ZipfileE
2750: 6e 74 72 79 20 2a 70 29 7b 0a 20 20 69 66 28 20  ntry *p){.  if( 
2760: 70 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  p ){.    sqlite3
2770: 5f 66 72 65 65 28 70 2d 3e 63 64 73 2e 7a 46 69  _free(p->cds.zFi
2780: 6c 65 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  le);.    sqlite3
2790: 5f 66 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a  _free(p);.  }.}.
27a0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 7a 69 70  .static void zip
27b0: 66 69 6c 65 43 6c 65 61 6e 75 70 54 72 61 6e 73  fileCleanupTrans
27c0: 61 63 74 69 6f 6e 28 5a 69 70 66 69 6c 65 54 61  action(ZipfileTa
27d0: 62 20 2a 70 54 61 62 29 7b 0a 20 20 5a 69 70 66  b *pTab){.  Zipf
27e0: 69 6c 65 45 6e 74 72 79 20 2a 70 45 6e 74 72 79  ileEntry *pEntry
27f0: 3b 0a 20 20 5a 69 70 66 69 6c 65 45 6e 74 72 79  ;.  ZipfileEntry
2800: 20 2a 70 4e 65 78 74 3b 0a 0a 20 20 69 66 28 20   *pNext;..  if( 
2810: 70 54 61 62 2d 3e 70 57 72 69 74 65 46 64 20 29  pTab->pWriteFd )
2820: 7b 0a 20 20 20 20 66 63 6c 6f 73 65 28 70 54 61  {.    fclose(pTa
2830: 62 2d 3e 70 57 72 69 74 65 46 64 29 3b 0a 20 20  b->pWriteFd);.  
2840: 20 20 70 54 61 62 2d 3e 70 57 72 69 74 65 46 64    pTab->pWriteFd
2850: 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 66 6f 72 28   = 0;.  }.  for(
2860: 70 45 6e 74 72 79 3d 70 54 61 62 2d 3e 70 46 69  pEntry=pTab->pFi
2870: 72 73 74 45 6e 74 72 79 3b 20 70 45 6e 74 72 79  rstEntry; pEntry
2880: 3b 20 70 45 6e 74 72 79 3d 70 4e 65 78 74 29 7b  ; pEntry=pNext){
2890: 0a 20 20 20 20 70 4e 65 78 74 20 3d 20 70 45 6e  .    pNext = pEn
28a0: 74 72 79 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  try->pNext;.    
28b0: 7a 69 70 66 69 6c 65 45 6e 74 72 79 46 72 65 65  zipfileEntryFree
28c0: 28 70 45 6e 74 72 79 29 3b 0a 20 20 7d 0a 20 20  (pEntry);.  }.  
28d0: 70 54 61 62 2d 3e 70 46 69 72 73 74 45 6e 74 72  pTab->pFirstEntr
28e0: 79 20 3d 20 30 3b 0a 20 20 70 54 61 62 2d 3e 70  y = 0;.  pTab->p
28f0: 4c 61 73 74 45 6e 74 72 79 20 3d 20 30 3b 0a 20  LastEntry = 0;. 
2900: 20 70 54 61 62 2d 3e 73 7a 43 75 72 72 65 6e 74   pTab->szCurrent
2910: 20 3d 20 30 3b 0a 20 20 70 54 61 62 2d 3e 73 7a   = 0;.  pTab->sz
2920: 4f 72 69 67 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a  Orig = 0;.}../*.
2930: 2a 2a 20 54 68 69 73 20 6d 65 74 68 6f 64 20 69  ** This method i
2940: 73 20 74 68 65 20 64 65 73 74 72 75 63 74 6f 72  s the destructor
2950: 20 66 6f 72 20 7a 69 70 66 69 6c 65 20 76 74 61   for zipfile vta
2960: 62 20 6f 62 6a 65 63 74 73 2e 0a 2a 2f 0a 73 74  b objects..*/.st
2970: 61 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65  atic int zipfile
2980: 44 69 73 63 6f 6e 6e 65 63 74 28 73 71 6c 69 74  Disconnect(sqlit
2990: 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b  e3_vtab *pVtab){
29a0: 0a 20 20 7a 69 70 66 69 6c 65 43 6c 65 61 6e 75  .  zipfileCleanu
29b0: 70 54 72 61 6e 73 61 63 74 69 6f 6e 28 28 5a 69  pTransaction((Zi
29c0: 70 66 69 6c 65 54 61 62 2a 29 70 56 74 61 62 29  pfileTab*)pVtab)
29d0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
29e0: 28 70 56 74 61 62 29 3b 0a 20 20 72 65 74 75 72  (pVtab);.  retur
29f0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
2a00: 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 72 75 63 74 6f  /*.** Constructo
2a10: 72 20 66 6f 72 20 61 20 6e 65 77 20 5a 69 70 66  r for a new Zipf
2a20: 69 6c 65 43 73 72 20 6f 62 6a 65 63 74 2e 0a 2a  ileCsr object..*
2a30: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70  /.static int zip
2a40: 66 69 6c 65 4f 70 65 6e 28 73 71 6c 69 74 65 33  fileOpen(sqlite3
2a50: 5f 76 74 61 62 20 2a 70 2c 20 73 71 6c 69 74 65  _vtab *p, sqlite
2a60: 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a  3_vtab_cursor **
2a70: 70 70 43 73 72 29 7b 0a 20 20 5a 69 70 66 69 6c  ppCsr){.  Zipfil
2a80: 65 54 61 62 20 2a 70 54 61 62 20 3d 20 28 5a 69  eTab *pTab = (Zi
2a90: 70 66 69 6c 65 54 61 62 2a 29 70 3b 0a 20 20 5a  pfileTab*)p;.  Z
2aa0: 69 70 66 69 6c 65 43 73 72 20 2a 70 43 73 72 3b  ipfileCsr *pCsr;
2ab0: 0a 20 20 70 43 73 72 20 3d 20 73 71 6c 69 74 65  .  pCsr = sqlite
2ac0: 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28  3_malloc(sizeof(
2ad0: 2a 70 43 73 72 29 29 3b 0a 20 20 2a 70 70 43 73  *pCsr));.  *ppCs
2ae0: 72 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61  r = (sqlite3_vta
2af0: 62 5f 63 75 72 73 6f 72 2a 29 70 43 73 72 3b 0a  b_cursor*)pCsr;.
2b00: 20 20 69 66 28 20 70 43 73 72 3d 3d 30 20 29 7b    if( pCsr==0 ){
2b10: 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49  .    return SQLI
2b20: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20  TE_NOMEM;.  }.  
2b30: 6d 65 6d 73 65 74 28 70 43 73 72 2c 20 30 2c 20  memset(pCsr, 0, 
2b40: 73 69 7a 65 6f 66 28 2a 70 43 73 72 29 29 3b 0a  sizeof(*pCsr));.
2b50: 20 20 70 43 73 72 2d 3e 69 49 64 20 3d 20 2b 2b    pCsr->iId = ++
2b60: 70 54 61 62 2d 3e 69 4e 65 78 74 43 73 72 69 64  pTab->iNextCsrid
2b70: 3b 0a 20 20 70 43 73 72 2d 3e 70 43 73 72 4e 65  ;.  pCsr->pCsrNe
2b80: 78 74 20 3d 20 70 54 61 62 2d 3e 70 43 73 72 4c  xt = pTab->pCsrL
2b90: 69 73 74 3b 0a 20 20 70 54 61 62 2d 3e 70 43 73  ist;.  pTab->pCs
2ba0: 72 4c 69 73 74 20 3d 20 70 43 73 72 3b 0a 20 20  rList = pCsr;.  
2bb0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
2bc0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74  ;.}../*.** Reset
2bd0: 20 61 20 63 75 72 73 6f 72 20 62 61 63 6b 20 74   a cursor back t
2be0: 6f 20 74 68 65 20 73 74 61 74 65 20 69 74 20 77  o the state it w
2bf0: 61 73 20 69 6e 20 77 68 65 6e 20 66 69 72 73 74  as in when first
2c00: 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 62 79 20   returned.** by 
2c10: 7a 69 70 66 69 6c 65 4f 70 65 6e 28 29 2e 0a 2a  zipfileOpen()..*
2c20: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 7a 69  /.static void zi
2c30: 70 66 69 6c 65 52 65 73 65 74 43 75 72 73 6f 72  pfileResetCursor
2c40: 28 5a 69 70 66 69 6c 65 43 73 72 20 2a 70 43 73  (ZipfileCsr *pCs
2c50: 72 29 7b 0a 20 20 5a 69 70 66 69 6c 65 45 6e 74  r){.  ZipfileEnt
2c60: 72 79 20 2a 70 3b 0a 20 20 5a 69 70 66 69 6c 65  ry *p;.  Zipfile
2c70: 45 6e 74 72 79 20 2a 70 4e 65 78 74 3b 0a 0a 20  Entry *pNext;.. 
2c80: 20 70 43 73 72 2d 3e 62 45 6f 66 20 3d 20 30 3b   pCsr->bEof = 0;
2c90: 0a 20 20 69 66 28 20 70 43 73 72 2d 3e 70 46 69  .  if( pCsr->pFi
2ca0: 6c 65 20 29 7b 0a 20 20 20 20 66 63 6c 6f 73 65  le ){.    fclose
2cb0: 28 70 43 73 72 2d 3e 70 46 69 6c 65 29 3b 0a 20  (pCsr->pFile);. 
2cc0: 20 20 20 70 43 73 72 2d 3e 70 46 69 6c 65 20 3d     pCsr->pFile =
2cd0: 20 30 3b 0a 20 20 20 20 7a 69 70 66 69 6c 65 45   0;.    zipfileE
2ce0: 6e 74 72 79 46 72 65 65 28 70 43 73 72 2d 3e 70  ntryFree(pCsr->p
2cf0: 43 75 72 72 65 6e 74 29 3b 0a 20 20 20 20 70 43  Current);.    pC
2d00: 73 72 2d 3e 70 43 75 72 72 65 6e 74 20 3d 20 30  sr->pCurrent = 0
2d10: 3b 0a 20 20 7d 0a 0a 20 20 66 6f 72 28 70 3d 70  ;.  }..  for(p=p
2d20: 43 73 72 2d 3e 70 46 72 65 65 45 6e 74 72 79 3b  Csr->pFreeEntry;
2d30: 20 70 3b 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20   p; p=pNext){.  
2d40: 20 20 70 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65    pNext = p->pNe
2d50: 78 74 3b 0a 20 20 20 20 7a 69 70 66 69 6c 65 45  xt;.    zipfileE
2d60: 6e 74 72 79 46 72 65 65 28 70 29 3b 0a 20 20 7d  ntryFree(p);.  }
2d70: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 73 74 72 75  .}../*.** Destru
2d80: 63 74 6f 72 20 66 6f 72 20 61 6e 20 5a 69 70 66  ctor for an Zipf
2d90: 69 6c 65 43 73 72 2e 0a 2a 2f 0a 73 74 61 74 69  ileCsr..*/.stati
2da0: 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 43 6c 6f  c int zipfileClo
2db0: 73 65 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  se(sqlite3_vtab_
2dc0: 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20  cursor *cur){.  
2dd0: 5a 69 70 66 69 6c 65 43 73 72 20 2a 70 43 73 72  ZipfileCsr *pCsr
2de0: 20 3d 20 28 5a 69 70 66 69 6c 65 43 73 72 2a 29   = (ZipfileCsr*)
2df0: 63 75 72 3b 0a 20 20 5a 69 70 66 69 6c 65 54 61  cur;.  ZipfileTa
2e00: 62 20 2a 70 54 61 62 20 3d 20 28 5a 69 70 66 69  b *pTab = (Zipfi
2e10: 6c 65 54 61 62 2a 29 28 70 43 73 72 2d 3e 62 61  leTab*)(pCsr->ba
2e20: 73 65 2e 70 56 74 61 62 29 3b 0a 20 20 5a 69 70  se.pVtab);.  Zip
2e30: 66 69 6c 65 43 73 72 20 2a 2a 70 70 3b 0a 20 20  fileCsr **pp;.  
2e40: 7a 69 70 66 69 6c 65 52 65 73 65 74 43 75 72 73  zipfileResetCurs
2e50: 6f 72 28 70 43 73 72 29 3b 0a 0a 20 20 2f 2a 20  or(pCsr);..  /* 
2e60: 52 65 6d 6f 76 65 20 74 68 69 73 20 63 75 72 73  Remove this curs
2e70: 6f 72 20 66 72 6f 6d 20 74 68 65 20 5a 69 70 66  or from the Zipf
2e80: 69 6c 65 54 61 62 2e 70 43 73 72 4c 69 73 74 20  ileTab.pCsrList 
2e90: 6c 69 73 74 2e 20 2a 2f 0a 20 20 66 6f 72 28 70  list. */.  for(p
2ea0: 70 3d 26 70 54 61 62 2d 3e 70 43 73 72 4c 69 73  p=&pTab->pCsrLis
2eb0: 74 3b 20 2a 70 70 3b 20 70 70 3d 26 28 28 2a 70  t; *pp; pp=&((*p
2ec0: 70 29 2d 3e 70 43 73 72 4e 65 78 74 29 29 7b 0a  p)->pCsrNext)){.
2ed0: 20 20 20 20 69 66 28 20 2a 70 70 3d 3d 70 43 73      if( *pp==pCs
2ee0: 72 20 29 7b 20 0a 20 20 20 20 20 20 2a 70 70 20  r ){ .      *pp 
2ef0: 3d 20 70 43 73 72 2d 3e 70 43 73 72 4e 65 78 74  = pCsr->pCsrNext
2f00: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
2f10: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 73 71 6c 69     }.  }..  sqli
2f20: 74 65 33 5f 66 72 65 65 28 70 43 73 72 29 3b 0a  te3_free(pCsr);.
2f30: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
2f40: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74  OK;.}../*.** Set
2f50: 20 74 68 65 20 65 72 72 6f 72 20 6d 65 73 73 61   the error messa
2f60: 67 65 20 66 6f 72 20 74 68 65 20 76 69 72 74 75  ge for the virtu
2f70: 61 6c 20 74 61 62 6c 65 20 61 73 73 6f 63 69 61  al table associa
2f80: 74 65 64 20 77 69 74 68 20 63 75 72 73 6f 72 0a  ted with cursor.
2f90: 2a 2a 20 70 43 73 72 20 74 6f 20 74 68 65 20 72  ** pCsr to the r
2fa0: 65 73 75 6c 74 73 20 6f 66 20 76 70 72 69 6e 74  esults of vprint
2fb0: 66 28 7a 46 6d 74 2c 20 2e 2e 2e 29 2e 0a 2a 2f  f(zFmt, ...)..*/
2fc0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 7a 69 70  .static void zip
2fd0: 66 69 6c 65 53 65 74 45 72 72 6d 73 67 28 5a 69  fileSetErrmsg(Zi
2fe0: 70 66 69 6c 65 43 73 72 20 2a 70 43 73 72 2c 20  pfileCsr *pCsr, 
2ff0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6d 74  const char *zFmt
3000: 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73  , ...){.  va_lis
3010: 74 20 61 70 3b 0a 20 20 76 61 5f 73 74 61 72 74  t ap;.  va_start
3020: 28 61 70 2c 20 7a 46 6d 74 29 3b 0a 20 20 70 43  (ap, zFmt);.  pC
3030: 73 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 2d 3e  sr->base.pVtab->
3040: 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65  zErrMsg = sqlite
3050: 33 5f 76 6d 70 72 69 6e 74 66 28 7a 46 6d 74 2c  3_vmprintf(zFmt,
3060: 20 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61   ap);.  va_end(a
3070: 70 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  p);.}..static in
3080: 74 20 7a 69 70 66 69 6c 65 52 65 61 64 44 61 74  t zipfileReadDat
3090: 61 28 0a 20 20 46 49 4c 45 20 2a 70 46 69 6c 65  a(.  FILE *pFile
30a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
30b0: 20 20 20 20 20 2f 2a 20 52 65 61 64 20 66 72 6f       /* Read fro
30c0: 6d 20 74 68 69 73 20 66 69 6c 65 20 2a 2f 0a 20  m this file */. 
30d0: 20 75 38 20 2a 61 52 65 61 64 2c 20 20 20 20 20   u8 *aRead,     
30e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
30f0: 20 2f 2a 20 52 65 61 64 20 69 6e 74 6f 20 74 68   /* Read into th
3100: 69 73 20 62 75 66 66 65 72 20 2a 2f 0a 20 20 69  is buffer */.  i
3110: 6e 74 20 6e 52 65 61 64 2c 20 20 20 20 20 20 20  nt nRead,       
3120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3130: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  * Number of byte
3140: 73 20 74 6f 20 72 65 61 64 20 2a 2f 0a 20 20 69  s to read */.  i
3150: 36 34 20 69 4f 66 66 2c 20 20 20 20 20 20 20 20  64 iOff,        
3160: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
3170: 2a 20 4f 66 66 73 65 74 20 74 6f 20 72 65 61 64  * Offset to read
3180: 20 66 72 6f 6d 20 2a 2f 0a 20 20 63 68 61 72 20   from */.  char 
3190: 2a 2a 70 7a 45 72 72 6d 73 67 20 20 20 20 20 20  **pzErrmsg      
31a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
31b0: 54 3a 20 45 72 72 6f 72 20 6d 65 73 73 61 67 65  T: Error message
31c0: 20 28 66 72 6f 6d 20 73 71 6c 69 74 65 33 5f 6d   (from sqlite3_m
31d0: 61 6c 6c 6f 63 29 20 2a 2f 0a 29 7b 0a 20 20 73  alloc) */.){.  s
31e0: 69 7a 65 5f 74 20 6e 3b 0a 20 20 66 73 65 65 6b  ize_t n;.  fseek
31f0: 28 70 46 69 6c 65 2c 20 28 6c 6f 6e 67 29 69 4f  (pFile, (long)iO
3200: 66 66 2c 20 53 45 45 4b 5f 53 45 54 29 3b 0a 20  ff, SEEK_SET);. 
3210: 20 6e 20 3d 20 66 72 65 61 64 28 61 52 65 61 64   n = fread(aRead
3220: 2c 20 31 2c 20 6e 52 65 61 64 2c 20 70 46 69 6c  , 1, nRead, pFil
3230: 65 29 3b 0a 20 20 69 66 28 20 28 69 6e 74 29 6e  e);.  if( (int)n
3240: 21 3d 6e 52 65 61 64 20 29 7b 0a 20 20 20 20 2a  !=nRead ){.    *
3250: 70 7a 45 72 72 6d 73 67 20 3d 20 73 71 6c 69 74  pzErrmsg = sqlit
3260: 65 33 5f 6d 70 72 69 6e 74 66 28 22 65 72 72 6f  e3_mprintf("erro
3270: 72 20 69 6e 20 66 72 65 61 64 28 29 22 29 3b 0a  r in fread()");.
3280: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
3290: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 72  E_ERROR;.  }.  r
32a0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
32b0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 7a  .}..static int z
32c0: 69 70 66 69 6c 65 41 70 70 65 6e 64 44 61 74 61  ipfileAppendData
32d0: 28 0a 20 20 5a 69 70 66 69 6c 65 54 61 62 20 2a  (.  ZipfileTab *
32e0: 70 54 61 62 2c 0a 20 20 63 6f 6e 73 74 20 75 38  pTab,.  const u8
32f0: 20 2a 61 57 72 69 74 65 2c 0a 20 20 69 6e 74 20   *aWrite,.  int 
3300: 6e 57 72 69 74 65 0a 29 7b 0a 20 20 73 69 7a 65  nWrite.){.  size
3310: 5f 74 20 6e 3b 0a 20 20 66 73 65 65 6b 28 70 54  _t n;.  fseek(pT
3320: 61 62 2d 3e 70 57 72 69 74 65 46 64 2c 20 28 6c  ab->pWriteFd, (l
3330: 6f 6e 67 29 70 54 61 62 2d 3e 73 7a 43 75 72 72  ong)pTab->szCurr
3340: 65 6e 74 2c 20 53 45 45 4b 5f 53 45 54 29 3b 0a  ent, SEEK_SET);.
3350: 20 20 6e 20 3d 20 66 77 72 69 74 65 28 61 57 72    n = fwrite(aWr
3360: 69 74 65 2c 20 31 2c 20 6e 57 72 69 74 65 2c 20  ite, 1, nWrite, 
3370: 70 54 61 62 2d 3e 70 57 72 69 74 65 46 64 29 3b  pTab->pWriteFd);
3380: 0a 20 20 69 66 28 20 28 69 6e 74 29 6e 21 3d 6e  .  if( (int)n!=n
3390: 57 72 69 74 65 20 29 7b 0a 20 20 20 20 70 54 61  Write ){.    pTa
33a0: 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 20  b->base.zErrMsg 
33b0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
33c0: 66 28 22 65 72 72 6f 72 20 69 6e 20 66 77 72 69  f("error in fwri
33d0: 74 65 28 29 22 29 3b 0a 20 20 20 20 72 65 74 75  te()");.    retu
33e0: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
33f0: 0a 20 20 7d 0a 20 20 70 54 61 62 2d 3e 73 7a 43  .  }.  pTab->szC
3400: 75 72 72 65 6e 74 20 2b 3d 20 6e 57 72 69 74 65  urrent += nWrite
3410: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
3420: 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  E_OK;.}..static 
3430: 75 31 36 20 7a 69 70 66 69 6c 65 47 65 74 55 31  u16 zipfileGetU1
3440: 36 28 63 6f 6e 73 74 20 75 38 20 2a 61 42 75 66  6(const u8 *aBuf
3450: 29 7b 0a 20 20 72 65 74 75 72 6e 20 28 61 42 75  ){.  return (aBu
3460: 66 5b 31 5d 20 3c 3c 20 38 29 20 2b 20 61 42 75  f[1] << 8) + aBu
3470: 66 5b 30 5d 3b 0a 7d 0a 73 74 61 74 69 63 20 75  f[0];.}.static u
3480: 33 32 20 7a 69 70 66 69 6c 65 47 65 74 55 33 32  32 zipfileGetU32
3490: 28 63 6f 6e 73 74 20 75 38 20 2a 61 42 75 66 29  (const u8 *aBuf)
34a0: 7b 0a 20 20 72 65 74 75 72 6e 20 28 28 75 33 32  {.  return ((u32
34b0: 29 28 61 42 75 66 5b 33 5d 29 20 3c 3c 20 32 34  )(aBuf[3]) << 24
34c0: 29 0a 20 20 20 20 20 20 20 2b 20 28 28 75 33 32  ).       + ((u32
34d0: 29 28 61 42 75 66 5b 32 5d 29 20 3c 3c 20 31 36  )(aBuf[2]) << 16
34e0: 29 0a 20 20 20 20 20 20 20 2b 20 28 28 75 33 32  ).       + ((u32
34f0: 29 28 61 42 75 66 5b 31 5d 29 20 3c 3c 20 20 38  )(aBuf[1]) <<  8
3500: 29 0a 20 20 20 20 20 20 20 2b 20 28 28 75 33 32  ).       + ((u32
3510: 29 28 61 42 75 66 5b 30 5d 29 20 3c 3c 20 20 30  )(aBuf[0]) <<  0
3520: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  );.}..static voi
3530: 64 20 7a 69 70 66 69 6c 65 50 75 74 55 31 36 28  d zipfilePutU16(
3540: 75 38 20 2a 61 42 75 66 2c 20 75 31 36 20 76 61  u8 *aBuf, u16 va
3550: 6c 29 7b 0a 20 20 61 42 75 66 5b 30 5d 20 3d 20  l){.  aBuf[0] = 
3560: 76 61 6c 20 26 20 30 78 46 46 3b 0a 20 20 61 42  val & 0xFF;.  aB
3570: 75 66 5b 31 5d 20 3d 20 28 76 61 6c 3e 3e 38 29  uf[1] = (val>>8)
3580: 20 26 20 30 78 46 46 3b 0a 7d 0a 73 74 61 74 69   & 0xFF;.}.stati
3590: 63 20 76 6f 69 64 20 7a 69 70 66 69 6c 65 50 75  c void zipfilePu
35a0: 74 55 33 32 28 75 38 20 2a 61 42 75 66 2c 20 75  tU32(u8 *aBuf, u
35b0: 33 32 20 76 61 6c 29 7b 0a 20 20 61 42 75 66 5b  32 val){.  aBuf[
35c0: 30 5d 20 3d 20 76 61 6c 20 26 20 30 78 46 46 3b  0] = val & 0xFF;
35d0: 0a 20 20 61 42 75 66 5b 31 5d 20 3d 20 28 76 61  .  aBuf[1] = (va
35e0: 6c 3e 3e 38 29 20 26 20 30 78 46 46 3b 0a 20 20  l>>8) & 0xFF;.  
35f0: 61 42 75 66 5b 32 5d 20 3d 20 28 76 61 6c 3e 3e  aBuf[2] = (val>>
3600: 31 36 29 20 26 20 30 78 46 46 3b 0a 20 20 61 42  16) & 0xFF;.  aB
3610: 75 66 5b 33 5d 20 3d 20 28 76 61 6c 3e 3e 32 34  uf[3] = (val>>24
3620: 29 20 26 20 30 78 46 46 3b 0a 7d 0a 0a 23 64 65  ) & 0xFF;.}..#de
3630: 66 69 6e 65 20 7a 69 70 66 69 6c 65 52 65 61 64  fine zipfileRead
3640: 33 32 28 61 42 75 66 29 20 28 20 61 42 75 66 2b  32(aBuf) ( aBuf+
3650: 3d 34 2c 20 7a 69 70 66 69 6c 65 47 65 74 55 33  =4, zipfileGetU3
3660: 32 28 61 42 75 66 2d 34 29 20 29 0a 23 64 65 66  2(aBuf-4) ).#def
3670: 69 6e 65 20 7a 69 70 66 69 6c 65 52 65 61 64 31  ine zipfileRead1
3680: 36 28 61 42 75 66 29 20 28 20 61 42 75 66 2b 3d  6(aBuf) ( aBuf+=
3690: 32 2c 20 7a 69 70 66 69 6c 65 47 65 74 55 31 36  2, zipfileGetU16
36a0: 28 61 42 75 66 2d 32 29 20 29 0a 0a 23 64 65 66  (aBuf-2) )..#def
36b0: 69 6e 65 20 7a 69 70 66 69 6c 65 57 72 69 74 65  ine zipfileWrite
36c0: 33 32 28 61 42 75 66 2c 76 61 6c 29 20 7b 20 7a  32(aBuf,val) { z
36d0: 69 70 66 69 6c 65 50 75 74 55 33 32 28 61 42 75  ipfilePutU32(aBu
36e0: 66 2c 76 61 6c 29 3b 20 61 42 75 66 2b 3d 34 3b  f,val); aBuf+=4;
36f0: 20 7d 0a 23 64 65 66 69 6e 65 20 7a 69 70 66 69   }.#define zipfi
3700: 6c 65 57 72 69 74 65 31 36 28 61 42 75 66 2c 76  leWrite16(aBuf,v
3710: 61 6c 29 20 7b 20 7a 69 70 66 69 6c 65 50 75 74  al) { zipfilePut
3720: 55 31 36 28 61 42 75 66 2c 76 61 6c 29 3b 20 61  U16(aBuf,val); a
3730: 42 75 66 2b 3d 32 3b 20 7d 0a 0a 2f 2a 0a 2a 2a  Buf+=2; }../*.**
3740: 20 4d 61 67 69 63 20 6e 75 6d 62 65 72 73 20 75   Magic numbers u
3750: 73 65 64 20 74 6f 20 72 65 61 64 20 43 44 53 20  sed to read CDS 
3760: 72 65 63 6f 72 64 73 2e 0a 2a 2f 0a 23 64 65 66  records..*/.#def
3770: 69 6e 65 20 5a 49 50 46 49 4c 45 5f 43 44 53 5f  ine ZIPFILE_CDS_
3780: 46 49 58 45 44 5f 53 5a 20 20 20 20 20 20 20 20  FIXED_SZ        
3790: 20 34 36 0a 23 64 65 66 69 6e 65 20 5a 49 50 46   46.#define ZIPF
37a0: 49 4c 45 5f 43 44 53 5f 4e 46 49 4c 45 5f 4f 46  ILE_CDS_NFILE_OF
37b0: 46 20 20 20 20 20 20 20 20 32 38 0a 23 64 65 66  F        28.#def
37c0: 69 6e 65 20 5a 49 50 46 49 4c 45 5f 43 44 53 5f  ine ZIPFILE_CDS_
37d0: 53 5a 43 4f 4d 50 52 45 53 53 45 44 5f 4f 46 46  SZCOMPRESSED_OFF
37e0: 20 32 30 0a 0a 2f 2a 0a 2a 2a 20 44 65 63 6f 64   20../*.** Decod
37f0: 65 20 74 68 65 20 43 44 53 20 72 65 63 6f 72 64  e the CDS record
3800: 20 69 6e 20 62 75 66 66 65 72 20 61 42 75 66 20   in buffer aBuf 
3810: 69 6e 74 6f 20 28 2a 70 43 44 53 29 2e 20 52 65  into (*pCDS). Re
3820: 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f  turn SQLITE_ERRO
3830: 52 0a 2a 2a 20 69 66 20 74 68 65 20 72 65 63 6f  R.** if the reco
3840: 72 64 20 69 73 20 6e 6f 74 20 77 65 6c 6c 2d 66  rd is not well-f
3850: 6f 72 6d 65 64 2c 20 6f 72 20 53 51 4c 49 54 45  ormed, or SQLITE
3860: 5f 4f 4b 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a  _OK otherwise..*
3870: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70  /.static int zip
3880: 66 69 6c 65 52 65 61 64 43 44 53 28 75 38 20 2a  fileReadCDS(u8 *
3890: 61 42 75 66 2c 20 5a 69 70 66 69 6c 65 43 44 53  aBuf, ZipfileCDS
38a0: 20 2a 70 43 44 53 29 7b 0a 20 20 75 38 20 2a 61   *pCDS){.  u8 *a
38b0: 52 65 61 64 20 3d 20 61 42 75 66 3b 0a 20 20 75  Read = aBuf;.  u
38c0: 33 32 20 73 69 67 20 3d 20 7a 69 70 66 69 6c 65  32 sig = zipfile
38d0: 52 65 61 64 33 32 28 61 52 65 61 64 29 3b 0a 20  Read32(aRead);. 
38e0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
38f0: 5f 4f 4b 3b 0a 20 20 69 66 28 20 73 69 67 21 3d  _OK;.  if( sig!=
3900: 5a 49 50 46 49 4c 45 5f 53 49 47 4e 41 54 55 52  ZIPFILE_SIGNATUR
3910: 45 5f 43 44 53 20 29 7b 0a 20 20 20 20 72 63 20  E_CDS ){.    rc 
3920: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
3930: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 43 44    }else{.    pCD
3940: 53 2d 3e 69 56 65 72 73 69 6f 6e 4d 61 64 65 42  S->iVersionMadeB
3950: 79 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31  y = zipfileRead1
3960: 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 43  6(aRead);.    pC
3970: 44 53 2d 3e 69 56 65 72 73 69 6f 6e 45 78 74 72  DS->iVersionExtr
3980: 61 63 74 20 3d 20 7a 69 70 66 69 6c 65 52 65 61  act = zipfileRea
3990: 64 31 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20  d16(aRead);.    
39a0: 70 43 44 53 2d 3e 66 6c 61 67 73 20 3d 20 7a 69  pCDS->flags = zi
39b0: 70 66 69 6c 65 52 65 61 64 31 36 28 61 52 65 61  pfileRead16(aRea
39c0: 64 29 3b 0a 20 20 20 20 70 43 44 53 2d 3e 69 43  d);.    pCDS->iC
39d0: 6f 6d 70 72 65 73 73 69 6f 6e 20 3d 20 7a 69 70  ompression = zip
39e0: 66 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64  fileRead16(aRead
39f0: 29 3b 0a 20 20 20 20 70 43 44 53 2d 3e 6d 54 69  );.    pCDS->mTi
3a00: 6d 65 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64  me = zipfileRead
3a10: 31 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70  16(aRead);.    p
3a20: 43 44 53 2d 3e 6d 44 61 74 65 20 3d 20 7a 69 70  CDS->mDate = zip
3a30: 66 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64  fileRead16(aRead
3a40: 29 3b 0a 20 20 20 20 70 43 44 53 2d 3e 63 72 63  );.    pCDS->crc
3a50: 33 32 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64  32 = zipfileRead
3a60: 33 32 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70  32(aRead);.    p
3a70: 43 44 53 2d 3e 73 7a 43 6f 6d 70 72 65 73 73 65  CDS->szCompresse
3a80: 64 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 33  d = zipfileRead3
3a90: 32 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 43  2(aRead);.    pC
3aa0: 44 53 2d 3e 73 7a 55 6e 63 6f 6d 70 72 65 73 73  DS->szUncompress
3ab0: 65 64 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64  ed = zipfileRead
3ac0: 33 32 28 61 52 65 61 64 29 3b 0a 20 20 20 20 61  32(aRead);.    a
3ad0: 73 73 65 72 74 28 20 61 52 65 61 64 3d 3d 26 61  ssert( aRead==&a
3ae0: 42 75 66 5b 5a 49 50 46 49 4c 45 5f 43 44 53 5f  Buf[ZIPFILE_CDS_
3af0: 4e 46 49 4c 45 5f 4f 46 46 5d 20 29 3b 0a 20 20  NFILE_OFF] );.  
3b00: 20 20 70 43 44 53 2d 3e 6e 46 69 6c 65 20 3d 20    pCDS->nFile = 
3b10: 7a 69 70 66 69 6c 65 52 65 61 64 31 36 28 61 52  zipfileRead16(aR
3b20: 65 61 64 29 3b 0a 20 20 20 20 70 43 44 53 2d 3e  ead);.    pCDS->
3b30: 6e 45 78 74 72 61 20 3d 20 7a 69 70 66 69 6c 65  nExtra = zipfile
3b40: 52 65 61 64 31 36 28 61 52 65 61 64 29 3b 0a 20  Read16(aRead);. 
3b50: 20 20 20 70 43 44 53 2d 3e 6e 43 6f 6d 6d 65 6e     pCDS->nCommen
3b60: 74 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31  t = zipfileRead1
3b70: 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 43  6(aRead);.    pC
3b80: 44 53 2d 3e 69 44 69 73 6b 53 74 61 72 74 20 3d  DS->iDiskStart =
3b90: 20 7a 69 70 66 69 6c 65 52 65 61 64 31 36 28 61   zipfileRead16(a
3ba0: 52 65 61 64 29 3b 0a 20 20 20 20 70 43 44 53 2d  Read);.    pCDS-
3bb0: 3e 69 49 6e 74 65 72 6e 61 6c 41 74 74 72 20 3d  >iInternalAttr =
3bc0: 20 7a 69 70 66 69 6c 65 52 65 61 64 31 36 28 61   zipfileRead16(a
3bd0: 52 65 61 64 29 3b 0a 20 20 20 20 70 43 44 53 2d  Read);.    pCDS-
3be0: 3e 69 45 78 74 65 72 6e 61 6c 41 74 74 72 20 3d  >iExternalAttr =
3bf0: 20 7a 69 70 66 69 6c 65 52 65 61 64 33 32 28 61   zipfileRead32(a
3c00: 52 65 61 64 29 3b 0a 20 20 20 20 70 43 44 53 2d  Read);.    pCDS-
3c10: 3e 69 4f 66 66 73 65 74 20 3d 20 7a 69 70 66 69  >iOffset = zipfi
3c20: 6c 65 52 65 61 64 33 32 28 61 52 65 61 64 29 3b  leRead32(aRead);
3c30: 0a 20 20 20 20 61 73 73 65 72 74 28 20 61 52 65  .    assert( aRe
3c40: 61 64 3d 3d 26 61 42 75 66 5b 5a 49 50 46 49 4c  ad==&aBuf[ZIPFIL
3c50: 45 5f 43 44 53 5f 46 49 58 45 44 5f 53 5a 5d 20  E_CDS_FIXED_SZ] 
3c60: 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e  );.  }..  return
3c70: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
3c80: 65 20 67 65 6e 65 72 61 6c 20 66 6f 72 6d 61 74  e general format
3c90: 20 6f 66 20 61 6e 20 65 78 74 72 61 20 66 69 65   of an extra fie
3ca0: 6c 64 20 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 48  ld is:.**.**   H
3cb0: 65 61 64 65 72 20 49 44 20 20 20 20 32 20 62 79  eader ID    2 by
3cc0: 74 65 73 0a 2a 2a 20 20 20 44 61 74 61 20 53 69  tes.**   Data Si
3cd0: 7a 65 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a  ze    2 bytes.**
3ce0: 20 20 20 44 61 74 61 20 20 20 20 20 20 20 20 20     Data         
3cf0: 4e 20 62 79 74 65 73 0a 2a 2f 0a 73 74 61 74 69  N bytes.*/.stati
3d00: 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 53 63 61  c int zipfileSca
3d10: 6e 45 78 74 72 61 28 75 38 20 2a 61 45 78 74 72  nExtra(u8 *aExtr
3d20: 61 2c 20 69 6e 74 20 6e 45 78 74 72 61 2c 20 75  a, int nExtra, u
3d30: 33 32 20 2a 70 6d 54 69 6d 65 29 7b 0a 20 20 69  32 *pmTime){.  i
3d40: 6e 74 20 72 65 74 20 3d 20 30 3b 0a 20 20 75 38  nt ret = 0;.  u8
3d50: 20 2a 70 20 3d 20 61 45 78 74 72 61 3b 0a 20 20   *p = aExtra;.  
3d60: 75 38 20 2a 70 45 6e 64 20 3d 20 26 61 45 78 74  u8 *pEnd = &aExt
3d70: 72 61 5b 6e 45 78 74 72 61 5d 3b 0a 0a 20 20 77  ra[nExtra];..  w
3d80: 68 69 6c 65 28 20 70 3c 70 45 6e 64 20 29 7b 0a  hile( p<pEnd ){.
3d90: 20 20 20 20 75 31 36 20 69 64 20 3d 20 7a 69 70      u16 id = zip
3da0: 66 69 6c 65 52 65 61 64 31 36 28 70 29 3b 0a 20  fileRead16(p);. 
3db0: 20 20 20 75 31 36 20 6e 42 79 74 65 20 3d 20 7a     u16 nByte = z
3dc0: 69 70 66 69 6c 65 52 65 61 64 31 36 28 70 29 3b  ipfileRead16(p);
3dd0: 0a 0a 20 20 20 20 73 77 69 74 63 68 28 20 69 64  ..    switch( id
3de0: 20 29 7b 0a 20 20 20 20 20 20 63 61 73 65 20 5a   ){.      case Z
3df0: 49 50 46 49 4c 45 5f 45 58 54 52 41 5f 54 49 4d  IPFILE_EXTRA_TIM
3e00: 45 53 54 41 4d 50 3a 20 7b 0a 20 20 20 20 20 20  ESTAMP: {.      
3e10: 20 20 75 38 20 62 20 3d 20 70 5b 30 5d 3b 0a 20    u8 b = p[0];. 
3e20: 20 20 20 20 20 20 20 69 66 28 20 62 20 26 20 30         if( b & 0
3e30: 78 30 31 20 29 7b 20 20 20 20 20 2f 2a 20 30 78  x01 ){     /* 0x
3e40: 30 31 20 2d 3e 20 6d 6f 64 74 69 6d 65 20 69 73  01 -> modtime is
3e50: 20 70 72 65 73 65 6e 74 20 2a 2f 0a 20 20 20 20   present */.    
3e60: 20 20 20 20 20 20 2a 70 6d 54 69 6d 65 20 3d 20        *pmTime = 
3e70: 7a 69 70 66 69 6c 65 47 65 74 55 33 32 28 26 70  zipfileGetU32(&p
3e80: 5b 31 5d 29 3b 0a 20 20 20 20 20 20 20 20 20 20  [1]);.          
3e90: 72 65 74 20 3d 20 31 3b 0a 20 20 20 20 20 20 20  ret = 1;.       
3ea0: 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b   }.        break
3eb0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
3ec0: 0a 20 20 20 20 70 20 2b 3d 20 6e 42 79 74 65 3b  .    p += nByte;
3ed0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 65  .  }.  return re
3ee0: 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 22 53 74 61  t;.}../*.** "Sta
3ef0: 6e 64 61 72 64 22 20 4d 53 2d 44 4f 53 20 74 69  ndard" MS-DOS ti
3f00: 6d 65 20 66 6f 72 6d 61 74 3a 0a 2a 2a 0a 2a 2a  me format:.**.**
3f10: 20 20 20 46 69 6c 65 20 6d 6f 64 69 66 69 63 61     File modifica
3f20: 74 69 6f 6e 20 74 69 6d 65 3a 0a 2a 2a 20 20 20  tion time:.**   
3f30: 20 20 42 69 74 73 20 30 30 2d 30 34 3a 20 73 65    Bits 00-04: se
3f40: 63 6f 6e 64 73 20 64 69 76 69 64 65 64 20 62 79  conds divided by
3f50: 20 32 0a 2a 2a 20 20 20 20 20 42 69 74 73 20 30   2.**     Bits 0
3f60: 35 2d 31 30 3a 20 6d 69 6e 75 74 65 0a 2a 2a 20  5-10: minute.** 
3f70: 20 20 20 20 42 69 74 73 20 31 31 2d 31 35 3a 20      Bits 11-15: 
3f80: 68 6f 75 72 0a 2a 2a 20 20 20 46 69 6c 65 20 6d  hour.**   File m
3f90: 6f 64 69 66 69 63 61 74 69 6f 6e 20 64 61 74 65  odification date
3fa0: 3a 0a 2a 2a 20 20 20 20 20 42 69 74 73 20 30 30  :.**     Bits 00
3fb0: 2d 30 34 3a 20 64 61 79 0a 2a 2a 20 20 20 20 20  -04: day.**     
3fc0: 42 69 74 73 20 30 35 2d 30 38 3a 20 6d 6f 6e 74  Bits 05-08: mont
3fd0: 68 20 28 31 2d 31 32 29 0a 2a 2a 20 20 20 20 20  h (1-12).**     
3fe0: 42 69 74 73 20 30 39 2d 31 35 3a 20 79 65 61 72  Bits 09-15: year
3ff0: 73 20 66 72 6f 6d 20 31 39 38 30 20 0a 2a 2f 0a  s from 1980 .*/.
4000: 73 74 61 74 69 63 20 74 69 6d 65 5f 74 20 7a 69  static time_t zi
4010: 70 66 69 6c 65 4d 74 69 6d 65 28 5a 69 70 66 69  pfileMtime(Zipfi
4020: 6c 65 43 44 53 20 2a 70 43 44 53 29 7b 0a 20 20  leCDS *pCDS){.  
4030: 73 74 72 75 63 74 20 74 6d 20 74 3b 0a 20 20 6d  struct tm t;.  m
4040: 65 6d 73 65 74 28 26 74 2c 20 30 2c 20 73 69 7a  emset(&t, 0, siz
4050: 65 6f 66 28 74 29 29 3b 0a 20 20 74 2e 74 6d 5f  eof(t));.  t.tm_
4060: 73 65 63 20 3d 20 28 70 43 44 53 2d 3e 6d 54 69  sec = (pCDS->mTi
4070: 6d 65 20 26 20 30 78 31 46 29 2a 32 3b 0a 20 20  me & 0x1F)*2;.  
4080: 74 2e 74 6d 5f 6d 69 6e 20 3d 20 28 70 43 44 53  t.tm_min = (pCDS
4090: 2d 3e 6d 54 69 6d 65 20 3e 3e 20 35 29 20 26 20  ->mTime >> 5) & 
40a0: 30 78 32 46 3b 0a 20 20 74 2e 74 6d 5f 68 6f 75  0x2F;.  t.tm_hou
40b0: 72 20 3d 20 28 70 43 44 53 2d 3e 6d 54 69 6d 65  r = (pCDS->mTime
40c0: 20 3e 3e 20 31 31 29 20 26 20 30 78 31 46 3b 0a   >> 11) & 0x1F;.
40d0: 0a 20 20 74 2e 74 6d 5f 6d 64 61 79 20 3d 20 28  .  t.tm_mday = (
40e0: 70 43 44 53 2d 3e 6d 44 61 74 65 20 26 20 30 78  pCDS->mDate & 0x
40f0: 31 46 29 3b 0a 20 20 74 2e 74 6d 5f 6d 6f 6e 20  1F);.  t.tm_mon 
4100: 3d 20 28 28 70 43 44 53 2d 3e 6d 44 61 74 65 20  = ((pCDS->mDate 
4110: 3e 3e 20 35 29 20 26 20 30 78 30 46 29 20 2d 20  >> 5) & 0x0F) - 
4120: 31 3b 0a 20 20 74 2e 74 6d 5f 79 65 61 72 20 3d  1;.  t.tm_year =
4130: 20 38 30 20 2b 20 28 28 70 43 44 53 2d 3e 6d 44   80 + ((pCDS->mD
4140: 61 74 65 20 3e 3e 20 39 29 20 26 20 30 78 37 46  ate >> 9) & 0x7F
4150: 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 6d 6b 74  );..  return mkt
4160: 69 6d 65 28 26 74 29 3b 0a 7d 0a 0a 73 74 61 74  ime(&t);.}..stat
4170: 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 52 65  ic int zipfileRe
4180: 61 64 4c 46 48 28 0a 20 20 75 38 20 2a 61 42 75  adLFH(.  u8 *aBu
4190: 66 66 65 72 2c 0a 20 20 5a 69 70 66 69 6c 65 4c  ffer,.  ZipfileL
41a0: 46 48 20 2a 70 4c 46 48 0a 29 7b 0a 20 20 75 38  FH *pLFH.){.  u8
41b0: 20 2a 61 52 65 61 64 20 3d 20 61 42 75 66 66 65   *aRead = aBuffe
41c0: 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  r;.  int rc = SQ
41d0: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 75 33 32 20  LITE_OK;..  u32 
41e0: 73 69 67 20 3d 20 7a 69 70 66 69 6c 65 52 65 61  sig = zipfileRea
41f0: 64 33 32 28 61 52 65 61 64 29 3b 0a 20 20 69 66  d32(aRead);.  if
4200: 28 20 73 69 67 21 3d 5a 49 50 46 49 4c 45 5f 53  ( sig!=ZIPFILE_S
4210: 49 47 4e 41 54 55 52 45 5f 4c 46 48 20 29 7b 0a  IGNATURE_LFH ){.
4220: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
4230: 45 52 52 4f 52 3b 0a 20 20 7d 65 6c 73 65 7b 0a  ERROR;.  }else{.
4240: 20 20 20 20 70 4c 46 48 2d 3e 69 56 65 72 73 69      pLFH->iVersi
4250: 6f 6e 45 78 74 72 61 63 74 20 3d 20 7a 69 70 66  onExtract = zipf
4260: 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64 29  ileRead16(aRead)
4270: 3b 0a 20 20 20 20 70 4c 46 48 2d 3e 66 6c 61 67  ;.    pLFH->flag
4280: 73 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31  s = zipfileRead1
4290: 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 4c  6(aRead);.    pL
42a0: 46 48 2d 3e 69 43 6f 6d 70 72 65 73 73 69 6f 6e  FH->iCompression
42b0: 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31 36   = zipfileRead16
42c0: 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 4c 46  (aRead);.    pLF
42d0: 48 2d 3e 6d 54 69 6d 65 20 3d 20 7a 69 70 66 69  H->mTime = zipfi
42e0: 6c 65 52 65 61 64 31 36 28 61 52 65 61 64 29 3b  leRead16(aRead);
42f0: 0a 20 20 20 20 70 4c 46 48 2d 3e 6d 44 61 74 65  .    pLFH->mDate
4300: 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31 36   = zipfileRead16
4310: 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 4c 46  (aRead);.    pLF
4320: 48 2d 3e 63 72 63 33 32 20 3d 20 7a 69 70 66 69  H->crc32 = zipfi
4330: 6c 65 52 65 61 64 33 32 28 61 52 65 61 64 29 3b  leRead32(aRead);
4340: 0a 20 20 20 20 70 4c 46 48 2d 3e 73 7a 43 6f 6d  .    pLFH->szCom
4350: 70 72 65 73 73 65 64 20 3d 20 7a 69 70 66 69 6c  pressed = zipfil
4360: 65 52 65 61 64 33 32 28 61 52 65 61 64 29 3b 0a  eRead32(aRead);.
4370: 20 20 20 20 70 4c 46 48 2d 3e 73 7a 55 6e 63 6f      pLFH->szUnco
4380: 6d 70 72 65 73 73 65 64 20 3d 20 7a 69 70 66 69  mpressed = zipfi
4390: 6c 65 52 65 61 64 33 32 28 61 52 65 61 64 29 3b  leRead32(aRead);
43a0: 0a 20 20 20 20 70 4c 46 48 2d 3e 6e 46 69 6c 65  .    pLFH->nFile
43b0: 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31 36   = zipfileRead16
43c0: 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 4c 46  (aRead);.    pLF
43d0: 48 2d 3e 6e 45 78 74 72 61 20 3d 20 7a 69 70 66  H->nExtra = zipf
43e0: 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64 29  ileRead16(aRead)
43f0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  ;.  }.  return r
4400: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64  c;.}../*.** Read
4410: 20 61 20 5a 69 70 20 61 72 63 68 69 76 65 20 43   a Zip archive C
4420: 44 53 20 68 65 61 64 65 72 20 66 72 6f 6d 20 6f  DS header from o
4430: 66 66 73 65 74 20 69 4f 66 66 20 6f 66 20 66 69  ffset iOff of fi
4440: 6c 65 20 70 46 69 6c 65 2e 20 52 65 74 75 72 6e  le pFile. Return
4450: 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66  .** SQLITE_OK if
4460: 20 73 75 63 63 65 73 73 66 75 6c 2c 20 6f 72 20   successful, or 
4470: 61 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 20  an SQLite error 
4480: 63 6f 64 65 20 6f 74 68 65 72 77 69 73 65 2e 0a  code otherwise..
4490: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69  */.static int zi
44a0: 70 66 69 6c 65 47 65 74 45 6e 74 72 79 28 0a 20  pfileGetEntry(. 
44b0: 20 5a 69 70 66 69 6c 65 54 61 62 20 2a 70 54 61   ZipfileTab *pTa
44c0: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
44d0: 20 2f 2a 20 53 74 6f 72 65 20 61 6e 79 20 65 72   /* Store any er
44e0: 72 6f 72 20 6d 65 73 73 61 67 65 20 68 65 72 65  ror message here
44f0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 75 38 20 2a   */.  const u8 *
4500: 61 42 6c 6f 62 2c 20 20 20 20 20 20 20 20 20 20  aBlob,          
4510: 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72        /* Pointer
4520: 20 74 6f 20 69 6e 2d 6d 65 6d 6f 72 79 20 66 69   to in-memory fi
4530: 6c 65 20 69 6d 61 67 65 20 2a 2f 0a 20 20 69 6e  le image */.  in
4540: 74 20 6e 42 6c 6f 62 2c 20 20 20 20 20 20 20 20  t nBlob,        
4550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
4560: 20 53 69 7a 65 20 6f 66 20 61 42 6c 6f 62 5b 5d   Size of aBlob[]
4570: 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 46   in bytes */.  F
4580: 49 4c 45 20 2a 70 46 69 6c 65 2c 20 20 20 20 20  ILE *pFile,     
4590: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
45a0: 2a 20 49 66 20 61 42 6c 6f 62 3d 3d 30 2c 20 72  * If aBlob==0, r
45b0: 65 61 64 20 66 72 6f 6d 20 74 68 69 73 20 66 69  ead from this fi
45c0: 6c 65 20 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66  le */.  i64 iOff
45d0: 2c 0a 20 20 5a 69 70 66 69 6c 65 45 6e 74 72 79  ,.  ZipfileEntry
45e0: 20 2a 2a 70 70 45 6e 74 72 79 0a 29 7b 0a 20 20   **ppEntry.){.  
45f0: 75 38 20 2a 61 52 65 61 64 3b 0a 20 20 63 68 61  u8 *aRead;.  cha
4600: 72 20 2a 2a 70 7a 45 72 72 20 3d 20 26 70 54 61  r **pzErr = &pTa
4610: 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d 73 67 3b  b->base.zErrMsg;
4620: 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49  .  int rc = SQLI
4630: 54 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 61 42  TE_OK;..  if( aB
4640: 6c 6f 62 3d 3d 30 20 29 7b 0a 20 20 20 20 61 52  lob==0 ){.    aR
4650: 65 61 64 20 3d 20 70 54 61 62 2d 3e 61 42 75 66  ead = pTab->aBuf
4660: 66 65 72 3b 0a 20 20 20 20 72 63 20 3d 20 7a 69  fer;.    rc = zi
4670: 70 66 69 6c 65 52 65 61 64 44 61 74 61 28 70 46  pfileReadData(pF
4680: 69 6c 65 2c 20 61 52 65 61 64 2c 20 5a 49 50 46  ile, aRead, ZIPF
4690: 49 4c 45 5f 43 44 53 5f 46 49 58 45 44 5f 53 5a  ILE_CDS_FIXED_SZ
46a0: 2c 20 69 4f 66 66 2c 20 70 7a 45 72 72 29 3b 0a  , iOff, pzErr);.
46b0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 61 52 65    }else{.    aRe
46c0: 61 64 20 3d 20 28 75 38 2a 29 26 61 42 6c 6f 62  ad = (u8*)&aBlob
46d0: 5b 69 4f 66 66 5d 3b 0a 20 20 7d 0a 0a 20 20 69  [iOff];.  }..  i
46e0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
46f0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 41 6c 6c   ){.    int nAll
4700: 6f 63 3b 0a 20 20 20 20 5a 69 70 66 69 6c 65 45  oc;.    ZipfileE
4710: 6e 74 72 79 20 2a 70 4e 65 77 3b 0a 0a 20 20 20  ntry *pNew;..   
4720: 20 69 6e 74 20 6e 46 69 6c 65 20 3d 20 7a 69 70   int nFile = zip
4730: 66 69 6c 65 47 65 74 55 31 36 28 26 61 52 65 61  fileGetU16(&aRea
4740: 64 5b 5a 49 50 46 49 4c 45 5f 43 44 53 5f 4e 46  d[ZIPFILE_CDS_NF
4750: 49 4c 45 5f 4f 46 46 5d 29 3b 0a 20 20 20 20 69  ILE_OFF]);.    i
4760: 6e 74 20 6e 45 78 74 72 61 20 3d 20 7a 69 70 66  nt nExtra = zipf
4770: 69 6c 65 47 65 74 55 31 36 28 26 61 52 65 61 64  ileGetU16(&aRead
4780: 5b 5a 49 50 46 49 4c 45 5f 43 44 53 5f 4e 46 49  [ZIPFILE_CDS_NFI
4790: 4c 45 5f 4f 46 46 2b 32 5d 29 3b 0a 20 20 20 20  LE_OFF+2]);.    
47a0: 6e 45 78 74 72 61 20 2b 3d 20 7a 69 70 66 69 6c  nExtra += zipfil
47b0: 65 47 65 74 55 31 36 28 26 61 52 65 61 64 5b 5a  eGetU16(&aRead[Z
47c0: 49 50 46 49 4c 45 5f 43 44 53 5f 4e 46 49 4c 45  IPFILE_CDS_NFILE
47d0: 5f 4f 46 46 2b 34 5d 29 3b 0a 0a 20 20 20 20 6e  _OFF+4]);..    n
47e0: 41 6c 6c 6f 63 20 3d 20 73 69 7a 65 6f 66 28 5a  Alloc = sizeof(Z
47f0: 69 70 66 69 6c 65 45 6e 74 72 79 29 20 2b 20 6e  ipfileEntry) + n
4800: 45 78 74 72 61 3b 0a 20 20 20 20 69 66 28 20 61  Extra;.    if( a
4810: 42 6c 6f 62 20 29 7b 0a 20 20 20 20 20 20 6e 41  Blob ){.      nA
4820: 6c 6c 6f 63 20 2b 3d 20 7a 69 70 66 69 6c 65 47  lloc += zipfileG
4830: 65 74 55 33 32 28 26 61 52 65 61 64 5b 5a 49 50  etU32(&aRead[ZIP
4840: 46 49 4c 45 5f 43 44 53 5f 53 5a 43 4f 4d 50 52  FILE_CDS_SZCOMPR
4850: 45 53 53 45 44 5f 4f 46 46 5d 29 3b 0a 20 20 20  ESSED_OFF]);.   
4860: 20 7d 0a 0a 20 20 20 20 70 4e 65 77 20 3d 20 28   }..    pNew = (
4870: 5a 69 70 66 69 6c 65 45 6e 74 72 79 2a 29 73 71  ZipfileEntry*)sq
4880: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 41 6c  lite3_malloc(nAl
4890: 6c 6f 63 29 3b 0a 20 20 20 20 69 66 28 20 70 4e  loc);.    if( pN
48a0: 65 77 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72  ew==0 ){.      r
48b0: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
48c0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
48d0: 20 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20     memset(pNew, 
48e0: 30 2c 20 73 69 7a 65 6f 66 28 5a 69 70 66 69 6c  0, sizeof(Zipfil
48f0: 65 45 6e 74 72 79 29 29 3b 0a 20 20 20 20 20 20  eEntry));.      
4900: 72 63 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64  rc = zipfileRead
4910: 43 44 53 28 61 52 65 61 64 2c 20 26 70 4e 65 77  CDS(aRead, &pNew
4920: 2d 3e 63 64 73 29 3b 0a 20 20 20 20 20 20 69 66  ->cds);.      if
4930: 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc!=SQLITE_OK 
4940: 29 7b 0a 20 20 20 20 20 20 20 20 2a 70 7a 45 72  ){.        *pzEr
4950: 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69  r = sqlite3_mpri
4960: 6e 74 66 28 22 66 61 69 6c 65 64 20 74 6f 20 72  ntf("failed to r
4970: 65 61 64 20 43 44 53 20 61 74 20 6f 66 66 73 65  ead CDS at offse
4980: 74 20 25 6c 6c 64 22 2c 20 69 4f 66 66 29 3b 0a  t %lld", iOff);.
4990: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
49a0: 61 42 6c 6f 62 3d 3d 30 20 29 7b 0a 20 20 20 20  aBlob==0 ){.    
49b0: 20 20 20 20 72 63 20 3d 20 7a 69 70 66 69 6c 65      rc = zipfile
49c0: 52 65 61 64 44 61 74 61 28 0a 20 20 20 20 20 20  ReadData(.      
49d0: 20 20 20 20 20 20 70 46 69 6c 65 2c 20 61 52 65        pFile, aRe
49e0: 61 64 2c 20 6e 45 78 74 72 61 2b 6e 46 69 6c 65  ad, nExtra+nFile
49f0: 2c 20 69 4f 66 66 2b 5a 49 50 46 49 4c 45 5f 43  , iOff+ZIPFILE_C
4a00: 44 53 5f 46 49 58 45 44 5f 53 5a 2c 20 70 7a 45  DS_FIXED_SZ, pzE
4a10: 72 72 0a 20 20 20 20 20 20 20 20 29 3b 0a 20 20  rr.        );.  
4a20: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4a30: 20 20 20 61 52 65 61 64 20 3d 20 28 75 38 2a 29     aRead = (u8*)
4a40: 26 61 42 6c 6f 62 5b 69 4f 66 66 20 2b 20 5a 49  &aBlob[iOff + ZI
4a50: 50 46 49 4c 45 5f 43 44 53 5f 46 49 58 45 44 5f  PFILE_CDS_FIXED_
4a60: 53 5a 5d 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  SZ];.      }.   
4a70: 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d   }..    if( rc==
4a80: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
4a90: 20 20 20 75 33 32 20 2a 70 74 20 3d 20 26 70 4e     u32 *pt = &pN
4aa0: 65 77 2d 3e 6d 55 6e 69 78 54 69 6d 65 3b 0a 20  ew->mUnixTime;. 
4ab0: 20 20 20 20 20 70 4e 65 77 2d 3e 63 64 73 2e 7a       pNew->cds.z
4ac0: 46 69 6c 65 20 3d 20 73 71 6c 69 74 65 33 5f 6d  File = sqlite3_m
4ad0: 70 72 69 6e 74 66 28 22 25 2e 2a 73 22 2c 20 6e  printf("%.*s", n
4ae0: 46 69 6c 65 2c 20 61 52 65 61 64 29 3b 20 0a 20  File, aRead); . 
4af0: 20 20 20 20 20 70 4e 65 77 2d 3e 61 45 78 74 72       pNew->aExtr
4b00: 61 20 3d 20 28 75 38 2a 29 26 70 4e 65 77 5b 31  a = (u8*)&pNew[1
4b10: 5d 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28  ];.      memcpy(
4b20: 70 4e 65 77 2d 3e 61 45 78 74 72 61 2c 20 26 61  pNew->aExtra, &a
4b30: 52 65 61 64 5b 6e 46 69 6c 65 5d 2c 20 6e 45 78  Read[nFile], nEx
4b40: 74 72 61 29 3b 0a 20 20 20 20 20 20 69 66 28 20  tra);.      if( 
4b50: 70 4e 65 77 2d 3e 63 64 73 2e 7a 46 69 6c 65 3d  pNew->cds.zFile=
4b60: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63  =0 ){.        rc
4b70: 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b   = SQLITE_NOMEM;
4b80: 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28  .      }else if(
4b90: 20 30 3d 3d 7a 69 70 66 69 6c 65 53 63 61 6e 45   0==zipfileScanE
4ba0: 78 74 72 61 28 26 61 52 65 61 64 5b 6e 46 69 6c  xtra(&aRead[nFil
4bb0: 65 5d 2c 20 70 4e 65 77 2d 3e 63 64 73 2e 6e 45  e], pNew->cds.nE
4bc0: 78 74 72 61 2c 20 70 74 29 20 29 7b 0a 20 20 20  xtra, pt) ){.   
4bd0: 20 20 20 20 20 70 4e 65 77 2d 3e 6d 55 6e 69 78       pNew->mUnix
4be0: 54 69 6d 65 20 3d 20 7a 69 70 66 69 6c 65 4d 74  Time = zipfileMt
4bf0: 69 6d 65 28 26 70 4e 65 77 2d 3e 63 64 73 29 3b  ime(&pNew->cds);
4c00: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a  .      }.    }..
4c10: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
4c20: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73  TE_OK ){.      s
4c30: 74 61 74 69 63 20 63 6f 6e 73 74 20 69 6e 74 20  tatic const int 
4c40: 73 7a 46 69 78 20 3d 20 5a 49 50 46 49 4c 45 5f  szFix = ZIPFILE_
4c50: 4c 46 48 5f 46 49 58 45 44 5f 53 5a 3b 0a 20 20  LFH_FIXED_SZ;.  
4c60: 20 20 20 20 5a 69 70 66 69 6c 65 4c 46 48 20 6c      ZipfileLFH l
4c70: 66 68 3b 0a 20 20 20 20 20 20 69 66 28 20 70 46  fh;.      if( pF
4c80: 69 6c 65 20 29 7b 0a 20 20 20 20 20 20 20 20 72  ile ){.        r
4c90: 63 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 44  c = zipfileReadD
4ca0: 61 74 61 28 70 46 69 6c 65 2c 20 61 52 65 61 64  ata(pFile, aRead
4cb0: 2c 20 73 7a 46 69 78 2c 20 70 4e 65 77 2d 3e 63  , szFix, pNew->c
4cc0: 64 73 2e 69 4f 66 66 73 65 74 2c 20 70 7a 45 72  ds.iOffset, pzEr
4cd0: 72 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  r);.      }else{
4ce0: 0a 20 20 20 20 20 20 20 20 61 52 65 61 64 20 3d  .        aRead =
4cf0: 20 28 75 38 2a 29 26 61 42 6c 6f 62 5b 70 4e 65   (u8*)&aBlob[pNe
4d00: 77 2d 3e 63 64 73 2e 69 4f 66 66 73 65 74 5d 3b  w->cds.iOffset];
4d10: 0a 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20  .      }..      
4d20: 72 63 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64  rc = zipfileRead
4d30: 4c 46 48 28 61 52 65 61 64 2c 20 26 6c 66 68 29  LFH(aRead, &lfh)
4d40: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
4d50: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
4d60: 20 20 20 20 20 70 4e 65 77 2d 3e 69 44 61 74 61       pNew->iData
4d70: 4f 66 66 20 3d 20 20 70 4e 65 77 2d 3e 63 64 73  Off =  pNew->cds
4d80: 2e 69 4f 66 66 73 65 74 20 2b 20 5a 49 50 46 49  .iOffset + ZIPFI
4d90: 4c 45 5f 4c 46 48 5f 46 49 58 45 44 5f 53 5a 3b  LE_LFH_FIXED_SZ;
4da0: 0a 20 20 20 20 20 20 20 20 70 4e 65 77 2d 3e 69  .        pNew->i
4db0: 44 61 74 61 4f 66 66 20 2b 3d 20 6c 66 68 2e 6e  DataOff += lfh.n
4dc0: 46 69 6c 65 20 2b 20 6c 66 68 2e 6e 45 78 74 72  File + lfh.nExtr
4dd0: 61 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 61  a;.        if( a
4de0: 42 6c 6f 62 20 26 26 20 70 4e 65 77 2d 3e 63 64  Blob && pNew->cd
4df0: 73 2e 73 7a 43 6f 6d 70 72 65 73 73 65 64 20 29  s.szCompressed )
4e00: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 4e 65 77  {.          pNew
4e10: 2d 3e 61 44 61 74 61 20 3d 20 26 70 4e 65 77 2d  ->aData = &pNew-
4e20: 3e 61 45 78 74 72 61 5b 6e 45 78 74 72 61 5d 3b  >aExtra[nExtra];
4e30: 0a 20 20 20 20 20 20 20 20 20 20 6d 65 6d 63 70  .          memcp
4e40: 79 28 70 4e 65 77 2d 3e 61 44 61 74 61 2c 20 26  y(pNew->aData, &
4e50: 61 42 6c 6f 62 5b 70 4e 65 77 2d 3e 69 44 61 74  aBlob[pNew->iDat
4e60: 61 4f 66 66 5d 2c 20 70 4e 65 77 2d 3e 63 64 73  aOff], pNew->cds
4e70: 2e 73 7a 43 6f 6d 70 72 65 73 73 65 64 29 3b 0a  .szCompressed);.
4e80: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
4e90: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 2a  }else{.        *
4ea0: 70 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f  pzErr = sqlite3_
4eb0: 6d 70 72 69 6e 74 66 28 22 66 61 69 6c 65 64 20  mprintf("failed 
4ec0: 74 6f 20 72 65 61 64 20 4c 46 48 20 61 74 20 6f  to read LFH at o
4ed0: 66 66 73 65 74 20 25 64 22 2c 20 0a 20 20 20 20  ffset %d", .    
4ee0: 20 20 20 20 20 20 20 20 28 69 6e 74 29 70 4e 65          (int)pNe
4ef0: 77 2d 3e 63 64 73 2e 69 4f 66 66 73 65 74 0a 20  w->cds.iOffset. 
4f00: 20 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20         );.      
4f10: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  }.    }..    if(
4f20: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
4f30: 7b 0a 20 20 20 20 20 20 7a 69 70 66 69 6c 65 45  {.      zipfileE
4f40: 6e 74 72 79 46 72 65 65 28 70 4e 65 77 29 3b 0a  ntryFree(pNew);.
4f50: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4f60: 20 2a 70 70 45 6e 74 72 79 20 3d 20 70 4e 65 77   *ppEntry = pNew
4f70: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
4f80: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
4f90: 74 69 63 20 46 49 4c 45 20 2a 7a 69 70 66 69 6c  tic FILE *zipfil
4fa0: 65 47 65 74 46 64 28 5a 69 70 66 69 6c 65 43 73  eGetFd(ZipfileCs
4fb0: 72 20 2a 70 43 73 72 29 7b 0a 20 20 69 66 28 20  r *pCsr){.  if( 
4fc0: 70 43 73 72 2d 3e 70 46 69 6c 65 20 29 20 72 65  pCsr->pFile ) re
4fd0: 74 75 72 6e 20 70 43 73 72 2d 3e 70 46 69 6c 65  turn pCsr->pFile
4fe0: 3b 0a 20 20 72 65 74 75 72 6e 20 28 28 5a 69 70  ;.  return ((Zip
4ff0: 66 69 6c 65 54 61 62 2a 29 28 70 43 73 72 2d 3e  fileTab*)(pCsr->
5000: 62 61 73 65 2e 70 56 74 61 62 29 29 2d 3e 70 57  base.pVtab))->pW
5010: 72 69 74 65 46 64 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  riteFd;.}.../*.*
5020: 2a 20 41 64 76 61 6e 63 65 20 61 6e 20 5a 69 70  * Advance an Zip
5030: 66 69 6c 65 43 73 72 20 74 6f 20 69 74 73 20 6e  fileCsr to its n
5040: 65 78 74 20 72 6f 77 20 6f 66 20 6f 75 74 70 75  ext row of outpu
5050: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t..*/.static int
5060: 20 7a 69 70 66 69 6c 65 4e 65 78 74 28 73 71 6c   zipfileNext(sql
5070: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
5080: 20 2a 63 75 72 29 7b 0a 20 20 5a 69 70 66 69 6c   *cur){.  Zipfil
5090: 65 43 73 72 20 2a 70 43 73 72 20 3d 20 28 5a 69  eCsr *pCsr = (Zi
50a0: 70 66 69 6c 65 43 73 72 2a 29 63 75 72 3b 0a 20  pfileCsr*)cur;. 
50b0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
50c0: 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 70 43 73 72  _OK;..  if( pCsr
50d0: 2d 3e 70 46 69 6c 65 20 29 7b 0a 20 20 20 20 69  ->pFile ){.    i
50e0: 36 34 20 69 45 6f 66 20 3d 20 70 43 73 72 2d 3e  64 iEof = pCsr->
50f0: 65 6f 63 64 2e 69 4f 66 66 73 65 74 20 2b 20 70  eocd.iOffset + p
5100: 43 73 72 2d 3e 65 6f 63 64 2e 6e 53 69 7a 65 3b  Csr->eocd.nSize;
5110: 0a 20 20 20 20 7a 69 70 66 69 6c 65 45 6e 74 72  .    zipfileEntr
5120: 79 46 72 65 65 28 70 43 73 72 2d 3e 70 43 75 72  yFree(pCsr->pCur
5130: 72 65 6e 74 29 3b 0a 20 20 20 20 70 43 73 72 2d  rent);.    pCsr-
5140: 3e 70 43 75 72 72 65 6e 74 20 3d 20 30 3b 0a 20  >pCurrent = 0;. 
5150: 20 20 20 69 66 28 20 70 43 73 72 2d 3e 69 4e 65     if( pCsr->iNe
5160: 78 74 4f 66 66 3e 3d 69 45 6f 66 20 29 7b 0a 20  xtOff>=iEof ){. 
5170: 20 20 20 20 20 70 43 73 72 2d 3e 62 45 6f 66 20       pCsr->bEof 
5180: 3d 20 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  = 1;.    }else{.
5190: 20 20 20 20 20 20 5a 69 70 66 69 6c 65 45 6e 74        ZipfileEnt
51a0: 72 79 20 2a 70 20 3d 20 30 3b 0a 20 20 20 20 20  ry *p = 0;.     
51b0: 20 5a 69 70 66 69 6c 65 54 61 62 20 2a 70 54 61   ZipfileTab *pTa
51c0: 62 20 3d 20 28 5a 69 70 66 69 6c 65 54 61 62 2a  b = (ZipfileTab*
51d0: 29 28 63 75 72 2d 3e 70 56 74 61 62 29 3b 0a 20  )(cur->pVtab);. 
51e0: 20 20 20 20 20 72 63 20 3d 20 7a 69 70 66 69 6c       rc = zipfil
51f0: 65 47 65 74 45 6e 74 72 79 28 70 54 61 62 2c 20  eGetEntry(pTab, 
5200: 30 2c 20 30 2c 20 70 43 73 72 2d 3e 70 46 69 6c  0, 0, pCsr->pFil
5210: 65 2c 20 70 43 73 72 2d 3e 69 4e 65 78 74 4f 66  e, pCsr->iNextOf
5220: 66 2c 20 26 70 29 3b 0a 20 20 20 20 20 20 69 66  f, &p);.      if
5230: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
5240: 29 7b 0a 20 20 20 20 20 20 20 20 70 43 73 72 2d  ){.        pCsr-
5250: 3e 69 4e 65 78 74 4f 66 66 20 2b 3d 20 5a 49 50  >iNextOff += ZIP
5260: 46 49 4c 45 5f 43 44 53 5f 46 49 58 45 44 5f 53  FILE_CDS_FIXED_S
5270: 5a 3b 0a 20 20 20 20 20 20 20 20 70 43 73 72 2d  Z;.        pCsr-
5280: 3e 69 4e 65 78 74 4f 66 66 20 2b 3d 20 28 69 6e  >iNextOff += (in
5290: 74 29 70 2d 3e 63 64 73 2e 6e 45 78 74 72 61 20  t)p->cds.nExtra 
52a0: 2b 20 70 2d 3e 63 64 73 2e 6e 46 69 6c 65 20 2b  + p->cds.nFile +
52b0: 20 70 2d 3e 63 64 73 2e 6e 43 6f 6d 6d 65 6e 74   p->cds.nComment
52c0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
52d0: 70 43 73 72 2d 3e 70 43 75 72 72 65 6e 74 20 3d  pCsr->pCurrent =
52e0: 20 70 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73   p;.    }.  }els
52f0: 65 7b 0a 20 20 20 20 69 66 28 20 21 70 43 73 72  e{.    if( !pCsr
5300: 2d 3e 62 4e 6f 6f 70 20 29 7b 0a 20 20 20 20 20  ->bNoop ){.     
5310: 20 70 43 73 72 2d 3e 70 43 75 72 72 65 6e 74 20   pCsr->pCurrent 
5320: 3d 20 70 43 73 72 2d 3e 70 43 75 72 72 65 6e 74  = pCsr->pCurrent
5330: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 7d 0a 20  ->pNext;.    }. 
5340: 20 20 20 69 66 28 20 70 43 73 72 2d 3e 70 43 75     if( pCsr->pCu
5350: 72 72 65 6e 74 3d 3d 30 20 29 7b 0a 20 20 20 20  rrent==0 ){.    
5360: 20 20 70 43 73 72 2d 3e 62 45 6f 66 20 3d 20 31    pCsr->bEof = 1
5370: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 70  ;.    }.  }..  p
5380: 43 73 72 2d 3e 62 4e 6f 6f 70 20 3d 20 30 3b 0a  Csr->bNoop = 0;.
5390: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
53a0: 73 74 61 74 69 63 20 76 6f 69 64 20 7a 69 70 66  static void zipf
53b0: 69 6c 65 4d 74 69 6d 65 54 6f 44 6f 73 28 5a 69  ileMtimeToDos(Zi
53c0: 70 66 69 6c 65 43 44 53 20 2a 70 43 64 73 2c 20  pfileCDS *pCds, 
53d0: 75 33 32 20 6d 54 69 6d 65 29 7b 0a 20 20 74 69  u32 mTime){.  ti
53e0: 6d 65 5f 74 20 74 20 3d 20 28 74 69 6d 65 5f 74  me_t t = (time_t
53f0: 29 6d 54 69 6d 65 3b 0a 20 20 73 74 72 75 63 74  )mTime;.  struct
5400: 20 74 6d 20 72 65 73 3b 0a 0a 23 69 66 20 21 64   tm res;..#if !d
5410: 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 20 26  efined(_WIN32) &
5420: 26 20 21 64 65 66 69 6e 65 64 28 57 49 4e 33 32  & !defined(WIN32
5430: 29 0a 20 20 6c 6f 63 61 6c 74 69 6d 65 5f 72 28  ).  localtime_r(
5440: 26 74 2c 20 26 72 65 73 29 3b 0a 23 65 6c 73 65  &t, &res);.#else
5450: 0a 20 20 6d 65 6d 63 70 79 28 26 72 65 73 2c 20  .  memcpy(&res, 
5460: 6c 6f 63 61 6c 74 69 6d 65 28 26 74 29 2c 20 73  localtime(&t), s
5470: 69 7a 65 6f 66 28 73 74 72 75 63 74 20 74 6d 29  izeof(struct tm)
5480: 29 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 70 43 64  );.#endif..  pCd
5490: 73 2d 3e 6d 54 69 6d 65 20 3d 20 28 75 31 36 29  s->mTime = (u16)
54a0: 28 0a 20 20 20 20 28 72 65 73 2e 74 6d 5f 73 65  (.    (res.tm_se
54b0: 63 20 2f 20 32 29 20 2b 20 0a 20 20 20 20 28 72  c / 2) + .    (r
54c0: 65 73 2e 74 6d 5f 6d 69 6e 20 3c 3c 20 35 29 20  es.tm_min << 5) 
54d0: 2b 0a 20 20 20 20 28 72 65 73 2e 74 6d 5f 68 6f  +.    (res.tm_ho
54e0: 75 72 20 3c 3c 20 31 31 29 29 3b 0a 0a 20 20 70  ur << 11));..  p
54f0: 43 64 73 2d 3e 6d 44 61 74 65 20 3d 20 28 75 31  Cds->mDate = (u1
5500: 36 29 28 0a 20 20 20 20 28 72 65 73 2e 74 6d 5f  6)(.    (res.tm_
5510: 6d 64 61 79 2d 31 29 20 2b 0a 20 20 20 20 28 28  mday-1) +.    ((
5520: 72 65 73 2e 74 6d 5f 6d 6f 6e 2b 31 29 20 3c 3c  res.tm_mon+1) <<
5530: 20 35 29 20 2b 0a 20 20 20 20 28 28 72 65 73 2e   5) +.    ((res.
5540: 74 6d 5f 79 65 61 72 2d 38 30 29 20 3c 3c 20 39  tm_year-80) << 9
5550: 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  ));.}..static vo
5560: 69 64 20 7a 69 70 66 69 6c 65 49 6e 66 6c 61 74  id zipfileInflat
5570: 65 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e  e(.  sqlite3_con
5580: 74 65 78 74 20 2a 70 43 74 78 2c 20 20 20 20 20  text *pCtx,     
5590: 20 20 20 20 20 2f 2a 20 53 74 6f 72 65 20 65 72       /* Store er
55a0: 72 6f 72 20 68 65 72 65 2c 20 69 66 20 61 6e 79  ror here, if any
55b0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 75 38 20 2a   */.  const u8 *
55c0: 61 49 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  aIn,            
55d0: 20 20 20 20 20 20 2f 2a 20 43 6f 6d 70 72 65 73        /* Compres
55e0: 73 65 64 20 64 61 74 61 20 2a 2f 0a 20 20 69 6e  sed data */.  in
55f0: 74 20 6e 49 6e 2c 20 20 20 20 20 20 20 20 20 20  t nIn,          
5600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5610: 20 53 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20   Size of buffer 
5620: 61 49 6e 5b 5d 20 69 6e 20 62 79 74 65 73 20 2a  aIn[] in bytes *
5630: 2f 0a 20 20 69 6e 74 20 6e 4f 75 74 20 20 20 20  /.  int nOut    
5640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5650: 20 20 20 20 2f 2a 20 45 78 70 65 63 74 65 64 20      /* Expected 
5660: 6f 75 74 70 75 74 20 73 69 7a 65 20 2a 2f 0a 29  output size */.)
5670: 7b 0a 20 20 75 38 20 2a 61 52 65 73 20 3d 20 73  {.  u8 *aRes = s
5680: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 4f  qlite3_malloc(nO
5690: 75 74 29 3b 0a 20 20 69 66 28 20 61 52 65 73 3d  ut);.  if( aRes=
56a0: 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  =0 ){.    sqlite
56b0: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f 6e  3_result_error_n
56c0: 6f 6d 65 6d 28 70 43 74 78 29 3b 0a 20 20 7d 65  omem(pCtx);.  }e
56d0: 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 65 72 72  lse{.    int err
56e0: 3b 0a 20 20 20 20 7a 5f 73 74 72 65 61 6d 20 73  ;.    z_stream s
56f0: 74 72 3b 0a 20 20 20 20 6d 65 6d 73 65 74 28 26  tr;.    memset(&
5700: 73 74 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73  str, 0, sizeof(s
5710: 74 72 29 29 3b 0a 0a 20 20 20 20 73 74 72 2e 6e  tr));..    str.n
5720: 65 78 74 5f 69 6e 20 3d 20 28 42 79 74 65 2a 29  ext_in = (Byte*)
5730: 61 49 6e 3b 0a 20 20 20 20 73 74 72 2e 61 76 61  aIn;.    str.ava
5740: 69 6c 5f 69 6e 20 3d 20 6e 49 6e 3b 0a 20 20 20  il_in = nIn;.   
5750: 20 73 74 72 2e 6e 65 78 74 5f 6f 75 74 20 3d 20   str.next_out = 
5760: 28 42 79 74 65 2a 29 61 52 65 73 3b 0a 20 20 20  (Byte*)aRes;.   
5770: 20 73 74 72 2e 61 76 61 69 6c 5f 6f 75 74 20 3d   str.avail_out =
5780: 20 6e 4f 75 74 3b 0a 0a 20 20 20 20 65 72 72 20   nOut;..    err 
5790: 3d 20 69 6e 66 6c 61 74 65 49 6e 69 74 32 28 26  = inflateInit2(&
57a0: 73 74 72 2c 20 2d 31 35 29 3b 0a 20 20 20 20 69  str, -15);.    i
57b0: 66 28 20 65 72 72 21 3d 5a 5f 4f 4b 20 29 7b 0a  f( err!=Z_OK ){.
57c0: 20 20 20 20 20 20 7a 69 70 66 69 6c 65 43 74 78        zipfileCtx
57d0: 45 72 72 6f 72 4d 73 67 28 70 43 74 78 2c 20 22  ErrorMsg(pCtx, "
57e0: 69 6e 66 6c 61 74 65 49 6e 69 74 32 28 29 20 66  inflateInit2() f
57f0: 61 69 6c 65 64 20 28 25 64 29 22 2c 20 65 72 72  ailed (%d)", err
5800: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
5810: 20 20 20 20 65 72 72 20 3d 20 69 6e 66 6c 61 74      err = inflat
5820: 65 28 26 73 74 72 2c 20 5a 5f 4e 4f 5f 46 4c 55  e(&str, Z_NO_FLU
5830: 53 48 29 3b 0a 20 20 20 20 20 20 69 66 28 20 65  SH);.      if( e
5840: 72 72 21 3d 5a 5f 53 54 52 45 41 4d 5f 45 4e 44  rr!=Z_STREAM_END
5850: 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 69 70 66   ){.        zipf
5860: 69 6c 65 43 74 78 45 72 72 6f 72 4d 73 67 28 70  ileCtxErrorMsg(p
5870: 43 74 78 2c 20 22 69 6e 66 6c 61 74 65 28 29 20  Ctx, "inflate() 
5880: 66 61 69 6c 65 64 20 28 25 64 29 22 2c 20 65 72  failed (%d)", er
5890: 72 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  r);.      }else{
58a0: 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33  .        sqlite3
58b0: 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28 70 43 74  _result_blob(pCt
58c0: 78 2c 20 61 52 65 73 2c 20 6e 4f 75 74 2c 20 53  x, aRes, nOut, S
58d0: 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29  QLITE_TRANSIENT)
58e0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
58f0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
5900: 28 61 52 65 73 29 3b 0a 20 20 20 20 69 6e 66 6c  (aRes);.    infl
5910: 61 74 65 45 6e 64 28 26 73 74 72 29 3b 0a 20 20  ateEnd(&str);.  
5920: 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  }.}..static int 
5930: 7a 69 70 66 69 6c 65 44 65 66 6c 61 74 65 28 0a  zipfileDeflate(.
5940: 20 20 5a 69 70 66 69 6c 65 54 61 62 20 2a 70 54    ZipfileTab *pT
5950: 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ab,             
5960: 20 20 2f 2a 20 53 65 74 20 65 72 72 6f 72 20 6d    /* Set error m
5970: 65 73 73 61 67 65 20 68 65 72 65 20 2a 2f 0a 20  essage here */. 
5980: 20 63 6f 6e 73 74 20 75 38 20 2a 61 49 6e 2c 20   const u8 *aIn, 
5990: 69 6e 74 20 6e 49 6e 2c 20 20 20 20 20 20 20 20  int nIn,        
59a0: 20 2f 2a 20 49 6e 70 75 74 20 2a 2f 0a 20 20 75   /* Input */.  u
59b0: 38 20 2a 2a 70 70 4f 75 74 2c 20 69 6e 74 20 2a  8 **ppOut, int *
59c0: 70 6e 4f 75 74 20 20 20 20 20 20 20 20 20 20 2f  pnOut          /
59d0: 2a 20 4f 75 74 70 75 74 20 2a 2f 0a 29 7b 0a 20  * Output */.){. 
59e0: 20 69 6e 74 20 6e 41 6c 6c 6f 63 20 3d 20 28 69   int nAlloc = (i
59f0: 6e 74 29 63 6f 6d 70 72 65 73 73 42 6f 75 6e 64  nt)compressBound
5a00: 28 6e 49 6e 29 3b 0a 20 20 75 38 20 2a 61 4f 75  (nIn);.  u8 *aOu
5a10: 74 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  t;.  int rc = SQ
5a20: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 61 4f 75 74  LITE_OK;..  aOut
5a30: 20 3d 20 28 75 38 2a 29 73 71 6c 69 74 65 33 5f   = (u8*)sqlite3_
5a40: 6d 61 6c 6c 6f 63 28 6e 41 6c 6c 6f 63 29 3b 0a  malloc(nAlloc);.
5a50: 20 20 69 66 28 20 61 4f 75 74 3d 3d 30 20 29 7b    if( aOut==0 ){
5a60: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
5a70: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b  _NOMEM;.  }else{
5a80: 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20  .    int res;.  
5a90: 20 20 7a 5f 73 74 72 65 61 6d 20 73 74 72 3b 0a    z_stream str;.
5aa0: 20 20 20 20 6d 65 6d 73 65 74 28 26 73 74 72 2c      memset(&str,
5ab0: 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72 29 29   0, sizeof(str))
5ac0: 3b 0a 20 20 20 20 73 74 72 2e 6e 65 78 74 5f 69  ;.    str.next_i
5ad0: 6e 20 3d 20 28 42 79 74 65 66 2a 29 61 49 6e 3b  n = (Bytef*)aIn;
5ae0: 0a 20 20 20 20 73 74 72 2e 61 76 61 69 6c 5f 69  .    str.avail_i
5af0: 6e 20 3d 20 6e 49 6e 3b 0a 20 20 20 20 73 74 72  n = nIn;.    str
5b00: 2e 6e 65 78 74 5f 6f 75 74 20 3d 20 61 4f 75 74  .next_out = aOut
5b10: 3b 0a 20 20 20 20 73 74 72 2e 61 76 61 69 6c 5f  ;.    str.avail_
5b20: 6f 75 74 20 3d 20 6e 41 6c 6c 6f 63 3b 0a 0a 20  out = nAlloc;.. 
5b30: 20 20 20 64 65 66 6c 61 74 65 49 6e 69 74 32 28     deflateInit2(
5b40: 26 73 74 72 2c 20 39 2c 20 5a 5f 44 45 46 4c 41  &str, 9, Z_DEFLA
5b50: 54 45 44 2c 20 2d 31 35 2c 20 38 2c 20 5a 5f 44  TED, -15, 8, Z_D
5b60: 45 46 41 55 4c 54 5f 53 54 52 41 54 45 47 59 29  EFAULT_STRATEGY)
5b70: 3b 0a 20 20 20 20 72 65 73 20 3d 20 64 65 66 6c  ;.    res = defl
5b80: 61 74 65 28 26 73 74 72 2c 20 5a 5f 46 49 4e 49  ate(&str, Z_FINI
5b90: 53 48 29 3b 0a 0a 20 20 20 20 69 66 28 20 72 65  SH);..    if( re
5ba0: 73 3d 3d 5a 5f 53 54 52 45 41 4d 5f 45 4e 44 20  s==Z_STREAM_END 
5bb0: 29 7b 0a 20 20 20 20 20 20 2a 70 70 4f 75 74 20  ){.      *ppOut 
5bc0: 3d 20 61 4f 75 74 3b 0a 20 20 20 20 20 20 2a 70  = aOut;.      *p
5bd0: 6e 4f 75 74 20 3d 20 28 69 6e 74 29 73 74 72 2e  nOut = (int)str.
5be0: 74 6f 74 61 6c 5f 6f 75 74 3b 0a 20 20 20 20 7d  total_out;.    }
5bf0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69  else{.      sqli
5c00: 74 65 33 5f 66 72 65 65 28 61 4f 75 74 29 3b 0a  te3_free(aOut);.
5c10: 20 20 20 20 20 20 70 54 61 62 2d 3e 62 61 73 65        pTab->base
5c20: 2e 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74  .zErrMsg = sqlit
5c30: 65 33 5f 6d 70 72 69 6e 74 66 28 22 7a 69 70 66  e3_mprintf("zipf
5c40: 69 6c 65 3a 20 64 65 66 6c 61 74 65 28 29 20 65  ile: deflate() e
5c50: 72 72 6f 72 22 29 3b 0a 20 20 20 20 20 20 72 63  rror");.      rc
5c60: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
5c70: 0a 20 20 20 20 7d 0a 20 20 20 20 64 65 66 6c 61  .    }.    defla
5c80: 74 65 45 6e 64 28 26 73 74 72 29 3b 0a 20 20 7d  teEnd(&str);.  }
5c90: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
5ca0: 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  .../*.** Return 
5cb0: 76 61 6c 75 65 73 20 6f 66 20 63 6f 6c 75 6d 6e  values of column
5cc0: 73 20 66 6f 72 20 74 68 65 20 72 6f 77 20 61 74  s for the row at
5cd0: 20 77 68 69 63 68 20 74 68 65 20 73 65 72 69 65   which the serie
5ce0: 73 5f 63 75 72 73 6f 72 0a 2a 2a 20 69 73 20 63  s_cursor.** is c
5cf0: 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74 69 6e  urrently pointin
5d00: 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  g..*/.static int
5d10: 20 7a 69 70 66 69 6c 65 43 6f 6c 75 6d 6e 28 0a   zipfileColumn(.
5d20: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63    sqlite3_vtab_c
5d30: 75 72 73 6f 72 20 2a 63 75 72 2c 20 20 20 2f 2a  ursor *cur,   /*
5d40: 20 54 68 65 20 63 75 72 73 6f 72 20 2a 2f 0a 20   The cursor */. 
5d50: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
5d60: 20 2a 63 74 78 2c 20 20 20 20 20 20 20 2f 2a 20   *ctx,       /* 
5d70: 46 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74  First argument t
5d80: 6f 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74  o sqlite3_result
5d90: 5f 2e 2e 2e 28 29 20 2a 2f 0a 20 20 69 6e 74 20  _...() */.  int 
5da0: 69 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i               
5db0: 20 20 20 20 20 20 20 20 2f 2a 20 57 68 69 63 68          /* Which
5dc0: 20 63 6f 6c 75 6d 6e 20 74 6f 20 72 65 74 75 72   column to retur
5dd0: 6e 20 2a 2f 0a 29 7b 0a 20 20 5a 69 70 66 69 6c  n */.){.  Zipfil
5de0: 65 43 73 72 20 2a 70 43 73 72 20 3d 20 28 5a 69  eCsr *pCsr = (Zi
5df0: 70 66 69 6c 65 43 73 72 2a 29 63 75 72 3b 0a 20  pfileCsr*)cur;. 
5e00: 20 5a 69 70 66 69 6c 65 43 44 53 20 2a 70 43 44   ZipfileCDS *pCD
5e10: 53 20 3d 20 26 70 43 73 72 2d 3e 70 43 75 72 72  S = &pCsr->pCurr
5e20: 65 6e 74 2d 3e 63 64 73 3b 0a 20 20 69 6e 74 20  ent->cds;.  int 
5e30: 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  rc = SQLITE_OK;.
5e40: 20 20 73 77 69 74 63 68 28 20 69 20 29 7b 0a 20    switch( i ){. 
5e50: 20 20 20 63 61 73 65 20 30 3a 20 20 20 2f 2a 20     case 0:   /* 
5e60: 6e 61 6d 65 20 2a 2f 0a 20 20 20 20 20 20 73 71  name */.      sq
5e70: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78  lite3_result_tex
5e80: 74 28 63 74 78 2c 20 70 43 44 53 2d 3e 7a 46 69  t(ctx, pCDS->zFi
5e90: 6c 65 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54  le, -1, SQLITE_T
5ea0: 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20 20 20  RANSIENT);.     
5eb0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65   break;.    case
5ec0: 20 31 3a 20 20 20 2f 2a 20 6d 6f 64 65 20 2a 2f   1:   /* mode */
5ed0: 0a 20 20 20 20 20 20 2f 2a 20 54 4f 44 4f 3a 20  .      /* TODO: 
5ee0: 57 68 65 74 68 65 72 20 6f 72 20 6e 6f 74 20 74  Whether or not t
5ef0: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 69 73 20  he following is 
5f00: 63 6f 72 72 65 63 74 20 73 75 72 65 6c 79 20 64  correct surely d
5f10: 65 70 65 6e 64 73 20 6f 6e 0a 20 20 20 20 20 20  epends on.      
5f20: 2a 2a 20 74 68 65 20 70 6c 61 74 66 6f 72 6d 20  ** the platform 
5f30: 6f 6e 20 77 68 69 63 68 20 74 68 65 20 61 72 63  on which the arc
5f40: 68 69 76 65 20 77 61 73 20 63 72 65 61 74 65 64  hive was created
5f50: 2e 20 20 2a 2f 0a 20 20 20 20 20 20 73 71 6c 69  .  */.      sqli
5f60: 74 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74 28 63  te3_result_int(c
5f70: 74 78 2c 20 70 43 44 53 2d 3e 69 45 78 74 65 72  tx, pCDS->iExter
5f80: 6e 61 6c 41 74 74 72 20 3e 3e 20 31 36 29 3b 0a  nalAttr >> 16);.
5f90: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
5fa0: 20 63 61 73 65 20 32 3a 20 7b 20 2f 2a 20 6d 74   case 2: { /* mt
5fb0: 69 6d 65 20 2a 2f 0a 20 20 20 20 20 20 73 71 6c  ime */.      sql
5fc0: 69 74 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74 36  ite3_result_int6
5fd0: 34 28 63 74 78 2c 20 70 43 73 72 2d 3e 70 43 75  4(ctx, pCsr->pCu
5fe0: 72 72 65 6e 74 2d 3e 6d 55 6e 69 78 54 69 6d 65  rrent->mUnixTime
5ff0: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
6000: 20 20 20 20 7d 0a 20 20 20 20 63 61 73 65 20 33      }.    case 3
6010: 3a 20 7b 20 2f 2a 20 73 7a 20 2a 2f 0a 20 20 20  : { /* sz */.   
6020: 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 76     if( sqlite3_v
6030: 74 61 62 5f 6e 6f 63 68 61 6e 67 65 28 63 74 78  tab_nochange(ctx
6040: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  )==0 ){.        
6050: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 69  sqlite3_result_i
6060: 6e 74 36 34 28 63 74 78 2c 20 70 43 44 53 2d 3e  nt64(ctx, pCDS->
6070: 73 7a 55 6e 63 6f 6d 70 72 65 73 73 65 64 29 3b  szUncompressed);
6080: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 62  .      }.      b
6090: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20  reak;.    }.    
60a0: 63 61 73 65 20 34 3a 20 20 20 2f 2a 20 72 61 77  case 4:   /* raw
60b0: 64 61 74 61 20 2a 2f 0a 20 20 20 20 20 20 69 66  data */.      if
60c0: 28 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 6e  ( sqlite3_vtab_n
60d0: 6f 63 68 61 6e 67 65 28 63 74 78 29 20 29 20 62  ochange(ctx) ) b
60e0: 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65 20 35  reak;.    case 5
60f0: 3a 20 7b 20 2f 2a 20 64 61 74 61 20 2a 2f 0a 20  : { /* data */. 
6100: 20 20 20 20 20 69 66 28 20 69 3d 3d 34 20 7c 7c       if( i==4 ||
6110: 20 70 43 44 53 2d 3e 69 43 6f 6d 70 72 65 73 73   pCDS->iCompress
6120: 69 6f 6e 3d 3d 30 20 7c 7c 20 70 43 44 53 2d 3e  ion==0 || pCDS->
6130: 69 43 6f 6d 70 72 65 73 73 69 6f 6e 3d 3d 38 20  iCompression==8 
6140: 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 73  ){.        int s
6150: 7a 20 3d 20 70 43 44 53 2d 3e 73 7a 43 6f 6d 70  z = pCDS->szComp
6160: 72 65 73 73 65 64 3b 0a 20 20 20 20 20 20 20 20  ressed;.        
6170: 69 6e 74 20 73 7a 46 69 6e 61 6c 20 3d 20 70 43  int szFinal = pC
6180: 44 53 2d 3e 73 7a 55 6e 63 6f 6d 70 72 65 73 73  DS->szUncompress
6190: 65 64 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  ed;.        if( 
61a0: 73 7a 46 69 6e 61 6c 3e 30 20 29 7b 0a 20 20 20  szFinal>0 ){.   
61b0: 20 20 20 20 20 20 20 75 38 20 2a 61 42 75 66 3b         u8 *aBuf;
61c0: 0a 20 20 20 20 20 20 20 20 20 20 75 38 20 2a 61  .          u8 *a
61d0: 46 72 65 65 20 3d 20 30 3b 0a 20 20 20 20 20 20  Free = 0;.      
61e0: 20 20 20 20 69 66 28 20 70 43 73 72 2d 3e 70 43      if( pCsr->pC
61f0: 75 72 72 65 6e 74 2d 3e 61 44 61 74 61 20 29 7b  urrent->aData ){
6200: 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 42 75  .            aBu
6210: 66 20 3d 20 70 43 73 72 2d 3e 70 43 75 72 72 65  f = pCsr->pCurre
6220: 6e 74 2d 3e 61 44 61 74 61 3b 0a 20 20 20 20 20  nt->aData;.     
6230: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
6240: 20 20 20 20 20 20 20 20 61 42 75 66 20 3d 20 61          aBuf = a
6250: 46 72 65 65 20 3d 20 73 71 6c 69 74 65 33 5f 6d  Free = sqlite3_m
6260: 61 6c 6c 6f 63 28 73 7a 29 3b 0a 20 20 20 20 20  alloc(sz);.     
6270: 20 20 20 20 20 20 20 69 66 28 20 61 42 75 66 3d         if( aBuf=
6280: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
6290: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
62a0: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20 20  NOMEM;.         
62b0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
62c0: 20 20 20 20 20 20 20 20 46 49 4c 45 20 2a 70 46          FILE *pF
62d0: 69 6c 65 20 3d 20 7a 69 70 66 69 6c 65 47 65 74  ile = zipfileGet
62e0: 46 64 28 70 43 73 72 29 3b 0a 20 20 20 20 20 20  Fd(pCsr);.      
62f0: 20 20 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d          if( rc==
6300: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
6310: 20 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20               rc 
6320: 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 44 61 74  = zipfileReadDat
6330: 61 28 70 46 69 6c 65 2c 20 61 42 75 66 2c 20 73  a(pFile, aBuf, s
6340: 7a 2c 20 70 43 73 72 2d 3e 70 43 75 72 72 65 6e  z, pCsr->pCurren
6350: 74 2d 3e 69 44 61 74 61 4f 66 66 2c 0a 20 20 20  t->iDataOff,.   
6360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6370: 20 26 70 43 73 72 2d 3e 62 61 73 65 2e 70 56 74   &pCsr->base.pVt
6380: 61 62 2d 3e 7a 45 72 72 4d 73 67 0a 20 20 20 20  ab->zErrMsg.    
6390: 20 20 20 20 20 20 20 20 20 20 20 20 29 3b 0a 20              );. 
63a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20               }. 
63b0: 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20             }.   
63c0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
63d0: 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54     if( rc==SQLIT
63e0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
63f0: 20 20 20 20 69 66 28 20 69 3d 3d 35 20 26 26 20      if( i==5 && 
6400: 70 43 44 53 2d 3e 69 43 6f 6d 70 72 65 73 73 69  pCDS->iCompressi
6410: 6f 6e 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  on ){.          
6420: 20 20 20 20 7a 69 70 66 69 6c 65 49 6e 66 6c 61      zipfileInfla
6430: 74 65 28 63 74 78 2c 20 61 42 75 66 2c 20 73 7a  te(ctx, aBuf, sz
6440: 2c 20 73 7a 46 69 6e 61 6c 29 3b 0a 20 20 20 20  , szFinal);.    
6450: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
6460: 20 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c               sql
6470: 69 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62  ite3_result_blob
6480: 28 63 74 78 2c 20 61 42 75 66 2c 20 73 7a 2c 20  (ctx, aBuf, sz, 
6490: 53 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54  SQLITE_TRANSIENT
64a0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d  );.            }
64b0: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
64c0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66         sqlite3_f
64d0: 72 65 65 28 61 46 72 65 65 29 3b 0a 20 20 20 20  ree(aFree);.    
64e0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
64f0: 20 20 20 20 20 2f 2a 20 46 69 67 75 72 65 20 6f       /* Figure o
6500: 75 74 20 69 66 20 74 68 69 73 20 69 73 20 61 20  ut if this is a 
6510: 64 69 72 65 63 74 6f 72 79 20 6f 72 20 61 20 7a  directory or a z
6520: 65 72 6f 2d 73 69 7a 65 64 20 66 69 6c 65 2e 20  ero-sized file. 
6530: 43 6f 6e 73 69 64 65 72 0a 20 20 20 20 20 20 20  Consider.       
6540: 20 20 20 2a 2a 20 69 74 20 74 6f 20 62 65 20 61     ** it to be a
6550: 20 64 69 72 65 63 74 6f 72 79 20 65 69 74 68 65   directory eithe
6560: 72 20 69 66 20 74 68 65 20 6d 6f 64 65 20 73 75  r if the mode su
6570: 67 67 65 73 74 73 20 73 6f 2c 20 6f 72 20 69 66  ggests so, or if
6580: 0a 20 20 20 20 20 20 20 20 20 20 2a 2a 20 74 68  .          ** th
6590: 65 20 66 69 6e 61 6c 20 63 68 61 72 61 63 74 65  e final characte
65a0: 72 20 69 6e 20 74 68 65 20 6e 61 6d 65 20 69 73  r in the name is
65b0: 20 27 2f 27 2e 20 20 2a 2f 0a 20 20 20 20 20 20   '/'.  */.      
65c0: 20 20 20 20 75 33 32 20 6d 6f 64 65 20 3d 20 70      u32 mode = p
65d0: 43 44 53 2d 3e 69 45 78 74 65 72 6e 61 6c 41 74  CDS->iExternalAt
65e0: 74 72 20 3e 3e 20 31 36 3b 0a 20 20 20 20 20 20  tr >> 16;.      
65f0: 20 20 20 20 69 66 28 20 21 28 6d 6f 64 65 20 26      if( !(mode &
6600: 20 53 5f 49 46 44 49 52 29 20 26 26 20 70 43 44   S_IFDIR) && pCD
6610: 53 2d 3e 7a 46 69 6c 65 5b 70 43 44 53 2d 3e 6e  S->zFile[pCDS->n
6620: 46 69 6c 65 2d 31 5d 21 3d 27 2f 27 20 29 7b 0a  File-1]!='/' ){.
6630: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
6640: 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f 62 28  te3_result_blob(
6650: 63 74 78 2c 20 22 22 2c 20 30 2c 20 53 51 4c 49  ctx, "", 0, SQLI
6660: 54 45 5f 53 54 41 54 49 43 29 3b 0a 20 20 20 20  TE_STATIC);.    
6670: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
6680: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
6690: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20  break;.    }.   
66a0: 20 63 61 73 65 20 36 3a 20 20 20 2f 2a 20 6d 65   case 6:   /* me
66b0: 74 68 6f 64 20 2a 2f 0a 20 20 20 20 20 20 73 71  thod */.      sq
66c0: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74  lite3_result_int
66d0: 28 63 74 78 2c 20 70 43 44 53 2d 3e 69 43 6f 6d  (ctx, pCDS->iCom
66e0: 70 72 65 73 73 69 6f 6e 29 3b 0a 20 20 20 20 20  pression);.     
66f0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61 73 65   break;.    case
6700: 20 37 3a 20 20 20 2f 2a 20 7a 20 2a 2f 0a 20 20   7:   /* z */.  
6710: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
6720: 6c 74 5f 69 6e 74 36 34 28 63 74 78 2c 20 70 43  lt_int64(ctx, pC
6730: 73 72 2d 3e 69 49 64 29 3b 0a 20 20 20 20 20 20  sr->iId);.      
6740: 62 72 65 61 6b 3b 0a 20 20 7d 0a 0a 20 20 72 65  break;.  }..  re
6750: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
6760: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 72 6f 77  * Return the row
6770: 69 64 20 66 6f 72 20 74 68 65 20 63 75 72 72 65  id for the curre
6780: 6e 74 20 72 6f 77 2e 0a 2a 2f 0a 73 74 61 74 69  nt row..*/.stati
6790: 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 52 6f 77  c int zipfileRow
67a0: 69 64 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  id(sqlite3_vtab_
67b0: 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c  cursor *cur, sql
67c0: 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69  ite_int64 *pRowi
67d0: 64 29 7b 0a 20 20 61 73 73 65 72 74 28 20 30 20  d){.  assert( 0 
67e0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  );.  return SQLI
67f0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
6800: 52 65 74 75 72 6e 20 54 52 55 45 20 69 66 20 74  Return TRUE if t
6810: 68 65 20 63 75 72 73 6f 72 20 68 61 73 20 62 65  he cursor has be
6820: 65 6e 20 6d 6f 76 65 64 20 6f 66 66 20 6f 66 20  en moved off of 
6830: 74 68 65 20 6c 61 73 74 0a 2a 2a 20 72 6f 77 20  the last.** row 
6840: 6f 66 20 6f 75 74 70 75 74 2e 0a 2a 2f 0a 73 74  of output..*/.st
6850: 61 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65  atic int zipfile
6860: 45 6f 66 28 73 71 6c 69 74 65 33 5f 76 74 61 62  Eof(sqlite3_vtab
6870: 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20  _cursor *cur){. 
6880: 20 5a 69 70 66 69 6c 65 43 73 72 20 2a 70 43 73   ZipfileCsr *pCs
6890: 72 20 3d 20 28 5a 69 70 66 69 6c 65 43 73 72 2a  r = (ZipfileCsr*
68a0: 29 63 75 72 3b 0a 20 20 72 65 74 75 72 6e 20 70  )cur;.  return p
68b0: 43 73 72 2d 3e 62 45 6f 66 3b 0a 7d 0a 0a 2f 2a  Csr->bEof;.}../*
68c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 7a  .*/.static int z
68d0: 69 70 66 69 6c 65 52 65 61 64 45 4f 43 44 28 0a  ipfileReadEOCD(.
68e0: 20 20 5a 69 70 66 69 6c 65 54 61 62 20 2a 70 54    ZipfileTab *pT
68f0: 61 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ab,             
6900: 20 20 2f 2a 20 52 65 74 75 72 6e 20 65 72 72 6f    /* Return erro
6910: 72 73 20 68 65 72 65 20 2a 2f 0a 20 20 63 6f 6e  rs here */.  con
6920: 73 74 20 75 38 20 2a 61 42 6c 6f 62 2c 20 20 20  st u8 *aBlob,   
6930: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
6940: 50 6f 69 6e 74 65 72 20 74 6f 20 69 6e 2d 6d 65  Pointer to in-me
6950: 6d 6f 72 79 20 66 69 6c 65 20 69 6d 61 67 65 20  mory file image 
6960: 2a 2f 0a 20 20 69 6e 74 20 6e 42 6c 6f 62 2c 20  */.  int nBlob, 
6970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6980: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
6990: 61 42 6c 6f 62 5b 5d 20 69 6e 20 62 79 74 65 73  aBlob[] in bytes
69a0: 20 2a 2f 0a 20 20 46 49 4c 45 20 2a 70 46 69 6c   */.  FILE *pFil
69b0: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
69c0: 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20 66 72        /* Read fr
69d0: 6f 6d 20 74 68 69 73 20 66 69 6c 65 20 69 66 20  om this file if 
69e0: 61 42 6c 6f 62 3d 3d 30 20 2a 2f 0a 20 20 5a 69  aBlob==0 */.  Zi
69f0: 70 66 69 6c 65 45 4f 43 44 20 2a 70 45 4f 43 44  pfileEOCD *pEOCD
6a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6a10: 20 4f 62 6a 65 63 74 20 74 6f 20 70 6f 70 75 6c   Object to popul
6a20: 61 74 65 20 2a 2f 0a 29 7b 0a 20 20 75 38 20 2a  ate */.){.  u8 *
6a30: 61 52 65 61 64 20 3d 20 70 54 61 62 2d 3e 61 42  aRead = pTab->aB
6a40: 75 66 66 65 72 3b 20 20 20 20 20 20 2f 2a 20 54  uffer;      /* T
6a50: 65 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72 20  emporary buffer 
6a60: 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 61 64 3b 20  */.  int nRead; 
6a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a80: 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 74 6f       /* Bytes to
6a90: 20 72 65 61 64 20 66 72 6f 6d 20 66 69 6c 65 20   read from file 
6aa0: 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  */.  int rc = SQ
6ab0: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20  LITE_OK;..  if( 
6ac0: 61 42 6c 6f 62 3d 3d 30 20 29 7b 0a 20 20 20 20  aBlob==0 ){.    
6ad0: 69 36 34 20 69 4f 66 66 3b 20 20 20 20 20 20 20  i64 iOff;       
6ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6af0: 20 4f 66 66 73 65 74 20 74 6f 20 72 65 61 64 20   Offset to read 
6b00: 66 72 6f 6d 20 2a 2f 0a 20 20 20 20 69 36 34 20  from */.    i64 
6b10: 73 7a 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20  szFile;         
6b20: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74            /* Tot
6b30: 61 6c 20 73 69 7a 65 20 6f 66 20 66 69 6c 65 20  al size of file 
6b40: 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20 20 20  in bytes */.    
6b50: 66 73 65 65 6b 28 70 46 69 6c 65 2c 20 30 2c 20  fseek(pFile, 0, 
6b60: 53 45 45 4b 5f 45 4e 44 29 3b 0a 20 20 20 20 73  SEEK_END);.    s
6b70: 7a 46 69 6c 65 20 3d 20 28 69 36 34 29 66 74 65  zFile = (i64)fte
6b80: 6c 6c 28 70 46 69 6c 65 29 3b 0a 20 20 20 20 69  ll(pFile);.    i
6b90: 66 28 20 73 7a 46 69 6c 65 3d 3d 30 20 29 7b 0a  f( szFile==0 ){.
6ba0: 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70 45 4f        memset(pEO
6bb0: 43 44 2c 20 30 2c 20 73 69 7a 65 6f 66 28 5a 69  CD, 0, sizeof(Zi
6bc0: 70 66 69 6c 65 45 4f 43 44 29 29 3b 0a 20 20 20  pfileEOCD));.   
6bd0: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
6be0: 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e  _OK;.    }.    n
6bf0: 52 65 61 64 20 3d 20 28 69 6e 74 29 28 4d 49 4e  Read = (int)(MIN
6c00: 28 73 7a 46 69 6c 65 2c 20 5a 49 50 46 49 4c 45  (szFile, ZIPFILE
6c10: 5f 42 55 46 46 45 52 5f 53 49 5a 45 29 29 3b 0a  _BUFFER_SIZE));.
6c20: 20 20 20 20 69 4f 66 66 20 3d 20 73 7a 46 69 6c      iOff = szFil
6c30: 65 20 2d 20 6e 52 65 61 64 3b 0a 20 20 20 20 72  e - nRead;.    r
6c40: 63 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 44  c = zipfileReadD
6c50: 61 74 61 28 70 46 69 6c 65 2c 20 61 52 65 61 64  ata(pFile, aRead
6c60: 2c 20 6e 52 65 61 64 2c 20 69 4f 66 66 2c 20 26  , nRead, iOff, &
6c70: 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72 72 4d  pTab->base.zErrM
6c80: 73 67 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  sg);.  }else{.  
6c90: 20 20 6e 52 65 61 64 20 3d 20 28 69 6e 74 29 28    nRead = (int)(
6ca0: 4d 49 4e 28 6e 42 6c 6f 62 2c 20 5a 49 50 46 49  MIN(nBlob, ZIPFI
6cb0: 4c 45 5f 42 55 46 46 45 52 5f 53 49 5a 45 29 29  LE_BUFFER_SIZE))
6cc0: 3b 0a 20 20 20 20 61 52 65 61 64 20 3d 20 28 75  ;.    aRead = (u
6cd0: 38 2a 29 26 61 42 6c 6f 62 5b 6e 42 6c 6f 62 2d  8*)&aBlob[nBlob-
6ce0: 6e 52 65 61 64 5d 3b 0a 20 20 7d 0a 0a 20 20 69  nRead];.  }..  i
6cf0: 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc==SQLITE_OK
6d00: 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 3b 0a 0a   ){.    int i;..
6d10: 20 20 20 20 2f 2a 20 53 63 61 6e 20 62 61 63 6b      /* Scan back
6d20: 77 61 72 64 73 20 6c 6f 6f 6b 69 6e 67 20 66 6f  wards looking fo
6d30: 72 20 74 68 65 20 73 69 67 6e 61 74 75 72 65 20  r the signature 
6d40: 62 79 74 65 73 20 2a 2f 0a 20 20 20 20 66 6f 72  bytes */.    for
6d50: 28 69 3d 6e 52 65 61 64 2d 32 30 3b 20 69 3e 3d  (i=nRead-20; i>=
6d60: 30 3b 20 69 2d 2d 29 7b 0a 20 20 20 20 20 20 69  0; i--){.      i
6d70: 66 28 20 61 52 65 61 64 5b 69 5d 3d 3d 30 78 35  f( aRead[i]==0x5
6d80: 30 20 26 26 20 61 52 65 61 64 5b 69 2b 31 5d 3d  0 && aRead[i+1]=
6d90: 3d 30 78 34 62 20 0a 20 20 20 20 20 20 20 26 26  =0x4b .       &&
6da0: 20 61 52 65 61 64 5b 69 2b 32 5d 3d 3d 30 78 30   aRead[i+2]==0x0
6db0: 35 20 26 26 20 61 52 65 61 64 5b 69 2b 33 5d 3d  5 && aRead[i+3]=
6dc0: 3d 30 78 30 36 20 0a 20 20 20 20 20 20 29 7b 0a  =0x06 .      ){.
6dd0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20          break;. 
6de0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
6df0: 20 69 66 28 20 69 3c 30 20 29 7b 0a 20 20 20 20   if( i<0 ){.    
6e00: 20 20 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72    pTab->base.zEr
6e10: 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d  rMsg = sqlite3_m
6e20: 70 72 69 6e 74 66 28 0a 20 20 20 20 20 20 20 20  printf(.        
6e30: 20 20 22 63 61 6e 6e 6f 74 20 66 69 6e 64 20 65    "cannot find e
6e40: 6e 64 20 6f 66 20 63 65 6e 74 72 61 6c 20 64 69  nd of central di
6e50: 72 65 63 74 6f 72 79 20 72 65 63 6f 72 64 22 0a  rectory record".
6e60: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 72        );.      r
6e70: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
6e80: 4f 52 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 61  OR;.    }..    a
6e90: 52 65 61 64 20 2b 3d 20 69 2b 34 3b 0a 20 20 20  Read += i+4;.   
6ea0: 20 70 45 4f 43 44 2d 3e 69 44 69 73 6b 20 3d 20   pEOCD->iDisk = 
6eb0: 7a 69 70 66 69 6c 65 52 65 61 64 31 36 28 61 52  zipfileRead16(aR
6ec0: 65 61 64 29 3b 0a 20 20 20 20 70 45 4f 43 44 2d  ead);.    pEOCD-
6ed0: 3e 69 46 69 72 73 74 44 69 73 6b 20 3d 20 7a 69  >iFirstDisk = zi
6ee0: 70 66 69 6c 65 52 65 61 64 31 36 28 61 52 65 61  pfileRead16(aRea
6ef0: 64 29 3b 0a 20 20 20 20 70 45 4f 43 44 2d 3e 6e  d);.    pEOCD->n
6f00: 45 6e 74 72 79 20 3d 20 7a 69 70 66 69 6c 65 52  Entry = zipfileR
6f10: 65 61 64 31 36 28 61 52 65 61 64 29 3b 0a 20 20  ead16(aRead);.  
6f20: 20 20 70 45 4f 43 44 2d 3e 6e 45 6e 74 72 79 54    pEOCD->nEntryT
6f30: 6f 74 61 6c 20 3d 20 7a 69 70 66 69 6c 65 52 65  otal = zipfileRe
6f40: 61 64 31 36 28 61 52 65 61 64 29 3b 0a 20 20 20  ad16(aRead);.   
6f50: 20 70 45 4f 43 44 2d 3e 6e 53 69 7a 65 20 3d 20   pEOCD->nSize = 
6f60: 7a 69 70 66 69 6c 65 52 65 61 64 33 32 28 61 52  zipfileRead32(aR
6f70: 65 61 64 29 3b 0a 20 20 20 20 70 45 4f 43 44 2d  ead);.    pEOCD-
6f80: 3e 69 4f 66 66 73 65 74 20 3d 20 7a 69 70 66 69  >iOffset = zipfi
6f90: 6c 65 52 65 61 64 33 32 28 61 52 65 61 64 29 3b  leRead32(aRead);
6fa0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53  .  }..  return S
6fb0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
6fc0: 2a 2a 20 41 64 64 20 6f 62 6a 65 63 74 20 70 4e  ** Add object pN
6fd0: 65 77 20 74 6f 20 74 68 65 20 65 6e 64 20 6f 66  ew to the end of
6fe0: 20 74 68 65 20 6c 69 6e 6b 65 64 20 6c 69 73 74   the linked list
6ff0: 20 74 68 61 74 20 62 65 67 69 6e 73 20 61 74 0a   that begins at.
7000: 2a 2a 20 5a 69 70 66 69 6c 65 54 61 62 2e 70 46  ** ZipfileTab.pF
7010: 69 72 73 74 45 6e 74 72 79 20 61 6e 64 20 65 6e  irstEntry and en
7020: 64 73 20 77 69 74 68 20 70 4c 61 73 74 45 6e 74  ds with pLastEnt
7030: 72 79 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ry..*/.static vo
7040: 69 64 20 7a 69 70 66 69 6c 65 41 64 64 45 6e 74  id zipfileAddEnt
7050: 72 79 28 0a 20 20 5a 69 70 66 69 6c 65 54 61 62  ry(.  ZipfileTab
7060: 20 2a 70 54 61 62 2c 20 0a 20 20 5a 69 70 66 69   *pTab, .  Zipfi
7070: 6c 65 45 6e 74 72 79 20 2a 70 42 65 66 6f 72 65  leEntry *pBefore
7080: 2c 20 0a 20 20 5a 69 70 66 69 6c 65 45 6e 74 72  , .  ZipfileEntr
7090: 79 20 2a 70 4e 65 77 0a 29 7b 0a 20 20 61 73 73  y *pNew.){.  ass
70a0: 65 72 74 28 20 28 70 54 61 62 2d 3e 70 46 69 72  ert( (pTab->pFir
70b0: 73 74 45 6e 74 72 79 3d 3d 30 29 3d 3d 28 70 54  stEntry==0)==(pT
70c0: 61 62 2d 3e 70 4c 61 73 74 45 6e 74 72 79 3d 3d  ab->pLastEntry==
70d0: 30 29 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  0) );.  assert( 
70e0: 70 4e 65 77 2d 3e 70 4e 65 78 74 3d 3d 30 20 29  pNew->pNext==0 )
70f0: 3b 0a 20 20 69 66 28 20 70 42 65 66 6f 72 65 3d  ;.  if( pBefore=
7100: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 70 54  =0 ){.    if( pT
7110: 61 62 2d 3e 70 46 69 72 73 74 45 6e 74 72 79 3d  ab->pFirstEntry=
7120: 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 54 61 62  =0 ){.      pTab
7130: 2d 3e 70 46 69 72 73 74 45 6e 74 72 79 20 3d 20  ->pFirstEntry = 
7140: 70 54 61 62 2d 3e 70 4c 61 73 74 45 6e 74 72 79  pTab->pLastEntry
7150: 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 7d 65 6c   = pNew;.    }el
7160: 73 65 7b 0a 20 20 20 20 20 20 61 73 73 65 72 74  se{.      assert
7170: 28 20 70 54 61 62 2d 3e 70 4c 61 73 74 45 6e 74  ( pTab->pLastEnt
7180: 72 79 2d 3e 70 4e 65 78 74 3d 3d 30 20 29 3b 0a  ry->pNext==0 );.
7190: 20 20 20 20 20 20 70 54 61 62 2d 3e 70 4c 61 73        pTab->pLas
71a0: 74 45 6e 74 72 79 2d 3e 70 4e 65 78 74 20 3d 20  tEntry->pNext = 
71b0: 70 4e 65 77 3b 0a 20 20 20 20 20 20 70 54 61 62  pNew;.      pTab
71c0: 2d 3e 70 4c 61 73 74 45 6e 74 72 79 20 3d 20 70  ->pLastEntry = p
71d0: 4e 65 77 3b 0a 20 20 20 20 7d 0a 20 20 7d 65 6c  New;.    }.  }el
71e0: 73 65 7b 0a 20 20 20 20 5a 69 70 66 69 6c 65 45  se{.    ZipfileE
71f0: 6e 74 72 79 20 2a 2a 70 70 3b 0a 20 20 20 20 66  ntry **pp;.    f
7200: 6f 72 28 70 70 3d 26 70 54 61 62 2d 3e 70 46 69  or(pp=&pTab->pFi
7210: 72 73 74 45 6e 74 72 79 3b 20 2a 70 70 21 3d 70  rstEntry; *pp!=p
7220: 42 65 66 6f 72 65 3b 20 70 70 3d 26 28 28 2a 70  Before; pp=&((*p
7230: 70 29 2d 3e 70 4e 65 78 74 29 29 3b 0a 20 20 20  p)->pNext));.   
7240: 20 70 4e 65 77 2d 3e 70 4e 65 78 74 20 3d 20 70   pNew->pNext = p
7250: 42 65 66 6f 72 65 3b 0a 20 20 20 20 2a 70 70 20  Before;.    *pp 
7260: 3d 20 70 4e 65 77 3b 0a 20 20 7d 0a 7d 0a 0a 73  = pNew;.  }.}..s
7270: 74 61 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c  tatic int zipfil
7280: 65 4c 6f 61 64 44 69 72 65 63 74 6f 72 79 28 5a  eLoadDirectory(Z
7290: 69 70 66 69 6c 65 54 61 62 20 2a 70 54 61 62 2c  ipfileTab *pTab,
72a0: 20 63 6f 6e 73 74 20 75 38 20 2a 61 42 6c 6f 62   const u8 *aBlob
72b0: 2c 20 69 6e 74 20 6e 42 6c 6f 62 29 7b 0a 20 20  , int nBlob){.  
72c0: 5a 69 70 66 69 6c 65 45 4f 43 44 20 65 6f 63 64  ZipfileEOCD eocd
72d0: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69 6e  ;.  int rc;.  in
72e0: 74 20 69 3b 0a 20 20 69 36 34 20 69 4f 66 66 3b  t i;.  i64 iOff;
72f0: 0a 0a 20 20 72 63 20 3d 20 7a 69 70 66 69 6c 65  ..  rc = zipfile
7300: 52 65 61 64 45 4f 43 44 28 70 54 61 62 2c 20 61  ReadEOCD(pTab, a
7310: 42 6c 6f 62 2c 20 6e 42 6c 6f 62 2c 20 70 54 61  Blob, nBlob, pTa
7320: 62 2d 3e 70 57 72 69 74 65 46 64 2c 20 26 65 6f  b->pWriteFd, &eo
7330: 63 64 29 3b 0a 20 20 69 4f 66 66 20 3d 20 65 6f  cd);.  iOff = eo
7340: 63 64 2e 69 4f 66 66 73 65 74 3b 0a 20 20 66 6f  cd.iOffset;.  fo
7350: 72 28 69 3d 30 3b 20 72 63 3d 3d 53 51 4c 49 54  r(i=0; rc==SQLIT
7360: 45 5f 4f 4b 20 26 26 20 69 3c 65 6f 63 64 2e 6e  E_OK && i<eocd.n
7370: 45 6e 74 72 79 3b 20 69 2b 2b 29 7b 0a 20 20 20  Entry; i++){.   
7380: 20 5a 69 70 66 69 6c 65 45 6e 74 72 79 20 2a 70   ZipfileEntry *p
7390: 4e 65 77 20 3d 20 30 3b 0a 20 20 20 20 72 63 20  New = 0;.    rc 
73a0: 3d 20 7a 69 70 66 69 6c 65 47 65 74 45 6e 74 72  = zipfileGetEntr
73b0: 79 28 70 54 61 62 2c 20 61 42 6c 6f 62 2c 20 6e  y(pTab, aBlob, n
73c0: 42 6c 6f 62 2c 20 70 54 61 62 2d 3e 70 57 72 69  Blob, pTab->pWri
73d0: 74 65 46 64 2c 20 69 4f 66 66 2c 20 26 70 4e 65  teFd, iOff, &pNe
73e0: 77 29 3b 0a 0a 20 20 20 20 69 66 28 20 72 63 3d  w);..    if( rc=
73f0: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
7400: 20 20 20 20 7a 69 70 66 69 6c 65 41 64 64 45 6e      zipfileAddEn
7410: 74 72 79 28 70 54 61 62 2c 20 30 2c 20 70 4e 65  try(pTab, 0, pNe
7420: 77 29 3b 0a 20 20 20 20 20 20 69 4f 66 66 20 2b  w);.      iOff +
7430: 3d 20 5a 49 50 46 49 4c 45 5f 43 44 53 5f 46 49  = ZIPFILE_CDS_FI
7440: 58 45 44 5f 53 5a 3b 0a 20 20 20 20 20 20 69 4f  XED_SZ;.      iO
7450: 66 66 20 2b 3d 20 28 69 6e 74 29 70 4e 65 77 2d  ff += (int)pNew-
7460: 3e 63 64 73 2e 6e 45 78 74 72 61 20 2b 20 70 4e  >cds.nExtra + pN
7470: 65 77 2d 3e 63 64 73 2e 6e 46 69 6c 65 20 2b 20  ew->cds.nFile + 
7480: 70 4e 65 77 2d 3e 63 64 73 2e 6e 43 6f 6d 6d 65  pNew->cds.nComme
7490: 6e 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  nt;.    }.  }.  
74a0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
74b0: 0a 2a 2a 20 78 46 69 6c 74 65 72 20 63 61 6c 6c  .** xFilter call
74c0: 62 61 63 6b 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  back..*/.static 
74d0: 69 6e 74 20 7a 69 70 66 69 6c 65 46 69 6c 74 65  int zipfileFilte
74e0: 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61  r(.  sqlite3_vta
74f0: 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20 0a  b_cursor *cur, .
7500: 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20 63 6f    int idxNum, co
7510: 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53 74 72  nst char *idxStr
7520: 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20 73 71  ,.  int argc, sq
7530: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72  lite3_value **ar
7540: 67 76 0a 29 7b 0a 20 20 5a 69 70 66 69 6c 65 54  gv.){.  ZipfileT
7550: 61 62 20 2a 70 54 61 62 20 3d 20 28 5a 69 70 66  ab *pTab = (Zipf
7560: 69 6c 65 54 61 62 2a 29 63 75 72 2d 3e 70 56 74  ileTab*)cur->pVt
7570: 61 62 3b 0a 20 20 5a 69 70 66 69 6c 65 43 73 72  ab;.  ZipfileCsr
7580: 20 2a 70 43 73 72 20 3d 20 28 5a 69 70 66 69 6c   *pCsr = (Zipfil
7590: 65 43 73 72 2a 29 63 75 72 3b 0a 20 20 63 6f 6e  eCsr*)cur;.  con
75a0: 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 3b 20  st char *zFile; 
75b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
75c0: 5a 69 70 20 66 69 6c 65 20 74 6f 20 73 63 61 6e  Zip file to scan
75d0: 20 2a 2f 0a 20 20 69 6e 74 20 72 63 20 3d 20 53   */.  int rc = S
75e0: 51 4c 49 54 45 5f 4f 4b 3b 20 20 20 20 20 20 20  QLITE_OK;       
75f0: 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72 6e 20        /* Return 
7600: 43 6f 64 65 20 2a 2f 0a 20 20 69 6e 74 20 62 49  Code */.  int bI
7610: 6e 4d 65 6d 6f 72 79 20 3d 20 30 3b 20 20 20 20  nMemory = 0;    
7620: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75            /* Tru
7630: 65 20 66 6f 72 20 61 6e 20 69 6e 2d 6d 65 6d 6f  e for an in-memo
7640: 72 79 20 7a 69 70 66 69 6c 65 20 2a 2f 0a 0a 20  ry zipfile */.. 
7650: 20 7a 69 70 66 69 6c 65 52 65 73 65 74 43 75 72   zipfileResetCur
7660: 73 6f 72 28 70 43 73 72 29 3b 0a 0a 20 20 69 66  sor(pCsr);..  if
7670: 28 20 70 54 61 62 2d 3e 7a 46 69 6c 65 20 29 7b  ( pTab->zFile ){
7680: 0a 20 20 20 20 7a 46 69 6c 65 20 3d 20 70 54 61  .    zFile = pTa
7690: 62 2d 3e 7a 46 69 6c 65 3b 0a 20 20 7d 65 6c 73  b->zFile;.  }els
76a0: 65 20 69 66 28 20 69 64 78 4e 75 6d 3d 3d 30 20  e if( idxNum==0 
76b0: 29 7b 0a 20 20 20 20 62 49 6e 4d 65 6d 6f 72 79  ){.    bInMemory
76c0: 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65 20 69 66   = 1;.  }else if
76d0: 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  ( sqlite3_value_
76e0: 74 79 70 65 28 61 72 67 76 5b 30 5d 29 3d 3d 53  type(argv[0])==S
76f0: 51 4c 49 54 45 5f 42 4c 4f 42 20 29 7b 0a 20 20  QLITE_BLOB ){.  
7700: 20 20 63 6f 6e 73 74 20 75 38 20 2a 61 42 6c 6f    const u8 *aBlo
7710: 62 20 3d 20 28 63 6f 6e 73 74 20 75 38 2a 29 73  b = (const u8*)s
7720: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 6c 6f  qlite3_value_blo
7730: 62 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20 20 20  b(argv[0]);.    
7740: 69 6e 74 20 6e 42 6c 6f 62 20 3d 20 73 71 6c 69  int nBlob = sqli
7750: 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28  te3_value_bytes(
7760: 61 72 67 76 5b 30 5d 29 3b 0a 20 20 20 20 61 73  argv[0]);.    as
7770: 73 65 72 74 28 20 70 54 61 62 2d 3e 70 46 69 72  sert( pTab->pFir
7780: 73 74 45 6e 74 72 79 3d 3d 30 20 29 3b 0a 20 20  stEntry==0 );.  
7790: 20 20 72 63 20 3d 20 7a 69 70 66 69 6c 65 4c 6f    rc = zipfileLo
77a0: 61 64 44 69 72 65 63 74 6f 72 79 28 70 54 61 62  adDirectory(pTab
77b0: 2c 20 61 42 6c 6f 62 2c 20 6e 42 6c 6f 62 29 3b  , aBlob, nBlob);
77c0: 0a 20 20 20 20 70 43 73 72 2d 3e 70 46 72 65 65  .    pCsr->pFree
77d0: 45 6e 74 72 79 20 3d 20 70 54 61 62 2d 3e 70 46  Entry = pTab->pF
77e0: 69 72 73 74 45 6e 74 72 79 3b 0a 20 20 20 20 70  irstEntry;.    p
77f0: 54 61 62 2d 3e 70 46 69 72 73 74 45 6e 74 72 79  Tab->pFirstEntry
7800: 20 3d 20 70 54 61 62 2d 3e 70 4c 61 73 74 45 6e   = pTab->pLastEn
7810: 74 72 79 20 3d 20 30 3b 0a 20 20 20 20 69 66 28  try = 0;.    if(
7820: 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc!=SQLITE_OK )
7830: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 20 20   return rc;.    
7840: 62 49 6e 4d 65 6d 6f 72 79 20 3d 20 31 3b 0a 20  bInMemory = 1;. 
7850: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 7a 46 69 6c   }else{.    zFil
7860: 65 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a  e = (const char*
7870: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74  )sqlite3_value_t
7880: 65 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20  ext(argv[0]);.  
7890: 7d 0a 0a 20 20 69 66 28 20 30 3d 3d 70 54 61 62  }..  if( 0==pTab
78a0: 2d 3e 70 57 72 69 74 65 46 64 20 26 26 20 30 3d  ->pWriteFd && 0=
78b0: 3d 62 49 6e 4d 65 6d 6f 72 79 20 29 7b 0a 20 20  =bInMemory ){.  
78c0: 20 20 70 43 73 72 2d 3e 70 46 69 6c 65 20 3d 20    pCsr->pFile = 
78d0: 66 6f 70 65 6e 28 7a 46 69 6c 65 2c 20 22 72 62  fopen(zFile, "rb
78e0: 22 29 3b 0a 20 20 20 20 69 66 28 20 70 43 73 72  ");.    if( pCsr
78f0: 2d 3e 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20  ->pFile==0 ){.  
7900: 20 20 20 20 7a 69 70 66 69 6c 65 53 65 74 45 72      zipfileSetEr
7910: 72 6d 73 67 28 70 43 73 72 2c 20 22 63 61 6e 6e  rmsg(pCsr, "cann
7920: 6f 74 20 6f 70 65 6e 20 66 69 6c 65 3a 20 25 73  ot open file: %s
7930: 22 2c 20 7a 46 69 6c 65 29 3b 0a 20 20 20 20 20  ", zFile);.     
7940: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52   rc = SQLITE_ERR
7950: 4f 52 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  OR;.    }else{. 
7960: 20 20 20 20 20 72 63 20 3d 20 7a 69 70 66 69 6c       rc = zipfil
7970: 65 52 65 61 64 45 4f 43 44 28 70 54 61 62 2c 20  eReadEOCD(pTab, 
7980: 30 2c 20 30 2c 20 70 43 73 72 2d 3e 70 46 69 6c  0, 0, pCsr->pFil
7990: 65 2c 20 26 70 43 73 72 2d 3e 65 6f 63 64 29 3b  e, &pCsr->eocd);
79a0: 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53  .      if( rc==S
79b0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
79c0: 20 20 20 20 69 66 28 20 70 43 73 72 2d 3e 65 6f      if( pCsr->eo
79d0: 63 64 2e 6e 45 6e 74 72 79 3d 3d 30 20 29 7b 0a  cd.nEntry==0 ){.
79e0: 20 20 20 20 20 20 20 20 20 20 70 43 73 72 2d 3e            pCsr->
79f0: 62 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20 20 20  bEof = 1;.      
7a00: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
7a10: 20 20 20 70 43 73 72 2d 3e 69 4e 65 78 74 4f 66     pCsr->iNextOf
7a20: 66 20 3d 20 70 43 73 72 2d 3e 65 6f 63 64 2e 69  f = pCsr->eocd.i
7a30: 4f 66 66 73 65 74 3b 0a 20 20 20 20 20 20 20 20  Offset;.        
7a40: 20 20 72 63 20 3d 20 7a 69 70 66 69 6c 65 4e 65    rc = zipfileNe
7a50: 78 74 28 63 75 72 29 3b 0a 20 20 20 20 20 20 20  xt(cur);.       
7a60: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d   }.      }.    }
7a70: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 43  .  }else{.    pC
7a80: 73 72 2d 3e 62 4e 6f 6f 70 20 3d 20 31 3b 0a 20  sr->bNoop = 1;. 
7a90: 20 20 20 70 43 73 72 2d 3e 70 43 75 72 72 65 6e     pCsr->pCurren
7aa0: 74 20 3d 20 70 43 73 72 2d 3e 70 46 72 65 65 45  t = pCsr->pFreeE
7ab0: 6e 74 72 79 20 3f 20 70 43 73 72 2d 3e 70 46 72  ntry ? pCsr->pFr
7ac0: 65 65 45 6e 74 72 79 20 3a 20 70 54 61 62 2d 3e  eeEntry : pTab->
7ad0: 70 46 69 72 73 74 45 6e 74 72 79 3b 0a 20 20 20  pFirstEntry;.   
7ae0: 20 72 63 20 3d 20 7a 69 70 66 69 6c 65 4e 65 78   rc = zipfileNex
7af0: 74 28 63 75 72 29 3b 0a 20 20 7d 0a 0a 20 20 72  t(cur);.  }..  r
7b00: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a  eturn rc;.}../*.
7b10: 2a 2a 20 78 42 65 73 74 49 6e 64 65 78 20 63 61  ** xBestIndex ca
7b20: 6c 6c 62 61 63 6b 2e 0a 2a 2f 0a 73 74 61 74 69  llback..*/.stati
7b30: 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 42 65 73  c int zipfileBes
7b40: 74 49 6e 64 65 78 28 0a 20 20 73 71 6c 69 74 65  tIndex(.  sqlite
7b50: 33 5f 76 74 61 62 20 2a 74 61 62 2c 0a 20 20 73  3_vtab *tab,.  s
7b60: 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66  qlite3_index_inf
7b70: 6f 20 2a 70 49 64 78 49 6e 66 6f 0a 29 7b 0a 20  o *pIdxInfo.){. 
7b80: 20 69 6e 74 20 69 3b 0a 0a 20 20 66 6f 72 28 69   int i;..  for(i
7b90: 3d 30 3b 20 69 3c 70 49 64 78 49 6e 66 6f 2d 3e  =0; i<pIdxInfo->
7ba0: 6e 43 6f 6e 73 74 72 61 69 6e 74 3b 20 69 2b 2b  nConstraint; i++
7bb0: 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 73 74 72  ){.    const str
7bc0: 75 63 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65  uct sqlite3_inde
7bd0: 78 5f 63 6f 6e 73 74 72 61 69 6e 74 20 2a 70 43  x_constraint *pC
7be0: 6f 6e 73 20 3d 20 26 70 49 64 78 49 6e 66 6f 2d  ons = &pIdxInfo-
7bf0: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 5b 69 5d 3b  >aConstraint[i];
7c00: 0a 20 20 20 20 69 66 28 20 70 43 6f 6e 73 2d 3e  .    if( pCons->
7c10: 75 73 61 62 6c 65 3d 3d 30 20 29 20 63 6f 6e 74  usable==0 ) cont
7c20: 69 6e 75 65 3b 0a 20 20 20 20 69 66 28 20 70 43  inue;.    if( pC
7c30: 6f 6e 73 2d 3e 6f 70 21 3d 53 51 4c 49 54 45 5f  ons->op!=SQLITE_
7c40: 49 4e 44 45 58 5f 43 4f 4e 53 54 52 41 49 4e 54  INDEX_CONSTRAINT
7c50: 5f 45 51 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a  _EQ ) continue;.
7c60: 20 20 20 20 69 66 28 20 70 43 6f 6e 73 2d 3e 69      if( pCons->i
7c70: 43 6f 6c 75 6d 6e 21 3d 5a 49 50 46 49 4c 45 5f  Column!=ZIPFILE_
7c80: 46 5f 43 4f 4c 55 4d 4e 5f 49 44 58 20 29 20 63  F_COLUMN_IDX ) c
7c90: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 62 72 65  ontinue;.    bre
7ca0: 61 6b 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69  ak;.  }..  if( i
7cb0: 3c 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73  <pIdxInfo->nCons
7cc0: 74 72 61 69 6e 74 20 29 7b 0a 20 20 20 20 70 49  traint ){.    pI
7cd0: 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61  dxInfo->aConstra
7ce0: 69 6e 74 55 73 61 67 65 5b 69 5d 2e 61 72 67 76  intUsage[i].argv
7cf0: 49 6e 64 65 78 20 3d 20 31 3b 0a 20 20 20 20 70  Index = 1;.    p
7d00: 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72  IdxInfo->aConstr
7d10: 61 69 6e 74 55 73 61 67 65 5b 69 5d 2e 6f 6d 69  aintUsage[i].omi
7d20: 74 20 3d 20 31 3b 0a 20 20 20 20 70 49 64 78 49  t = 1;.    pIdxI
7d30: 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 43 6f  nfo->estimatedCo
7d40: 73 74 20 3d 20 31 30 30 30 2e 30 3b 0a 20 20 20  st = 1000.0;.   
7d50: 20 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75   pIdxInfo->idxNu
7d60: 6d 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a  m = 1;.  }else{.
7d70: 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73      pIdxInfo->es
7d80: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 28 64  timatedCost = (d
7d90: 6f 75 62 6c 65 29 28 28 28 73 71 6c 69 74 65 33  ouble)(((sqlite3
7da0: 5f 69 6e 74 36 34 29 31 29 20 3c 3c 20 35 30 29  _int64)1) << 50)
7db0: 3b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e  ;.    pIdxInfo->
7dc0: 69 64 78 4e 75 6d 20 3d 20 30 3b 0a 20 20 7d 0a  idxNum = 0;.  }.
7dd0: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
7de0: 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 5a  _OK;.}..static Z
7df0: 69 70 66 69 6c 65 45 6e 74 72 79 20 2a 7a 69 70  ipfileEntry *zip
7e00: 66 69 6c 65 4e 65 77 45 6e 74 72 79 28 63 6f 6e  fileNewEntry(con
7e10: 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c 20  st char *zPath, 
7e20: 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20 5a 69  int nData){.  Zi
7e30: 70 66 69 6c 65 45 6e 74 72 79 20 2a 70 4e 65 77  pfileEntry *pNew
7e40: 3b 0a 20 20 70 4e 65 77 20 3d 20 73 71 6c 69 74  ;.  pNew = sqlit
7e50: 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  e3_malloc(sizeof
7e60: 28 5a 69 70 66 69 6c 65 45 6e 74 72 79 29 20 2b  (ZipfileEntry) +
7e70: 20 6e 44 61 74 61 29 3b 0a 20 20 69 66 28 20 70   nData);.  if( p
7e80: 4e 65 77 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65  New ){.    memse
7e90: 74 28 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f  t(pNew, 0, sizeo
7ea0: 66 28 5a 69 70 66 69 6c 65 45 6e 74 72 79 29 29  f(ZipfileEntry))
7eb0: 3b 0a 20 20 20 20 69 66 28 20 6e 44 61 74 61 20  ;.    if( nData 
7ec0: 29 7b 0a 20 20 20 20 20 20 70 4e 65 77 2d 3e 61  ){.      pNew->a
7ed0: 44 61 74 61 20 3d 20 28 75 38 2a 29 26 70 4e 65  Data = (u8*)&pNe
7ee0: 77 5b 31 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20  w[1];.    }.    
7ef0: 70 4e 65 77 2d 3e 63 64 73 2e 7a 46 69 6c 65 20  pNew->cds.zFile 
7f00: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
7f10: 66 28 22 25 73 22 2c 20 7a 50 61 74 68 29 3b 0a  f("%s", zPath);.
7f20: 20 20 20 20 69 66 28 20 70 4e 65 77 2d 3e 63 64      if( pNew->cd
7f30: 73 2e 7a 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20  s.zFile==0 ){.  
7f40: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
7f50: 28 70 4e 65 77 29 3b 0a 20 20 20 20 20 20 70 4e  (pNew);.      pN
7f60: 65 77 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20  ew = 0;.    }.  
7f70: 7d 0a 20 20 72 65 74 75 72 6e 20 70 4e 65 77 3b  }.  return pNew;
7f80: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 7a  .}..static int z
7f90: 69 70 66 69 6c 65 53 65 72 69 61 6c 69 7a 65 4c  ipfileSerializeL
7fa0: 46 48 28 5a 69 70 66 69 6c 65 45 6e 74 72 79 20  FH(ZipfileEntry 
7fb0: 2a 70 45 6e 74 72 79 2c 20 75 38 20 2a 61 42 75  *pEntry, u8 *aBu
7fc0: 66 29 7b 0a 20 20 5a 69 70 66 69 6c 65 43 44 53  f){.  ZipfileCDS
7fd0: 20 2a 70 43 64 73 20 3d 20 26 70 45 6e 74 72 79   *pCds = &pEntry
7fe0: 2d 3e 63 64 73 3b 0a 20 20 75 38 20 2a 61 20 3d  ->cds;.  u8 *a =
7ff0: 20 61 42 75 66 3b 0a 0a 20 20 70 43 64 73 2d 3e   aBuf;..  pCds->
8000: 6e 45 78 74 72 61 20 3d 20 39 3b 0a 0a 20 20 2f  nExtra = 9;..  /
8010: 2a 20 57 72 69 74 65 20 74 68 65 20 4c 46 48 20  * Write the LFH 
8020: 69 74 73 65 6c 66 20 2a 2f 0a 20 20 7a 69 70 66  itself */.  zipf
8030: 69 6c 65 57 72 69 74 65 33 32 28 61 2c 20 5a 49  ileWrite32(a, ZI
8040: 50 46 49 4c 45 5f 53 49 47 4e 41 54 55 52 45 5f  PFILE_SIGNATURE_
8050: 4c 46 48 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57  LFH);.  zipfileW
8060: 72 69 74 65 31 36 28 61 2c 20 70 43 64 73 2d 3e  rite16(a, pCds->
8070: 69 56 65 72 73 69 6f 6e 45 78 74 72 61 63 74 29  iVersionExtract)
8080: 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65  ;.  zipfileWrite
8090: 31 36 28 61 2c 20 70 43 64 73 2d 3e 66 6c 61 67  16(a, pCds->flag
80a0: 73 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69  s);.  zipfileWri
80b0: 74 65 31 36 28 61 2c 20 70 43 64 73 2d 3e 69 43  te16(a, pCds->iC
80c0: 6f 6d 70 72 65 73 73 69 6f 6e 29 3b 0a 20 20 7a  ompression);.  z
80d0: 69 70 66 69 6c 65 57 72 69 74 65 31 36 28 61 2c  ipfileWrite16(a,
80e0: 20 70 43 64 73 2d 3e 6d 54 69 6d 65 29 3b 0a 20   pCds->mTime);. 
80f0: 20 7a 69 70 66 69 6c 65 57 72 69 74 65 31 36 28   zipfileWrite16(
8100: 61 2c 20 70 43 64 73 2d 3e 6d 44 61 74 65 29 3b  a, pCds->mDate);
8110: 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65 33  .  zipfileWrite3
8120: 32 28 61 2c 20 70 43 64 73 2d 3e 63 72 63 33 32  2(a, pCds->crc32
8130: 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74  );.  zipfileWrit
8140: 65 33 32 28 61 2c 20 70 43 64 73 2d 3e 73 7a 43  e32(a, pCds->szC
8150: 6f 6d 70 72 65 73 73 65 64 29 3b 0a 20 20 7a 69  ompressed);.  zi
8160: 70 66 69 6c 65 57 72 69 74 65 33 32 28 61 2c 20  pfileWrite32(a, 
8170: 70 43 64 73 2d 3e 73 7a 55 6e 63 6f 6d 70 72 65  pCds->szUncompre
8180: 73 73 65 64 29 3b 0a 20 20 7a 69 70 66 69 6c 65  ssed);.  zipfile
8190: 57 72 69 74 65 31 36 28 61 2c 20 28 75 31 36 29  Write16(a, (u16)
81a0: 70 43 64 73 2d 3e 6e 46 69 6c 65 29 3b 0a 20 20  pCds->nFile);.  
81b0: 7a 69 70 66 69 6c 65 57 72 69 74 65 31 36 28 61  zipfileWrite16(a
81c0: 2c 20 70 43 64 73 2d 3e 6e 45 78 74 72 61 29 3b  , pCds->nExtra);
81d0: 0a 20 20 61 73 73 65 72 74 28 20 61 3d 3d 26 61  .  assert( a==&a
81e0: 42 75 66 5b 5a 49 50 46 49 4c 45 5f 4c 46 48 5f  Buf[ZIPFILE_LFH_
81f0: 46 49 58 45 44 5f 53 5a 5d 20 29 3b 0a 0a 20 20  FIXED_SZ] );..  
8200: 2f 2a 20 41 64 64 20 74 68 65 20 66 69 6c 65 20  /* Add the file 
8210: 6e 61 6d 65 20 2a 2f 0a 20 20 6d 65 6d 63 70 79  name */.  memcpy
8220: 28 61 2c 20 70 43 64 73 2d 3e 7a 46 69 6c 65 2c  (a, pCds->zFile,
8230: 20 28 69 6e 74 29 70 43 64 73 2d 3e 6e 46 69 6c   (int)pCds->nFil
8240: 65 29 3b 0a 20 20 61 20 2b 3d 20 28 69 6e 74 29  e);.  a += (int)
8250: 70 43 64 73 2d 3e 6e 46 69 6c 65 3b 0a 0a 20 20  pCds->nFile;..  
8260: 2f 2a 20 54 68 65 20 22 65 78 74 72 61 22 20 64  /* The "extra" d
8270: 61 74 61 20 2a 2f 0a 20 20 7a 69 70 66 69 6c 65  ata */.  zipfile
8280: 57 72 69 74 65 31 36 28 61 2c 20 5a 49 50 46 49  Write16(a, ZIPFI
8290: 4c 45 5f 45 58 54 52 41 5f 54 49 4d 45 53 54 41  LE_EXTRA_TIMESTA
82a0: 4d 50 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72  MP);.  zipfileWr
82b0: 69 74 65 31 36 28 61 2c 20 35 29 3b 0a 20 20 2a  ite16(a, 5);.  *
82c0: 61 2b 2b 20 3d 20 30 78 30 31 3b 0a 20 20 7a 69  a++ = 0x01;.  zi
82d0: 70 66 69 6c 65 57 72 69 74 65 33 32 28 61 2c 20  pfileWrite32(a, 
82e0: 70 45 6e 74 72 79 2d 3e 6d 55 6e 69 78 54 69 6d  pEntry->mUnixTim
82f0: 65 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 61 2d  e);..  return a-
8300: 61 42 75 66 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  aBuf;.}..static 
8310: 69 6e 74 20 7a 69 70 66 69 6c 65 41 70 70 65 6e  int zipfileAppen
8320: 64 45 6e 74 72 79 28 0a 20 20 5a 69 70 66 69 6c  dEntry(.  Zipfil
8330: 65 54 61 62 20 2a 70 54 61 62 2c 0a 20 20 5a 69  eTab *pTab,.  Zi
8340: 70 66 69 6c 65 45 6e 74 72 79 20 2a 70 45 6e 74  pfileEntry *pEnt
8350: 72 79 2c 0a 20 20 63 6f 6e 73 74 20 75 38 20 2a  ry,.  const u8 *
8360: 70 44 61 74 61 2c 0a 20 20 69 6e 74 20 6e 44 61  pData,.  int nDa
8370: 74 61 0a 29 7b 0a 20 20 75 38 20 2a 61 42 75 66  ta.){.  u8 *aBuf
8380: 20 3d 20 70 54 61 62 2d 3e 61 42 75 66 66 65 72   = pTab->aBuffer
8390: 3b 0a 20 20 69 6e 74 20 6e 42 75 66 3b 0a 20 20  ;.  int nBuf;.  
83a0: 69 6e 74 20 72 63 3b 0a 0a 20 20 6e 42 75 66 20  int rc;..  nBuf 
83b0: 3d 20 7a 69 70 66 69 6c 65 53 65 72 69 61 6c 69  = zipfileSeriali
83c0: 7a 65 4c 46 48 28 70 45 6e 74 72 79 2c 20 61 42  zeLFH(pEntry, aB
83d0: 75 66 29 3b 0a 20 20 72 63 20 3d 20 7a 69 70 66  uf);.  rc = zipf
83e0: 69 6c 65 41 70 70 65 6e 64 44 61 74 61 28 70 54  ileAppendData(pT
83f0: 61 62 2c 20 61 42 75 66 2c 20 6e 42 75 66 29 3b  ab, aBuf, nBuf);
8400: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
8410: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
8420: 20 7a 69 70 66 69 6c 65 41 70 70 65 6e 64 44 61   zipfileAppendDa
8430: 74 61 28 70 54 61 62 2c 20 70 44 61 74 61 2c 20  ta(pTab, pData, 
8440: 6e 44 61 74 61 29 3b 0a 20 20 7d 0a 0a 20 20 72  nData);.  }..  r
8450: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
8460: 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 47  tic int zipfileG
8470: 65 74 4d 6f 64 65 28 0a 20 20 5a 69 70 66 69 6c  etMode(.  Zipfil
8480: 65 54 61 62 20 2a 70 54 61 62 2c 20 0a 20 20 73  eTab *pTab, .  s
8490: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 56  qlite3_value *pV
84a0: 61 6c 2c 20 0a 20 20 75 33 32 20 64 65 66 61 75  al, .  u32 defau
84b0: 6c 74 4d 6f 64 65 2c 20 20 20 20 20 20 20 20 20  ltMode,         
84c0: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
84d0: 74 6f 20 75 73 65 20 69 66 20 70 56 61 6c 20 49  to use if pVal I
84e0: 53 20 4e 55 4c 4c 20 2a 2f 0a 20 20 75 33 32 20  S NULL */.  u32 
84f0: 2a 70 4d 6f 64 65 0a 29 7b 0a 20 20 63 6f 6e 73  *pMode.){.  cons
8500: 74 20 63 68 61 72 20 2a 7a 20 3d 20 28 63 6f 6e  t char *z = (con
8510: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
8520: 5f 76 61 6c 75 65 5f 74 65 78 74 28 70 56 61 6c  _value_text(pVal
8530: 29 3b 0a 20 20 75 33 32 20 6d 6f 64 65 20 3d 20  );.  u32 mode = 
8540: 30 3b 0a 20 20 69 66 28 20 7a 3d 3d 30 20 29 7b  0;.  if( z==0 ){
8550: 0a 20 20 20 20 6d 6f 64 65 20 3d 20 64 65 66 61  .    mode = defa
8560: 75 6c 74 4d 6f 64 65 3b 0a 20 20 7d 65 6c 73 65  ultMode;.  }else
8570: 20 69 66 28 20 7a 5b 30 5d 3e 3d 27 30 27 20 26   if( z[0]>='0' &
8580: 26 20 7a 5b 30 5d 3c 3d 27 39 27 20 29 7b 0a 20  & z[0]<='9' ){. 
8590: 20 20 20 6d 6f 64 65 20 3d 20 28 75 6e 73 69 67     mode = (unsig
85a0: 6e 65 64 20 69 6e 74 29 73 71 6c 69 74 65 33 5f  ned int)sqlite3_
85b0: 76 61 6c 75 65 5f 69 6e 74 28 70 56 61 6c 29 3b  value_int(pVal);
85c0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 63 6f  .  }else{.    co
85d0: 6e 73 74 20 63 68 61 72 20 7a 54 65 6d 70 6c 61  nst char zTempla
85e0: 74 65 5b 31 31 5d 20 3d 20 22 2d 72 77 78 72 77  te[11] = "-rwxrw
85f0: 78 72 77 78 22 3b 0a 20 20 20 20 69 6e 74 20 69  xrwx";.    int i
8600: 3b 0a 20 20 20 20 69 66 28 20 73 74 72 6c 65 6e  ;.    if( strlen
8610: 28 7a 29 21 3d 31 30 20 29 20 67 6f 74 6f 20 70  (z)!=10 ) goto p
8620: 61 72 73 65 5f 65 72 72 6f 72 3b 0a 20 20 20 20  arse_error;.    
8630: 73 77 69 74 63 68 28 20 7a 5b 30 5d 20 29 7b 0a  switch( z[0] ){.
8640: 20 20 20 20 20 20 63 61 73 65 20 27 2d 27 3a 20        case '-': 
8650: 6d 6f 64 65 20 7c 3d 20 53 5f 49 46 52 45 47 3b  mode |= S_IFREG;
8660: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61   break;.      ca
8670: 73 65 20 27 64 27 3a 20 6d 6f 64 65 20 7c 3d 20  se 'd': mode |= 
8680: 53 5f 49 46 44 49 52 3b 20 62 72 65 61 6b 3b 0a  S_IFDIR; break;.
8690: 23 69 66 20 21 64 65 66 69 6e 65 64 28 5f 57 49  #if !defined(_WI
86a0: 4e 33 32 29 20 26 26 20 21 64 65 66 69 6e 65 64  N32) && !defined
86b0: 28 57 49 4e 33 32 29 0a 20 20 20 20 20 20 63 61  (WIN32).      ca
86c0: 73 65 20 27 6c 27 3a 20 6d 6f 64 65 20 7c 3d 20  se 'l': mode |= 
86d0: 53 5f 49 46 4c 4e 4b 3b 20 62 72 65 61 6b 3b 0a  S_IFLNK; break;.
86e0: 23 65 6e 64 69 66 0a 20 20 20 20 20 20 64 65 66  #endif.      def
86f0: 61 75 6c 74 3a 20 67 6f 74 6f 20 70 61 72 73 65  ault: goto parse
8700: 5f 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a 20 20  _error;.    }.  
8710: 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 31 30 3b    for(i=1; i<10;
8720: 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28   i++){.      if(
8730: 20 7a 5b 69 5d 3d 3d 7a 54 65 6d 70 6c 61 74 65   z[i]==zTemplate
8740: 5b 69 5d 20 29 20 6d 6f 64 65 20 7c 3d 20 31 20  [i] ) mode |= 1 
8750: 3c 3c 20 28 39 2d 69 29 3b 0a 20 20 20 20 20 20  << (9-i);.      
8760: 65 6c 73 65 20 69 66 28 20 7a 5b 69 5d 21 3d 27  else if( z[i]!='
8770: 2d 27 20 29 20 67 6f 74 6f 20 70 61 72 73 65 5f  -' ) goto parse_
8780: 65 72 72 6f 72 3b 0a 20 20 20 20 7d 0a 20 20 7d  error;.    }.  }
8790: 0a 20 20 2a 70 4d 6f 64 65 20 3d 20 6d 6f 64 65  .  *pMode = mode
87a0: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
87b0: 45 5f 4f 4b 3b 0a 0a 20 70 61 72 73 65 5f 65 72  E_OK;.. parse_er
87c0: 72 6f 72 3a 0a 20 20 70 54 61 62 2d 3e 62 61 73  ror:.  pTab->bas
87d0: 65 2e 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69  e.zErrMsg = sqli
87e0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 7a 69 70  te3_mprintf("zip
87f0: 66 69 6c 65 3a 20 70 61 72 73 65 20 65 72 72 6f  file: parse erro
8800: 72 20 69 6e 20 6d 6f 64 65 3a 20 25 73 22 2c 20  r in mode: %s", 
8810: 7a 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  z);.  return SQL
8820: 49 54 45 5f 45 52 52 4f 52 3b 0a 7d 0a 0a 2f 2a  ITE_ERROR;.}../*
8830: 0a 2a 2a 20 42 6f 74 68 20 28 63 6f 6e 73 74 20  .** Both (const 
8840: 63 68 61 72 2a 29 20 61 72 67 75 6d 65 6e 74 73  char*) arguments
8850: 20 70 6f 69 6e 74 20 74 6f 20 6e 75 6c 2d 74 65   point to nul-te
8860: 72 6d 69 6e 61 74 65 64 20 73 74 72 69 6e 67 73  rminated strings
8870: 2e 20 41 72 67 75 6d 65 6e 74 0a 2a 2a 20 6e 42  . Argument.** nB
8880: 20 69 73 20 74 68 65 20 76 61 6c 75 65 20 6f 66   is the value of
8890: 20 73 74 72 6c 65 6e 28 7a 42 29 2e 20 54 68 69   strlen(zB). Thi
88a0: 73 20 66 75 6e 63 74 69 6f 6e 20 72 65 74 75 72  s function retur
88b0: 6e 73 20 30 20 69 66 20 74 68 65 20 73 74 72 69  ns 0 if the stri
88c0: 6e 67 73 20 61 72 65 0a 2a 2a 20 69 64 65 6e 74  ngs are.** ident
88d0: 69 63 61 6c 2c 20 69 67 6e 6f 72 69 6e 67 20 61  ical, ignoring a
88e0: 6e 79 20 74 72 61 69 6c 69 6e 67 20 27 2f 27 20  ny trailing '/' 
88f0: 63 68 61 72 61 63 74 65 72 20 69 6e 20 65 69 74  character in eit
8900: 68 65 72 20 70 61 74 68 2e 20 20 2a 2f 0a 73 74  her path.  */.st
8910: 61 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65  atic int zipfile
8920: 43 6f 6d 70 61 72 65 50 61 74 68 28 63 6f 6e 73  ComparePath(cons
8930: 74 20 63 68 61 72 20 2a 7a 41 2c 20 63 6f 6e 73  t char *zA, cons
8940: 74 20 63 68 61 72 20 2a 7a 42 2c 20 69 6e 74 20  t char *zB, int 
8950: 6e 42 29 7b 0a 20 20 69 6e 74 20 6e 41 20 3d 20  nB){.  int nA = 
8960: 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a 41 29 3b  (int)strlen(zA);
8970: 0a 20 20 69 66 28 20 7a 41 5b 6e 41 2d 31 5d 3d  .  if( zA[nA-1]=
8980: 3d 27 2f 27 20 29 20 6e 41 2d 2d 3b 0a 20 20 69  ='/' ) nA--;.  i
8990: 66 28 20 7a 42 5b 6e 42 2d 31 5d 3d 3d 27 2f 27  f( zB[nB-1]=='/'
89a0: 20 29 20 6e 42 2d 2d 3b 0a 20 20 69 66 28 20 6e   ) nB--;.  if( n
89b0: 41 3d 3d 6e 42 20 26 26 20 6d 65 6d 63 6d 70 28  A==nB && memcmp(
89c0: 7a 41 2c 20 7a 42 2c 20 6e 41 29 3d 3d 30 20 29  zA, zB, nA)==0 )
89d0: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 72 65 74   return 0;.  ret
89e0: 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 1;.}../*.** 
89f0: 78 55 70 64 61 74 65 20 6d 65 74 68 6f 64 2e 0a  xUpdate method..
8a00: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69  */.static int zi
8a10: 70 66 69 6c 65 55 70 64 61 74 65 28 0a 20 20 73  pfileUpdate(.  s
8a20: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74  qlite3_vtab *pVt
8a30: 61 62 2c 20 0a 20 20 69 6e 74 20 6e 56 61 6c 2c  ab, .  int nVal,
8a40: 20 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75   .  sqlite3_valu
8a50: 65 20 2a 2a 61 70 56 61 6c 2c 20 0a 20 20 73 71  e **apVal, .  sq
8a60: 6c 69 74 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77  lite_int64 *pRow
8a70: 69 64 0a 29 7b 0a 20 20 5a 69 70 66 69 6c 65 54  id.){.  ZipfileT
8a80: 61 62 20 2a 70 54 61 62 20 3d 20 28 5a 69 70 66  ab *pTab = (Zipf
8a90: 69 6c 65 54 61 62 2a 29 70 56 74 61 62 3b 0a 20  ileTab*)pVtab;. 
8aa0: 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45   int rc = SQLITE
8ab0: 5f 4f 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20  _OK;            
8ac0: 20 2f 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20   /* Return Code 
8ad0: 2a 2f 0a 20 20 5a 69 70 66 69 6c 65 45 6e 74 72  */.  ZipfileEntr
8ae0: 79 20 2a 70 4e 65 77 20 3d 20 30 3b 20 20 20 20  y *pNew = 0;    
8af0: 20 20 20 20 20 2f 2a 20 4e 65 77 20 69 6e 2d 6d       /* New in-m
8b00: 65 6d 6f 72 79 20 43 44 53 20 65 6e 74 72 79 20  emory CDS entry 
8b10: 2a 2f 0a 0a 20 20 75 33 32 20 6d 6f 64 65 20 3d  */..  u32 mode =
8b20: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
8b30: 20 20 20 20 20 20 2f 2a 20 4d 6f 64 65 20 66 6f        /* Mode fo
8b40: 72 20 6e 65 77 20 65 6e 74 72 79 20 2a 2f 0a 20  r new entry */. 
8b50: 20 69 36 34 20 6d 54 69 6d 65 20 3d 20 30 3b 20   i64 mTime = 0; 
8b60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b70: 20 2f 2a 20 4d 6f 64 69 66 69 63 61 74 69 6f 6e   /* Modification
8b80: 20 74 69 6d 65 20 66 6f 72 20 6e 65 77 20 65 6e   time for new en
8b90: 74 72 79 20 2a 2f 0a 20 20 69 36 34 20 73 7a 20  try */.  i64 sz 
8ba0: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
8bb0: 20 20 20 20 20 20 20 20 20 2f 2a 20 55 6e 63 6f           /* Unco
8bc0: 6d 70 72 65 73 73 65 64 20 73 69 7a 65 20 2a 2f  mpressed size */
8bd0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
8be0: 50 61 74 68 20 3d 20 30 3b 20 20 20 20 20 20 20  Path = 0;       
8bf0: 20 20 20 2f 2a 20 50 61 74 68 20 66 6f 72 20 6e     /* Path for n
8c00: 65 77 20 65 6e 74 72 79 20 2a 2f 0a 20 20 69 6e  ew entry */.  in
8c10: 74 20 6e 50 61 74 68 20 3d 20 30 3b 20 20 20 20  t nPath = 0;    
8c20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8c30: 20 73 74 72 6c 65 6e 28 7a 50 61 74 68 29 20 2a   strlen(zPath) *
8c40: 2f 0a 20 20 63 6f 6e 73 74 20 75 38 20 2a 70 44  /.  const u8 *pD
8c50: 61 74 61 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ata = 0;        
8c60: 20 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74      /* Pointer t
8c70: 6f 20 62 75 66 66 65 72 20 63 6f 6e 74 61 69 6e  o buffer contain
8c80: 69 6e 67 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20  ing content */. 
8c90: 20 69 6e 74 20 6e 44 61 74 61 20 3d 20 30 3b 20   int nData = 0; 
8ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8cb0: 20 2f 2a 20 53 69 7a 65 20 6f 66 20 70 44 61 74   /* Size of pDat
8cc0: 61 20 62 75 66 66 65 72 20 69 6e 20 62 79 74 65  a buffer in byte
8cd0: 73 20 2a 2f 0a 20 20 69 6e 74 20 69 4d 65 74 68  s */.  int iMeth
8ce0: 6f 64 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  od = 0;         
8cf0: 20 20 20 20 20 20 20 2f 2a 20 43 6f 6d 70 72 65         /* Compre
8d00: 73 73 69 6f 6e 20 6d 65 74 68 6f 64 20 66 6f 72  ssion method for
8d10: 20 6e 65 77 20 65 6e 74 72 79 20 2a 2f 0a 20 20   new entry */.  
8d20: 75 38 20 2a 70 46 72 65 65 20 3d 20 30 3b 20 20  u8 *pFree = 0;  
8d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8d40: 2f 2a 20 46 72 65 65 20 74 68 69 73 20 2a 2f 0a  /* Free this */.
8d50: 20 20 63 68 61 72 20 2a 7a 46 72 65 65 20 3d 20    char *zFree = 
8d60: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
8d70: 20 20 2f 2a 20 41 6c 73 6f 20 66 72 65 65 20 74    /* Also free t
8d80: 68 69 73 20 2a 2f 0a 20 20 5a 69 70 66 69 6c 65  his */.  Zipfile
8d90: 45 6e 74 72 79 20 2a 70 4f 6c 64 20 3d 20 30 3b  Entry *pOld = 0;
8da0: 0a 20 20 69 6e 74 20 62 49 73 44 69 72 20 3d 20  .  int bIsDir = 
8db0: 30 3b 0a 20 20 75 33 32 20 69 43 72 63 33 32 20  0;.  u32 iCrc32 
8dc0: 3d 20 30 3b 0a 0a 20 20 61 73 73 65 72 74 28 20  = 0;..  assert( 
8dd0: 28 70 54 61 62 2d 3e 7a 46 69 6c 65 3d 3d 30 29  (pTab->zFile==0)
8de0: 3d 3d 28 70 54 61 62 2d 3e 70 57 72 69 74 65 46  ==(pTab->pWriteF
8df0: 64 3d 3d 30 29 20 29 3b 0a 0a 20 20 2f 2a 20 49  d==0) );..  /* I
8e00: 66 20 74 68 69 73 20 69 73 20 61 20 44 45 4c 45  f this is a DELE
8e10: 54 45 20 6f 72 20 55 50 44 41 54 45 2c 20 66 69  TE or UPDATE, fi
8e20: 6e 64 20 74 68 65 20 61 72 63 68 69 76 65 20 65  nd the archive e
8e30: 6e 74 72 79 20 74 6f 20 64 65 6c 65 74 65 2e 20  ntry to delete. 
8e40: 2a 2f 0a 20 20 69 66 28 20 73 71 6c 69 74 65 33  */.  if( sqlite3
8e50: 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70 56 61  _value_type(apVa
8e60: 6c 5b 30 5d 29 21 3d 53 51 4c 49 54 45 5f 4e 55  l[0])!=SQLITE_NU
8e70: 4c 4c 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20  LL ){.    const 
8e80: 63 68 61 72 20 2a 7a 44 65 6c 65 74 65 20 3d 20  char *zDelete = 
8e90: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c  (const char*)sql
8ea0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
8eb0: 61 70 56 61 6c 5b 30 5d 29 3b 0a 20 20 20 20 69  apVal[0]);.    i
8ec0: 6e 74 20 6e 44 65 6c 65 74 65 20 3d 20 28 69 6e  nt nDelete = (in
8ed0: 74 29 73 74 72 6c 65 6e 28 7a 44 65 6c 65 74 65  t)strlen(zDelete
8ee0: 29 3b 0a 20 20 20 20 66 6f 72 28 70 4f 6c 64 3d  );.    for(pOld=
8ef0: 70 54 61 62 2d 3e 70 46 69 72 73 74 45 6e 74 72  pTab->pFirstEntr
8f00: 79 3b 20 31 3b 20 70 4f 6c 64 3d 70 4f 6c 64 2d  y; 1; pOld=pOld-
8f10: 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 69  >pNext){.      i
8f20: 66 28 20 7a 69 70 66 69 6c 65 43 6f 6d 70 61 72  f( zipfileCompar
8f30: 65 50 61 74 68 28 70 4f 6c 64 2d 3e 63 64 73 2e  ePath(pOld->cds.
8f40: 7a 46 69 6c 65 2c 20 7a 44 65 6c 65 74 65 2c 20  zFile, zDelete, 
8f50: 6e 44 65 6c 65 74 65 29 3d 3d 30 20 29 7b 0a 20  nDelete)==0 ){. 
8f60: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
8f70: 20 20 20 20 7d 0a 20 20 20 20 20 20 61 73 73 65      }.      asse
8f80: 72 74 28 20 70 4f 6c 64 2d 3e 70 4e 65 78 74 20  rt( pOld->pNext 
8f90: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
8fa0: 69 66 28 20 6e 56 61 6c 3e 31 20 29 7b 0a 20 20  if( nVal>1 ){.  
8fb0: 20 20 2f 2a 20 43 68 65 63 6b 20 74 68 61 74 20    /* Check that 
8fc0: 22 73 7a 22 20 61 6e 64 20 22 72 61 77 64 61 74  "sz" and "rawdat
8fd0: 61 22 20 61 72 65 20 62 6f 74 68 20 4e 55 4c 4c  a" are both NULL
8fe0: 3a 20 2a 2f 0a 20 20 20 20 69 66 28 20 73 71 6c  : */.    if( sql
8ff0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28  ite3_value_type(
9000: 61 70 56 61 6c 5b 35 5d 29 21 3d 53 51 4c 49 54  apVal[5])!=SQLIT
9010: 45 5f 4e 55 4c 4c 0a 20 20 20 20 20 7c 7c 20 73  E_NULL.     || s
9020: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 79 70  qlite3_value_typ
9030: 65 28 61 70 56 61 6c 5b 36 5d 29 21 3d 53 51 4c  e(apVal[6])!=SQL
9040: 49 54 45 5f 4e 55 4c 4c 0a 20 20 20 20 29 7b 0a  ITE_NULL.    ){.
9050: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
9060: 45 5f 43 4f 4e 53 54 52 41 49 4e 54 3b 0a 20 20  E_CONSTRAINT;.  
9070: 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d    }..    if( rc=
9080: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
9090: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
90a0: 76 61 6c 75 65 5f 74 79 70 65 28 61 70 56 61 6c  value_type(apVal
90b0: 5b 37 5d 29 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c  [7])==SQLITE_NUL
90c0: 4c 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20  L ){.        /* 
90d0: 64 61 74 61 3d 4e 55 4c 4c 2e 20 41 20 64 69 72  data=NULL. A dir
90e0: 65 63 74 6f 72 79 20 2a 2f 0a 20 20 20 20 20 20  ectory */.      
90f0: 20 20 62 49 73 44 69 72 20 3d 20 31 3b 0a 20 20    bIsDir = 1;.  
9100: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
9110: 20 20 20 2f 2a 20 56 61 6c 75 65 20 73 70 65 63     /* Value spec
9120: 69 66 69 65 64 20 66 6f 72 20 22 64 61 74 61 22  ified for "data"
9130: 2c 20 61 6e 64 20 70 6f 73 73 69 62 6c 79 20 22  , and possibly "
9140: 6d 65 74 68 6f 64 22 2e 20 54 68 69 73 20 6d 75  method". This mu
9150: 73 74 20 62 65 0a 20 20 20 20 20 20 20 20 2a 2a  st be.        **
9160: 20 61 20 72 65 67 75 6c 61 72 20 66 69 6c 65 20   a regular file 
9170: 6f 72 20 61 20 73 79 6d 6c 69 6e 6b 2e 20 2a 2f  or a symlink. */
9180: 0a 20 20 20 20 20 20 20 20 63 6f 6e 73 74 20 75  .        const u
9190: 38 20 2a 61 49 6e 20 3d 20 73 71 6c 69 74 65 33  8 *aIn = sqlite3
91a0: 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 61 70 56 61  _value_blob(apVa
91b0: 6c 5b 37 5d 29 3b 0a 20 20 20 20 20 20 20 20 69  l[7]);.        i
91c0: 6e 74 20 6e 49 6e 20 3d 20 73 71 6c 69 74 65 33  nt nIn = sqlite3
91d0: 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 61 70 56  _value_bytes(apV
91e0: 61 6c 5b 37 5d 29 3b 0a 20 20 20 20 20 20 20 20  al[7]);.        
91f0: 69 6e 74 20 62 41 75 74 6f 20 3d 20 73 71 6c 69  int bAuto = sqli
9200: 74 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61  te3_value_type(a
9210: 70 56 61 6c 5b 38 5d 29 3d 3d 53 51 4c 49 54 45  pVal[8])==SQLITE
9220: 5f 4e 55 4c 4c 3b 0a 0a 20 20 20 20 20 20 20 20  _NULL;..        
9230: 69 4d 65 74 68 6f 64 20 3d 20 73 71 6c 69 74 65  iMethod = sqlite
9240: 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 70 56 61  3_value_int(apVa
9250: 6c 5b 38 5d 29 3b 0a 20 20 20 20 20 20 20 20 73  l[8]);.        s
9260: 7a 20 3d 20 6e 49 6e 3b 0a 20 20 20 20 20 20 20  z = nIn;.       
9270: 20 70 44 61 74 61 20 3d 20 61 49 6e 3b 0a 20 20   pData = aIn;.  
9280: 20 20 20 20 20 20 6e 44 61 74 61 20 3d 20 6e 49        nData = nI
9290: 6e 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 69  n;.        if( i
92a0: 4d 65 74 68 6f 64 21 3d 30 20 26 26 20 69 4d 65  Method!=0 && iMe
92b0: 74 68 6f 64 21 3d 38 20 29 7b 0a 20 20 20 20 20  thod!=8 ){.     
92c0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
92d0: 5f 43 4f 4e 53 54 52 41 49 4e 54 3b 0a 20 20 20  _CONSTRAINT;.   
92e0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
92f0: 20 20 20 20 20 20 69 66 28 20 62 41 75 74 6f 20        if( bAuto 
9300: 7c 7c 20 69 4d 65 74 68 6f 64 20 29 7b 0a 20 20  || iMethod ){.  
9310: 20 20 20 20 20 20 20 20 20 20 69 6e 74 20 6e 43            int nC
9320: 6d 70 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  mp;.            
9330: 72 63 20 3d 20 7a 69 70 66 69 6c 65 44 65 66 6c  rc = zipfileDefl
9340: 61 74 65 28 70 54 61 62 2c 20 61 49 6e 2c 20 6e  ate(pTab, aIn, n
9350: 49 6e 2c 20 26 70 46 72 65 65 2c 20 26 6e 43 6d  In, &pFree, &nCm
9360: 70 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  p);.            
9370: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
9380: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  K ){.           
9390: 20 20 20 69 66 28 20 69 4d 65 74 68 6f 64 20 7c     if( iMethod |
93a0: 7c 20 6e 43 6d 70 3c 6e 49 6e 20 29 7b 0a 20 20  | nCmp<nIn ){.  
93b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 4d                iM
93c0: 65 74 68 6f 64 20 3d 20 38 3b 0a 20 20 20 20 20  ethod = 8;.     
93d0: 20 20 20 20 20 20 20 20 20 20 20 70 44 61 74 61             pData
93e0: 20 3d 20 70 46 72 65 65 3b 0a 20 20 20 20 20 20   = pFree;.      
93f0: 20 20 20 20 20 20 20 20 20 20 6e 44 61 74 61 20            nData 
9400: 3d 20 6e 43 6d 70 3b 0a 20 20 20 20 20 20 20 20  = nCmp;.        
9410: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
9420: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20      }.          
9430: 7d 0a 20 20 20 20 20 20 20 20 20 20 69 43 72 63  }.          iCrc
9440: 33 32 20 3d 20 63 72 63 33 32 28 30 2c 20 61 49  32 = crc32(0, aI
9450: 6e 2c 20 6e 49 6e 29 3b 0a 20 20 20 20 20 20 20  n, nIn);.       
9460: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d   }.      }.    }
9470: 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ..    if( rc==SQ
9480: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
9490: 20 72 63 20 3d 20 7a 69 70 66 69 6c 65 47 65 74   rc = zipfileGet
94a0: 4d 6f 64 65 28 70 54 61 62 2c 20 61 70 56 61 6c  Mode(pTab, apVal
94b0: 5b 33 5d 2c 20 0a 20 20 20 20 20 20 20 20 20 20  [3], .          
94c0: 28 62 49 73 44 69 72 20 3f 20 28 53 5f 49 46 44  (bIsDir ? (S_IFD
94d0: 49 52 20 2b 20 30 37 35 35 29 20 3a 20 28 53 5f  IR + 0755) : (S_
94e0: 49 46 52 45 47 20 2b 20 30 36 34 34 29 29 2c 20  IFREG + 0644)), 
94f0: 26 6d 6f 64 65 0a 20 20 20 20 20 20 29 3b 0a 20  &mode.      );. 
9500: 20 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c       if( rc==SQL
9510: 49 54 45 5f 4f 4b 20 26 26 20 28 62 49 73 44 69  ITE_OK && (bIsDi
9520: 72 20 3d 3d 20 28 28 6d 6f 64 65 20 26 20 53 5f  r == ((mode & S_
9530: 49 46 44 49 52 29 3d 3d 30 29 29 20 29 7b 0a 20  IFDIR)==0)) ){. 
9540: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 22 6d         /* The "m
9550: 6f 64 65 22 20 61 74 74 72 69 62 75 74 65 20 69  ode" attribute i
9560: 73 20 61 20 64 69 72 65 63 74 6f 72 79 2c 20 62  s a directory, b
9570: 75 74 20 64 61 74 61 20 68 61 73 20 62 65 65 6e  ut data has been
9580: 20 73 70 65 63 69 66 69 65 64 2e 0a 20 20 20 20   specified..    
9590: 20 20 20 20 2a 2a 20 4f 72 20 76 69 63 65 2d 76      ** Or vice-v
95a0: 65 72 73 61 20 2d 20 6e 6f 20 64 61 74 61 20 62  ersa - no data b
95b0: 75 74 20 22 6d 6f 64 65 22 20 69 73 20 61 20 66  ut "mode" is a f
95c0: 69 6c 65 20 6f 72 20 73 79 6d 6c 69 6e 6b 2e 20  ile or symlink. 
95d0: 20 2a 2f 0a 20 20 20 20 20 20 20 20 72 63 20 3d   */.        rc =
95e0: 20 53 51 4c 49 54 45 5f 43 4f 4e 53 54 52 41 49   SQLITE_CONSTRAI
95f0: 4e 54 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  NT;.      }.    
9600: 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53  }..    if( rc==S
9610: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
9620: 20 20 7a 50 61 74 68 20 3d 20 28 63 6f 6e 73 74    zPath = (const
9630: 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76   char*)sqlite3_v
9640: 61 6c 75 65 5f 74 65 78 74 28 61 70 56 61 6c 5b  alue_text(apVal[
9650: 32 5d 29 3b 0a 20 20 20 20 20 20 6e 50 61 74 68  2]);.      nPath
9660: 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28 7a   = (int)strlen(z
9670: 50 61 74 68 29 3b 0a 20 20 20 20 20 20 69 66 28  Path);.      if(
9680: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74   sqlite3_value_t
9690: 79 70 65 28 61 70 56 61 6c 5b 34 5d 29 3d 3d 53  ype(apVal[4])==S
96a0: 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b 0a 20 20  QLITE_NULL ){.  
96b0: 20 20 20 20 20 20 6d 54 69 6d 65 20 3d 20 28 73        mTime = (s
96c0: 71 6c 69 74 65 33 5f 69 6e 74 36 34 29 74 69 6d  qlite3_int64)tim
96d0: 65 28 30 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73  e(0);.      }els
96e0: 65 7b 0a 20 20 20 20 20 20 20 20 6d 54 69 6d 65  e{.        mTime
96f0: 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65   = sqlite3_value
9700: 5f 69 6e 74 36 34 28 61 70 56 61 6c 5b 34 5d 29  _int64(apVal[4])
9710: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
9720: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
9730: 49 54 45 5f 4f 4b 20 26 26 20 62 49 73 44 69 72  ITE_OK && bIsDir
9740: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 46 6f 72   ){.      /* For
9750: 20 61 20 64 69 72 65 63 74 6f 72 79 2c 20 63 68   a directory, ch
9760: 65 63 6b 20 74 68 61 74 20 74 68 65 20 6c 61 73  eck that the las
9770: 74 20 63 68 61 72 61 63 74 65 72 20 69 6e 20 74  t character in t
9780: 68 65 20 70 61 74 68 20 69 73 20 61 0a 20 20 20  he path is a.   
9790: 20 20 20 2a 2a 20 27 2f 27 2e 20 54 68 69 73 20     ** '/'. This 
97a0: 61 70 70 65 61 72 73 20 74 6f 20 62 65 20 72 65  appears to be re
97b0: 71 75 69 72 65 64 20 66 6f 72 20 63 6f 6d 70 61  quired for compa
97c0: 74 69 62 69 6c 69 74 79 20 77 69 74 68 20 69 6e  tibility with in
97d0: 66 6f 2d 7a 69 70 0a 20 20 20 20 20 20 2a 2a 20  fo-zip.      ** 
97e0: 28 74 68 65 20 75 6e 7a 69 70 20 63 6f 6d 6d 61  (the unzip comma
97f0: 6e 64 20 6f 6e 20 75 6e 69 78 29 2e 20 49 74 20  nd on unix). It 
9800: 64 6f 65 73 20 6e 6f 74 20 63 72 65 61 74 65 20  does not create 
9810: 64 69 72 65 63 74 6f 72 69 65 73 0a 20 20 20 20  directories.    
9820: 20 20 2a 2a 20 6f 74 68 65 72 77 69 73 65 2e 20    ** otherwise. 
9830: 20 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 7a 50   */.      if( zP
9840: 61 74 68 5b 6e 50 61 74 68 2d 31 5d 21 3d 27 2f  ath[nPath-1]!='/
9850: 27 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 46 72  ' ){.        zFr
9860: 65 65 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  ee = sqlite3_mpr
9870: 69 6e 74 66 28 22 25 73 2f 22 2c 20 7a 50 61 74  intf("%s/", zPat
9880: 68 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20  h);.        if( 
9890: 7a 46 72 65 65 3d 3d 30 20 29 7b 20 72 63 20 3d  zFree==0 ){ rc =
98a0: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 20 7d   SQLITE_NOMEM; }
98b0: 0a 20 20 20 20 20 20 20 20 7a 50 61 74 68 20 3d  .        zPath =
98c0: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 7a 46   (const char*)zF
98d0: 72 65 65 3b 0a 20 20 20 20 20 20 20 20 6e 50 61  ree;.        nPa
98e0: 74 68 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20  th++;.      }.  
98f0: 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43 68 65 63    }..    /* Chec
9900: 6b 20 74 68 61 74 20 77 65 27 72 65 20 6e 6f 74  k that we're not
9910: 20 69 6e 73 65 72 74 69 6e 67 20 61 20 64 75 70   inserting a dup
9920: 6c 69 63 61 74 65 20 65 6e 74 72 79 20 2a 2f 0a  licate entry */.
9930: 20 20 20 20 69 66 28 20 70 4f 6c 64 3d 3d 30 20      if( pOld==0 
9940: 26 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  && rc==SQLITE_OK
9950: 20 29 7b 0a 20 20 20 20 20 20 5a 69 70 66 69 6c   ){.      Zipfil
9960: 65 45 6e 74 72 79 20 2a 70 3b 0a 20 20 20 20 20  eEntry *p;.     
9970: 20 66 6f 72 28 70 3d 70 54 61 62 2d 3e 70 46 69   for(p=pTab->pFi
9980: 72 73 74 45 6e 74 72 79 3b 20 70 3b 20 70 3d 70  rstEntry; p; p=p
9990: 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20  ->pNext){.      
99a0: 20 20 69 66 28 20 7a 69 70 66 69 6c 65 43 6f 6d    if( zipfileCom
99b0: 70 61 72 65 50 61 74 68 28 70 2d 3e 63 64 73 2e  parePath(p->cds.
99c0: 7a 46 69 6c 65 2c 20 7a 50 61 74 68 2c 20 6e 50  zFile, zPath, nP
99d0: 61 74 68 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  ath)==0 ){.     
99e0: 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45       rc = SQLITE
99f0: 5f 43 4f 4e 53 54 52 41 49 4e 54 3b 0a 20 20 20  _CONSTRAINT;.   
9a00: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
9a10: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
9a20: 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72      }..    if( r
9a30: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
9a40: 20 20 20 20 20 20 2f 2a 20 43 72 65 61 74 65 20        /* Create 
9a50: 74 68 65 20 6e 65 77 20 43 44 53 20 72 65 63 6f  the new CDS reco
9a60: 72 64 2e 20 2a 2f 0a 20 20 20 20 20 20 70 4e 65  rd. */.      pNe
9a70: 77 20 3d 20 7a 69 70 66 69 6c 65 4e 65 77 45 6e  w = zipfileNewEn
9a80: 74 72 79 28 7a 50 61 74 68 2c 20 70 54 61 62 2d  try(zPath, pTab-
9a90: 3e 7a 46 69 6c 65 20 3f 20 30 20 3a 20 28 6e 44  >zFile ? 0 : (nD
9aa0: 61 74 61 2b 31 29 29 3b 0a 20 20 20 20 20 20 69  ata+1));.      i
9ab0: 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20 20  f( pNew==0 ){.  
9ac0: 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54        rc = SQLIT
9ad0: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d  E_NOMEM;.      }
9ae0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 4e  else{.        pN
9af0: 65 77 2d 3e 63 64 73 2e 69 56 65 72 73 69 6f 6e  ew->cds.iVersion
9b00: 4d 61 64 65 42 79 20 3d 20 5a 49 50 46 49 4c 45  MadeBy = ZIPFILE
9b10: 5f 4e 45 57 45 4e 54 52 59 5f 4d 41 44 45 42 59  _NEWENTRY_MADEBY
9b20: 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 77 2d 3e  ;.        pNew->
9b30: 63 64 73 2e 69 56 65 72 73 69 6f 6e 45 78 74 72  cds.iVersionExtr
9b40: 61 63 74 20 3d 20 5a 49 50 46 49 4c 45 5f 4e 45  act = ZIPFILE_NE
9b50: 57 45 4e 54 52 59 5f 52 45 51 55 49 52 45 44 3b  WENTRY_REQUIRED;
9b60: 0a 20 20 20 20 20 20 20 20 70 4e 65 77 2d 3e 63  .        pNew->c
9b70: 64 73 2e 66 6c 61 67 73 20 3d 20 5a 49 50 46 49  ds.flags = ZIPFI
9b80: 4c 45 5f 4e 45 57 45 4e 54 52 59 5f 46 4c 41 47  LE_NEWENTRY_FLAG
9b90: 53 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 77 2d  S;.        pNew-
9ba0: 3e 63 64 73 2e 69 43 6f 6d 70 72 65 73 73 69 6f  >cds.iCompressio
9bb0: 6e 20 3d 20 28 75 31 36 29 69 4d 65 74 68 6f 64  n = (u16)iMethod
9bc0: 3b 0a 20 20 20 20 20 20 20 20 7a 69 70 66 69 6c  ;.        zipfil
9bd0: 65 4d 74 69 6d 65 54 6f 44 6f 73 28 26 70 4e 65  eMtimeToDos(&pNe
9be0: 77 2d 3e 63 64 73 2c 20 28 75 33 32 29 6d 54 69  w->cds, (u32)mTi
9bf0: 6d 65 29 3b 0a 20 20 20 20 20 20 20 20 70 4e 65  me);.        pNe
9c00: 77 2d 3e 63 64 73 2e 63 72 63 33 32 20 3d 20 69  w->cds.crc32 = i
9c10: 43 72 63 33 32 3b 0a 20 20 20 20 20 20 20 20 70  Crc32;.        p
9c20: 4e 65 77 2d 3e 63 64 73 2e 73 7a 43 6f 6d 70 72  New->cds.szCompr
9c30: 65 73 73 65 64 20 3d 20 6e 44 61 74 61 3b 0a 20  essed = nData;. 
9c40: 20 20 20 20 20 20 20 70 4e 65 77 2d 3e 63 64 73         pNew->cds
9c50: 2e 73 7a 55 6e 63 6f 6d 70 72 65 73 73 65 64 20  .szUncompressed 
9c60: 3d 20 28 75 33 32 29 73 7a 3b 0a 20 20 20 20 20  = (u32)sz;.     
9c70: 20 20 20 70 4e 65 77 2d 3e 63 64 73 2e 69 45 78     pNew->cds.iEx
9c80: 74 65 72 6e 61 6c 41 74 74 72 20 3d 20 28 6d 6f  ternalAttr = (mo
9c90: 64 65 3c 3c 31 36 29 3b 0a 20 20 20 20 20 20 20  de<<16);.       
9ca0: 20 70 4e 65 77 2d 3e 63 64 73 2e 69 4f 66 66 73   pNew->cds.iOffs
9cb0: 65 74 20 3d 20 28 75 33 32 29 70 54 61 62 2d 3e  et = (u32)pTab->
9cc0: 73 7a 43 75 72 72 65 6e 74 3b 0a 20 20 20 20 20  szCurrent;.     
9cd0: 20 20 20 70 4e 65 77 2d 3e 63 64 73 2e 6e 46 69     pNew->cds.nFi
9ce0: 6c 65 20 3d 20 6e 50 61 74 68 3b 0a 20 20 20 20  le = nPath;.    
9cf0: 20 20 20 20 70 4e 65 77 2d 3e 6d 55 6e 69 78 54      pNew->mUnixT
9d00: 69 6d 65 20 3d 20 28 75 33 32 29 6d 54 69 6d 65  ime = (u32)mTime
9d10: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70 54  ;.        if( pT
9d20: 61 62 2d 3e 7a 46 69 6c 65 20 29 7b 0a 20 20 20  ab->zFile ){.   
9d30: 20 20 20 20 20 20 20 72 63 20 3d 20 7a 69 70 66         rc = zipf
9d40: 69 6c 65 41 70 70 65 6e 64 45 6e 74 72 79 28 70  ileAppendEntry(p
9d50: 54 61 62 2c 20 70 4e 65 77 2c 20 70 44 61 74 61  Tab, pNew, pData
9d60: 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20  , nData);.      
9d70: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
9d80: 20 20 20 6d 65 6d 63 70 79 28 70 4e 65 77 2d 3e     memcpy(pNew->
9d90: 61 44 61 74 61 2c 20 70 44 61 74 61 2c 20 6e 44  aData, pData, nD
9da0: 61 74 61 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ata);.        }.
9db0: 20 20 20 20 20 20 20 20 7a 69 70 66 69 6c 65 41          zipfileA
9dc0: 64 64 45 6e 74 72 79 28 70 54 61 62 2c 20 70 4f  ddEntry(pTab, pO
9dd0: 6c 64 2c 20 70 4e 65 77 29 3b 0a 20 20 20 20 20  ld, pNew);.     
9de0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
9df0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
9e00: 4b 20 26 26 20 70 4f 6c 64 20 29 7b 0a 20 20 20  K && pOld ){.   
9e10: 20 5a 69 70 66 69 6c 65 45 6e 74 72 79 20 2a 2a   ZipfileEntry **
9e20: 70 70 3b 0a 20 20 20 20 5a 69 70 66 69 6c 65 43  pp;.    ZipfileC
9e30: 73 72 20 2a 70 43 73 72 3b 0a 20 20 20 20 66 6f  sr *pCsr;.    fo
9e40: 72 28 70 43 73 72 3d 70 54 61 62 2d 3e 70 43 73  r(pCsr=pTab->pCs
9e50: 72 4c 69 73 74 3b 20 70 43 73 72 3b 20 70 43 73  rList; pCsr; pCs
9e60: 72 3d 70 43 73 72 2d 3e 70 43 73 72 4e 65 78 74  r=pCsr->pCsrNext
9e70: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 43 73  ){.      if( pCs
9e80: 72 2d 3e 70 43 75 72 72 65 6e 74 3d 3d 70 4f 6c  r->pCurrent==pOl
9e90: 64 20 29 7b 0a 20 20 20 20 20 20 20 20 70 43 73  d ){.        pCs
9ea0: 72 2d 3e 70 43 75 72 72 65 6e 74 20 3d 20 70 4f  r->pCurrent = pO
9eb0: 6c 64 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20  ld->pNext;.     
9ec0: 20 20 20 70 43 73 72 2d 3e 62 4e 6f 6f 70 20 3d     pCsr->bNoop =
9ed0: 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   1;.      }.    
9ee0: 7d 0a 20 20 20 20 66 6f 72 28 70 70 3d 26 70 54  }.    for(pp=&pT
9ef0: 61 62 2d 3e 70 46 69 72 73 74 45 6e 74 72 79 3b  ab->pFirstEntry;
9f00: 20 28 2a 70 70 29 21 3d 70 4f 6c 64 3b 20 70 70   (*pp)!=pOld; pp
9f10: 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65 78 74 29  =&((*pp)->pNext)
9f20: 29 3b 0a 20 20 20 20 2a 70 70 20 3d 20 28 2a 70  );.    *pp = (*p
9f30: 70 29 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 7a  p)->pNext;.    z
9f40: 69 70 66 69 6c 65 45 6e 74 72 79 46 72 65 65 28  ipfileEntryFree(
9f50: 70 4f 6c 64 29 3b 0a 20 20 7d 0a 0a 20 20 73 71  pOld);.  }..  sq
9f60: 6c 69 74 65 33 5f 66 72 65 65 28 70 46 72 65 65  lite3_free(pFree
9f70: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
9f80: 65 28 7a 46 72 65 65 29 3b 0a 20 20 72 65 74 75  e(zFree);.  retu
9f90: 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn rc;.}..static
9fa0: 20 69 6e 74 20 7a 69 70 66 69 6c 65 53 65 72 69   int zipfileSeri
9fb0: 61 6c 69 7a 65 45 4f 43 44 28 5a 69 70 66 69 6c  alizeEOCD(Zipfil
9fc0: 65 45 4f 43 44 20 2a 70 2c 20 75 38 20 2a 61 42  eEOCD *p, u8 *aB
9fd0: 75 66 29 7b 0a 20 20 75 38 20 2a 61 20 3d 20 61  uf){.  u8 *a = a
9fe0: 42 75 66 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72  Buf;.  zipfileWr
9ff0: 69 74 65 33 32 28 61 2c 20 5a 49 50 46 49 4c 45  ite32(a, ZIPFILE
a000: 5f 53 49 47 4e 41 54 55 52 45 5f 45 4f 43 44 29  _SIGNATURE_EOCD)
a010: 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65  ;.  zipfileWrite
a020: 31 36 28 61 2c 20 70 2d 3e 69 44 69 73 6b 29 3b  16(a, p->iDisk);
a030: 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65 31  .  zipfileWrite1
a040: 36 28 61 2c 20 70 2d 3e 69 46 69 72 73 74 44 69  6(a, p->iFirstDi
a050: 73 6b 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72  sk);.  zipfileWr
a060: 69 74 65 31 36 28 61 2c 20 70 2d 3e 6e 45 6e 74  ite16(a, p->nEnt
a070: 72 79 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72  ry);.  zipfileWr
a080: 69 74 65 31 36 28 61 2c 20 70 2d 3e 6e 45 6e 74  ite16(a, p->nEnt
a090: 72 79 54 6f 74 61 6c 29 3b 0a 20 20 7a 69 70 66  ryTotal);.  zipf
a0a0: 69 6c 65 57 72 69 74 65 33 32 28 61 2c 20 70 2d  ileWrite32(a, p-
a0b0: 3e 6e 53 69 7a 65 29 3b 0a 20 20 7a 69 70 66 69  >nSize);.  zipfi
a0c0: 6c 65 57 72 69 74 65 33 32 28 61 2c 20 70 2d 3e  leWrite32(a, p->
a0d0: 69 4f 66 66 73 65 74 29 3b 0a 20 20 7a 69 70 66  iOffset);.  zipf
a0e0: 69 6c 65 57 72 69 74 65 31 36 28 61 2c 20 30 29  ileWrite16(a, 0)
a0f0: 3b 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65  ;        /* Size
a100: 20 6f 66 20 74 72 61 69 6c 69 6e 67 20 63 6f 6d   of trailing com
a110: 6d 65 6e 74 20 69 6e 20 62 79 74 65 73 2a 2f 0a  ment in bytes*/.
a120: 0a 20 20 72 65 74 75 72 6e 20 61 2d 61 42 75 66  .  return a-aBuf
a130: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
a140: 7a 69 70 66 69 6c 65 41 70 70 65 6e 64 45 4f 43  zipfileAppendEOC
a150: 44 28 5a 69 70 66 69 6c 65 54 61 62 20 2a 70 54  D(ZipfileTab *pT
a160: 61 62 2c 20 5a 69 70 66 69 6c 65 45 4f 43 44 20  ab, ZipfileEOCD 
a170: 2a 70 29 7b 0a 20 20 69 6e 74 20 6e 42 75 66 20  *p){.  int nBuf 
a180: 3d 20 7a 69 70 66 69 6c 65 53 65 72 69 61 6c 69  = zipfileSeriali
a190: 7a 65 45 4f 43 44 28 70 2c 20 70 54 61 62 2d 3e  zeEOCD(p, pTab->
a1a0: 61 42 75 66 66 65 72 29 3b 0a 20 20 61 73 73 65  aBuffer);.  asse
a1b0: 72 74 28 20 6e 42 75 66 3d 3d 5a 49 50 46 49 4c  rt( nBuf==ZIPFIL
a1c0: 45 5f 45 4f 43 44 5f 46 49 58 45 44 5f 53 5a 20  E_EOCD_FIXED_SZ 
a1d0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a 69 70 66  );.  return zipf
a1e0: 69 6c 65 41 70 70 65 6e 64 44 61 74 61 28 70 54  ileAppendData(pT
a1f0: 61 62 2c 20 70 54 61 62 2d 3e 61 42 75 66 66 65  ab, pTab->aBuffe
a200: 72 2c 20 6e 42 75 66 29 3b 0a 7d 0a 0a 73 74 61  r, nBuf);.}..sta
a210: 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 42  tic int zipfileB
a220: 65 67 69 6e 28 73 71 6c 69 74 65 33 5f 76 74 61  egin(sqlite3_vta
a230: 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 5a 69 70  b *pVtab){.  Zip
a240: 66 69 6c 65 54 61 62 20 2a 70 54 61 62 20 3d 20  fileTab *pTab = 
a250: 28 5a 69 70 66 69 6c 65 54 61 62 2a 29 70 56 74  (ZipfileTab*)pVt
a260: 61 62 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  ab;.  int rc = S
a270: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 61 73 73  QLITE_OK;..  ass
a280: 65 72 74 28 20 70 54 61 62 2d 3e 70 57 72 69 74  ert( pTab->pWrit
a290: 65 46 64 3d 3d 30 20 29 3b 0a 20 20 69 66 28 20  eFd==0 );.  if( 
a2a0: 70 54 61 62 2d 3e 7a 46 69 6c 65 20 29 7b 0a 20  pTab->zFile ){. 
a2b0: 20 20 20 2f 2a 20 4f 70 65 6e 20 61 20 77 72 69     /* Open a wri
a2c0: 74 65 20 66 64 20 6f 6e 20 74 68 65 20 66 69 6c  te fd on the fil
a2d0: 65 2e 20 41 6c 73 6f 20 6c 6f 61 64 20 74 68 65  e. Also load the
a2e0: 20 65 6e 74 69 72 65 20 63 65 6e 74 72 61 6c 20   entire central 
a2f0: 64 69 72 65 63 74 6f 72 79 0a 20 20 20 20 2a 2a  directory.    **
a300: 20 73 74 72 75 63 74 75 72 65 20 69 6e 74 6f 20   structure into 
a310: 6d 65 6d 6f 72 79 2e 20 44 75 72 69 6e 67 20 74  memory. During t
a320: 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 61  he transaction a
a330: 6e 79 20 6e 65 77 20 66 69 6c 65 20 64 61 74 61  ny new file data
a340: 20 69 73 20 0a 20 20 20 20 2a 2a 20 61 70 70 65   is .    ** appe
a350: 6e 64 65 64 20 74 6f 20 74 68 65 20 61 72 63 68  nded to the arch
a360: 69 76 65 20 66 69 6c 65 2c 20 62 75 74 20 74 68  ive file, but th
a370: 65 20 63 65 6e 74 72 61 6c 20 64 69 72 65 63 74  e central direct
a380: 6f 72 79 20 69 73 20 61 63 63 75 6d 75 6c 61 74  ory is accumulat
a390: 65 64 0a 20 20 20 20 2a 2a 20 69 6e 20 6d 61 69  ed.    ** in mai
a3a0: 6e 2d 6d 65 6d 6f 72 79 20 75 6e 74 69 6c 20 74  n-memory until t
a3b0: 68 65 20 74 72 61 6e 73 61 63 74 69 6f 6e 20 69  he transaction i
a3c0: 73 20 63 6f 6d 6d 69 74 74 65 64 2e 20 20 2a 2f  s committed.  */
a3d0: 0a 20 20 20 20 70 54 61 62 2d 3e 70 57 72 69 74  .    pTab->pWrit
a3e0: 65 46 64 20 3d 20 66 6f 70 65 6e 28 70 54 61 62  eFd = fopen(pTab
a3f0: 2d 3e 7a 46 69 6c 65 2c 20 22 61 62 2b 22 29 3b  ->zFile, "ab+");
a400: 0a 20 20 20 20 69 66 28 20 70 54 61 62 2d 3e 70  .    if( pTab->p
a410: 57 72 69 74 65 46 64 3d 3d 30 20 29 7b 0a 20 20  WriteFd==0 ){.  
a420: 20 20 20 20 70 54 61 62 2d 3e 62 61 73 65 2e 7a      pTab->base.z
a430: 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33  ErrMsg = sqlite3
a440: 5f 6d 70 72 69 6e 74 66 28 0a 20 20 20 20 20 20  _mprintf(.      
a450: 20 20 20 20 22 7a 69 70 66 69 6c 65 3a 20 66 61      "zipfile: fa
a460: 69 6c 65 64 20 74 6f 20 6f 70 65 6e 20 66 69 6c  iled to open fil
a470: 65 20 25 73 20 66 6f 72 20 77 72 69 74 69 6e 67  e %s for writing
a480: 22 2c 20 70 54 61 62 2d 3e 7a 46 69 6c 65 0a 20  ", pTab->zFile. 
a490: 20 20 20 20 20 29 3b 0a 20 20 20 20 20 20 72 63       );.      rc
a4a0: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
a4b0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
a4c0: 20 20 66 73 65 65 6b 28 70 54 61 62 2d 3e 70 57    fseek(pTab->pW
a4d0: 72 69 74 65 46 64 2c 20 30 2c 20 53 45 45 4b 5f  riteFd, 0, SEEK_
a4e0: 45 4e 44 29 3b 0a 20 20 20 20 20 20 70 54 61 62  END);.      pTab
a4f0: 2d 3e 73 7a 43 75 72 72 65 6e 74 20 3d 20 70 54  ->szCurrent = pT
a500: 61 62 2d 3e 73 7a 4f 72 69 67 20 3d 20 28 69 36  ab->szOrig = (i6
a510: 34 29 66 74 65 6c 6c 28 70 54 61 62 2d 3e 70 57  4)ftell(pTab->pW
a520: 72 69 74 65 46 64 29 3b 0a 20 20 20 20 20 20 72  riteFd);.      r
a530: 63 20 3d 20 7a 69 70 66 69 6c 65 4c 6f 61 64 44  c = zipfileLoadD
a540: 69 72 65 63 74 6f 72 79 28 70 54 61 62 2c 20 30  irectory(pTab, 0
a550: 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20  , 0);.    }..   
a560: 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f   if( rc!=SQLITE_
a570: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 7a 69 70 66  OK ){.      zipf
a580: 69 6c 65 43 6c 65 61 6e 75 70 54 72 61 6e 73 61  ileCleanupTransa
a590: 63 74 69 6f 6e 28 70 54 61 62 29 3b 0a 20 20 20  ction(pTab);.   
a5a0: 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e   }.  }..  return
a5b0: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65   rc;.}../*.** Se
a5c0: 72 69 61 6c 69 7a 65 20 74 68 65 20 43 44 53 20  rialize the CDS 
a5d0: 73 74 72 75 63 74 75 72 65 20 69 6e 74 6f 20 62  structure into b
a5e0: 75 66 66 65 72 20 61 42 75 66 5b 5d 2e 20 52 65  uffer aBuf[]. Re
a5f0: 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 0a  turn the number.
a600: 2a 2a 20 6f 66 20 62 79 74 65 73 20 77 72 69 74  ** of bytes writ
a610: 74 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ten..*/.static i
a620: 6e 74 20 7a 69 70 66 69 6c 65 53 65 72 69 61 6c  nt zipfileSerial
a630: 69 7a 65 43 44 53 28 5a 69 70 66 69 6c 65 45 6e  izeCDS(ZipfileEn
a640: 74 72 79 20 2a 70 45 6e 74 72 79 2c 20 75 38 20  try *pEntry, u8 
a650: 2a 61 42 75 66 29 7b 0a 20 20 75 38 20 2a 61 20  *aBuf){.  u8 *a 
a660: 3d 20 61 42 75 66 3b 0a 20 20 5a 69 70 66 69 6c  = aBuf;.  Zipfil
a670: 65 43 44 53 20 2a 70 43 44 53 20 3d 20 26 70 45  eCDS *pCDS = &pE
a680: 6e 74 72 79 2d 3e 63 64 73 3b 0a 0a 20 20 69 66  ntry->cds;..  if
a690: 28 20 70 45 6e 74 72 79 2d 3e 61 45 78 74 72 61  ( pEntry->aExtra
a6a0: 3d 3d 30 20 29 7b 0a 20 20 20 20 70 43 44 53 2d  ==0 ){.    pCDS-
a6b0: 3e 6e 45 78 74 72 61 20 3d 20 39 3b 0a 20 20 7d  >nExtra = 9;.  }
a6c0: 0a 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65  ..  zipfileWrite
a6d0: 33 32 28 61 2c 20 5a 49 50 46 49 4c 45 5f 53 49  32(a, ZIPFILE_SI
a6e0: 47 4e 41 54 55 52 45 5f 43 44 53 29 3b 0a 20 20  GNATURE_CDS);.  
a6f0: 7a 69 70 66 69 6c 65 57 72 69 74 65 31 36 28 61  zipfileWrite16(a
a700: 2c 20 70 43 44 53 2d 3e 69 56 65 72 73 69 6f 6e  , pCDS->iVersion
a710: 4d 61 64 65 42 79 29 3b 0a 20 20 7a 69 70 66 69  MadeBy);.  zipfi
a720: 6c 65 57 72 69 74 65 31 36 28 61 2c 20 70 43 44  leWrite16(a, pCD
a730: 53 2d 3e 69 56 65 72 73 69 6f 6e 45 78 74 72 61  S->iVersionExtra
a740: 63 74 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72  ct);.  zipfileWr
a750: 69 74 65 31 36 28 61 2c 20 70 43 44 53 2d 3e 66  ite16(a, pCDS->f
a760: 6c 61 67 73 29 3b 0a 20 20 7a 69 70 66 69 6c 65  lags);.  zipfile
a770: 57 72 69 74 65 31 36 28 61 2c 20 70 43 44 53 2d  Write16(a, pCDS-
a780: 3e 69 43 6f 6d 70 72 65 73 73 69 6f 6e 29 3b 0a  >iCompression);.
a790: 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65 31 36    zipfileWrite16
a7a0: 28 61 2c 20 70 43 44 53 2d 3e 6d 54 69 6d 65 29  (a, pCDS->mTime)
a7b0: 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65  ;.  zipfileWrite
a7c0: 31 36 28 61 2c 20 70 43 44 53 2d 3e 6d 44 61 74  16(a, pCDS->mDat
a7d0: 65 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69  e);.  zipfileWri
a7e0: 74 65 33 32 28 61 2c 20 70 43 44 53 2d 3e 63 72  te32(a, pCDS->cr
a7f0: 63 33 32 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57  c32);.  zipfileW
a800: 72 69 74 65 33 32 28 61 2c 20 70 43 44 53 2d 3e  rite32(a, pCDS->
a810: 73 7a 43 6f 6d 70 72 65 73 73 65 64 29 3b 0a 20  szCompressed);. 
a820: 20 7a 69 70 66 69 6c 65 57 72 69 74 65 33 32 28   zipfileWrite32(
a830: 61 2c 20 70 43 44 53 2d 3e 73 7a 55 6e 63 6f 6d  a, pCDS->szUncom
a840: 70 72 65 73 73 65 64 29 3b 0a 20 20 61 73 73 65  pressed);.  asse
a850: 72 74 28 20 61 3d 3d 26 61 42 75 66 5b 5a 49 50  rt( a==&aBuf[ZIP
a860: 46 49 4c 45 5f 43 44 53 5f 4e 46 49 4c 45 5f 4f  FILE_CDS_NFILE_O
a870: 46 46 5d 20 29 3b 0a 20 20 7a 69 70 66 69 6c 65  FF] );.  zipfile
a880: 57 72 69 74 65 31 36 28 61 2c 20 70 43 44 53 2d  Write16(a, pCDS-
a890: 3e 6e 46 69 6c 65 29 3b 0a 20 20 7a 69 70 66 69  >nFile);.  zipfi
a8a0: 6c 65 57 72 69 74 65 31 36 28 61 2c 20 70 43 44  leWrite16(a, pCD
a8b0: 53 2d 3e 6e 45 78 74 72 61 29 3b 0a 20 20 7a 69  S->nExtra);.  zi
a8c0: 70 66 69 6c 65 57 72 69 74 65 31 36 28 61 2c 20  pfileWrite16(a, 
a8d0: 70 43 44 53 2d 3e 6e 43 6f 6d 6d 65 6e 74 29 3b  pCDS->nComment);
a8e0: 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65 31  .  zipfileWrite1
a8f0: 36 28 61 2c 20 70 43 44 53 2d 3e 69 44 69 73 6b  6(a, pCDS->iDisk
a900: 53 74 61 72 74 29 3b 0a 20 20 7a 69 70 66 69 6c  Start);.  zipfil
a910: 65 57 72 69 74 65 31 36 28 61 2c 20 70 43 44 53  eWrite16(a, pCDS
a920: 2d 3e 69 49 6e 74 65 72 6e 61 6c 41 74 74 72 29  ->iInternalAttr)
a930: 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65  ;.  zipfileWrite
a940: 33 32 28 61 2c 20 70 43 44 53 2d 3e 69 45 78 74  32(a, pCDS->iExt
a950: 65 72 6e 61 6c 41 74 74 72 29 3b 0a 20 20 7a 69  ernalAttr);.  zi
a960: 70 66 69 6c 65 57 72 69 74 65 33 32 28 61 2c 20  pfileWrite32(a, 
a970: 70 43 44 53 2d 3e 69 4f 66 66 73 65 74 29 3b 0a  pCDS->iOffset);.
a980: 0a 20 20 6d 65 6d 63 70 79 28 61 2c 20 70 43 44  .  memcpy(a, pCD
a990: 53 2d 3e 7a 46 69 6c 65 2c 20 70 43 44 53 2d 3e  S->zFile, pCDS->
a9a0: 6e 46 69 6c 65 29 3b 0a 20 20 61 20 2b 3d 20 70  nFile);.  a += p
a9b0: 43 44 53 2d 3e 6e 46 69 6c 65 3b 0a 0a 20 20 69  CDS->nFile;..  i
a9c0: 66 28 20 70 45 6e 74 72 79 2d 3e 61 45 78 74 72  f( pEntry->aExtr
a9d0: 61 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 20 3d  a ){.    int n =
a9e0: 20 28 69 6e 74 29 70 43 44 53 2d 3e 6e 45 78 74   (int)pCDS->nExt
a9f0: 72 61 20 2b 20 28 69 6e 74 29 70 43 44 53 2d 3e  ra + (int)pCDS->
aa00: 6e 43 6f 6d 6d 65 6e 74 3b 0a 20 20 20 20 6d 65  nComment;.    me
aa10: 6d 63 70 79 28 61 2c 20 70 45 6e 74 72 79 2d 3e  mcpy(a, pEntry->
aa20: 61 45 78 74 72 61 2c 20 6e 29 3b 0a 20 20 20 20  aExtra, n);.    
aa30: 61 20 2b 3d 20 6e 3b 0a 20 20 7d 65 6c 73 65 7b  a += n;.  }else{
aa40: 0a 20 20 20 20 61 73 73 65 72 74 28 20 70 43 44  .    assert( pCD
aa50: 53 2d 3e 6e 45 78 74 72 61 3d 3d 39 20 29 3b 0a  S->nExtra==9 );.
aa60: 20 20 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65      zipfileWrite
aa70: 31 36 28 61 2c 20 5a 49 50 46 49 4c 45 5f 45 58  16(a, ZIPFILE_EX
aa80: 54 52 41 5f 54 49 4d 45 53 54 41 4d 50 29 3b 0a  TRA_TIMESTAMP);.
aa90: 20 20 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65      zipfileWrite
aaa0: 31 36 28 61 2c 20 35 29 3b 0a 20 20 20 20 2a 61  16(a, 5);.    *a
aab0: 2b 2b 20 3d 20 30 78 30 31 3b 0a 20 20 20 20 7a  ++ = 0x01;.    z
aac0: 69 70 66 69 6c 65 57 72 69 74 65 33 32 28 61 2c  ipfileWrite32(a,
aad0: 20 70 45 6e 74 72 79 2d 3e 6d 55 6e 69 78 54 69   pEntry->mUnixTi
aae0: 6d 65 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  me);.  }..  retu
aaf0: 72 6e 20 61 2d 61 42 75 66 3b 0a 7d 0a 0a 73 74  rn a-aBuf;.}..st
ab00: 61 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65  atic int zipfile
ab10: 43 6f 6d 6d 69 74 28 73 71 6c 69 74 65 33 5f 76  Commit(sqlite3_v
ab20: 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20 5a  tab *pVtab){.  Z
ab30: 69 70 66 69 6c 65 54 61 62 20 2a 70 54 61 62 20  ipfileTab *pTab 
ab40: 3d 20 28 5a 69 70 66 69 6c 65 54 61 62 2a 29 70  = (ZipfileTab*)p
ab50: 56 74 61 62 3b 0a 20 20 69 6e 74 20 72 63 20 3d  Vtab;.  int rc =
ab60: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69 66   SQLITE_OK;.  if
ab70: 28 20 70 54 61 62 2d 3e 70 57 72 69 74 65 46 64  ( pTab->pWriteFd
ab80: 20 29 7b 0a 20 20 20 20 69 36 34 20 69 4f 66 66   ){.    i64 iOff
ab90: 73 65 74 20 3d 20 70 54 61 62 2d 3e 73 7a 43 75  set = pTab->szCu
aba0: 72 72 65 6e 74 3b 0a 20 20 20 20 5a 69 70 66 69  rrent;.    Zipfi
abb0: 6c 65 45 6e 74 72 79 20 2a 70 3b 0a 20 20 20 20  leEntry *p;.    
abc0: 5a 69 70 66 69 6c 65 45 4f 43 44 20 65 6f 63 64  ZipfileEOCD eocd
abd0: 3b 0a 20 20 20 20 69 6e 74 20 6e 45 6e 74 72 79  ;.    int nEntry
abe0: 20 3d 20 30 3b 0a 0a 20 20 20 20 2f 2a 20 57 72   = 0;..    /* Wr
abf0: 69 74 65 20 6f 75 74 20 61 6c 6c 20 65 6e 74 72  ite out all entr
ac00: 69 65 73 20 2a 2f 0a 20 20 20 20 66 6f 72 28 70  ies */.    for(p
ac10: 3d 70 54 61 62 2d 3e 70 46 69 72 73 74 45 6e 74  =pTab->pFirstEnt
ac20: 72 79 3b 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  ry; rc==SQLITE_O
ac30: 4b 20 26 26 20 70 3b 20 70 3d 70 2d 3e 70 4e 65  K && p; p=p->pNe
ac40: 78 74 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e  xt){.      int n
ac50: 20 3d 20 7a 69 70 66 69 6c 65 53 65 72 69 61 6c   = zipfileSerial
ac60: 69 7a 65 43 44 53 28 70 2c 20 70 54 61 62 2d 3e  izeCDS(p, pTab->
ac70: 61 42 75 66 66 65 72 29 3b 0a 20 20 20 20 20 20  aBuffer);.      
ac80: 72 63 20 3d 20 7a 69 70 66 69 6c 65 41 70 70 65  rc = zipfileAppe
ac90: 6e 64 44 61 74 61 28 70 54 61 62 2c 20 70 54 61  ndData(pTab, pTa
aca0: 62 2d 3e 61 42 75 66 66 65 72 2c 20 6e 29 3b 0a  b->aBuffer, n);.
acb0: 20 20 20 20 20 20 6e 45 6e 74 72 79 2b 2b 3b 0a        nEntry++;.
acc0: 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 57 72      }..    /* Wr
acd0: 69 74 65 20 6f 75 74 20 74 68 65 20 45 4f 43 44  ite out the EOCD
ace0: 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 20 20 65   record */.    e
acf0: 6f 63 64 2e 69 44 69 73 6b 20 3d 20 30 3b 0a 20  ocd.iDisk = 0;. 
ad00: 20 20 20 65 6f 63 64 2e 69 46 69 72 73 74 44 69     eocd.iFirstDi
ad10: 73 6b 20 3d 20 30 3b 0a 20 20 20 20 65 6f 63 64  sk = 0;.    eocd
ad20: 2e 6e 45 6e 74 72 79 20 3d 20 28 75 31 36 29 6e  .nEntry = (u16)n
ad30: 45 6e 74 72 79 3b 0a 20 20 20 20 65 6f 63 64 2e  Entry;.    eocd.
ad40: 6e 45 6e 74 72 79 54 6f 74 61 6c 20 3d 20 28 75  nEntryTotal = (u
ad50: 31 36 29 6e 45 6e 74 72 79 3b 0a 20 20 20 20 65  16)nEntry;.    e
ad60: 6f 63 64 2e 6e 53 69 7a 65 20 3d 20 28 75 33 32  ocd.nSize = (u32
ad70: 29 28 70 54 61 62 2d 3e 73 7a 43 75 72 72 65 6e  )(pTab->szCurren
ad80: 74 20 2d 20 69 4f 66 66 73 65 74 29 3b 0a 20 20  t - iOffset);.  
ad90: 20 20 65 6f 63 64 2e 69 4f 66 66 73 65 74 20 3d    eocd.iOffset =
ada0: 20 28 75 33 32 29 69 4f 66 66 73 65 74 3b 0a 20   (u32)iOffset;. 
adb0: 20 20 20 72 63 20 3d 20 7a 69 70 66 69 6c 65 41     rc = zipfileA
adc0: 70 70 65 6e 64 45 4f 43 44 28 70 54 61 62 2c 20  ppendEOCD(pTab, 
add0: 26 65 6f 63 64 29 3b 0a 0a 20 20 20 20 7a 69 70  &eocd);..    zip
ade0: 66 69 6c 65 43 6c 65 61 6e 75 70 54 72 61 6e 73  fileCleanupTrans
adf0: 61 63 74 69 6f 6e 28 70 54 61 62 29 3b 0a 20 20  action(pTab);.  
ae00: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
ae10: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70  ..static int zip
ae20: 66 69 6c 65 52 6f 6c 6c 62 61 63 6b 28 73 71 6c  fileRollback(sql
ae30: 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62  ite3_vtab *pVtab
ae40: 29 7b 0a 20 20 72 65 74 75 72 6e 20 7a 69 70 66  ){.  return zipf
ae50: 69 6c 65 43 6f 6d 6d 69 74 28 70 56 74 61 62 29  ileCommit(pVtab)
ae60: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 5a 69 70 66  ;.}..static Zipf
ae70: 69 6c 65 43 73 72 20 2a 7a 69 70 66 69 6c 65 46  ileCsr *zipfileF
ae80: 69 6e 64 43 75 72 73 6f 72 28 5a 69 70 66 69 6c  indCursor(Zipfil
ae90: 65 54 61 62 20 2a 70 54 61 62 2c 20 69 36 34 20  eTab *pTab, i64 
aea0: 69 49 64 29 7b 0a 20 20 5a 69 70 66 69 6c 65 43  iId){.  ZipfileC
aeb0: 73 72 20 2a 70 43 73 72 3b 0a 20 20 66 6f 72 28  sr *pCsr;.  for(
aec0: 70 43 73 72 3d 70 54 61 62 2d 3e 70 43 73 72 4c  pCsr=pTab->pCsrL
aed0: 69 73 74 3b 20 70 43 73 72 3b 20 70 43 73 72 3d  ist; pCsr; pCsr=
aee0: 70 43 73 72 2d 3e 70 43 73 72 4e 65 78 74 29 7b  pCsr->pCsrNext){
aef0: 0a 20 20 20 20 69 66 28 20 69 49 64 3d 3d 70 43  .    if( iId==pC
af00: 73 72 2d 3e 69 49 64 20 29 20 62 72 65 61 6b 3b  sr->iId ) break;
af10: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70 43  .  }.  return pC
af20: 73 72 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  sr;.}..static vo
af30: 69 64 20 7a 69 70 66 69 6c 65 46 75 6e 63 74 69  id zipfileFuncti
af40: 6f 6e 43 64 73 28 0a 20 20 73 71 6c 69 74 65 33  onCds(.  sqlite3
af50: 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78  _context *contex
af60: 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20  t,.  int argc,. 
af70: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
af80: 2a 61 72 67 76 0a 29 7b 0a 20 20 5a 69 70 66 69  *argv.){.  Zipfi
af90: 6c 65 43 73 72 20 2a 70 43 73 72 3b 0a 20 20 5a  leCsr *pCsr;.  Z
afa0: 69 70 66 69 6c 65 54 61 62 20 2a 70 54 61 62 20  ipfileTab *pTab 
afb0: 3d 20 28 5a 69 70 66 69 6c 65 54 61 62 2a 29 73  = (ZipfileTab*)s
afc0: 71 6c 69 74 65 33 5f 75 73 65 72 5f 64 61 74 61  qlite3_user_data
afd0: 28 63 6f 6e 74 65 78 74 29 3b 0a 20 20 61 73 73  (context);.  ass
afe0: 65 72 74 28 20 61 72 67 63 3e 30 20 29 3b 0a 0a  ert( argc>0 );..
aff0: 20 20 70 43 73 72 20 3d 20 7a 69 70 66 69 6c 65    pCsr = zipfile
b000: 46 69 6e 64 43 75 72 73 6f 72 28 70 54 61 62 2c  FindCursor(pTab,
b010: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69   sqlite3_value_i
b020: 6e 74 36 34 28 61 72 67 76 5b 30 5d 29 29 3b 0a  nt64(argv[0]));.
b030: 20 20 69 66 28 20 70 43 73 72 20 29 7b 0a 20 20    if( pCsr ){.  
b040: 20 20 5a 69 70 66 69 6c 65 43 44 53 20 2a 70 20    ZipfileCDS *p 
b050: 3d 20 26 70 43 73 72 2d 3e 70 43 75 72 72 65 6e  = &pCsr->pCurren
b060: 74 2d 3e 63 64 73 3b 0a 20 20 20 20 63 68 61 72  t->cds;.    char
b070: 20 2a 7a 52 65 73 20 3d 20 73 71 6c 69 74 65 33   *zRes = sqlite3
b080: 5f 6d 70 72 69 6e 74 66 28 22 7b 22 0a 20 20 20  _mprintf("{".   
b090: 20 20 20 20 20 22 5c 22 76 65 72 73 69 6f 6e 2d       "\"version-
b0a0: 6d 61 64 65 2d 62 79 5c 22 20 3a 20 25 75 2c 20  made-by\" : %u, 
b0b0: 22 0a 20 20 20 20 20 20 20 20 22 5c 22 76 65 72  ".        "\"ver
b0c0: 73 69 6f 6e 2d 74 6f 2d 65 78 74 72 61 63 74 5c  sion-to-extract\
b0d0: 22 20 3a 20 25 75 2c 20 22 0a 20 20 20 20 20 20  " : %u, ".      
b0e0: 20 20 22 5c 22 66 6c 61 67 73 5c 22 20 3a 20 25    "\"flags\" : %
b0f0: 75 2c 20 22 0a 20 20 20 20 20 20 20 20 22 5c 22  u, ".        "\"
b100: 63 6f 6d 70 72 65 73 73 69 6f 6e 5c 22 20 3a 20  compression\" : 
b110: 25 75 2c 20 22 0a 20 20 20 20 20 20 20 20 22 5c  %u, ".        "\
b120: 22 74 69 6d 65 5c 22 20 3a 20 25 75 2c 20 22 0a  "time\" : %u, ".
b130: 20 20 20 20 20 20 20 20 22 5c 22 64 61 74 65 5c          "\"date\
b140: 22 20 3a 20 25 75 2c 20 22 0a 20 20 20 20 20 20  " : %u, ".      
b150: 20 20 22 5c 22 63 72 63 33 32 5c 22 20 3a 20 25    "\"crc32\" : %
b160: 75 2c 20 22 0a 20 20 20 20 20 20 20 20 22 5c 22  u, ".        "\"
b170: 63 6f 6d 70 72 65 73 73 65 64 2d 73 69 7a 65 5c  compressed-size\
b180: 22 20 3a 20 25 75 2c 20 22 0a 20 20 20 20 20 20  " : %u, ".      
b190: 20 20 22 5c 22 75 6e 63 6f 6d 70 72 65 73 73 65    "\"uncompresse
b1a0: 64 2d 73 69 7a 65 5c 22 20 3a 20 25 75 2c 20 22  d-size\" : %u, "
b1b0: 0a 20 20 20 20 20 20 20 20 22 5c 22 66 69 6c 65  .        "\"file
b1c0: 2d 6e 61 6d 65 2d 6c 65 6e 67 74 68 5c 22 20 3a  -name-length\" :
b1d0: 20 25 75 2c 20 22 0a 20 20 20 20 20 20 20 20 22   %u, ".        "
b1e0: 5c 22 65 78 74 72 61 2d 66 69 65 6c 64 2d 6c 65  \"extra-field-le
b1f0: 6e 67 74 68 5c 22 20 3a 20 25 75 2c 20 22 0a 20  ngth\" : %u, ". 
b200: 20 20 20 20 20 20 20 22 5c 22 66 69 6c 65 2d 63         "\"file-c
b210: 6f 6d 6d 65 6e 74 2d 6c 65 6e 67 74 68 5c 22 20  omment-length\" 
b220: 3a 20 25 75 2c 20 22 0a 20 20 20 20 20 20 20 20  : %u, ".        
b230: 22 5c 22 64 69 73 6b 2d 6e 75 6d 62 65 72 2d 73  "\"disk-number-s
b240: 74 61 72 74 5c 22 20 3a 20 25 75 2c 20 22 0a 20  tart\" : %u, ". 
b250: 20 20 20 20 20 20 20 22 5c 22 69 6e 74 65 72 6e         "\"intern
b260: 61 6c 2d 61 74 74 72 5c 22 20 3a 20 25 75 2c 20  al-attr\" : %u, 
b270: 22 0a 20 20 20 20 20 20 20 20 22 5c 22 65 78 74  ".        "\"ext
b280: 65 72 6e 61 6c 2d 61 74 74 72 5c 22 20 3a 20 25  ernal-attr\" : %
b290: 75 2c 20 22 0a 20 20 20 20 20 20 20 20 22 5c 22  u, ".        "\"
b2a0: 6f 66 66 73 65 74 5c 22 20 3a 20 25 75 20 7d 22  offset\" : %u }"
b2b0: 2c 0a 20 20 20 20 20 20 20 20 28 75 33 32 29 70  ,.        (u32)p
b2c0: 2d 3e 69 56 65 72 73 69 6f 6e 4d 61 64 65 42 79  ->iVersionMadeBy
b2d0: 2c 20 28 75 33 32 29 70 2d 3e 69 56 65 72 73 69  , (u32)p->iVersi
b2e0: 6f 6e 45 78 74 72 61 63 74 2c 0a 20 20 20 20 20  onExtract,.     
b2f0: 20 20 20 28 75 33 32 29 70 2d 3e 66 6c 61 67 73     (u32)p->flags
b300: 2c 20 28 75 33 32 29 70 2d 3e 69 43 6f 6d 70 72  , (u32)p->iCompr
b310: 65 73 73 69 6f 6e 2c 0a 20 20 20 20 20 20 20 20  ession,.        
b320: 28 75 33 32 29 70 2d 3e 6d 54 69 6d 65 2c 20 28  (u32)p->mTime, (
b330: 75 33 32 29 70 2d 3e 6d 44 61 74 65 2c 0a 20 20  u32)p->mDate,.  
b340: 20 20 20 20 20 20 28 75 33 32 29 70 2d 3e 63 72        (u32)p->cr
b350: 63 33 32 2c 20 28 75 33 32 29 70 2d 3e 73 7a 43  c32, (u32)p->szC
b360: 6f 6d 70 72 65 73 73 65 64 2c 0a 20 20 20 20 20  ompressed,.     
b370: 20 20 20 28 75 33 32 29 70 2d 3e 73 7a 55 6e 63     (u32)p->szUnc
b380: 6f 6d 70 72 65 73 73 65 64 2c 20 28 75 33 32 29  ompressed, (u32)
b390: 70 2d 3e 6e 46 69 6c 65 2c 0a 20 20 20 20 20 20  p->nFile,.      
b3a0: 20 20 28 75 33 32 29 70 2d 3e 6e 45 78 74 72 61    (u32)p->nExtra
b3b0: 2c 20 28 75 33 32 29 70 2d 3e 6e 43 6f 6d 6d 65  , (u32)p->nComme
b3c0: 6e 74 2c 0a 20 20 20 20 20 20 20 20 28 75 33 32  nt,.        (u32
b3d0: 29 70 2d 3e 69 44 69 73 6b 53 74 61 72 74 2c 20  )p->iDiskStart, 
b3e0: 28 75 33 32 29 70 2d 3e 69 49 6e 74 65 72 6e 61  (u32)p->iInterna
b3f0: 6c 41 74 74 72 2c 0a 20 20 20 20 20 20 20 20 28  lAttr,.        (
b400: 75 33 32 29 70 2d 3e 69 45 78 74 65 72 6e 61 6c  u32)p->iExternal
b410: 41 74 74 72 2c 20 28 75 33 32 29 70 2d 3e 69 4f  Attr, (u32)p->iO
b420: 66 66 73 65 74 0a 20 20 20 20 29 3b 0a 0a 20 20  ffset.    );..  
b430: 20 20 69 66 28 20 7a 52 65 73 3d 3d 30 20 29 7b    if( zRes==0 ){
b440: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72  .      sqlite3_r
b450: 65 73 75 6c 74 5f 65 72 72 6f 72 5f 6e 6f 6d 65  esult_error_nome
b460: 6d 28 63 6f 6e 74 65 78 74 29 3b 0a 20 20 20 20  m(context);.    
b470: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 71 6c  }else{.      sql
b480: 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 74  ite3_result_text
b490: 28 63 6f 6e 74 65 78 74 2c 20 7a 52 65 73 2c 20  (context, zRes, 
b4a0: 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53  -1, SQLITE_TRANS
b4b0: 49 45 4e 54 29 3b 0a 20 20 20 20 20 20 73 71 6c  IENT);.      sql
b4c0: 69 74 65 33 5f 66 72 65 65 28 7a 52 65 73 29 3b  ite3_free(zRes);
b4d0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 73 74  .    }.  }.}..st
b4e0: 61 74 69 63 20 76 6f 69 64 20 7a 69 70 66 69 6c  atic void zipfil
b4f0: 65 46 72 65 65 28 76 6f 69 64 20 2a 70 29 20 7b  eFree(void *p) {
b500: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29   sqlite3_free(p)
b510: 3b 20 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ; }..static void
b520: 20 7a 69 70 66 69 6c 65 46 75 6e 63 74 69 6f 6e   zipfileFunction
b530: 42 6c 6f 62 28 0a 20 20 73 71 6c 69 74 65 33 5f  Blob(.  sqlite3_
b540: 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 74  context *context
b550: 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 20  ,.  int argc,.  
b560: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
b570: 61 72 67 76 0a 29 7b 0a 20 20 5a 69 70 66 69 6c  argv.){.  Zipfil
b580: 65 43 73 72 20 2a 70 43 73 72 3b 0a 20 20 5a 69  eCsr *pCsr;.  Zi
b590: 70 66 69 6c 65 54 61 62 20 2a 70 54 61 62 20 3d  pfileTab *pTab =
b5a0: 20 28 5a 69 70 66 69 6c 65 54 61 62 2a 29 73 71   (ZipfileTab*)sq
b5b0: 6c 69 74 65 33 5f 75 73 65 72 5f 64 61 74 61 28  lite3_user_data(
b5c0: 63 6f 6e 74 65 78 74 29 3b 0a 20 20 5a 69 70 66  context);.  Zipf
b5d0: 69 6c 65 45 6e 74 72 79 20 2a 70 3b 0a 20 20 69  ileEntry *p;.  i
b5e0: 6e 74 20 6e 42 6f 64 79 20 3d 20 30 3b 0a 20 20  nt nBody = 0;.  
b5f0: 69 6e 74 20 6e 43 64 73 20 3d 20 30 3b 0a 20 20  int nCds = 0;.  
b600: 69 6e 74 20 6e 45 6f 63 64 20 3d 20 5a 49 50 46  int nEocd = ZIPF
b610: 49 4c 45 5f 45 4f 43 44 5f 46 49 58 45 44 5f 53  ILE_EOCD_FIXED_S
b620: 5a 3b 0a 20 20 5a 69 70 66 69 6c 65 45 4f 43 44  Z;.  ZipfileEOCD
b630: 20 65 6f 63 64 3b 0a 0a 20 20 75 38 20 2a 61 5a   eocd;..  u8 *aZ
b640: 69 70 3b 0a 20 20 69 6e 74 20 6e 5a 69 70 3b 0a  ip;.  int nZip;.
b650: 0a 20 20 75 38 20 2a 61 42 6f 64 79 3b 0a 20 20  .  u8 *aBody;.  
b660: 75 38 20 2a 61 43 64 73 3b 0a 0a 20 20 70 43 73  u8 *aCds;..  pCs
b670: 72 20 3d 20 7a 69 70 66 69 6c 65 46 69 6e 64 43  r = zipfileFindC
b680: 75 72 73 6f 72 28 70 54 61 62 2c 20 73 71 6c 69  ursor(pTab, sqli
b690: 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28  te3_value_int64(
b6a0: 61 72 67 76 5b 30 5d 29 29 3b 0a 20 20 69 66 28  argv[0]));.  if(
b6b0: 20 70 43 73 72 2d 3e 70 46 69 6c 65 20 7c 7c 20   pCsr->pFile || 
b6c0: 70 54 61 62 2d 3e 7a 46 69 6c 65 20 29 7b 0a 20  pTab->zFile ){. 
b6d0: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
b6e0: 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74 2c  t_error(context,
b6f0: 20 22 69 6c 6c 65 67 61 6c 20 75 73 65 20 6f 66   "illegal use of
b700: 20 7a 69 70 66 69 6c 65 5f 62 6c 6f 62 28 29 22   zipfile_blob()"
b710: 2c 20 2d 31 29 3b 0a 20 20 20 20 72 65 74 75 72  , -1);.    retur
b720: 6e 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 46 69 67  n;.  }..  /* Fig
b730: 75 72 65 20 6f 75 74 20 68 6f 77 20 6c 61 72 67  ure out how larg
b740: 65 20 74 68 65 20 66 69 6e 61 6c 20 66 69 6c 65  e the final file
b750: 20 77 69 6c 6c 20 62 65 20 2a 2f 0a 20 20 66 6f   will be */.  fo
b760: 72 28 70 3d 70 54 61 62 2d 3e 70 46 69 72 73 74  r(p=pTab->pFirst
b770: 45 6e 74 72 79 3b 20 70 3b 20 70 3d 70 2d 3e 70  Entry; p; p=p->p
b780: 4e 65 78 74 29 7b 0a 20 20 20 20 6e 42 6f 64 79  Next){.    nBody
b790: 20 2b 3d 20 5a 49 50 46 49 4c 45 5f 4c 46 48 5f   += ZIPFILE_LFH_
b7a0: 46 49 58 45 44 5f 53 5a 20 2b 20 70 2d 3e 63 64  FIXED_SZ + p->cd
b7b0: 73 2e 6e 46 69 6c 65 20 2b 20 39 20 2b 20 70 2d  s.nFile + 9 + p-
b7c0: 3e 63 64 73 2e 73 7a 43 6f 6d 70 72 65 73 73 65  >cds.szCompresse
b7d0: 64 3b 0a 20 20 20 20 6e 43 64 73 20 2b 3d 20 5a  d;.    nCds += Z
b7e0: 49 50 46 49 4c 45 5f 43 44 53 5f 46 49 58 45 44  IPFILE_CDS_FIXED
b7f0: 5f 53 5a 20 2b 20 70 2d 3e 63 64 73 2e 6e 46 69  _SZ + p->cds.nFi
b800: 6c 65 20 2b 20 39 3b 0a 20 20 7d 0a 0a 20 20 2f  le + 9;.  }..  /
b810: 2a 20 41 6c 6c 6f 63 61 74 65 20 73 70 61 63 65  * Allocate space
b820: 20 74 6f 20 63 72 65 61 74 65 20 74 68 65 20 73   to create the s
b830: 65 72 69 61 6c 69 7a 65 64 20 66 69 6c 65 20 2a  erialized file *
b840: 2f 0a 20 20 6e 5a 69 70 20 3d 20 6e 42 6f 64 79  /.  nZip = nBody
b850: 20 2b 20 6e 43 64 73 20 2b 20 6e 45 6f 63 64 3b   + nCds + nEocd;
b860: 0a 20 20 61 5a 69 70 20 3d 20 28 75 38 2a 29 73  .  aZip = (u8*)s
b870: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 5a  qlite3_malloc(nZ
b880: 69 70 29 3b 0a 20 20 69 66 28 20 61 5a 69 70 3d  ip);.  if( aZip=
b890: 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  =0 ){.    sqlite
b8a0: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f 6e  3_result_error_n
b8b0: 6f 6d 65 6d 28 63 6f 6e 74 65 78 74 29 3b 0a 20  omem(context);. 
b8c0: 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20     return;.  }. 
b8d0: 20 61 42 6f 64 79 20 3d 20 61 5a 69 70 3b 0a 20   aBody = aZip;. 
b8e0: 20 61 43 64 73 20 3d 20 26 61 5a 69 70 5b 6e 42   aCds = &aZip[nB
b8f0: 6f 64 79 5d 3b 0a 0a 20 20 2f 2a 20 50 6f 70 75  ody];..  /* Popu
b900: 6c 61 74 65 20 74 68 65 20 62 6f 64 79 20 61 6e  late the body an
b910: 64 20 43 44 53 20 2a 2f 0a 20 20 6d 65 6d 73 65  d CDS */.  memse
b920: 74 28 26 65 6f 63 64 2c 20 30 2c 20 73 69 7a 65  t(&eocd, 0, size
b930: 6f 66 28 65 6f 63 64 29 29 3b 0a 20 20 66 6f 72  of(eocd));.  for
b940: 28 70 3d 70 54 61 62 2d 3e 70 46 69 72 73 74 45  (p=pTab->pFirstE
b950: 6e 74 72 79 3b 20 70 3b 20 70 3d 70 2d 3e 70 4e  ntry; p; p=p->pN
b960: 65 78 74 29 7b 0a 20 20 20 20 70 2d 3e 63 64 73  ext){.    p->cds
b970: 2e 69 4f 66 66 73 65 74 20 3d 20 28 61 42 6f 64  .iOffset = (aBod
b980: 79 20 2d 20 61 5a 69 70 29 3b 0a 20 20 20 20 61  y - aZip);.    a
b990: 42 6f 64 79 20 2b 3d 20 7a 69 70 66 69 6c 65 53  Body += zipfileS
b9a0: 65 72 69 61 6c 69 7a 65 4c 46 48 28 70 2c 20 61  erializeLFH(p, a
b9b0: 42 6f 64 79 29 3b 0a 20 20 20 20 69 66 28 20 70  Body);.    if( p
b9c0: 2d 3e 63 64 73 2e 73 7a 43 6f 6d 70 72 65 73 73  ->cds.szCompress
b9d0: 65 64 20 29 7b 0a 20 20 20 20 20 20 6d 65 6d 63  ed ){.      memc
b9e0: 70 79 28 61 42 6f 64 79 2c 20 70 2d 3e 61 44 61  py(aBody, p->aDa
b9f0: 74 61 2c 20 70 2d 3e 63 64 73 2e 73 7a 43 6f 6d  ta, p->cds.szCom
ba00: 70 72 65 73 73 65 64 29 3b 0a 20 20 20 20 20 20  pressed);.      
ba10: 61 42 6f 64 79 20 2b 3d 20 70 2d 3e 63 64 73 2e  aBody += p->cds.
ba20: 73 7a 43 6f 6d 70 72 65 73 73 65 64 3b 0a 20 20  szCompressed;.  
ba30: 20 20 7d 0a 20 20 20 20 61 43 64 73 20 2b 3d 20    }.    aCds += 
ba40: 7a 69 70 66 69 6c 65 53 65 72 69 61 6c 69 7a 65  zipfileSerialize
ba50: 43 44 53 28 70 2c 20 61 43 64 73 29 3b 0a 20 20  CDS(p, aCds);.  
ba60: 20 20 65 6f 63 64 2e 6e 45 6e 74 72 79 2b 2b 3b    eocd.nEntry++;
ba70: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 41 70 70 65 6e  .  }..  /* Appen
ba80: 64 20 74 68 65 20 45 4f 43 44 20 72 65 63 6f 72  d the EOCD recor
ba90: 64 20 2a 2f 0a 20 20 61 73 73 65 72 74 28 20 61  d */.  assert( a
baa0: 42 6f 64 79 3d 3d 26 61 5a 69 70 5b 6e 42 6f 64  Body==&aZip[nBod
bab0: 79 5d 20 29 3b 0a 20 20 61 73 73 65 72 74 28 20  y] );.  assert( 
bac0: 61 43 64 73 3d 3d 26 61 5a 69 70 5b 6e 42 6f 64  aCds==&aZip[nBod
bad0: 79 2b 6e 43 64 73 5d 20 29 3b 0a 20 20 65 6f 63  y+nCds] );.  eoc
bae0: 64 2e 6e 45 6e 74 72 79 54 6f 74 61 6c 20 3d 20  d.nEntryTotal = 
baf0: 65 6f 63 64 2e 6e 45 6e 74 72 79 3b 0a 20 20 65  eocd.nEntry;.  e
bb00: 6f 63 64 2e 6e 53 69 7a 65 20 3d 20 6e 43 64 73  ocd.nSize = nCds
bb10: 3b 0a 20 20 65 6f 63 64 2e 69 4f 66 66 73 65 74  ;.  eocd.iOffset
bb20: 20 3d 20 6e 42 6f 64 79 3b 0a 20 20 7a 69 70 66   = nBody;.  zipf
bb30: 69 6c 65 53 65 72 69 61 6c 69 7a 65 45 4f 43 44  ileSerializeEOCD
bb40: 28 26 65 6f 63 64 2c 20 61 43 64 73 29 3b 0a 0a  (&eocd, aCds);..
bb50: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
bb60: 5f 62 6c 6f 62 28 63 6f 6e 74 65 78 74 2c 20 61  _blob(context, a
bb70: 5a 69 70 2c 20 6e 5a 69 70 2c 20 7a 69 70 66 69  Zip, nZip, zipfi
bb80: 6c 65 46 72 65 65 29 3b 0a 7d 0a 0a 0a 2f 2a 0a  leFree);.}.../*.
bb90: 2a 2a 20 78 46 69 6e 64 46 75 6e 63 74 69 6f 6e  ** xFindFunction
bba0: 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73 74 61 74   method..*/.stat
bbb0: 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 46 69  ic int zipfileFi
bbc0: 6e 64 46 75 6e 63 74 69 6f 6e 28 0a 20 20 73 71  ndFunction(.  sq
bbd0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
bbe0: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  b,            /*
bbf0: 20 56 69 72 74 75 61 6c 20 74 61 62 6c 65 20 68   Virtual table h
bc00: 61 6e 64 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e  andle */.  int n
bc10: 41 72 67 2c 20 20 20 20 20 20 20 20 20 20 20 20  Arg,            
bc20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75             /* Nu
bc30: 6d 62 65 72 20 6f 66 20 53 51 4c 20 66 75 6e 63  mber of SQL func
bc40: 74 69 6f 6e 20 61 72 67 75 6d 65 6e 74 73 20 2a  tion arguments *
bc50: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
bc60: 7a 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20  zName,          
bc70: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 53      /* Name of S
bc80: 51 4c 20 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 20  QL function */. 
bc90: 20 76 6f 69 64 20 28 2a 2a 70 78 46 75 6e 63 29   void (**pxFunc)
bca0: 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74  (sqlite3_context
bcb0: 2a 2c 69 6e 74 2c 73 71 6c 69 74 65 33 5f 76 61  *,int,sqlite3_va
bcc0: 6c 75 65 2a 2a 29 2c 20 2f 2a 20 4f 55 54 3a 20  lue**), /* OUT: 
bcd0: 52 65 73 75 6c 74 20 2a 2f 0a 20 20 76 6f 69 64  Result */.  void
bce0: 20 2a 2a 70 70 41 72 67 20 20 20 20 20 20 20 20   **ppArg        
bcf0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
bd00: 55 54 3a 20 55 73 65 72 20 64 61 74 61 20 66 6f  UT: User data fo
bd10: 72 20 2a 70 78 46 75 6e 63 20 2a 2f 0a 29 7b 0a  r *pxFunc */.){.
bd20: 20 20 69 66 28 20 6e 41 72 67 3e 30 20 29 7b 0a    if( nArg>0 ){.
bd30: 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f      if( sqlite3_
bd40: 73 74 72 69 63 6d 70 28 22 7a 69 70 66 69 6c 65  stricmp("zipfile
bd50: 5f 63 64 73 22 2c 20 7a 4e 61 6d 65 29 3d 3d 30  _cds", zName)==0
bd60: 20 29 7b 0a 20 20 20 20 20 20 2a 70 78 46 75 6e   ){.      *pxFun
bd70: 63 20 3d 20 7a 69 70 66 69 6c 65 46 75 6e 63 74  c = zipfileFunct
bd80: 69 6f 6e 43 64 73 3b 0a 20 20 20 20 20 20 2a 70  ionCds;.      *p
bd90: 70 41 72 67 20 3d 20 28 76 6f 69 64 2a 29 70 56  pArg = (void*)pV
bda0: 74 61 62 3b 0a 20 20 20 20 20 20 72 65 74 75 72  tab;.      retur
bdb0: 6e 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69  n 1;.    }.    i
bdc0: 66 28 20 73 71 6c 69 74 65 33 5f 73 74 72 69 63  f( sqlite3_stric
bdd0: 6d 70 28 22 7a 69 70 66 69 6c 65 5f 62 6c 6f 62  mp("zipfile_blob
bde0: 22 2c 20 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a  ", zName)==0 ){.
bdf0: 20 20 20 20 20 20 2a 70 78 46 75 6e 63 20 3d 20        *pxFunc = 
be00: 7a 69 70 66 69 6c 65 46 75 6e 63 74 69 6f 6e 42  zipfileFunctionB
be10: 6c 6f 62 3b 0a 20 20 20 20 20 20 2a 70 70 41 72  lob;.      *ppAr
be20: 67 20 3d 20 28 76 6f 69 64 2a 29 70 56 74 61 62  g = (void*)pVtab
be30: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 31  ;.      return 1
be40: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72  ;.    }.  }..  r
be50: 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn 0;.}../*.*
be60: 2a 20 52 65 67 69 73 74 65 72 20 74 68 65 20 22  * Register the "
be70: 7a 69 70 66 69 6c 65 22 20 76 69 72 74 75 61 6c  zipfile" virtual
be80: 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69   table..*/.stati
be90: 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 52 65 67  c int zipfileReg
bea0: 69 73 74 65 72 28 73 71 6c 69 74 65 33 20 2a 64  ister(sqlite3 *d
beb0: 62 29 7b 0a 20 20 73 74 61 74 69 63 20 73 71 6c  b){.  static sql
bec0: 69 74 65 33 5f 6d 6f 64 75 6c 65 20 7a 69 70 66  ite3_module zipf
bed0: 69 6c 65 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20  ileModule = {.  
bee0: 20 20 31 2c 20 20 20 20 20 20 20 20 20 20 20 20    1,            
bef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
bf00: 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 20 20  iVersion */.    
bf10: 7a 69 70 66 69 6c 65 43 6f 6e 6e 65 63 74 2c 20  zipfileConnect, 
bf20: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
bf30: 72 65 61 74 65 20 2a 2f 0a 20 20 20 20 7a 69 70  reate */.    zip
bf40: 66 69 6c 65 43 6f 6e 6e 65 63 74 2c 20 20 20 20  fileConnect,    
bf50: 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6e 6e          /* xConn
bf60: 65 63 74 20 2a 2f 0a 20 20 20 20 7a 69 70 66 69  ect */.    zipfi
bf70: 6c 65 42 65 73 74 49 6e 64 65 78 2c 20 20 20 20  leBestIndex,    
bf80: 20 20 20 20 20 20 2f 2a 20 78 42 65 73 74 49 6e        /* xBestIn
bf90: 64 65 78 20 2a 2f 0a 20 20 20 20 7a 69 70 66 69  dex */.    zipfi
bfa0: 6c 65 44 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20  leDisconnect,   
bfb0: 20 20 20 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e        /* xDiscon
bfc0: 6e 65 63 74 20 2a 2f 0a 20 20 20 20 7a 69 70 66  nect */.    zipf
bfd0: 69 6c 65 44 69 73 63 6f 6e 6e 65 63 74 2c 20 20  ileDisconnect,  
bfe0: 20 20 20 20 20 20 20 2f 2a 20 78 44 65 73 74 72         /* xDestr
bff0: 6f 79 20 2a 2f 0a 20 20 20 20 7a 69 70 66 69 6c  oy */.    zipfil
c000: 65 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20 20  eOpen,          
c010: 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d 20       /* xOpen - 
c020: 6f 70 65 6e 20 61 20 63 75 72 73 6f 72 20 2a 2f  open a cursor */
c030: 0a 20 20 20 20 7a 69 70 66 69 6c 65 43 6c 6f 73  .    zipfileClos
c040: 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e,              
c050: 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73  /* xClose - clos
c060: 65 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20  e a cursor */.  
c070: 20 20 7a 69 70 66 69 6c 65 46 69 6c 74 65 72 2c    zipfileFilter,
c080: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
c090: 78 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67  xFilter - config
c0a0: 75 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61  ure scan constra
c0b0: 69 6e 74 73 20 2a 2f 0a 20 20 20 20 7a 69 70 66  ints */.    zipf
c0c0: 69 6c 65 4e 65 78 74 2c 20 20 20 20 20 20 20 20  ileNext,        
c0d0: 20 20 20 20 20 20 20 2f 2a 20 78 4e 65 78 74 20         /* xNext 
c0e0: 2d 20 61 64 76 61 6e 63 65 20 61 20 63 75 72 73  - advance a curs
c0f0: 6f 72 20 2a 2f 0a 20 20 20 20 7a 69 70 66 69 6c  or */.    zipfil
c100: 65 45 6f 66 2c 20 20 20 20 20 20 20 20 20 20 20  eEof,           
c110: 20 20 20 20 20 2f 2a 20 78 45 6f 66 20 2d 20 63       /* xEof - c
c120: 68 65 63 6b 20 66 6f 72 20 65 6e 64 20 6f 66 20  heck for end of 
c130: 73 63 61 6e 20 2a 2f 0a 20 20 20 20 7a 69 70 66  scan */.    zipf
c140: 69 6c 65 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20  ileColumn,      
c150: 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d         /* xColum
c160: 6e 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f  n - read data */
c170: 0a 20 20 20 20 7a 69 70 66 69 6c 65 52 6f 77 69  .    zipfileRowi
c180: 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d,              
c190: 2f 2a 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64  /* xRowid - read
c1a0: 20 64 61 74 61 20 2a 2f 0a 20 20 20 20 7a 69 70   data */.    zip
c1b0: 66 69 6c 65 55 70 64 61 74 65 2c 20 20 20 20 20  fileUpdate,     
c1c0: 20 20 20 20 20 20 20 20 2f 2a 20 78 55 70 64 61          /* xUpda
c1d0: 74 65 20 2a 2f 0a 20 20 20 20 7a 69 70 66 69 6c  te */.    zipfil
c1e0: 65 42 65 67 69 6e 2c 20 20 20 20 20 20 20 20 20  eBegin,         
c1f0: 20 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2a       /* xBegin *
c200: 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20  /.    0,        
c210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c220: 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20 20   /* xSync */.   
c230: 20 7a 69 70 66 69 6c 65 43 6f 6d 6d 69 74 2c 20   zipfileCommit, 
c240: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
c250: 43 6f 6d 6d 69 74 20 2a 2f 0a 20 20 20 20 7a 69  Commit */.    zi
c260: 70 66 69 6c 65 52 6f 6c 6c 62 61 63 6b 2c 20 20  pfileRollback,  
c270: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c           /* xRol
c280: 6c 62 61 63 6b 20 2a 2f 0a 20 20 20 20 7a 69 70  lback */.    zip
c290: 66 69 6c 65 46 69 6e 64 46 75 6e 63 74 69 6f 6e  fileFindFunction
c2a0: 2c 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64  ,       /* xFind
c2b0: 4d 65 74 68 6f 64 20 2a 2f 0a 20 20 20 20 30 2c  Method */.    0,
c2c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c2d0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6e           /* xRen
c2e0: 61 6d 65 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20 69  ame */.  };..  i
c2f0: 6e 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  nt rc = sqlite3_
c300: 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 64 62  create_module(db
c310: 2c 20 22 7a 69 70 66 69 6c 65 22 20 20 2c 20 26  , "zipfile"  , &
c320: 7a 69 70 66 69 6c 65 4d 6f 64 75 6c 65 2c 20 30  zipfileModule, 0
c330: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  );.  if( rc==SQL
c340: 49 54 45 5f 4f 4b 20 29 20 72 63 20 3d 20 73 71  ITE_OK ) rc = sq
c350: 6c 69 74 65 33 5f 6f 76 65 72 6c 6f 61 64 5f 66  lite3_overload_f
c360: 75 6e 63 74 69 6f 6e 28 64 62 2c 20 22 7a 69 70  unction(db, "zip
c370: 66 69 6c 65 5f 63 64 73 22 2c 20 2d 31 29 3b 0a  file_cds", -1);.
c380: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
c390: 5f 4f 4b 20 29 20 72 63 20 3d 20 73 71 6c 69 74  _OK ) rc = sqlit
c3a0: 65 33 5f 6f 76 65 72 6c 6f 61 64 5f 66 75 6e 63  e3_overload_func
c3b0: 74 69 6f 6e 28 64 62 2c 20 22 7a 69 70 66 69 6c  tion(db, "zipfil
c3c0: 65 5f 62 6c 6f 62 22 2c 20 2d 31 29 3b 0a 20 20  e_blob", -1);.  
c3d0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 23 65 6c  return rc;.}.#el
c3e0: 73 65 20 20 20 20 20 20 20 20 20 2f 2a 20 53 51  se         /* SQ
c3f0: 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41  LITE_OMIT_VIRTUA
c400: 4c 54 41 42 4c 45 20 2a 2f 0a 23 20 64 65 66 69  LTABLE */.# defi
c410: 6e 65 20 7a 69 70 66 69 6c 65 52 65 67 69 73 74  ne zipfileRegist
c420: 65 72 28 78 29 20 53 51 4c 49 54 45 5f 4f 4b 0a  er(x) SQLITE_OK.
c430: 23 65 6e 64 69 66 0a 0a 23 69 66 64 65 66 20 5f  #endif..#ifdef _
c440: 57 49 4e 33 32 0a 5f 5f 64 65 63 6c 73 70 65 63  WIN32.__declspec
c450: 28 64 6c 6c 65 78 70 6f 72 74 29 0a 23 65 6e 64  (dllexport).#end
c460: 69 66 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 7a  if.int sqlite3_z
c470: 69 70 66 69 6c 65 5f 69 6e 69 74 28 0a 20 20 73  ipfile_init(.  s
c480: 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20 20 63  qlite3 *db, .  c
c490: 68 61 72 20 2a 2a 70 7a 45 72 72 4d 73 67 2c 20  har **pzErrMsg, 
c4a0: 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33  .  const sqlite3
c4b0: 5f 61 70 69 5f 72 6f 75 74 69 6e 65 73 20 2a 70  _api_routines *p
c4c0: 41 70 69 0a 29 7b 0a 20 20 53 51 4c 49 54 45 5f  Api.){.  SQLITE_
c4d0: 45 58 54 45 4e 53 49 4f 4e 5f 49 4e 49 54 32 28  EXTENSION_INIT2(
c4e0: 70 41 70 69 29 3b 0a 20 20 28 76 6f 69 64 29 70  pApi);.  (void)p
c4f0: 7a 45 72 72 4d 73 67 3b 20 20 2f 2a 20 55 6e 75  zErrMsg;  /* Unu
c500: 73 65 64 20 70 61 72 61 6d 65 74 65 72 20 2a 2f  sed parameter */
c510: 0a 20 20 72 65 74 75 72 6e 20 7a 69 70 66 69 6c  .  return zipfil
c520: 65 52 65 67 69 73 74 65 72 28 64 62 29 3b 0a 7d  eRegister(db);.}
c530: 0a                                               .