/ Hex Artifact Content
Login

Artifact ead25f062cee790b7c764ce8d2c6ad32a7ac82fc31ea80f69be99948f96f2d19:


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 2a 0a 2a 2a 20 5a 49 50 46 49 4c 45  d..**.** ZIPFILE
0b10: 5f 53 49 47 4e 41 54 55 52 45 5f 45 4f 43 44 0a  _SIGNATURE_EOCD.
0b20: 2a 2a 20 20 20 46 69 72 73 74 20 34 20 62 79 74  **   First 4 byt
0b30: 65 73 20 6f 66 20 61 20 76 61 6c 69 64 20 45 4f  es of a valid EO
0b40: 43 44 20 72 65 63 6f 72 64 2e 0a 2a 2f 0a 23 64  CD record..*/.#d
0b50: 65 66 69 6e 65 20 5a 49 50 46 49 4c 45 5f 45 58  efine ZIPFILE_EX
0b60: 54 52 41 5f 54 49 4d 45 53 54 41 4d 50 20 20 20  TRA_TIMESTAMP   
0b70: 30 78 35 34 35 35 0a 23 64 65 66 69 6e 65 20 5a  0x5455.#define Z
0b80: 49 50 46 49 4c 45 5f 4e 45 57 45 4e 54 52 59 5f  IPFILE_NEWENTRY_
0b90: 4d 41 44 45 42 59 20 20 20 28 28 33 3c 3c 38 29  MADEBY   ((3<<8)
0ba0: 20 2b 20 33 30 29 0a 23 64 65 66 69 6e 65 20 5a   + 30).#define Z
0bb0: 49 50 46 49 4c 45 5f 4e 45 57 45 4e 54 52 59 5f  IPFILE_NEWENTRY_
0bc0: 52 45 51 55 49 52 45 44 20 32 30 0a 23 64 65 66  REQUIRED 20.#def
0bd0: 69 6e 65 20 5a 49 50 46 49 4c 45 5f 4e 45 57 45  ine ZIPFILE_NEWE
0be0: 4e 54 52 59 5f 46 4c 41 47 53 20 20 20 20 30 78  NTRY_FLAGS    0x
0bf0: 38 30 30 0a 23 64 65 66 69 6e 65 20 5a 49 50 46  800.#define ZIPF
0c00: 49 4c 45 5f 53 49 47 4e 41 54 55 52 45 5f 43 44  ILE_SIGNATURE_CD
0c10: 53 20 20 20 20 20 30 78 30 32 30 31 34 62 35 30  S     0x02014b50
0c20: 0a 23 64 65 66 69 6e 65 20 5a 49 50 46 49 4c 45  .#define ZIPFILE
0c30: 5f 53 49 47 4e 41 54 55 52 45 5f 4c 46 48 20 20  _SIGNATURE_LFH  
0c40: 20 20 20 30 78 30 34 30 33 34 62 35 30 0a 23 64     0x04034b50.#d
0c50: 65 66 69 6e 65 20 5a 49 50 46 49 4c 45 5f 53 49  efine ZIPFILE_SI
0c60: 47 4e 41 54 55 52 45 5f 45 4f 43 44 20 20 20 20  GNATURE_EOCD    
0c70: 30 78 30 36 30 35 34 62 35 30 0a 0a 2f 2a 0a 2a  0x06054b50../*.*
0c80: 2a 20 54 68 65 20 73 69 7a 65 73 20 6f 66 20 74  * The sizes of t
0c90: 68 65 20 66 69 78 65 64 2d 73 69 7a 65 20 70 61  he fixed-size pa
0ca0: 72 74 20 6f 66 20 65 61 63 68 20 6f 66 20 74 68  rt of each of th
0cb0: 65 20 74 68 72 65 65 20 6d 61 69 6e 20 64 61 74  e three main dat
0cc0: 61 20 0a 2a 2a 20 73 74 72 75 63 74 75 72 65 73  a .** structures
0cd0: 20 69 6e 20 61 20 7a 69 70 20 61 72 63 68 69 76   in a zip archiv
0ce0: 65 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 5a 49  e..*/.#define ZI
0cf0: 50 46 49 4c 45 5f 4c 46 48 5f 46 49 58 45 44 5f  PFILE_LFH_FIXED_
0d00: 53 5a 20 20 20 20 20 20 33 30 0a 23 64 65 66 69  SZ      30.#defi
0d10: 6e 65 20 5a 49 50 46 49 4c 45 5f 45 4f 43 44 5f  ne ZIPFILE_EOCD_
0d20: 46 49 58 45 44 5f 53 5a 20 20 20 20 20 32 32 0a  FIXED_SZ     22.
0d30: 23 64 65 66 69 6e 65 20 5a 49 50 46 49 4c 45 5f  #define ZIPFILE_
0d40: 43 44 53 5f 46 49 58 45 44 5f 53 5a 20 20 20 20  CDS_FIXED_SZ    
0d50: 20 20 34 36 0a 0a 2f 2a 0a 2a 2a 2a 20 34 2e 33    46../*.*** 4.3
0d60: 2e 31 36 20 20 45 6e 64 20 6f 66 20 63 65 6e 74  .16  End of cent
0d70: 72 61 6c 20 64 69 72 65 63 74 6f 72 79 20 72 65  ral directory re
0d80: 63 6f 72 64 3a 0a 2a 2a 2a 0a 2a 2a 2a 20 20 20  cord:.***.***   
0d90: 65 6e 64 20 6f 66 20 63 65 6e 74 72 61 6c 20 64  end of central d
0da0: 69 72 20 73 69 67 6e 61 74 75 72 65 20 20 20 20  ir signature    
0db0: 34 20 62 79 74 65 73 20 20 28 30 78 30 36 30 35  4 bytes  (0x0605
0dc0: 34 62 35 30 29 0a 2a 2a 2a 20 20 20 6e 75 6d 62  4b50).***   numb
0dd0: 65 72 20 6f 66 20 74 68 69 73 20 64 69 73 6b 20  er of this disk 
0de0: 20 20 20 20 20 20 20 20 20 20 20 20 32 20 62 79              2 by
0df0: 74 65 73 0a 2a 2a 2a 20 20 20 6e 75 6d 62 65 72  tes.***   number
0e00: 20 6f 66 20 74 68 65 20 64 69 73 6b 20 77 69 74   of the disk wit
0e10: 68 20 74 68 65 0a 2a 2a 2a 20 20 20 73 74 61 72  h the.***   star
0e20: 74 20 6f 66 20 74 68 65 20 63 65 6e 74 72 61 6c  t of the central
0e30: 20 64 69 72 65 63 74 6f 72 79 20 20 32 20 62 79   directory  2 by
0e40: 74 65 73 0a 2a 2a 2a 20 20 20 74 6f 74 61 6c 20  tes.***   total 
0e50: 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  number of entrie
0e60: 73 20 69 6e 20 74 68 65 0a 2a 2a 2a 20 20 20 63  s in the.***   c
0e70: 65 6e 74 72 61 6c 20 64 69 72 65 63 74 6f 72 79  entral directory
0e80: 20 6f 6e 20 74 68 69 73 20 64 69 73 6b 20 20 32   on this disk  2
0e90: 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20 74 6f 74   bytes.***   tot
0ea0: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 65 6e 74  al number of ent
0eb0: 72 69 65 73 20 69 6e 0a 2a 2a 2a 20 20 20 74 68  ries in.***   th
0ec0: 65 20 63 65 6e 74 72 61 6c 20 64 69 72 65 63 74  e central direct
0ed0: 6f 72 79 20 20 20 20 20 20 20 20 20 20 20 32 20  ory           2 
0ee0: 62 79 74 65 73 0a 2a 2a 2a 20 20 20 73 69 7a 65  bytes.***   size
0ef0: 20 6f 66 20 74 68 65 20 63 65 6e 74 72 61 6c 20   of the central 
0f00: 64 69 72 65 63 74 6f 72 79 20 20 20 34 20 62 79  directory   4 by
0f10: 74 65 73 0a 2a 2a 2a 20 20 20 6f 66 66 73 65 74  tes.***   offset
0f20: 20 6f 66 20 73 74 61 72 74 20 6f 66 20 63 65 6e   of start of cen
0f30: 74 72 61 6c 0a 2a 2a 2a 20 20 20 64 69 72 65 63  tral.***   direc
0f40: 74 6f 72 79 20 77 69 74 68 20 72 65 73 70 65 63  tory with respec
0f50: 74 20 74 6f 0a 2a 2a 2a 20 20 20 74 68 65 20 73  t to.***   the s
0f60: 74 61 72 74 69 6e 67 20 64 69 73 6b 20 6e 75 6d  tarting disk num
0f70: 62 65 72 20 20 20 20 20 20 20 20 34 20 62 79 74  ber        4 byt
0f80: 65 73 0a 2a 2a 2a 20 20 20 2e 5a 49 50 20 66 69  es.***   .ZIP fi
0f90: 6c 65 20 63 6f 6d 6d 65 6e 74 20 6c 65 6e 67 74  le comment lengt
0fa0: 68 20 20 20 20 20 20 20 20 32 20 62 79 74 65 73  h        2 bytes
0fb0: 0a 2a 2a 2a 20 20 20 2e 5a 49 50 20 66 69 6c 65  .***   .ZIP file
0fc0: 20 63 6f 6d 6d 65 6e 74 20 20 20 20 20 20 20 28   comment       (
0fd0: 76 61 72 69 61 62 6c 65 20 73 69 7a 65 29 0a 2a  variable size).*
0fe0: 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  /.typedef struct
0ff0: 20 5a 69 70 66 69 6c 65 45 4f 43 44 20 5a 69 70   ZipfileEOCD Zip
1000: 66 69 6c 65 45 4f 43 44 3b 0a 73 74 72 75 63 74  fileEOCD;.struct
1010: 20 5a 69 70 66 69 6c 65 45 4f 43 44 20 7b 0a 20   ZipfileEOCD {. 
1020: 20 75 31 36 20 69 44 69 73 6b 3b 0a 20 20 75 31   u16 iDisk;.  u1
1030: 36 20 69 46 69 72 73 74 44 69 73 6b 3b 0a 20 20  6 iFirstDisk;.  
1040: 75 31 36 20 6e 45 6e 74 72 79 3b 0a 20 20 75 31  u16 nEntry;.  u1
1050: 36 20 6e 45 6e 74 72 79 54 6f 74 61 6c 3b 0a 20  6 nEntryTotal;. 
1060: 20 75 33 32 20 6e 53 69 7a 65 3b 0a 20 20 75 33   u32 nSize;.  u3
1070: 32 20 69 4f 66 66 73 65 74 3b 0a 7d 3b 0a 0a 2f  2 iOffset;.};../
1080: 2a 0a 2a 2a 2a 20 34 2e 33 2e 31 32 20 20 43 65  *.*** 4.3.12  Ce
1090: 6e 74 72 61 6c 20 64 69 72 65 63 74 6f 72 79 20  ntral directory 
10a0: 73 74 72 75 63 74 75 72 65 3a 0a 2a 2a 2a 0a 2a  structure:.***.*
10b0: 2a 2a 20 2e 2e 2e 0a 2a 2a 2a 0a 2a 2a 2a 20 20  ** ....***.***  
10c0: 20 63 65 6e 74 72 61 6c 20 66 69 6c 65 20 68 65   central file he
10d0: 61 64 65 72 20 73 69 67 6e 61 74 75 72 65 20 20  ader signature  
10e0: 20 34 20 62 79 74 65 73 20 20 28 30 78 30 32 30   4 bytes  (0x020
10f0: 31 34 62 35 30 29 0a 2a 2a 2a 20 20 20 76 65 72  14b50).***   ver
1100: 73 69 6f 6e 20 6d 61 64 65 20 62 79 20 20 20 20  sion made by    
1110: 20 20 20 20 20 20 20 20 20 20 20 20 20 32 20 62               2 b
1120: 79 74 65 73 0a 2a 2a 2a 20 20 20 76 65 72 73 69  ytes.***   versi
1130: 6f 6e 20 6e 65 65 64 65 64 20 74 6f 20 65 78 74  on needed to ext
1140: 72 61 63 74 20 20 20 20 20 20 20 32 20 62 79 74  ract       2 byt
1150: 65 73 0a 2a 2a 2a 20 20 20 67 65 6e 65 72 61 6c  es.***   general
1160: 20 70 75 72 70 6f 73 65 20 62 69 74 20 66 6c 61   purpose bit fla
1170: 67 20 20 20 20 20 20 20 20 32 20 62 79 74 65 73  g        2 bytes
1180: 0a 2a 2a 2a 20 20 20 63 6f 6d 70 72 65 73 73 69  .***   compressi
1190: 6f 6e 20 6d 65 74 68 6f 64 20 20 20 20 20 20 20  on method       
11a0: 20 20 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a         2 bytes.*
11b0: 2a 2a 20 20 20 6c 61 73 74 20 6d 6f 64 20 66 69  **   last mod fi
11c0: 6c 65 20 74 69 6d 65 20 20 20 20 20 20 20 20 20  le time         
11d0: 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a 2a       2 bytes.***
11e0: 20 20 20 6c 61 73 74 20 6d 6f 64 20 66 69 6c 65     last mod file
11f0: 20 64 61 74 65 20 20 20 20 20 20 20 20 20 20 20   date           
1200: 20 20 20 32 20 62 79 74 65 73 0a 2a 2a 2a 20 20     2 bytes.***  
1210: 20 63 72 63 2d 33 32 20 20 20 20 20 20 20 20 20   crc-32         
1220: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1230: 20 34 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20 63   4 bytes.***   c
1240: 6f 6d 70 72 65 73 73 65 64 20 73 69 7a 65 20 20  ompressed size  
1250: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 34                 4
1260: 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20 75 6e 63   bytes.***   unc
1270: 6f 6d 70 72 65 73 73 65 64 20 73 69 7a 65 20 20  ompressed size  
1280: 20 20 20 20 20 20 20 20 20 20 20 20 20 34 20 62               4 b
1290: 79 74 65 73 0a 2a 2a 2a 20 20 20 66 69 6c 65 20  ytes.***   file 
12a0: 6e 61 6d 65 20 6c 65 6e 67 74 68 20 20 20 20 20  name length     
12b0: 20 20 20 20 20 20 20 20 20 20 20 32 20 62 79 74             2 byt
12c0: 65 73 0a 2a 2a 2a 20 20 20 65 78 74 72 61 20 66  es.***   extra f
12d0: 69 65 6c 64 20 6c 65 6e 67 74 68 20 20 20 20 20  ield length     
12e0: 20 20 20 20 20 20 20 20 20 32 20 62 79 74 65 73           2 bytes
12f0: 0a 2a 2a 2a 20 20 20 66 69 6c 65 20 63 6f 6d 6d  .***   file comm
1300: 65 6e 74 20 6c 65 6e 67 74 68 20 20 20 20 20 20  ent length      
1310: 20 20 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a         2 bytes.*
1320: 2a 2a 20 20 20 64 69 73 6b 20 6e 75 6d 62 65 72  **   disk number
1330: 20 73 74 61 72 74 20 20 20 20 20 20 20 20 20 20   start          
1340: 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a 2a       2 bytes.***
1350: 20 20 20 69 6e 74 65 72 6e 61 6c 20 66 69 6c 65     internal file
1360: 20 61 74 74 72 69 62 75 74 65 73 20 20 20 20 20   attributes     
1370: 20 20 20 32 20 62 79 74 65 73 0a 2a 2a 2a 20 20     2 bytes.***  
1380: 20 65 78 74 65 72 6e 61 6c 20 66 69 6c 65 20 61   external file a
1390: 74 74 72 69 62 75 74 65 73 20 20 20 20 20 20 20  ttributes       
13a0: 20 34 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20 72   4 bytes.***   r
13b0: 65 6c 61 74 69 76 65 20 6f 66 66 73 65 74 20 6f  elative offset o
13c0: 66 20 6c 6f 63 61 6c 20 68 65 61 64 65 72 20 34  f local header 4
13d0: 20 62 79 74 65 73 0a 2a 2f 0a 74 79 70 65 64 65   bytes.*/.typede
13e0: 66 20 73 74 72 75 63 74 20 5a 69 70 66 69 6c 65  f struct Zipfile
13f0: 43 44 53 20 5a 69 70 66 69 6c 65 43 44 53 3b 0a  CDS ZipfileCDS;.
1400: 73 74 72 75 63 74 20 5a 69 70 66 69 6c 65 43 44  struct ZipfileCD
1410: 53 20 7b 0a 20 20 75 31 36 20 69 56 65 72 73 69  S {.  u16 iVersi
1420: 6f 6e 4d 61 64 65 42 79 3b 0a 20 20 75 31 36 20  onMadeBy;.  u16 
1430: 69 56 65 72 73 69 6f 6e 45 78 74 72 61 63 74 3b  iVersionExtract;
1440: 0a 20 20 75 31 36 20 66 6c 61 67 73 3b 0a 20 20  .  u16 flags;.  
1450: 75 31 36 20 69 43 6f 6d 70 72 65 73 73 69 6f 6e  u16 iCompression
1460: 3b 0a 20 20 75 31 36 20 6d 54 69 6d 65 3b 0a 20  ;.  u16 mTime;. 
1470: 20 75 31 36 20 6d 44 61 74 65 3b 0a 20 20 75 33   u16 mDate;.  u3
1480: 32 20 63 72 63 33 32 3b 0a 20 20 75 33 32 20 73  2 crc32;.  u32 s
1490: 7a 43 6f 6d 70 72 65 73 73 65 64 3b 0a 20 20 75  zCompressed;.  u
14a0: 33 32 20 73 7a 55 6e 63 6f 6d 70 72 65 73 73 65  32 szUncompresse
14b0: 64 3b 0a 20 20 75 31 36 20 6e 46 69 6c 65 3b 0a  d;.  u16 nFile;.
14c0: 20 20 75 31 36 20 6e 45 78 74 72 61 3b 0a 20 20    u16 nExtra;.  
14d0: 75 31 36 20 6e 43 6f 6d 6d 65 6e 74 3b 0a 20 20  u16 nComment;.  
14e0: 75 31 36 20 69 44 69 73 6b 53 74 61 72 74 3b 0a  u16 iDiskStart;.
14f0: 20 20 75 31 36 20 69 49 6e 74 65 72 6e 61 6c 41    u16 iInternalA
1500: 74 74 72 3b 0a 20 20 75 33 32 20 69 45 78 74 65  ttr;.  u32 iExte
1510: 72 6e 61 6c 41 74 74 72 3b 0a 20 20 75 33 32 20  rnalAttr;.  u32 
1520: 69 4f 66 66 73 65 74 3b 0a 20 20 63 68 61 72 20  iOffset;.  char 
1530: 2a 7a 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20  *zFile;         
1540: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
1550: 6c 65 6e 61 6d 65 20 28 73 71 6c 69 74 65 33 5f  lename (sqlite3_
1560: 6d 61 6c 6c 6f 63 28 29 29 20 2a 2f 0a 7d 3b 0a  malloc()) */.};.
1570: 0a 2f 2a 0a 2a 2a 2a 20 34 2e 33 2e 37 20 20 4c  ./*.*** 4.3.7  L
1580: 6f 63 61 6c 20 66 69 6c 65 20 68 65 61 64 65 72  ocal file header
1590: 3a 0a 2a 2a 2a 0a 2a 2a 2a 20 20 20 6c 6f 63 61  :.***.***   loca
15a0: 6c 20 66 69 6c 65 20 68 65 61 64 65 72 20 73 69  l file header si
15b0: 67 6e 61 74 75 72 65 20 20 20 20 20 34 20 62 79  gnature     4 by
15c0: 74 65 73 20 20 28 30 78 30 34 30 33 34 62 35 30  tes  (0x04034b50
15d0: 29 0a 2a 2a 2a 20 20 20 76 65 72 73 69 6f 6e 20  ).***   version 
15e0: 6e 65 65 64 65 64 20 74 6f 20 65 78 74 72 61 63  needed to extrac
15f0: 74 20 20 20 20 20 20 20 32 20 62 79 74 65 73 0a  t       2 bytes.
1600: 2a 2a 2a 20 20 20 67 65 6e 65 72 61 6c 20 70 75  ***   general pu
1610: 72 70 6f 73 65 20 62 69 74 20 66 6c 61 67 20 20  rpose bit flag  
1620: 20 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a        2 bytes.**
1630: 2a 20 20 20 63 6f 6d 70 72 65 73 73 69 6f 6e 20  *   compression 
1640: 6d 65 74 68 6f 64 20 20 20 20 20 20 20 20 20 20  method          
1650: 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a 2a 20      2 bytes.*** 
1660: 20 20 6c 61 73 74 20 6d 6f 64 20 66 69 6c 65 20    last mod file 
1670: 74 69 6d 65 20 20 20 20 20 20 20 20 20 20 20 20  time            
1680: 20 20 32 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20    2 bytes.***   
1690: 6c 61 73 74 20 6d 6f 64 20 66 69 6c 65 20 64 61  last mod file da
16a0: 74 65 20 20 20 20 20 20 20 20 20 20 20 20 20 20  te              
16b0: 32 20 62 79 74 65 73 0a 2a 2a 2a 20 20 20 63 72  2 bytes.***   cr
16c0: 63 2d 33 32 20 20 20 20 20 20 20 20 20 20 20 20  c-32            
16d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 34 20                4 
16e0: 62 79 74 65 73 0a 2a 2a 2a 20 20 20 63 6f 6d 70  bytes.***   comp
16f0: 72 65 73 73 65 64 20 73 69 7a 65 20 20 20 20 20  ressed size     
1700: 20 20 20 20 20 20 20 20 20 20 20 20 34 20 62 79              4 by
1710: 74 65 73 0a 2a 2a 2a 20 20 20 75 6e 63 6f 6d 70  tes.***   uncomp
1720: 72 65 73 73 65 64 20 73 69 7a 65 20 20 20 20 20  ressed size     
1730: 20 20 20 20 20 20 20 20 20 20 34 20 62 79 74 65            4 byte
1740: 73 0a 2a 2a 2a 20 20 20 66 69 6c 65 20 6e 61 6d  s.***   file nam
1750: 65 20 6c 65 6e 67 74 68 20 20 20 20 20 20 20 20  e length        
1760: 20 20 20 20 20 20 20 20 32 20 62 79 74 65 73 0a          2 bytes.
1770: 2a 2a 2a 20 20 20 65 78 74 72 61 20 66 69 65 6c  ***   extra fiel
1780: 64 20 6c 65 6e 67 74 68 20 20 20 20 20 20 20 20  d length        
1790: 20 20 20 20 20 20 32 20 62 79 74 65 73 0a 2a 2a        2 bytes.**
17a0: 2a 20 20 20 0a 2a 2f 0a 74 79 70 65 64 65 66 20  *   .*/.typedef 
17b0: 73 74 72 75 63 74 20 5a 69 70 66 69 6c 65 4c 46  struct ZipfileLF
17c0: 48 20 5a 69 70 66 69 6c 65 4c 46 48 3b 0a 73 74  H ZipfileLFH;.st
17d0: 72 75 63 74 20 5a 69 70 66 69 6c 65 4c 46 48 20  ruct ZipfileLFH 
17e0: 7b 0a 20 20 75 31 36 20 69 56 65 72 73 69 6f 6e  {.  u16 iVersion
17f0: 45 78 74 72 61 63 74 3b 0a 20 20 75 31 36 20 66  Extract;.  u16 f
1800: 6c 61 67 73 3b 0a 20 20 75 31 36 20 69 43 6f 6d  lags;.  u16 iCom
1810: 70 72 65 73 73 69 6f 6e 3b 0a 20 20 75 31 36 20  pression;.  u16 
1820: 6d 54 69 6d 65 3b 0a 20 20 75 31 36 20 6d 44 61  mTime;.  u16 mDa
1830: 74 65 3b 0a 20 20 75 33 32 20 63 72 63 33 32 3b  te;.  u32 crc32;
1840: 0a 20 20 75 33 32 20 73 7a 43 6f 6d 70 72 65 73  .  u32 szCompres
1850: 73 65 64 3b 0a 20 20 75 33 32 20 73 7a 55 6e 63  sed;.  u32 szUnc
1860: 6f 6d 70 72 65 73 73 65 64 3b 0a 20 20 75 31 36  ompressed;.  u16
1870: 20 6e 46 69 6c 65 3b 0a 20 20 75 31 36 20 6e 45   nFile;.  u16 nE
1880: 78 74 72 61 3b 0a 7d 3b 0a 0a 74 79 70 65 64 65  xtra;.};..typede
1890: 66 20 73 74 72 75 63 74 20 5a 69 70 66 69 6c 65  f struct Zipfile
18a0: 45 6e 74 72 79 20 5a 69 70 66 69 6c 65 45 6e 74  Entry ZipfileEnt
18b0: 72 79 3b 0a 73 74 72 75 63 74 20 5a 69 70 66 69  ry;.struct Zipfi
18c0: 6c 65 45 6e 74 72 79 20 7b 0a 20 20 5a 69 70 66  leEntry {.  Zipf
18d0: 69 6c 65 43 44 53 20 63 64 73 3b 20 20 20 20 20  ileCDS cds;     
18e0: 20 20 20 20 20 20 20 2f 2a 20 50 61 72 73 65 64         /* Parsed
18f0: 20 43 44 53 20 72 65 63 6f 72 64 20 2a 2f 0a 20   CDS record */. 
1900: 20 75 33 32 20 6d 55 6e 69 78 54 69 6d 65 3b 20   u32 mUnixTime; 
1910: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
1920: 6f 64 69 66 69 63 61 74 69 6f 6e 20 74 69 6d 65  odification time
1930: 2c 20 69 6e 20 55 4e 49 58 20 66 6f 72 6d 61 74  , in UNIX format
1940: 20 2a 2f 0a 20 20 75 38 20 2a 61 45 78 74 72 61   */.  u8 *aExtra
1950: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
1960: 20 2f 2a 20 63 64 73 2e 6e 45 78 74 72 61 2b 63   /* cds.nExtra+c
1970: 64 73 2e 6e 43 6f 6d 6d 65 6e 74 20 62 79 74 65  ds.nComment byte
1980: 73 20 6f 66 20 65 78 74 72 61 20 64 61 74 61 20  s of extra data 
1990: 2a 2f 0a 20 20 69 36 34 20 69 44 61 74 61 4f 66  */.  i64 iDataOf
19a0: 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f;              
19b0: 2f 2a 20 4f 66 66 73 65 74 20 74 6f 20 64 61 74  /* Offset to dat
19c0: 61 20 69 6e 20 66 69 6c 65 20 28 69 66 20 61 44  a in file (if aD
19d0: 61 74 61 3d 3d 30 29 20 2a 2f 0a 20 20 75 38 20  ata==0) */.  u8 
19e0: 2a 61 44 61 74 61 3b 20 20 20 20 20 20 20 20 20  *aData;         
19f0: 20 20 20 20 20 20 20 20 2f 2a 20 63 64 73 2e 73          /* cds.s
1a00: 7a 43 6f 6d 70 72 65 73 73 65 64 20 62 79 74 65  zCompressed byte
1a10: 73 20 6f 66 20 63 6f 6d 70 72 65 73 73 65 64 20  s of compressed 
1a20: 64 61 74 61 20 2a 2f 0a 20 20 5a 69 70 66 69 6c  data */.  Zipfil
1a30: 65 45 6e 74 72 79 20 2a 70 4e 65 78 74 3b 20 20  eEntry *pNext;  
1a40: 20 20 20 20 20 2f 2a 20 4e 65 78 74 20 65 6c 65       /* Next ele
1a50: 6d 65 6e 74 20 69 6e 20 69 6e 2d 6d 65 6d 6f 72  ment in in-memor
1a60: 79 20 43 44 53 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 20  y CDS */.};../* 
1a70: 0a 2a 2a 20 43 75 72 73 6f 72 20 74 79 70 65 20  .** Cursor type 
1a80: 66 6f 72 20 7a 69 70 66 69 6c 65 20 74 61 62 6c  for zipfile tabl
1a90: 65 73 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73  es..*/.typedef s
1aa0: 74 72 75 63 74 20 5a 69 70 66 69 6c 65 43 73 72  truct ZipfileCsr
1ab0: 20 5a 69 70 66 69 6c 65 43 73 72 3b 0a 73 74 72   ZipfileCsr;.str
1ac0: 75 63 74 20 5a 69 70 66 69 6c 65 43 73 72 20 7b  uct ZipfileCsr {
1ad0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  .  sqlite3_vtab_
1ae0: 63 75 72 73 6f 72 20 62 61 73 65 3b 20 20 2f 2a  cursor base;  /*
1af0: 20 42 61 73 65 20 63 6c 61 73 73 20 2d 20 6d 75   Base class - mu
1b00: 73 74 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 20  st be first */. 
1b10: 20 69 36 34 20 69 49 64 3b 20 20 20 20 20 20 20   i64 iId;       
1b20: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
1b30: 75 72 73 6f 72 20 49 44 20 2a 2f 0a 20 20 75 38  ursor ID */.  u8
1b40: 20 62 45 6f 66 3b 20 20 20 20 20 20 20 20 20 20   bEof;          
1b50: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
1b60: 20 77 68 65 6e 20 61 74 20 45 4f 46 20 2a 2f 0a   when at EOF */.
1b70: 20 20 75 38 20 62 4e 6f 6f 70 3b 20 20 20 20 20    u8 bNoop;     
1b80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1b90: 49 66 20 6e 65 78 74 20 78 4e 65 78 74 28 29 20  If next xNext() 
1ba0: 63 61 6c 6c 20 69 73 20 6e 6f 2d 6f 70 20 2a 2f  call is no-op */
1bb0: 0a 0a 20 20 2f 2a 20 55 73 65 64 20 6f 75 74 73  ..  /* Used outs
1bc0: 69 64 65 20 6f 66 20 77 72 69 74 65 20 74 72 61  ide of write tra
1bd0: 6e 73 61 63 74 69 6f 6e 73 20 2a 2f 0a 20 20 46  nsactions */.  F
1be0: 49 4c 45 20 2a 70 46 69 6c 65 3b 20 20 20 20 20  ILE *pFile;     
1bf0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 5a 69 70            /* Zip
1c00: 20 66 69 6c 65 20 2a 2f 0a 20 20 69 36 34 20 69   file */.  i64 i
1c10: 4e 65 78 74 4f 66 66 3b 20 20 20 20 20 20 20 20  NextOff;        
1c20: 20 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20        /* Offset 
1c30: 6f 66 20 6e 65 78 74 20 72 65 63 6f 72 64 20 69  of next record i
1c40: 6e 20 63 65 6e 74 72 61 6c 20 64 69 72 65 63 74  n central direct
1c50: 6f 72 79 20 2a 2f 0a 20 20 5a 69 70 66 69 6c 65  ory */.  Zipfile
1c60: 45 4f 43 44 20 65 6f 63 64 3b 20 20 20 20 20 20  EOCD eocd;      
1c70: 20 20 20 20 2f 2a 20 50 61 72 73 65 20 6f 66 20      /* Parse of 
1c80: 63 65 6e 74 72 61 6c 20 64 69 72 65 63 74 6f 72  central director
1c90: 79 20 72 65 63 6f 72 64 20 2a 2f 0a 0a 20 20 5a  y record */..  Z
1ca0: 69 70 66 69 6c 65 45 6e 74 72 79 20 2a 70 46 72  ipfileEntry *pFr
1cb0: 65 65 45 6e 74 72 79 3b 20 20 2f 2a 20 46 72 65  eeEntry;  /* Fre
1cc0: 65 20 74 68 69 73 20 6c 69 73 74 20 77 68 65 6e  e this list when
1cd0: 20 63 75 72 73 6f 72 20 69 73 20 63 6c 6f 73 65   cursor is close
1ce0: 64 20 6f 72 20 72 65 73 65 74 20 2a 2f 0a 20 20  d or reset */.  
1cf0: 5a 69 70 66 69 6c 65 45 6e 74 72 79 20 2a 70 43  ZipfileEntry *pC
1d00: 75 72 72 65 6e 74 3b 20 20 20 20 2f 2a 20 43 75  urrent;    /* Cu
1d10: 72 72 65 6e 74 20 65 6e 74 72 79 20 2a 2f 0a 20  rrent entry */. 
1d20: 20 5a 69 70 66 69 6c 65 43 73 72 20 2a 70 43 73   ZipfileCsr *pCs
1d30: 72 4e 65 78 74 3b 20 20 20 20 20 20 2f 2a 20 4e  rNext;      /* N
1d40: 65 78 74 20 63 75 72 73 6f 72 20 6f 6e 20 73 61  ext cursor on sa
1d50: 6d 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  me virtual table
1d60: 20 2a 2f 0a 7d 3b 0a 0a 74 79 70 65 64 65 66 20   */.};..typedef 
1d70: 73 74 72 75 63 74 20 5a 69 70 66 69 6c 65 54 61  struct ZipfileTa
1d80: 62 20 5a 69 70 66 69 6c 65 54 61 62 3b 0a 73 74  b ZipfileTab;.st
1d90: 72 75 63 74 20 5a 69 70 66 69 6c 65 54 61 62 20  ruct ZipfileTab 
1da0: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62  {.  sqlite3_vtab
1db0: 20 62 61 73 65 3b 20 20 20 20 20 20 20 20 20 2f   base;         /
1dc0: 2a 20 42 61 73 65 20 63 6c 61 73 73 20 2d 20 6d  * Base class - m
1dd0: 75 73 74 20 62 65 20 66 69 72 73 74 20 2a 2f 0a  ust be first */.
1de0: 20 20 63 68 61 72 20 2a 7a 46 69 6c 65 3b 20 20    char *zFile;  
1df0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1e00: 5a 69 70 20 66 69 6c 65 20 74 68 69 73 20 74 61  Zip file this ta
1e10: 62 6c 65 20 61 63 63 65 73 73 65 73 20 28 6d 61  ble accesses (ma
1e20: 79 20 62 65 20 4e 55 4c 4c 29 20 2a 2f 0a 20 20  y be NULL) */.  
1e30: 75 38 20 2a 61 42 75 66 66 65 72 3b 20 20 20 20  u8 *aBuffer;    
1e40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 65             /* Te
1e50: 6d 70 6f 72 61 72 79 20 62 75 66 66 65 72 20 75  mporary buffer u
1e60: 73 65 64 20 66 6f 72 20 76 61 72 69 6f 75 73 20  sed for various 
1e70: 74 61 73 6b 73 20 2a 2f 0a 0a 20 20 5a 69 70 66  tasks */..  Zipf
1e80: 69 6c 65 43 73 72 20 2a 70 43 73 72 4c 69 73 74  ileCsr *pCsrList
1e90: 3b 20 20 20 20 20 20 2f 2a 20 4c 69 73 74 20 6f  ;      /* List o
1ea0: 66 20 63 75 72 73 6f 72 73 20 2a 2f 0a 20 20 69  f cursors */.  i
1eb0: 36 34 20 69 4e 65 78 74 43 73 72 69 64 3b 0a 0a  64 iNextCsrid;..
1ec0: 20 20 2f 2a 20 54 68 65 20 66 6f 6c 6c 6f 77 69    /* The followi
1ed0: 6e 67 20 61 72 65 20 75 73 65 64 20 62 79 20 77  ng are used by w
1ee0: 72 69 74 65 20 74 72 61 6e 73 61 63 74 69 6f 6e  rite transaction
1ef0: 73 20 6f 6e 6c 79 20 2a 2f 0a 20 20 5a 69 70 66  s only */.  Zipf
1f00: 69 6c 65 45 6e 74 72 79 20 2a 70 46 69 72 73 74  ileEntry *pFirst
1f10: 45 6e 74 72 79 3b 20 2f 2a 20 4c 69 6e 6b 65 64  Entry; /* Linked
1f20: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 66 69 6c   list of all fil
1f30: 65 73 20 28 69 66 20 70 57 72 69 74 65 46 64 21  es (if pWriteFd!
1f40: 3d 30 29 20 2a 2f 0a 20 20 5a 69 70 66 69 6c 65  =0) */.  Zipfile
1f50: 45 6e 74 72 79 20 2a 70 4c 61 73 74 45 6e 74 72  Entry *pLastEntr
1f60: 79 3b 20 20 2f 2a 20 4c 61 73 74 20 65 6c 65 6d  y;  /* Last elem
1f70: 65 6e 74 20 69 6e 20 70 46 69 72 73 74 45 6e 74  ent in pFirstEnt
1f80: 72 79 20 6c 69 73 74 20 2a 2f 0a 20 20 46 49 4c  ry list */.  FIL
1f90: 45 20 2a 70 57 72 69 74 65 46 64 3b 20 20 20 20  E *pWriteFd;    
1fa0: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20          /* File 
1fb0: 68 61 6e 64 6c 65 20 6f 70 65 6e 20 6f 6e 20 7a  handle open on z
1fc0: 69 70 20 61 72 63 68 69 76 65 20 2a 2f 0a 20 20  ip archive */.  
1fd0: 69 36 34 20 73 7a 43 75 72 72 65 6e 74 3b 20 20  i64 szCurrent;  
1fe0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75             /* Cu
1ff0: 72 72 65 6e 74 20 73 69 7a 65 20 6f 66 20 7a 69  rrent size of zi
2000: 70 20 61 72 63 68 69 76 65 20 2a 2f 0a 20 20 69  p archive */.  i
2010: 36 34 20 73 7a 4f 72 69 67 3b 20 20 20 20 20 20  64 szOrig;      
2020: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
2030: 65 20 6f 66 20 61 72 63 68 69 76 65 20 61 74 20  e of archive at 
2040: 73 74 61 72 74 20 6f 66 20 74 72 61 6e 73 61 63  start of transac
2050: 74 69 6f 6e 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  tion */.};../*.*
2060: 2a 20 53 65 74 20 74 68 65 20 65 72 72 6f 72 20  * Set the error 
2070: 6d 65 73 73 61 67 65 20 63 6f 6e 74 61 69 6e 65  message containe
2080: 64 20 69 6e 20 63 6f 6e 74 65 78 74 20 63 74 78  d in context ctx
2090: 20 74 6f 20 74 68 65 20 72 65 73 75 6c 74 73 20   to the results 
20a0: 6f 66 0a 2a 2a 20 76 70 72 69 6e 74 66 28 7a 46  of.** vprintf(zF
20b0: 6d 74 2c 20 2e 2e 2e 29 2e 0a 2a 2f 0a 73 74 61  mt, ...)..*/.sta
20c0: 74 69 63 20 76 6f 69 64 20 7a 69 70 66 69 6c 65  tic void zipfile
20d0: 43 74 78 45 72 72 6f 72 4d 73 67 28 73 71 6c 69  CtxErrorMsg(sqli
20e0: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78  te3_context *ctx
20f0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46  , const char *zF
2100: 6d 74 2c 20 2e 2e 2e 29 7b 0a 20 20 63 68 61 72  mt, ...){.  char
2110: 20 2a 7a 4d 73 67 20 3d 20 30 3b 0a 20 20 76 61   *zMsg = 0;.  va
2120: 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73  _list ap;.  va_s
2130: 74 61 72 74 28 61 70 2c 20 7a 46 6d 74 29 3b 0a  tart(ap, zFmt);.
2140: 20 20 7a 4d 73 67 20 3d 20 73 71 6c 69 74 65 33    zMsg = sqlite3
2150: 5f 76 6d 70 72 69 6e 74 66 28 7a 46 6d 74 2c 20  _vmprintf(zFmt, 
2160: 61 70 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 72  ap);.  sqlite3_r
2170: 65 73 75 6c 74 5f 65 72 72 6f 72 28 63 74 78 2c  esult_error(ctx,
2180: 20 7a 4d 73 67 2c 20 2d 31 29 3b 0a 20 20 73 71   zMsg, -1);.  sq
2190: 6c 69 74 65 33 5f 66 72 65 65 28 7a 4d 73 67 29  lite3_free(zMsg)
21a0: 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a  ;.  va_end(ap);.
21b0: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 73 74 72 69  }../*.** If stri
21c0: 6e 67 20 7a 49 6e 20 69 73 20 71 75 6f 74 65 64  ng zIn is quoted
21d0: 2c 20 64 65 71 75 6f 74 65 20 69 74 20 69 6e 20  , dequote it in 
21e0: 70 6c 61 63 65 2e 20 4f 74 68 65 72 77 69 73 65  place. Otherwise
21f0: 2c 20 69 66 20 74 68 65 20 73 74 72 69 6e 67 0a  , if the string.
2200: 2a 2a 20 69 73 20 6e 6f 74 20 71 75 6f 74 65 64  ** is not quoted
2210: 2c 20 64 6f 20 6e 6f 74 68 69 6e 67 2e 0a 2a 2f  , do nothing..*/
2220: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 7a 69 70  .static void zip
2230: 66 69 6c 65 44 65 71 75 6f 74 65 28 63 68 61 72  fileDequote(char
2240: 20 2a 7a 49 6e 29 7b 0a 20 20 63 68 61 72 20 71   *zIn){.  char q
2250: 20 3d 20 7a 49 6e 5b 30 5d 3b 0a 20 20 69 66 28   = zIn[0];.  if(
2260: 20 71 3d 3d 27 22 27 20 7c 7c 20 71 3d 3d 27 5c   q=='"' || q=='\
2270: 27 27 20 7c 7c 20 71 3d 3d 27 60 27 20 7c 7c 20  '' || q=='`' || 
2280: 71 3d 3d 27 5b 27 20 29 7b 0a 20 20 20 20 63 68  q=='[' ){.    ch
2290: 61 72 20 63 3b 0a 20 20 20 20 69 6e 74 20 69 49  ar c;.    int iI
22a0: 6e 20 3d 20 31 3b 0a 20 20 20 20 69 6e 74 20 69  n = 1;.    int i
22b0: 4f 75 74 20 3d 20 30 3b 0a 20 20 20 20 69 66 28  Out = 0;.    if(
22c0: 20 71 3d 3d 27 5b 27 20 29 20 71 20 3d 20 27 5d   q=='[' ) q = ']
22d0: 27 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 28 63  ';.    while( (c
22e0: 20 3d 20 7a 49 6e 5b 69 49 6e 2b 2b 5d 29 20 29   = zIn[iIn++]) )
22f0: 7b 0a 20 20 20 20 20 20 69 66 28 20 63 3d 3d 71  {.      if( c==q
2300: 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20   ){.        if( 
2310: 7a 49 6e 5b 69 49 6e 2b 2b 5d 21 3d 71 20 29 20  zIn[iIn++]!=q ) 
2320: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
2330: 20 20 20 20 20 7a 49 6e 5b 69 4f 75 74 2b 2b 5d       zIn[iOut++]
2340: 20 3d 20 63 3b 0a 20 20 20 20 7d 0a 20 20 20 20   = c;.    }.    
2350: 7a 49 6e 5b 69 4f 75 74 5d 20 3d 20 27 5c 30 27  zIn[iOut] = '\0'
2360: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  ;.  }.}../*.** C
2370: 6f 6e 73 74 72 75 63 74 20 61 20 6e 65 77 20 5a  onstruct a new Z
2380: 69 70 66 69 6c 65 54 61 62 20 76 69 72 74 75 61  ipfileTab virtua
2390: 6c 20 74 61 62 6c 65 20 6f 62 6a 65 63 74 2e 0a  l table object..
23a0: 2a 2a 20 0a 2a 2a 20 20 20 61 72 67 76 5b 30 5d  ** .**   argv[0]
23b0: 20 20 20 2d 3e 20 6d 6f 64 75 6c 65 20 6e 61 6d     -> module nam
23c0: 65 20 20 28 22 7a 69 70 66 69 6c 65 22 29 0a 2a  e  ("zipfile").*
23d0: 2a 20 20 20 61 72 67 76 5b 31 5d 20 20 20 2d 3e  *   argv[1]   ->
23e0: 20 64 61 74 61 62 61 73 65 20 6e 61 6d 65 0a 2a   database name.*
23f0: 2a 20 20 20 61 72 67 76 5b 32 5d 20 20 20 2d 3e  *   argv[2]   ->
2400: 20 74 61 62 6c 65 20 6e 61 6d 65 0a 2a 2a 20 20   table name.**  
2410: 20 61 72 67 76 5b 2e 2e 2e 5d 20 2d 3e 20 22 63   argv[...] -> "c
2420: 6f 6c 75 6d 6e 20 6e 61 6d 65 22 20 61 6e 64 20  olumn name" and 
2430: 6f 74 68 65 72 20 6d 6f 64 75 6c 65 20 61 72 67  other module arg
2440: 75 6d 65 6e 74 20 66 69 65 6c 64 73 2e 0a 2a 2f  ument fields..*/
2450: 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70 66  .static int zipf
2460: 69 6c 65 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71  ileConnect(.  sq
2470: 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69  lite3 *db,.  voi
2480: 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61  d *pAux,.  int a
2490: 72 67 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  rgc, const char 
24a0: 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73  *const*argv,.  s
24b0: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70  qlite3_vtab **pp
24c0: 56 74 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70  Vtab,.  char **p
24d0: 7a 45 72 72 0a 29 7b 0a 20 20 69 6e 74 20 6e 42  zErr.){.  int nB
24e0: 79 74 65 20 3d 20 73 69 7a 65 6f 66 28 5a 69 70  yte = sizeof(Zip
24f0: 66 69 6c 65 54 61 62 29 20 2b 20 5a 49 50 46 49  fileTab) + ZIPFI
2500: 4c 45 5f 42 55 46 46 45 52 5f 53 49 5a 45 3b 0a  LE_BUFFER_SIZE;.
2510: 20 20 69 6e 74 20 6e 46 69 6c 65 20 3d 20 30 3b    int nFile = 0;
2520: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
2530: 46 69 6c 65 20 3d 20 30 3b 0a 20 20 5a 69 70 66  File = 0;.  Zipf
2540: 69 6c 65 54 61 62 20 2a 70 4e 65 77 20 3d 20 30  ileTab *pNew = 0
2550: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 2f  ;.  int rc;..  /
2560: 2a 20 49 66 20 74 68 65 20 74 61 62 6c 65 20 6e  * If the table n
2570: 61 6d 65 20 69 73 20 6e 6f 74 20 22 7a 69 70 66  ame is not "zipf
2580: 69 6c 65 22 2c 20 72 65 71 75 69 72 65 20 74 68  ile", require th
2590: 61 74 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20  at the argument 
25a0: 62 65 0a 20 20 2a 2a 20 73 70 65 63 69 66 69 65  be.  ** specifie
25b0: 64 2e 20 54 68 69 73 20 73 74 6f 70 73 20 7a 69  d. This stops zi
25c0: 70 66 69 6c 65 20 74 61 62 6c 65 73 20 66 72 6f  pfile tables fro
25d0: 6d 20 62 65 69 6e 67 20 63 72 65 61 74 65 64 20  m being created 
25e0: 61 73 3a 0a 20 20 2a 2a 0a 20 20 2a 2a 20 20 20  as:.  **.  **   
25f0: 43 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54  CREATE VIRTUAL T
2600: 41 42 4c 45 20 7a 7a 7a 20 55 53 49 4e 47 20 7a  ABLE zzz USING z
2610: 69 70 66 69 6c 65 28 29 3b 0a 20 20 2a 2a 0a 20  ipfile();.  **. 
2620: 20 2a 2a 20 49 74 20 64 6f 65 73 20 6e 6f 74 20   ** It does not 
2630: 70 72 65 76 65 6e 74 3a 0a 20 20 2a 2a 0a 20 20  prevent:.  **.  
2640: 2a 2a 20 20 20 43 52 45 41 54 45 20 56 49 52 54  **   CREATE VIRT
2650: 55 41 4c 20 54 41 42 4c 45 20 7a 69 70 66 69 6c  UAL TABLE zipfil
2660: 65 20 55 53 49 4e 47 20 7a 69 70 66 69 6c 65 28  e USING zipfile(
2670: 29 3b 0a 20 20 2a 2f 0a 20 20 61 73 73 65 72 74  );.  */.  assert
2680: 28 20 30 3d 3d 73 71 6c 69 74 65 33 5f 73 74 72  ( 0==sqlite3_str
2690: 69 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22 7a  icmp(argv[0], "z
26a0: 69 70 66 69 6c 65 22 29 20 29 3b 0a 20 20 69 66  ipfile") );.  if
26b0: 28 20 28 30 21 3d 73 71 6c 69 74 65 33 5f 73 74  ( (0!=sqlite3_st
26c0: 72 69 63 6d 70 28 61 72 67 76 5b 32 5d 2c 20 22  ricmp(argv[2], "
26d0: 7a 69 70 66 69 6c 65 22 29 20 26 26 20 61 72 67  zipfile") && arg
26e0: 63 3c 34 29 20 7c 7c 20 61 72 67 63 3e 34 20 29  c<4) || argc>4 )
26f0: 7b 0a 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73  {.    *pzErr = s
2700: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
2710: 7a 69 70 66 69 6c 65 20 63 6f 6e 73 74 72 75 63  zipfile construc
2720: 74 6f 72 20 72 65 71 75 69 72 65 73 20 6f 6e 65  tor requires one
2730: 20 61 72 67 75 6d 65 6e 74 22 29 3b 0a 20 20 20   argument");.   
2740: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45   return SQLITE_E
2750: 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  RROR;.  }..  if(
2760: 20 61 72 67 63 3e 33 20 29 7b 0a 20 20 20 20 7a   argc>3 ){.    z
2770: 46 69 6c 65 20 3d 20 61 72 67 76 5b 33 5d 3b 0a  File = argv[3];.
2780: 20 20 20 20 6e 46 69 6c 65 20 3d 20 28 69 6e 74      nFile = (int
2790: 29 73 74 72 6c 65 6e 28 7a 46 69 6c 65 29 2b 31  )strlen(zFile)+1
27a0: 3b 0a 20 20 7d 0a 0a 20 20 72 63 20 3d 20 73 71  ;.  }..  rc = sq
27b0: 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74  lite3_declare_vt
27c0: 61 62 28 64 62 2c 20 5a 49 50 46 49 4c 45 5f 53  ab(db, ZIPFILE_S
27d0: 43 48 45 4d 41 29 3b 0a 20 20 69 66 28 20 72 63  CHEMA);.  if( rc
27e0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
27f0: 20 20 20 70 4e 65 77 20 3d 20 28 5a 69 70 66 69     pNew = (Zipfi
2800: 6c 65 54 61 62 2a 29 73 71 6c 69 74 65 33 5f 6d  leTab*)sqlite3_m
2810: 61 6c 6c 6f 63 28 6e 42 79 74 65 2b 6e 46 69 6c  alloc(nByte+nFil
2820: 65 29 3b 0a 20 20 20 20 69 66 28 20 70 4e 65 77  e);.    if( pNew
2830: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
2840: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 6d  ITE_NOMEM;.    m
2850: 65 6d 73 65 74 28 70 4e 65 77 2c 20 30 2c 20 6e  emset(pNew, 0, n
2860: 42 79 74 65 2b 6e 46 69 6c 65 29 3b 0a 20 20 20  Byte+nFile);.   
2870: 20 70 4e 65 77 2d 3e 61 42 75 66 66 65 72 20 3d   pNew->aBuffer =
2880: 20 28 75 38 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a   (u8*)&pNew[1];.
2890: 20 20 20 20 69 66 28 20 7a 46 69 6c 65 20 29 7b      if( zFile ){
28a0: 0a 20 20 20 20 20 20 70 4e 65 77 2d 3e 7a 46 69  .      pNew->zFi
28b0: 6c 65 20 3d 20 28 63 68 61 72 2a 29 26 70 4e 65  le = (char*)&pNe
28c0: 77 2d 3e 61 42 75 66 66 65 72 5b 5a 49 50 46 49  w->aBuffer[ZIPFI
28d0: 4c 45 5f 42 55 46 46 45 52 5f 53 49 5a 45 5d 3b  LE_BUFFER_SIZE];
28e0: 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70 4e  .      memcpy(pN
28f0: 65 77 2d 3e 7a 46 69 6c 65 2c 20 7a 46 69 6c 65  ew->zFile, zFile
2900: 2c 20 6e 46 69 6c 65 29 3b 0a 20 20 20 20 20 20  , nFile);.      
2910: 7a 69 70 66 69 6c 65 44 65 71 75 6f 74 65 28 70  zipfileDequote(p
2920: 4e 65 77 2d 3e 7a 46 69 6c 65 29 3b 0a 20 20 20  New->zFile);.   
2930: 20 7d 0a 20 20 7d 0a 20 20 2a 70 70 56 74 61 62   }.  }.  *ppVtab
2940: 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62   = (sqlite3_vtab
2950: 2a 29 70 4e 65 77 3b 0a 20 20 72 65 74 75 72 6e  *)pNew;.  return
2960: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 46 72   rc;.}../*.** Fr
2970: 65 65 20 74 68 65 20 5a 69 70 66 69 6c 65 45 6e  ee the ZipfileEn
2980: 74 72 79 20 73 74 72 75 63 74 75 72 65 20 69 6e  try structure in
2990: 64 69 63 61 74 65 64 20 62 79 20 74 68 65 20 6f  dicated by the o
29a0: 6e 6c 79 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f  nly argument..*/
29b0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 7a 69 70  .static void zip
29c0: 66 69 6c 65 45 6e 74 72 79 46 72 65 65 28 5a 69  fileEntryFree(Zi
29d0: 70 66 69 6c 65 45 6e 74 72 79 20 2a 70 29 7b 0a  pfileEntry *p){.
29e0: 20 20 69 66 28 20 70 20 29 7b 0a 20 20 20 20 73    if( p ){.    s
29f0: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 2d 3e 63  qlite3_free(p->c
2a00: 64 73 2e 7a 46 69 6c 65 29 3b 0a 20 20 20 20 73  ds.zFile);.    s
2a10: 71 6c 69 74 65 33 5f 66 72 65 65 28 70 29 3b 0a  qlite3_free(p);.
2a20: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6c    }.}../*.** Rel
2a30: 65 61 73 65 20 72 65 73 6f 75 72 63 65 73 20 74  ease resources t
2a40: 68 61 74 20 73 68 6f 75 6c 64 20 62 65 20 66 72  hat should be fr
2a50: 65 65 64 20 61 74 20 74 68 65 20 65 6e 64 20 6f  eed at the end o
2a60: 66 20 61 20 77 72 69 74 65 20 0a 2a 2a 20 74 72  f a write .** tr
2a70: 61 6e 73 61 63 74 69 6f 6e 2e 0a 2a 2f 0a 73 74  ansaction..*/.st
2a80: 61 74 69 63 20 76 6f 69 64 20 7a 69 70 66 69 6c  atic void zipfil
2a90: 65 43 6c 65 61 6e 75 70 54 72 61 6e 73 61 63 74  eCleanupTransact
2aa0: 69 6f 6e 28 5a 69 70 66 69 6c 65 54 61 62 20 2a  ion(ZipfileTab *
2ab0: 70 54 61 62 29 7b 0a 20 20 5a 69 70 66 69 6c 65  pTab){.  Zipfile
2ac0: 45 6e 74 72 79 20 2a 70 45 6e 74 72 79 3b 0a 20  Entry *pEntry;. 
2ad0: 20 5a 69 70 66 69 6c 65 45 6e 74 72 79 20 2a 70   ZipfileEntry *p
2ae0: 4e 65 78 74 3b 0a 0a 20 20 69 66 28 20 70 54 61  Next;..  if( pTa
2af0: 62 2d 3e 70 57 72 69 74 65 46 64 20 29 7b 0a 20  b->pWriteFd ){. 
2b00: 20 20 20 66 63 6c 6f 73 65 28 70 54 61 62 2d 3e     fclose(pTab->
2b10: 70 57 72 69 74 65 46 64 29 3b 0a 20 20 20 20 70  pWriteFd);.    p
2b20: 54 61 62 2d 3e 70 57 72 69 74 65 46 64 20 3d 20  Tab->pWriteFd = 
2b30: 30 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 70 45 6e  0;.  }.  for(pEn
2b40: 74 72 79 3d 70 54 61 62 2d 3e 70 46 69 72 73 74  try=pTab->pFirst
2b50: 45 6e 74 72 79 3b 20 70 45 6e 74 72 79 3b 20 70  Entry; pEntry; p
2b60: 45 6e 74 72 79 3d 70 4e 65 78 74 29 7b 0a 20 20  Entry=pNext){.  
2b70: 20 20 70 4e 65 78 74 20 3d 20 70 45 6e 74 72 79    pNext = pEntry
2b80: 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 7a 69 70  ->pNext;.    zip
2b90: 66 69 6c 65 45 6e 74 72 79 46 72 65 65 28 70 45  fileEntryFree(pE
2ba0: 6e 74 72 79 29 3b 0a 20 20 7d 0a 20 20 70 54 61  ntry);.  }.  pTa
2bb0: 62 2d 3e 70 46 69 72 73 74 45 6e 74 72 79 20 3d  b->pFirstEntry =
2bc0: 20 30 3b 0a 20 20 70 54 61 62 2d 3e 70 4c 61 73   0;.  pTab->pLas
2bd0: 74 45 6e 74 72 79 20 3d 20 30 3b 0a 20 20 70 54  tEntry = 0;.  pT
2be0: 61 62 2d 3e 73 7a 43 75 72 72 65 6e 74 20 3d 20  ab->szCurrent = 
2bf0: 30 3b 0a 20 20 70 54 61 62 2d 3e 73 7a 4f 72 69  0;.  pTab->szOri
2c00: 67 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  g = 0;.}../*.** 
2c10: 54 68 69 73 20 6d 65 74 68 6f 64 20 69 73 20 74  This method is t
2c20: 68 65 20 64 65 73 74 72 75 63 74 6f 72 20 66 6f  he destructor fo
2c30: 72 20 7a 69 70 66 69 6c 65 20 76 74 61 62 20 6f  r zipfile vtab o
2c40: 62 6a 65 63 74 73 2e 0a 2a 2f 0a 73 74 61 74 69  bjects..*/.stati
2c50: 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 44 69 73  c int zipfileDis
2c60: 63 6f 6e 6e 65 63 74 28 73 71 6c 69 74 65 33 5f  connect(sqlite3_
2c70: 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20  vtab *pVtab){.  
2c80: 7a 69 70 66 69 6c 65 43 6c 65 61 6e 75 70 54 72  zipfileCleanupTr
2c90: 61 6e 73 61 63 74 69 6f 6e 28 28 5a 69 70 66 69  ansaction((Zipfi
2ca0: 6c 65 54 61 62 2a 29 70 56 74 61 62 29 3b 0a 20  leTab*)pVtab);. 
2cb0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 56   sqlite3_free(pV
2cc0: 74 61 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  tab);.  return S
2cd0: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
2ce0: 2a 2a 20 43 6f 6e 73 74 72 75 63 74 6f 72 20 66  ** Constructor f
2cf0: 6f 72 20 61 20 6e 65 77 20 5a 69 70 66 69 6c 65  or a new Zipfile
2d00: 43 73 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73  Csr object..*/.s
2d10: 74 61 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c  tatic int zipfil
2d20: 65 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 74  eOpen(sqlite3_vt
2d30: 61 62 20 2a 70 2c 20 73 71 6c 69 74 65 33 5f 76  ab *p, sqlite3_v
2d40: 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43  tab_cursor **ppC
2d50: 73 72 29 7b 0a 20 20 5a 69 70 66 69 6c 65 54 61  sr){.  ZipfileTa
2d60: 62 20 2a 70 54 61 62 20 3d 20 28 5a 69 70 66 69  b *pTab = (Zipfi
2d70: 6c 65 54 61 62 2a 29 70 3b 0a 20 20 5a 69 70 66  leTab*)p;.  Zipf
2d80: 69 6c 65 43 73 72 20 2a 70 43 73 72 3b 0a 20 20  ileCsr *pCsr;.  
2d90: 70 43 73 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d  pCsr = sqlite3_m
2da0: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a 70 43  alloc(sizeof(*pC
2db0: 73 72 29 29 3b 0a 20 20 2a 70 70 43 73 72 20 3d  sr));.  *ppCsr =
2dc0: 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63   (sqlite3_vtab_c
2dd0: 75 72 73 6f 72 2a 29 70 43 73 72 3b 0a 20 20 69  ursor*)pCsr;.  i
2de0: 66 28 20 70 43 73 72 3d 3d 30 20 29 7b 0a 20 20  f( pCsr==0 ){.  
2df0: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
2e00: 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 6d 65 6d  NOMEM;.  }.  mem
2e10: 73 65 74 28 70 43 73 72 2c 20 30 2c 20 73 69 7a  set(pCsr, 0, siz
2e20: 65 6f 66 28 2a 70 43 73 72 29 29 3b 0a 20 20 70  eof(*pCsr));.  p
2e30: 43 73 72 2d 3e 69 49 64 20 3d 20 2b 2b 70 54 61  Csr->iId = ++pTa
2e40: 62 2d 3e 69 4e 65 78 74 43 73 72 69 64 3b 0a 20  b->iNextCsrid;. 
2e50: 20 70 43 73 72 2d 3e 70 43 73 72 4e 65 78 74 20   pCsr->pCsrNext 
2e60: 3d 20 70 54 61 62 2d 3e 70 43 73 72 4c 69 73 74  = pTab->pCsrList
2e70: 3b 0a 20 20 70 54 61 62 2d 3e 70 43 73 72 4c 69  ;.  pTab->pCsrLi
2e80: 73 74 20 3d 20 70 43 73 72 3b 0a 20 20 72 65 74  st = pCsr;.  ret
2e90: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
2ea0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74 20 61 20  ../*.** Reset a 
2eb0: 63 75 72 73 6f 72 20 62 61 63 6b 20 74 6f 20 74  cursor back to t
2ec0: 68 65 20 73 74 61 74 65 20 69 74 20 77 61 73 20  he state it was 
2ed0: 69 6e 20 77 68 65 6e 20 66 69 72 73 74 20 72 65  in when first re
2ee0: 74 75 72 6e 65 64 0a 2a 2a 20 62 79 20 7a 69 70  turned.** by zip
2ef0: 66 69 6c 65 4f 70 65 6e 28 29 2e 0a 2a 2f 0a 73  fileOpen()..*/.s
2f00: 74 61 74 69 63 20 76 6f 69 64 20 7a 69 70 66 69  tatic void zipfi
2f10: 6c 65 52 65 73 65 74 43 75 72 73 6f 72 28 5a 69  leResetCursor(Zi
2f20: 70 66 69 6c 65 43 73 72 20 2a 70 43 73 72 29 7b  pfileCsr *pCsr){
2f30: 0a 20 20 5a 69 70 66 69 6c 65 45 6e 74 72 79 20  .  ZipfileEntry 
2f40: 2a 70 3b 0a 20 20 5a 69 70 66 69 6c 65 45 6e 74  *p;.  ZipfileEnt
2f50: 72 79 20 2a 70 4e 65 78 74 3b 0a 0a 20 20 70 43  ry *pNext;..  pC
2f60: 73 72 2d 3e 62 45 6f 66 20 3d 20 30 3b 0a 20 20  sr->bEof = 0;.  
2f70: 69 66 28 20 70 43 73 72 2d 3e 70 46 69 6c 65 20  if( pCsr->pFile 
2f80: 29 7b 0a 20 20 20 20 66 63 6c 6f 73 65 28 70 43  ){.    fclose(pC
2f90: 73 72 2d 3e 70 46 69 6c 65 29 3b 0a 20 20 20 20  sr->pFile);.    
2fa0: 70 43 73 72 2d 3e 70 46 69 6c 65 20 3d 20 30 3b  pCsr->pFile = 0;
2fb0: 0a 20 20 20 20 7a 69 70 66 69 6c 65 45 6e 74 72  .    zipfileEntr
2fc0: 79 46 72 65 65 28 70 43 73 72 2d 3e 70 43 75 72  yFree(pCsr->pCur
2fd0: 72 65 6e 74 29 3b 0a 20 20 20 20 70 43 73 72 2d  rent);.    pCsr-
2fe0: 3e 70 43 75 72 72 65 6e 74 20 3d 20 30 3b 0a 20  >pCurrent = 0;. 
2ff0: 20 7d 0a 0a 20 20 66 6f 72 28 70 3d 70 43 73 72   }..  for(p=pCsr
3000: 2d 3e 70 46 72 65 65 45 6e 74 72 79 3b 20 70 3b  ->pFreeEntry; p;
3010: 20 70 3d 70 4e 65 78 74 29 7b 0a 20 20 20 20 70   p=pNext){.    p
3020: 4e 65 78 74 20 3d 20 70 2d 3e 70 4e 65 78 74 3b  Next = p->pNext;
3030: 0a 20 20 20 20 7a 69 70 66 69 6c 65 45 6e 74 72  .    zipfileEntr
3040: 79 46 72 65 65 28 70 29 3b 0a 20 20 7d 0a 7d 0a  yFree(p);.  }.}.
3050: 0a 2f 2a 0a 2a 2a 20 44 65 73 74 72 75 63 74 6f  ./*.** Destructo
3060: 72 20 66 6f 72 20 61 6e 20 5a 69 70 66 69 6c 65  r for an Zipfile
3070: 43 73 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  Csr..*/.static i
3080: 6e 74 20 7a 69 70 66 69 6c 65 43 6c 6f 73 65 28  nt zipfileClose(
3090: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
30a0: 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 5a 69 70  sor *cur){.  Zip
30b0: 66 69 6c 65 43 73 72 20 2a 70 43 73 72 20 3d 20  fileCsr *pCsr = 
30c0: 28 5a 69 70 66 69 6c 65 43 73 72 2a 29 63 75 72  (ZipfileCsr*)cur
30d0: 3b 0a 20 20 5a 69 70 66 69 6c 65 54 61 62 20 2a  ;.  ZipfileTab *
30e0: 70 54 61 62 20 3d 20 28 5a 69 70 66 69 6c 65 54  pTab = (ZipfileT
30f0: 61 62 2a 29 28 70 43 73 72 2d 3e 62 61 73 65 2e  ab*)(pCsr->base.
3100: 70 56 74 61 62 29 3b 0a 20 20 5a 69 70 66 69 6c  pVtab);.  Zipfil
3110: 65 43 73 72 20 2a 2a 70 70 3b 0a 20 20 7a 69 70  eCsr **pp;.  zip
3120: 66 69 6c 65 52 65 73 65 74 43 75 72 73 6f 72 28  fileResetCursor(
3130: 70 43 73 72 29 3b 0a 0a 20 20 2f 2a 20 52 65 6d  pCsr);..  /* Rem
3140: 6f 76 65 20 74 68 69 73 20 63 75 72 73 6f 72 20  ove this cursor 
3150: 66 72 6f 6d 20 74 68 65 20 5a 69 70 66 69 6c 65  from the Zipfile
3160: 54 61 62 2e 70 43 73 72 4c 69 73 74 20 6c 69 73  Tab.pCsrList lis
3170: 74 2e 20 2a 2f 0a 20 20 66 6f 72 28 70 70 3d 26  t. */.  for(pp=&
3180: 70 54 61 62 2d 3e 70 43 73 72 4c 69 73 74 3b 20  pTab->pCsrList; 
3190: 2a 70 70 3b 20 70 70 3d 26 28 28 2a 70 70 29 2d  *pp; pp=&((*pp)-
31a0: 3e 70 43 73 72 4e 65 78 74 29 29 7b 0a 20 20 20  >pCsrNext)){.   
31b0: 20 69 66 28 20 2a 70 70 3d 3d 70 43 73 72 20 29   if( *pp==pCsr )
31c0: 7b 20 0a 20 20 20 20 20 20 2a 70 70 20 3d 20 70  { .      *pp = p
31d0: 43 73 72 2d 3e 70 43 73 72 4e 65 78 74 3b 0a 20  Csr->pCsrNext;. 
31e0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
31f0: 7d 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  }.  }..  sqlite3
3200: 5f 66 72 65 65 28 70 43 73 72 29 3b 0a 20 20 72  _free(pCsr);.  r
3210: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
3220: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68  .}../*.** Set th
3230: 65 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65 20  e error message 
3240: 66 6f 72 20 74 68 65 20 76 69 72 74 75 61 6c 20  for the virtual 
3250: 74 61 62 6c 65 20 61 73 73 6f 63 69 61 74 65 64  table associated
3260: 20 77 69 74 68 20 63 75 72 73 6f 72 0a 2a 2a 20   with cursor.** 
3270: 70 43 73 72 20 74 6f 20 74 68 65 20 72 65 73 75  pCsr to the resu
3280: 6c 74 73 20 6f 66 20 76 70 72 69 6e 74 66 28 7a  lts of vprintf(z
3290: 46 6d 74 2c 20 2e 2e 2e 29 2e 0a 2a 2f 0a 73 74  Fmt, ...)..*/.st
32a0: 61 74 69 63 20 76 6f 69 64 20 7a 69 70 66 69 6c  atic void zipfil
32b0: 65 53 65 74 45 72 72 6d 73 67 28 5a 69 70 66 69  eSetErrmsg(Zipfi
32c0: 6c 65 43 73 72 20 2a 70 43 73 72 2c 20 63 6f 6e  leCsr *pCsr, con
32d0: 73 74 20 63 68 61 72 20 2a 7a 46 6d 74 2c 20 2e  st char *zFmt, .
32e0: 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61  ..){.  va_list a
32f0: 70 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70  p;.  va_start(ap
3300: 2c 20 7a 46 6d 74 29 3b 0a 20 20 70 43 73 72 2d  , zFmt);.  pCsr-
3310: 3e 62 61 73 65 2e 70 56 74 61 62 2d 3e 7a 45 72  >base.pVtab->zEr
3320: 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 76  rMsg = sqlite3_v
3330: 6d 70 72 69 6e 74 66 28 7a 46 6d 74 2c 20 61 70  mprintf(zFmt, ap
3340: 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b  );.  va_end(ap);
3350: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 6e  .}../*.** Read n
3360: 52 65 61 64 20 62 79 74 65 73 20 6f 66 20 64 61  Read bytes of da
3370: 74 61 20 66 72 6f 6d 20 6f 66 66 73 65 74 20 69  ta from offset i
3380: 4f 66 66 20 6f 66 20 66 69 6c 65 20 70 46 69 6c  Off of file pFil
3390: 65 20 69 6e 74 6f 20 62 75 66 66 65 72 0a 2a 2a  e into buffer.**
33a0: 20 61 52 65 61 64 5b 5d 2e 20 52 65 74 75 72 6e   aRead[]. Return
33b0: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 66 20 73 75   SQLITE_OK if su
33c0: 63 63 65 73 73 66 75 6c 2c 20 6f 72 20 61 6e 20  ccessful, or an 
33d0: 53 51 4c 69 74 65 20 65 72 72 6f 72 20 63 6f 64  SQLite error cod
33e0: 65 0a 2a 2a 20 6f 74 68 65 72 77 69 73 65 2e 20  e.** otherwise. 
33f0: 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72  .**.** If an err
3400: 6f 72 20 64 6f 65 73 20 6f 63 63 75 72 2c 20 6f  or does occur, o
3410: 75 74 70 75 74 20 76 61 72 69 61 62 6c 65 20 28  utput variable (
3420: 2a 70 7a 45 72 72 6d 73 67 29 20 6d 61 79 20 62  *pzErrmsg) may b
3430: 65 20 73 65 74 20 74 6f 20 70 6f 69 6e 74 0a 2a  e set to point.*
3440: 2a 20 74 6f 20 61 6e 20 45 6e 67 6c 69 73 68 20  * to an English 
3450: 6c 61 6e 67 75 61 67 65 20 65 72 72 6f 72 20 6d  language error m
3460: 65 73 73 61 67 65 2e 20 49 74 20 69 73 20 74 68  essage. It is th
3470: 65 20 72 65 73 70 6f 6e 73 69 62 69 6c 69 74 79  e responsibility
3480: 20 6f 66 20 74 68 65 0a 2a 2a 20 63 61 6c 6c 65   of the.** calle
3490: 72 20 74 6f 20 65 76 65 6e 74 75 61 6c 6c 79 20  r to eventually 
34a0: 66 72 65 65 20 74 68 69 73 20 62 75 66 66 65 72  free this buffer
34b0: 20 75 73 69 6e 67 0a 2a 2a 20 73 71 6c 69 74 65   using.** sqlite
34c0: 33 5f 66 72 65 65 28 29 2e 0a 2a 2f 0a 73 74 61  3_free()..*/.sta
34d0: 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 52  tic int zipfileR
34e0: 65 61 64 44 61 74 61 28 0a 20 20 46 49 4c 45 20  eadData(.  FILE 
34f0: 2a 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20 20  *pFile,         
3500: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65             /* Re
3510: 61 64 20 66 72 6f 6d 20 74 68 69 73 20 66 69 6c  ad from this fil
3520: 65 20 2a 2f 0a 20 20 75 38 20 2a 61 52 65 61 64  e */.  u8 *aRead
3530: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
3540: 20 20 20 20 20 20 20 2f 2a 20 52 65 61 64 20 69         /* Read i
3550: 6e 74 6f 20 74 68 69 73 20 62 75 66 66 65 72 20  nto this buffer 
3560: 2a 2f 0a 20 20 69 6e 74 20 6e 52 65 61 64 2c 20  */.  int nRead, 
3570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3580: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
3590: 66 20 62 79 74 65 73 20 74 6f 20 72 65 61 64 20  f bytes to read 
35a0: 2a 2f 0a 20 20 69 36 34 20 69 4f 66 66 2c 20 20  */.  i64 iOff,  
35b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
35c0: 20 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 74       /* Offset t
35d0: 6f 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20  o read from */. 
35e0: 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 6d 73 67   char **pzErrmsg
35f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3600: 20 2f 2a 20 4f 55 54 3a 20 45 72 72 6f 72 20 6d   /* OUT: Error m
3610: 65 73 73 61 67 65 20 28 66 72 6f 6d 20 73 71 6c  essage (from sql
3620: 69 74 65 33 5f 6d 61 6c 6c 6f 63 29 20 2a 2f 0a  ite3_malloc) */.
3630: 29 7b 0a 20 20 73 69 7a 65 5f 74 20 6e 3b 0a 20  ){.  size_t n;. 
3640: 20 66 73 65 65 6b 28 70 46 69 6c 65 2c 20 28 6c   fseek(pFile, (l
3650: 6f 6e 67 29 69 4f 66 66 2c 20 53 45 45 4b 5f 53  ong)iOff, SEEK_S
3660: 45 54 29 3b 0a 20 20 6e 20 3d 20 66 72 65 61 64  ET);.  n = fread
3670: 28 61 52 65 61 64 2c 20 31 2c 20 6e 52 65 61 64  (aRead, 1, nRead
3680: 2c 20 70 46 69 6c 65 29 3b 0a 20 20 69 66 28 20  , pFile);.  if( 
3690: 28 69 6e 74 29 6e 21 3d 6e 52 65 61 64 20 29 7b  (int)n!=nRead ){
36a0: 0a 20 20 20 20 2a 70 7a 45 72 72 6d 73 67 20 3d  .    *pzErrmsg =
36b0: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
36c0: 28 22 65 72 72 6f 72 20 69 6e 20 66 72 65 61 64  ("error in fread
36d0: 28 29 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  ()");.    return
36e0: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20   SQLITE_ERROR;. 
36f0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
3700: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 73 74 61 74 69 63  TE_OK;.}..static
3710: 20 69 6e 74 20 7a 69 70 66 69 6c 65 41 70 70 65   int zipfileAppe
3720: 6e 64 44 61 74 61 28 0a 20 20 5a 69 70 66 69 6c  ndData(.  Zipfil
3730: 65 54 61 62 20 2a 70 54 61 62 2c 0a 20 20 63 6f  eTab *pTab,.  co
3740: 6e 73 74 20 75 38 20 2a 61 57 72 69 74 65 2c 0a  nst u8 *aWrite,.
3750: 20 20 69 6e 74 20 6e 57 72 69 74 65 0a 29 7b 0a    int nWrite.){.
3760: 20 20 73 69 7a 65 5f 74 20 6e 3b 0a 20 20 66 73    size_t n;.  fs
3770: 65 65 6b 28 70 54 61 62 2d 3e 70 57 72 69 74 65  eek(pTab->pWrite
3780: 46 64 2c 20 28 6c 6f 6e 67 29 70 54 61 62 2d 3e  Fd, (long)pTab->
3790: 73 7a 43 75 72 72 65 6e 74 2c 20 53 45 45 4b 5f  szCurrent, SEEK_
37a0: 53 45 54 29 3b 0a 20 20 6e 20 3d 20 66 77 72 69  SET);.  n = fwri
37b0: 74 65 28 61 57 72 69 74 65 2c 20 31 2c 20 6e 57  te(aWrite, 1, nW
37c0: 72 69 74 65 2c 20 70 54 61 62 2d 3e 70 57 72 69  rite, pTab->pWri
37d0: 74 65 46 64 29 3b 0a 20 20 69 66 28 20 28 69 6e  teFd);.  if( (in
37e0: 74 29 6e 21 3d 6e 57 72 69 74 65 20 29 7b 0a 20  t)n!=nWrite ){. 
37f0: 20 20 20 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45     pTab->base.zE
3800: 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f  rrMsg = sqlite3_
3810: 6d 70 72 69 6e 74 66 28 22 65 72 72 6f 72 20 69  mprintf("error i
3820: 6e 20 66 77 72 69 74 65 28 29 22 29 3b 0a 20 20  n fwrite()");.  
3830: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
3840: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 70 54 61  ERROR;.  }.  pTa
3850: 62 2d 3e 73 7a 43 75 72 72 65 6e 74 20 2b 3d 20  b->szCurrent += 
3860: 6e 57 72 69 74 65 3b 0a 20 20 72 65 74 75 72 6e  nWrite;.  return
3870: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
3880: 2a 0a 2a 2a 20 52 65 61 64 20 61 6e 64 20 72 65  *.** Read and re
3890: 74 75 72 6e 20 61 20 31 36 2d 62 69 74 20 6c 69  turn a 16-bit li
38a0: 74 74 6c 65 2d 65 6e 64 69 61 6e 20 75 6e 73 69  ttle-endian unsi
38b0: 67 6e 65 64 20 69 6e 74 65 67 65 72 20 66 72 6f  gned integer fro
38c0: 6d 20 62 75 66 66 65 72 20 61 42 75 66 2e 0a 2a  m buffer aBuf..*
38d0: 2f 0a 73 74 61 74 69 63 20 75 31 36 20 7a 69 70  /.static u16 zip
38e0: 66 69 6c 65 47 65 74 55 31 36 28 63 6f 6e 73 74  fileGetU16(const
38f0: 20 75 38 20 2a 61 42 75 66 29 7b 0a 20 20 72 65   u8 *aBuf){.  re
3900: 74 75 72 6e 20 28 61 42 75 66 5b 31 5d 20 3c 3c  turn (aBuf[1] <<
3910: 20 38 29 20 2b 20 61 42 75 66 5b 30 5d 3b 0a 7d   8) + aBuf[0];.}
3920: 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 61 6e 64  ../*.** Read and
3930: 20 72 65 74 75 72 6e 20 61 20 33 32 2d 62 69 74   return a 32-bit
3940: 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61 6e 20 75   little-endian u
3950: 6e 73 69 67 6e 65 64 20 69 6e 74 65 67 65 72 20  nsigned integer 
3960: 66 72 6f 6d 20 62 75 66 66 65 72 20 61 42 75 66  from buffer aBuf
3970: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 75 33 32 20  ..*/.static u32 
3980: 7a 69 70 66 69 6c 65 47 65 74 55 33 32 28 63 6f  zipfileGetU32(co
3990: 6e 73 74 20 75 38 20 2a 61 42 75 66 29 7b 0a 20  nst u8 *aBuf){. 
39a0: 20 72 65 74 75 72 6e 20 28 28 75 33 32 29 28 61   return ((u32)(a
39b0: 42 75 66 5b 33 5d 29 20 3c 3c 20 32 34 29 0a 20  Buf[3]) << 24). 
39c0: 20 20 20 20 20 20 2b 20 28 28 75 33 32 29 28 61        + ((u32)(a
39d0: 42 75 66 5b 32 5d 29 20 3c 3c 20 31 36 29 0a 20  Buf[2]) << 16). 
39e0: 20 20 20 20 20 20 2b 20 28 28 75 33 32 29 28 61        + ((u32)(a
39f0: 42 75 66 5b 31 5d 29 20 3c 3c 20 20 38 29 0a 20  Buf[1]) <<  8). 
3a00: 20 20 20 20 20 20 2b 20 28 28 75 33 32 29 28 61        + ((u32)(a
3a10: 42 75 66 5b 30 5d 29 20 3c 3c 20 20 30 29 3b 0a  Buf[0]) <<  0);.
3a20: 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 61  }../*.** Write a
3a30: 20 31 36 2d 62 69 74 20 6c 69 74 74 6c 65 20 65   16-bit little e
3a40: 6e 64 69 61 74 65 20 69 6e 74 65 67 65 72 20 69  ndiate integer i
3a50: 6e 74 6f 20 62 75 66 66 65 72 20 61 42 75 66 2e  nto buffer aBuf.
3a60: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
3a70: 7a 69 70 66 69 6c 65 50 75 74 55 31 36 28 75 38  zipfilePutU16(u8
3a80: 20 2a 61 42 75 66 2c 20 75 31 36 20 76 61 6c 29   *aBuf, u16 val)
3a90: 7b 0a 20 20 61 42 75 66 5b 30 5d 20 3d 20 76 61  {.  aBuf[0] = va
3aa0: 6c 20 26 20 30 78 46 46 3b 0a 20 20 61 42 75 66  l & 0xFF;.  aBuf
3ab0: 5b 31 5d 20 3d 20 28 76 61 6c 3e 3e 38 29 20 26  [1] = (val>>8) &
3ac0: 20 30 78 46 46 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   0xFF;.}../*.** 
3ad0: 57 72 69 74 65 20 61 20 33 32 2d 62 69 74 20 6c  Write a 32-bit l
3ae0: 69 74 74 6c 65 20 65 6e 64 69 61 74 65 20 69 6e  ittle endiate in
3af0: 74 65 67 65 72 20 69 6e 74 6f 20 62 75 66 66 65  teger into buffe
3b00: 72 20 61 42 75 66 2e 0a 2a 2f 0a 73 74 61 74 69  r aBuf..*/.stati
3b10: 63 20 76 6f 69 64 20 7a 69 70 66 69 6c 65 50 75  c void zipfilePu
3b20: 74 55 33 32 28 75 38 20 2a 61 42 75 66 2c 20 75  tU32(u8 *aBuf, u
3b30: 33 32 20 76 61 6c 29 7b 0a 20 20 61 42 75 66 5b  32 val){.  aBuf[
3b40: 30 5d 20 3d 20 76 61 6c 20 26 20 30 78 46 46 3b  0] = val & 0xFF;
3b50: 0a 20 20 61 42 75 66 5b 31 5d 20 3d 20 28 76 61  .  aBuf[1] = (va
3b60: 6c 3e 3e 38 29 20 26 20 30 78 46 46 3b 0a 20 20  l>>8) & 0xFF;.  
3b70: 61 42 75 66 5b 32 5d 20 3d 20 28 76 61 6c 3e 3e  aBuf[2] = (val>>
3b80: 31 36 29 20 26 20 30 78 46 46 3b 0a 20 20 61 42  16) & 0xFF;.  aB
3b90: 75 66 5b 33 5d 20 3d 20 28 76 61 6c 3e 3e 32 34  uf[3] = (val>>24
3ba0: 29 20 26 20 30 78 46 46 3b 0a 7d 0a 0a 23 64 65  ) & 0xFF;.}..#de
3bb0: 66 69 6e 65 20 7a 69 70 66 69 6c 65 52 65 61 64  fine zipfileRead
3bc0: 33 32 28 61 42 75 66 29 20 28 20 61 42 75 66 2b  32(aBuf) ( aBuf+
3bd0: 3d 34 2c 20 7a 69 70 66 69 6c 65 47 65 74 55 33  =4, zipfileGetU3
3be0: 32 28 61 42 75 66 2d 34 29 20 29 0a 23 64 65 66  2(aBuf-4) ).#def
3bf0: 69 6e 65 20 7a 69 70 66 69 6c 65 52 65 61 64 31  ine zipfileRead1
3c00: 36 28 61 42 75 66 29 20 28 20 61 42 75 66 2b 3d  6(aBuf) ( aBuf+=
3c10: 32 2c 20 7a 69 70 66 69 6c 65 47 65 74 55 31 36  2, zipfileGetU16
3c20: 28 61 42 75 66 2d 32 29 20 29 0a 0a 23 64 65 66  (aBuf-2) )..#def
3c30: 69 6e 65 20 7a 69 70 66 69 6c 65 57 72 69 74 65  ine zipfileWrite
3c40: 33 32 28 61 42 75 66 2c 76 61 6c 29 20 7b 20 7a  32(aBuf,val) { z
3c50: 69 70 66 69 6c 65 50 75 74 55 33 32 28 61 42 75  ipfilePutU32(aBu
3c60: 66 2c 76 61 6c 29 3b 20 61 42 75 66 2b 3d 34 3b  f,val); aBuf+=4;
3c70: 20 7d 0a 23 64 65 66 69 6e 65 20 7a 69 70 66 69   }.#define zipfi
3c80: 6c 65 57 72 69 74 65 31 36 28 61 42 75 66 2c 76  leWrite16(aBuf,v
3c90: 61 6c 29 20 7b 20 7a 69 70 66 69 6c 65 50 75 74  al) { zipfilePut
3ca0: 55 31 36 28 61 42 75 66 2c 76 61 6c 29 3b 20 61  U16(aBuf,val); a
3cb0: 42 75 66 2b 3d 32 3b 20 7d 0a 0a 2f 2a 0a 2a 2a  Buf+=2; }../*.**
3cc0: 20 4d 61 67 69 63 20 6e 75 6d 62 65 72 73 20 75   Magic numbers u
3cd0: 73 65 64 20 74 6f 20 72 65 61 64 20 43 44 53 20  sed to read CDS 
3ce0: 72 65 63 6f 72 64 73 2e 0a 2a 2f 0a 23 64 65 66  records..*/.#def
3cf0: 69 6e 65 20 5a 49 50 46 49 4c 45 5f 43 44 53 5f  ine ZIPFILE_CDS_
3d00: 4e 46 49 4c 45 5f 4f 46 46 20 20 20 20 20 20 20  NFILE_OFF       
3d10: 20 32 38 0a 23 64 65 66 69 6e 65 20 5a 49 50 46   28.#define ZIPF
3d20: 49 4c 45 5f 43 44 53 5f 53 5a 43 4f 4d 50 52 45  ILE_CDS_SZCOMPRE
3d30: 53 53 45 44 5f 4f 46 46 20 32 30 0a 0a 2f 2a 0a  SSED_OFF 20../*.
3d40: 2a 2a 20 44 65 63 6f 64 65 20 74 68 65 20 43 44  ** Decode the CD
3d50: 53 20 72 65 63 6f 72 64 20 69 6e 20 62 75 66 66  S record in buff
3d60: 65 72 20 61 42 75 66 20 69 6e 74 6f 20 28 2a 70  er aBuf into (*p
3d70: 43 44 53 29 2e 20 52 65 74 75 72 6e 20 53 51 4c  CDS). Return SQL
3d80: 49 54 45 5f 45 52 52 4f 52 0a 2a 2a 20 69 66 20  ITE_ERROR.** if 
3d90: 74 68 65 20 72 65 63 6f 72 64 20 69 73 20 6e 6f  the record is no
3da0: 74 20 77 65 6c 6c 2d 66 6f 72 6d 65 64 2c 20 6f  t well-formed, o
3db0: 72 20 53 51 4c 49 54 45 5f 4f 4b 20 6f 74 68 65  r SQLITE_OK othe
3dc0: 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  rwise..*/.static
3dd0: 20 69 6e 74 20 7a 69 70 66 69 6c 65 52 65 61 64   int zipfileRead
3de0: 43 44 53 28 75 38 20 2a 61 42 75 66 2c 20 5a 69  CDS(u8 *aBuf, Zi
3df0: 70 66 69 6c 65 43 44 53 20 2a 70 43 44 53 29 7b  pfileCDS *pCDS){
3e00: 0a 20 20 75 38 20 2a 61 52 65 61 64 20 3d 20 61  .  u8 *aRead = a
3e10: 42 75 66 3b 0a 20 20 75 33 32 20 73 69 67 20 3d  Buf;.  u32 sig =
3e20: 20 7a 69 70 66 69 6c 65 52 65 61 64 33 32 28 61   zipfileRead32(a
3e30: 52 65 61 64 29 3b 0a 20 20 69 6e 74 20 72 63 20  Read);.  int rc 
3e40: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 69  = SQLITE_OK;.  i
3e50: 66 28 20 73 69 67 21 3d 5a 49 50 46 49 4c 45 5f  f( sig!=ZIPFILE_
3e60: 53 49 47 4e 41 54 55 52 45 5f 43 44 53 20 29 7b  SIGNATURE_CDS ){
3e70: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
3e80: 5f 45 52 52 4f 52 3b 0a 20 20 7d 65 6c 73 65 7b  _ERROR;.  }else{
3e90: 0a 20 20 20 20 70 43 44 53 2d 3e 69 56 65 72 73  .    pCDS->iVers
3ea0: 69 6f 6e 4d 61 64 65 42 79 20 3d 20 7a 69 70 66  ionMadeBy = zipf
3eb0: 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64 29  ileRead16(aRead)
3ec0: 3b 0a 20 20 20 20 70 43 44 53 2d 3e 69 56 65 72  ;.    pCDS->iVer
3ed0: 73 69 6f 6e 45 78 74 72 61 63 74 20 3d 20 7a 69  sionExtract = zi
3ee0: 70 66 69 6c 65 52 65 61 64 31 36 28 61 52 65 61  pfileRead16(aRea
3ef0: 64 29 3b 0a 20 20 20 20 70 43 44 53 2d 3e 66 6c  d);.    pCDS->fl
3f00: 61 67 73 20 3d 20 7a 69 70 66 69 6c 65 52 65 61  ags = zipfileRea
3f10: 64 31 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20  d16(aRead);.    
3f20: 70 43 44 53 2d 3e 69 43 6f 6d 70 72 65 73 73 69  pCDS->iCompressi
3f30: 6f 6e 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64  on = zipfileRead
3f40: 31 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70  16(aRead);.    p
3f50: 43 44 53 2d 3e 6d 54 69 6d 65 20 3d 20 7a 69 70  CDS->mTime = zip
3f60: 66 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64  fileRead16(aRead
3f70: 29 3b 0a 20 20 20 20 70 43 44 53 2d 3e 6d 44 61  );.    pCDS->mDa
3f80: 74 65 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64  te = zipfileRead
3f90: 31 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70  16(aRead);.    p
3fa0: 43 44 53 2d 3e 63 72 63 33 32 20 3d 20 7a 69 70  CDS->crc32 = zip
3fb0: 66 69 6c 65 52 65 61 64 33 32 28 61 52 65 61 64  fileRead32(aRead
3fc0: 29 3b 0a 20 20 20 20 70 43 44 53 2d 3e 73 7a 43  );.    pCDS->szC
3fd0: 6f 6d 70 72 65 73 73 65 64 20 3d 20 7a 69 70 66  ompressed = zipf
3fe0: 69 6c 65 52 65 61 64 33 32 28 61 52 65 61 64 29  ileRead32(aRead)
3ff0: 3b 0a 20 20 20 20 70 43 44 53 2d 3e 73 7a 55 6e  ;.    pCDS->szUn
4000: 63 6f 6d 70 72 65 73 73 65 64 20 3d 20 7a 69 70  compressed = zip
4010: 66 69 6c 65 52 65 61 64 33 32 28 61 52 65 61 64  fileRead32(aRead
4020: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 61  );.    assert( a
4030: 52 65 61 64 3d 3d 26 61 42 75 66 5b 5a 49 50 46  Read==&aBuf[ZIPF
4040: 49 4c 45 5f 43 44 53 5f 4e 46 49 4c 45 5f 4f 46  ILE_CDS_NFILE_OF
4050: 46 5d 20 29 3b 0a 20 20 20 20 70 43 44 53 2d 3e  F] );.    pCDS->
4060: 6e 46 69 6c 65 20 3d 20 7a 69 70 66 69 6c 65 52  nFile = zipfileR
4070: 65 61 64 31 36 28 61 52 65 61 64 29 3b 0a 20 20  ead16(aRead);.  
4080: 20 20 70 43 44 53 2d 3e 6e 45 78 74 72 61 20 3d    pCDS->nExtra =
4090: 20 7a 69 70 66 69 6c 65 52 65 61 64 31 36 28 61   zipfileRead16(a
40a0: 52 65 61 64 29 3b 0a 20 20 20 20 70 43 44 53 2d  Read);.    pCDS-
40b0: 3e 6e 43 6f 6d 6d 65 6e 74 20 3d 20 7a 69 70 66  >nComment = zipf
40c0: 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64 29  ileRead16(aRead)
40d0: 3b 0a 20 20 20 20 70 43 44 53 2d 3e 69 44 69 73  ;.    pCDS->iDis
40e0: 6b 53 74 61 72 74 20 3d 20 7a 69 70 66 69 6c 65  kStart = zipfile
40f0: 52 65 61 64 31 36 28 61 52 65 61 64 29 3b 0a 20  Read16(aRead);. 
4100: 20 20 20 70 43 44 53 2d 3e 69 49 6e 74 65 72 6e     pCDS->iIntern
4110: 61 6c 41 74 74 72 20 3d 20 7a 69 70 66 69 6c 65  alAttr = zipfile
4120: 52 65 61 64 31 36 28 61 52 65 61 64 29 3b 0a 20  Read16(aRead);. 
4130: 20 20 20 70 43 44 53 2d 3e 69 45 78 74 65 72 6e     pCDS->iExtern
4140: 61 6c 41 74 74 72 20 3d 20 7a 69 70 66 69 6c 65  alAttr = zipfile
4150: 52 65 61 64 33 32 28 61 52 65 61 64 29 3b 0a 20  Read32(aRead);. 
4160: 20 20 20 70 43 44 53 2d 3e 69 4f 66 66 73 65 74     pCDS->iOffset
4170: 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 33 32   = zipfileRead32
4180: 28 61 52 65 61 64 29 3b 0a 20 20 20 20 61 73 73  (aRead);.    ass
4190: 65 72 74 28 20 61 52 65 61 64 3d 3d 26 61 42 75  ert( aRead==&aBu
41a0: 66 5b 5a 49 50 46 49 4c 45 5f 43 44 53 5f 46 49  f[ZIPFILE_CDS_FI
41b0: 58 45 44 5f 53 5a 5d 20 29 3b 0a 20 20 7d 0a 0a  XED_SZ] );.  }..
41c0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
41d0: 2f 2a 0a 2a 2a 20 44 65 63 6f 64 65 20 74 68 65  /*.** Decode the
41e0: 20 4c 46 48 20 72 65 63 6f 72 64 20 69 6e 20 62   LFH record in b
41f0: 75 66 66 65 72 20 61 42 75 66 20 69 6e 74 6f 20  uffer aBuf into 
4200: 28 2a 70 4c 46 48 29 2e 20 52 65 74 75 72 6e 20  (*pLFH). Return 
4210: 53 51 4c 49 54 45 5f 45 52 52 4f 52 0a 2a 2a 20  SQLITE_ERROR.** 
4220: 69 66 20 74 68 65 20 72 65 63 6f 72 64 20 69 73  if the record is
4230: 20 6e 6f 74 20 77 65 6c 6c 2d 66 6f 72 6d 65 64   not well-formed
4240: 2c 20 6f 72 20 53 51 4c 49 54 45 5f 4f 4b 20 6f  , or SQLITE_OK o
4250: 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61  therwise..*/.sta
4260: 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 52  tic int zipfileR
4270: 65 61 64 4c 46 48 28 0a 20 20 75 38 20 2a 61 42  eadLFH(.  u8 *aB
4280: 75 66 66 65 72 2c 0a 20 20 5a 69 70 66 69 6c 65  uffer,.  Zipfile
4290: 4c 46 48 20 2a 70 4c 46 48 0a 29 7b 0a 20 20 75  LFH *pLFH.){.  u
42a0: 38 20 2a 61 52 65 61 64 20 3d 20 61 42 75 66 66  8 *aRead = aBuff
42b0: 65 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  er;.  int rc = S
42c0: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 75 33 32  QLITE_OK;..  u32
42d0: 20 73 69 67 20 3d 20 7a 69 70 66 69 6c 65 52 65   sig = zipfileRe
42e0: 61 64 33 32 28 61 52 65 61 64 29 3b 0a 20 20 69  ad32(aRead);.  i
42f0: 66 28 20 73 69 67 21 3d 5a 49 50 46 49 4c 45 5f  f( sig!=ZIPFILE_
4300: 53 49 47 4e 41 54 55 52 45 5f 4c 46 48 20 29 7b  SIGNATURE_LFH ){
4310: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
4320: 5f 45 52 52 4f 52 3b 0a 20 20 7d 65 6c 73 65 7b  _ERROR;.  }else{
4330: 0a 20 20 20 20 70 4c 46 48 2d 3e 69 56 65 72 73  .    pLFH->iVers
4340: 69 6f 6e 45 78 74 72 61 63 74 20 3d 20 7a 69 70  ionExtract = zip
4350: 66 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64  fileRead16(aRead
4360: 29 3b 0a 20 20 20 20 70 4c 46 48 2d 3e 66 6c 61  );.    pLFH->fla
4370: 67 73 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64  gs = zipfileRead
4380: 31 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70  16(aRead);.    p
4390: 4c 46 48 2d 3e 69 43 6f 6d 70 72 65 73 73 69 6f  LFH->iCompressio
43a0: 6e 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31  n = zipfileRead1
43b0: 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 4c  6(aRead);.    pL
43c0: 46 48 2d 3e 6d 54 69 6d 65 20 3d 20 7a 69 70 66  FH->mTime = zipf
43d0: 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64 29  ileRead16(aRead)
43e0: 3b 0a 20 20 20 20 70 4c 46 48 2d 3e 6d 44 61 74  ;.    pLFH->mDat
43f0: 65 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31  e = zipfileRead1
4400: 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 4c  6(aRead);.    pL
4410: 46 48 2d 3e 63 72 63 33 32 20 3d 20 7a 69 70 66  FH->crc32 = zipf
4420: 69 6c 65 52 65 61 64 33 32 28 61 52 65 61 64 29  ileRead32(aRead)
4430: 3b 0a 20 20 20 20 70 4c 46 48 2d 3e 73 7a 43 6f  ;.    pLFH->szCo
4440: 6d 70 72 65 73 73 65 64 20 3d 20 7a 69 70 66 69  mpressed = zipfi
4450: 6c 65 52 65 61 64 33 32 28 61 52 65 61 64 29 3b  leRead32(aRead);
4460: 0a 20 20 20 20 70 4c 46 48 2d 3e 73 7a 55 6e 63  .    pLFH->szUnc
4470: 6f 6d 70 72 65 73 73 65 64 20 3d 20 7a 69 70 66  ompressed = zipf
4480: 69 6c 65 52 65 61 64 33 32 28 61 52 65 61 64 29  ileRead32(aRead)
4490: 3b 0a 20 20 20 20 70 4c 46 48 2d 3e 6e 46 69 6c  ;.    pLFH->nFil
44a0: 65 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31  e = zipfileRead1
44b0: 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 4c  6(aRead);.    pL
44c0: 46 48 2d 3e 6e 45 78 74 72 61 20 3d 20 7a 69 70  FH->nExtra = zip
44d0: 66 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64  fileRead16(aRead
44e0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
44f0: 72 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 42 75  rc;.}.../*.** Bu
4500: 66 66 65 72 20 61 45 78 74 72 61 20 28 73 69 7a  ffer aExtra (siz
4510: 65 20 6e 45 78 74 72 61 20 62 79 74 65 73 29 20  e nExtra bytes) 
4520: 63 6f 6e 74 61 69 6e 73 20 7a 69 70 20 61 72 63  contains zip arc
4530: 68 69 76 65 20 22 65 78 74 72 61 22 20 66 69 65  hive "extra" fie
4540: 6c 64 73 2e 0a 2a 2a 20 53 63 61 6e 20 74 68 72  lds..** Scan thr
4550: 6f 75 67 68 20 74 68 69 73 20 62 75 66 66 65 72  ough this buffer
4560: 20 74 6f 20 66 69 6e 64 20 61 6e 20 22 65 78 74   to find an "ext
4570: 72 61 2d 74 69 6d 65 73 74 61 6d 70 22 20 66 69  ra-timestamp" fi
4580: 65 6c 64 2e 20 49 66 20 6f 6e 65 0a 2a 2a 20 65  eld. If one.** e
4590: 78 69 73 74 73 2c 20 65 78 74 72 61 63 74 20 74  xists, extract t
45a0: 68 65 20 33 32 2d 62 69 74 20 6d 6f 64 69 66 69  he 32-bit modifi
45b0: 63 61 74 69 6f 6e 2d 74 69 6d 65 73 74 61 6d 70  cation-timestamp
45c0: 20 66 72 6f 6d 20 69 74 20 61 6e 64 20 73 74 6f   from it and sto
45d0: 72 65 0a 2a 2a 20 74 68 65 20 76 61 6c 75 65 20  re.** the value 
45e0: 69 6e 20 6f 75 74 70 75 74 20 70 61 72 61 6d 65  in output parame
45f0: 74 65 72 20 2a 70 6d 54 69 6d 65 2e 0a 2a 2a 0a  ter *pmTime..**.
4600: 2a 2a 20 5a 65 72 6f 20 69 73 20 72 65 74 75 72  ** Zero is retur
4610: 6e 65 64 20 69 66 20 6e 6f 20 65 78 74 72 61 2d  ned if no extra-
4620: 74 69 6d 65 73 74 61 6d 70 20 72 65 63 6f 72 64  timestamp record
4630: 20 63 6f 75 6c 64 20 62 65 20 66 6f 75 6e 64 20   could be found 
4640: 28 61 6e 64 20 73 6f 0a 2a 2a 20 2a 70 6d 54 69  (and so.** *pmTi
4650: 6d 65 20 69 73 20 6c 65 66 74 20 75 6e 63 68 61  me is left uncha
4660: 6e 67 65 64 29 2c 20 6f 72 20 6e 6f 6e 2d 7a 65  nged), or non-ze
4670: 72 6f 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2a  ro otherwise..**
4680: 0a 2a 2a 20 54 68 65 20 67 65 6e 65 72 61 6c 20  .** The general 
4690: 66 6f 72 6d 61 74 20 6f 66 20 61 6e 20 65 78 74  format of an ext
46a0: 72 61 20 66 69 65 6c 64 20 69 73 3a 0a 2a 2a 0a  ra field is:.**.
46b0: 2a 2a 20 20 20 48 65 61 64 65 72 20 49 44 20 20  **   Header ID  
46c0: 20 20 32 20 62 79 74 65 73 0a 2a 2a 20 20 20 44    2 bytes.**   D
46d0: 61 74 61 20 53 69 7a 65 20 20 20 20 32 20 62 79  ata Size    2 by
46e0: 74 65 73 0a 2a 2a 20 20 20 44 61 74 61 20 20 20  tes.**   Data   
46f0: 20 20 20 20 20 20 4e 20 62 79 74 65 73 0a 2a 2f        N bytes.*/
4700: 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70 66  .static int zipf
4710: 69 6c 65 53 63 61 6e 45 78 74 72 61 28 75 38 20  ileScanExtra(u8 
4720: 2a 61 45 78 74 72 61 2c 20 69 6e 74 20 6e 45 78  *aExtra, int nEx
4730: 74 72 61 2c 20 75 33 32 20 2a 70 6d 54 69 6d 65  tra, u32 *pmTime
4740: 29 7b 0a 20 20 69 6e 74 20 72 65 74 20 3d 20 30  ){.  int ret = 0
4750: 3b 0a 20 20 75 38 20 2a 70 20 3d 20 61 45 78 74  ;.  u8 *p = aExt
4760: 72 61 3b 0a 20 20 75 38 20 2a 70 45 6e 64 20 3d  ra;.  u8 *pEnd =
4770: 20 26 61 45 78 74 72 61 5b 6e 45 78 74 72 61 5d   &aExtra[nExtra]
4780: 3b 0a 0a 20 20 77 68 69 6c 65 28 20 70 3c 70 45  ;..  while( p<pE
4790: 6e 64 20 29 7b 0a 20 20 20 20 75 31 36 20 69 64  nd ){.    u16 id
47a0: 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31 36   = zipfileRead16
47b0: 28 70 29 3b 0a 20 20 20 20 75 31 36 20 6e 42 79  (p);.    u16 nBy
47c0: 74 65 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64  te = zipfileRead
47d0: 31 36 28 70 29 3b 0a 0a 20 20 20 20 73 77 69 74  16(p);..    swit
47e0: 63 68 28 20 69 64 20 29 7b 0a 20 20 20 20 20 20  ch( id ){.      
47f0: 63 61 73 65 20 5a 49 50 46 49 4c 45 5f 45 58 54  case ZIPFILE_EXT
4800: 52 41 5f 54 49 4d 45 53 54 41 4d 50 3a 20 7b 0a  RA_TIMESTAMP: {.
4810: 20 20 20 20 20 20 20 20 75 38 20 62 20 3d 20 70          u8 b = p
4820: 5b 30 5d 3b 0a 20 20 20 20 20 20 20 20 69 66 28  [0];.        if(
4830: 20 62 20 26 20 30 78 30 31 20 29 7b 20 20 20 20   b & 0x01 ){    
4840: 20 2f 2a 20 30 78 30 31 20 2d 3e 20 6d 6f 64 74   /* 0x01 -> modt
4850: 69 6d 65 20 69 73 20 70 72 65 73 65 6e 74 20 2a  ime is present *
4860: 2f 0a 20 20 20 20 20 20 20 20 20 20 2a 70 6d 54  /.          *pmT
4870: 69 6d 65 20 3d 20 7a 69 70 66 69 6c 65 47 65 74  ime = zipfileGet
4880: 55 33 32 28 26 70 5b 31 5d 29 3b 0a 20 20 20 20  U32(&p[1]);.    
4890: 20 20 20 20 20 20 72 65 74 20 3d 20 31 3b 0a 20        ret = 1;. 
48a0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
48b0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
48c0: 20 20 20 20 7d 0a 0a 20 20 20 20 70 20 2b 3d 20      }..    p += 
48d0: 6e 42 79 74 65 3b 0a 20 20 7d 0a 20 20 72 65 74  nByte;.  }.  ret
48e0: 75 72 6e 20 72 65 74 3b 0a 7d 0a 0a 2f 2a 0a 2a  urn ret;.}../*.*
48f0: 2a 20 43 6f 6e 76 65 72 74 20 74 68 65 20 73 74  * Convert the st
4900: 61 6e 64 61 72 64 20 4d 53 2d 44 4f 53 20 74 69  andard MS-DOS ti
4910: 6d 65 73 74 61 6d 70 20 73 74 6f 72 65 64 20 69  mestamp stored i
4920: 6e 20 74 68 65 20 6d 54 69 6d 65 20 61 6e 64 20  n the mTime and 
4930: 6d 44 61 74 65 0a 2a 2a 20 66 69 65 6c 64 73 20  mDate.** fields 
4940: 6f 66 20 74 68 65 20 43 44 53 20 73 74 72 75 63  of the CDS struc
4950: 74 75 72 65 20 70 61 73 73 65 64 20 61 73 20 74  ture passed as t
4960: 68 65 20 6f 6e 6c 79 20 61 72 67 75 6d 65 6e 74  he only argument
4970: 20 74 6f 20 61 20 33 32 2d 62 69 74 0a 2a 2a 20   to a 32-bit.** 
4980: 55 4e 49 58 20 73 65 63 6f 6e 64 73 2d 73 69 6e  UNIX seconds-sin
4990: 63 65 2d 74 68 65 2d 65 70 6f 63 68 20 74 69 6d  ce-the-epoch tim
49a0: 65 73 74 61 6d 70 2e 20 52 65 74 75 72 6e 20 74  estamp. Return t
49b0: 68 65 20 72 65 73 75 6c 74 2e 0a 2a 2a 0a 2a 2a  he result..**.**
49c0: 20 22 53 74 61 6e 64 61 72 64 22 20 4d 53 2d 44   "Standard" MS-D
49d0: 4f 53 20 74 69 6d 65 20 66 6f 72 6d 61 74 3a 0a  OS time format:.
49e0: 2a 2a 0a 2a 2a 20 20 20 46 69 6c 65 20 6d 6f 64  **.**   File mod
49f0: 69 66 69 63 61 74 69 6f 6e 20 74 69 6d 65 3a 0a  ification time:.
4a00: 2a 2a 20 20 20 20 20 42 69 74 73 20 30 30 2d 30  **     Bits 00-0
4a10: 34 3a 20 73 65 63 6f 6e 64 73 20 64 69 76 69 64  4: seconds divid
4a20: 65 64 20 62 79 20 32 0a 2a 2a 20 20 20 20 20 42  ed by 2.**     B
4a30: 69 74 73 20 30 35 2d 31 30 3a 20 6d 69 6e 75 74  its 05-10: minut
4a40: 65 0a 2a 2a 20 20 20 20 20 42 69 74 73 20 31 31  e.**     Bits 11
4a50: 2d 31 35 3a 20 68 6f 75 72 0a 2a 2a 20 20 20 46  -15: hour.**   F
4a60: 69 6c 65 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e  ile modification
4a70: 20 64 61 74 65 3a 0a 2a 2a 20 20 20 20 20 42 69   date:.**     Bi
4a80: 74 73 20 30 30 2d 30 34 3a 20 64 61 79 0a 2a 2a  ts 00-04: day.**
4a90: 20 20 20 20 20 42 69 74 73 20 30 35 2d 30 38 3a       Bits 05-08:
4aa0: 20 6d 6f 6e 74 68 20 28 31 2d 31 32 29 0a 2a 2a   month (1-12).**
4ab0: 20 20 20 20 20 42 69 74 73 20 30 39 2d 31 35 3a       Bits 09-15:
4ac0: 20 79 65 61 72 73 20 66 72 6f 6d 20 31 39 38 30   years from 1980
4ad0: 20 0a 2a 2a 0a 2a 2a 20 68 74 74 70 73 3a 2f 2f   .**.** https://
4ae0: 6d 73 64 6e 2e 6d 69 63 72 6f 73 6f 66 74 2e 63  msdn.microsoft.c
4af0: 6f 6d 2f 65 6e 2d 75 73 2f 6c 69 62 72 61 72 79  om/en-us/library
4b00: 2f 39 6b 6b 66 39 74 61 68 2e 61 73 70 78 0a 2a  /9kkf9tah.aspx.*
4b10: 2f 0a 73 74 61 74 69 63 20 74 69 6d 65 5f 74 20  /.static time_t 
4b20: 7a 69 70 66 69 6c 65 4d 74 69 6d 65 28 5a 69 70  zipfileMtime(Zip
4b30: 66 69 6c 65 43 44 53 20 2a 70 43 44 53 29 7b 0a  fileCDS *pCDS){.
4b40: 20 20 73 74 72 75 63 74 20 74 6d 20 74 3b 0a 20    struct tm t;. 
4b50: 20 6d 65 6d 73 65 74 28 26 74 2c 20 30 2c 20 73   memset(&t, 0, s
4b60: 69 7a 65 6f 66 28 74 29 29 3b 0a 20 20 74 2e 74  izeof(t));.  t.t
4b70: 6d 5f 73 65 63 20 3d 20 28 70 43 44 53 2d 3e 6d  m_sec = (pCDS->m
4b80: 54 69 6d 65 20 26 20 30 78 31 46 29 2a 32 3b 0a  Time & 0x1F)*2;.
4b90: 20 20 74 2e 74 6d 5f 6d 69 6e 20 3d 20 28 70 43    t.tm_min = (pC
4ba0: 44 53 2d 3e 6d 54 69 6d 65 20 3e 3e 20 35 29 20  DS->mTime >> 5) 
4bb0: 26 20 30 78 32 46 3b 0a 20 20 74 2e 74 6d 5f 68  & 0x2F;.  t.tm_h
4bc0: 6f 75 72 20 3d 20 28 70 43 44 53 2d 3e 6d 54 69  our = (pCDS->mTi
4bd0: 6d 65 20 3e 3e 20 31 31 29 20 26 20 30 78 31 46  me >> 11) & 0x1F
4be0: 3b 0a 0a 20 20 74 2e 74 6d 5f 6d 64 61 79 20 3d  ;..  t.tm_mday =
4bf0: 20 28 70 43 44 53 2d 3e 6d 44 61 74 65 20 26 20   (pCDS->mDate & 
4c00: 30 78 31 46 29 3b 0a 20 20 74 2e 74 6d 5f 6d 6f  0x1F);.  t.tm_mo
4c10: 6e 20 3d 20 28 28 70 43 44 53 2d 3e 6d 44 61 74  n = ((pCDS->mDat
4c20: 65 20 3e 3e 20 35 29 20 26 20 30 78 30 46 29 20  e >> 5) & 0x0F) 
4c30: 2d 20 31 3b 0a 20 20 74 2e 74 6d 5f 79 65 61 72  - 1;.  t.tm_year
4c40: 20 3d 20 38 30 20 2b 20 28 28 70 43 44 53 2d 3e   = 80 + ((pCDS->
4c50: 6d 44 61 74 65 20 3e 3e 20 39 29 20 26 20 30 78  mDate >> 9) & 0x
4c60: 37 46 29 3b 0a 0a 20 20 72 65 74 75 72 6e 20 6d  7F);..  return m
4c70: 6b 74 69 6d 65 28 26 74 29 3b 0a 7d 0a 0a 2f 2a  ktime(&t);.}../*
4c80: 0a 2a 2a 20 54 68 65 20 6f 70 70 6f 73 69 74 65  .** The opposite
4c90: 20 6f 66 20 7a 69 70 66 69 6c 65 4d 74 69 6d 65   of zipfileMtime
4ca0: 28 29 2e 20 54 68 69 73 20 66 75 6e 63 74 69 6f  (). This functio
4cb0: 6e 20 70 6f 70 75 6c 61 74 65 73 20 74 68 65 20  n populates the 
4cc0: 6d 54 69 6d 65 20 61 6e 64 0a 2a 2a 20 6d 44 61  mTime and.** mDa
4cd0: 74 65 20 66 69 65 6c 64 73 20 6f 66 20 74 68 65  te fields of the
4ce0: 20 43 44 53 20 73 74 72 75 63 74 75 72 65 20 70   CDS structure p
4cf0: 61 73 73 65 64 20 61 73 20 74 68 65 20 66 69 72  assed as the fir
4d00: 73 74 20 61 72 67 75 6d 65 6e 74 20 61 63 63 6f  st argument acco
4d10: 72 64 69 6e 67 0a 2a 2a 20 74 6f 20 74 68 65 20  rding.** to the 
4d20: 55 4e 49 58 20 74 69 6d 65 73 74 61 6d 70 20 76  UNIX timestamp v
4d30: 61 6c 75 65 20 70 61 73 73 65 64 20 61 73 20 74  alue passed as t
4d40: 68 65 20 73 65 63 6f 6e 64 2e 0a 2a 2f 0a 73 74  he second..*/.st
4d50: 61 74 69 63 20 76 6f 69 64 20 7a 69 70 66 69 6c  atic void zipfil
4d60: 65 4d 74 69 6d 65 54 6f 44 6f 73 28 5a 69 70 66  eMtimeToDos(Zipf
4d70: 69 6c 65 43 44 53 20 2a 70 43 64 73 2c 20 75 33  ileCDS *pCds, u3
4d80: 32 20 6d 55 6e 69 78 54 69 6d 65 29 7b 0a 20 20  2 mUnixTime){.  
4d90: 74 69 6d 65 5f 74 20 74 20 3d 20 28 74 69 6d 65  time_t t = (time
4da0: 5f 74 29 6d 55 6e 69 78 54 69 6d 65 3b 0a 20 20  _t)mUnixTime;.  
4db0: 73 74 72 75 63 74 20 74 6d 20 72 65 73 3b 0a 0a  struct tm res;..
4dc0: 23 69 66 20 21 64 65 66 69 6e 65 64 28 5f 57 49  #if !defined(_WI
4dd0: 4e 33 32 29 20 26 26 20 21 64 65 66 69 6e 65 64  N32) && !defined
4de0: 28 57 49 4e 33 32 29 0a 20 20 6c 6f 63 61 6c 74  (WIN32).  localt
4df0: 69 6d 65 5f 72 28 26 74 2c 20 26 72 65 73 29 3b  ime_r(&t, &res);
4e00: 0a 23 65 6c 73 65 0a 20 20 6d 65 6d 63 70 79 28  .#else.  memcpy(
4e10: 26 72 65 73 2c 20 6c 6f 63 61 6c 74 69 6d 65 28  &res, localtime(
4e20: 26 74 29 2c 20 73 69 7a 65 6f 66 28 73 74 72 75  &t), sizeof(stru
4e30: 63 74 20 74 6d 29 29 3b 0a 23 65 6e 64 69 66 0a  ct tm));.#endif.
4e40: 0a 20 20 70 43 64 73 2d 3e 6d 54 69 6d 65 20 3d  .  pCds->mTime =
4e50: 20 28 75 31 36 29 28 0a 20 20 20 20 28 72 65 73   (u16)(.    (res
4e60: 2e 74 6d 5f 73 65 63 20 2f 20 32 29 20 2b 20 0a  .tm_sec / 2) + .
4e70: 20 20 20 20 28 72 65 73 2e 74 6d 5f 6d 69 6e 20      (res.tm_min 
4e80: 3c 3c 20 35 29 20 2b 0a 20 20 20 20 28 72 65 73  << 5) +.    (res
4e90: 2e 74 6d 5f 68 6f 75 72 20 3c 3c 20 31 31 29 29  .tm_hour << 11))
4ea0: 3b 0a 0a 20 20 70 43 64 73 2d 3e 6d 44 61 74 65  ;..  pCds->mDate
4eb0: 20 3d 20 28 75 31 36 29 28 0a 20 20 20 20 28 72   = (u16)(.    (r
4ec0: 65 73 2e 74 6d 5f 6d 64 61 79 2d 31 29 20 2b 0a  es.tm_mday-1) +.
4ed0: 20 20 20 20 28 28 72 65 73 2e 74 6d 5f 6d 6f 6e      ((res.tm_mon
4ee0: 2b 31 29 20 3c 3c 20 35 29 20 2b 0a 20 20 20 20  +1) << 5) +.    
4ef0: 28 28 72 65 73 2e 74 6d 5f 79 65 61 72 2d 38 30  ((res.tm_year-80
4f00: 29 20 3c 3c 20 39 29 29 3b 0a 7d 0a 0a 2f 2a 0a  ) << 9));.}../*.
4f10: 2a 2a 20 49 66 20 61 42 6c 6f 62 20 69 73 20 6e  ** If aBlob is n
4f20: 6f 74 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 69 74  ot NULL, then it
4f30: 20 69 73 20 61 20 70 6f 69 6e 74 65 72 20 74 6f   is a pointer to
4f40: 20 61 20 62 75 66 66 65 72 20 28 6e 42 6c 6f 62   a buffer (nBlob
4f50: 20 62 79 74 65 73 20 69 6e 0a 2a 2a 20 73 69 7a   bytes in.** siz
4f60: 65 29 20 63 6f 6e 74 61 69 6e 69 6e 67 20 61 6e  e) containing an
4f70: 20 65 6e 74 69 72 65 20 7a 69 70 20 61 72 63 68   entire zip arch
4f80: 69 76 65 20 69 6d 61 67 65 2e 20 4f 72 2c 20 69  ive image. Or, i
4f90: 66 20 61 42 6c 6f 62 20 69 73 20 4e 55 4c 4c 2c  f aBlob is NULL,
4fa0: 0a 2a 2a 20 74 68 65 6e 20 70 46 69 6c 65 20 69  .** then pFile i
4fb0: 73 20 61 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20  s a file-handle 
4fc0: 6f 70 65 6e 20 6f 6e 20 61 20 7a 69 70 20 66 69  open on a zip fi
4fd0: 6c 65 2e 20 49 6e 20 65 69 74 68 65 72 20 63 61  le. In either ca
4fe0: 73 65 2c 20 74 68 69 73 0a 2a 2a 20 66 75 6e 63  se, this.** func
4ff0: 74 69 6f 6e 20 63 72 65 61 74 65 73 20 61 20 5a  tion creates a Z
5000: 69 70 66 69 6c 65 45 6e 74 72 79 20 6f 62 6a 65  ipfileEntry obje
5010: 63 74 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20  ct based on the 
5020: 7a 69 70 20 61 72 63 68 69 76 65 20 65 6e 74 72  zip archive entr
5030: 79 0a 2a 2a 20 66 6f 72 20 77 68 69 63 68 20 74  y.** for which t
5040: 68 65 20 43 44 53 20 72 65 63 6f 72 64 20 69 73  he CDS record is
5050: 20 61 74 20 6f 66 66 73 65 74 20 69 4f 66 66 2e   at offset iOff.
5060: 0a 2a 2a 0a 2a 2a 20 49 66 20 73 75 63 63 65 73  .**.** If succes
5070: 73 66 75 6c 2c 20 53 51 4c 49 54 45 5f 4f 4b 20  sful, SQLITE_OK 
5080: 69 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20  is returned and 
5090: 28 2a 70 70 45 6e 74 72 79 29 20 73 65 74 20 74  (*ppEntry) set t
50a0: 6f 20 70 6f 69 6e 74 20 74 6f 0a 2a 2a 20 74 68  o point to.** th
50b0: 65 20 6e 65 77 20 6f 62 6a 65 63 74 2e 20 4f 74  e new object. Ot
50c0: 68 65 72 77 69 73 65 2c 20 61 6e 20 53 51 4c 69  herwise, an SQLi
50d0: 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69 73  te error code is
50e0: 20 72 65 74 75 72 6e 65 64 20 61 6e 64 20 74 68   returned and th
50f0: 65 0a 2a 2a 20 66 69 6e 61 6c 20 76 61 6c 75 65  e.** final value
5100: 20 6f 66 20 28 2a 70 70 45 6e 74 72 79 29 20 75   of (*ppEntry) u
5110: 6e 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 73 74 61  ndefined..*/.sta
5120: 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 47  tic int zipfileG
5130: 65 74 45 6e 74 72 79 28 0a 20 20 5a 69 70 66 69  etEntry(.  Zipfi
5140: 6c 65 54 61 62 20 2a 70 54 61 62 2c 20 20 20 20  leTab *pTab,    
5150: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 74             /* St
5160: 6f 72 65 20 61 6e 79 20 65 72 72 6f 72 20 6d 65  ore any error me
5170: 73 73 61 67 65 20 68 65 72 65 20 2a 2f 0a 20 20  ssage here */.  
5180: 63 6f 6e 73 74 20 75 38 20 2a 61 42 6c 6f 62 2c  const u8 *aBlob,
5190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
51a0: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 69 6e  /* Pointer to in
51b0: 2d 6d 65 6d 6f 72 79 20 66 69 6c 65 20 69 6d 61  -memory file ima
51c0: 67 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 42 6c 6f  ge */.  int nBlo
51d0: 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  b,              
51e0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
51f0: 6f 66 20 61 42 6c 6f 62 5b 5d 20 69 6e 20 62 79  of aBlob[] in by
5200: 74 65 73 20 2a 2f 0a 20 20 46 49 4c 45 20 2a 70  tes */.  FILE *p
5210: 46 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20  File,           
5220: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 66 20 61           /* If a
5230: 42 6c 6f 62 3d 3d 30 2c 20 72 65 61 64 20 66 72  Blob==0, read fr
5240: 6f 6d 20 74 68 69 73 20 66 69 6c 65 20 2a 2f 0a  om this file */.
5250: 20 20 69 36 34 20 69 4f 66 66 2c 20 20 20 20 20    i64 iOff,     
5260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5270: 20 20 2f 2a 20 4f 66 66 73 65 74 20 6f 66 20 43    /* Offset of C
5280: 44 53 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20 5a  DS record */.  Z
5290: 69 70 66 69 6c 65 45 6e 74 72 79 20 2a 2a 70 70  ipfileEntry **pp
52a0: 45 6e 74 72 79 20 20 20 20 20 20 20 20 20 20 2f  Entry          /
52b0: 2a 20 4f 55 54 3a 20 50 6f 69 6e 74 65 72 20 74  * OUT: Pointer t
52c0: 6f 20 6e 65 77 20 6f 62 6a 65 63 74 20 2a 2f 0a  o new object */.
52d0: 29 7b 0a 20 20 75 38 20 2a 61 52 65 61 64 3b 0a  ){.  u8 *aRead;.
52e0: 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 20 3d    char **pzErr =
52f0: 20 26 70 54 61 62 2d 3e 62 61 73 65 2e 7a 45 72   &pTab->base.zEr
5300: 72 4d 73 67 3b 0a 20 20 69 6e 74 20 72 63 20 3d  rMsg;.  int rc =
5310: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 69   SQLITE_OK;..  i
5320: 66 28 20 61 42 6c 6f 62 3d 3d 30 20 29 7b 0a 20  f( aBlob==0 ){. 
5330: 20 20 20 61 52 65 61 64 20 3d 20 70 54 61 62 2d     aRead = pTab-
5340: 3e 61 42 75 66 66 65 72 3b 0a 20 20 20 20 72 63  >aBuffer;.    rc
5350: 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 44 61   = zipfileReadDa
5360: 74 61 28 70 46 69 6c 65 2c 20 61 52 65 61 64 2c  ta(pFile, aRead,
5370: 20 5a 49 50 46 49 4c 45 5f 43 44 53 5f 46 49 58   ZIPFILE_CDS_FIX
5380: 45 44 5f 53 5a 2c 20 69 4f 66 66 2c 20 70 7a 45  ED_SZ, iOff, pzE
5390: 72 72 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  rr);.  }else{.  
53a0: 20 20 61 52 65 61 64 20 3d 20 28 75 38 2a 29 26    aRead = (u8*)&
53b0: 61 42 6c 6f 62 5b 69 4f 66 66 5d 3b 0a 20 20 7d  aBlob[iOff];.  }
53c0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  ..  if( rc==SQLI
53d0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e 74  TE_OK ){.    int
53e0: 20 6e 41 6c 6c 6f 63 3b 0a 20 20 20 20 5a 69 70   nAlloc;.    Zip
53f0: 66 69 6c 65 45 6e 74 72 79 20 2a 70 4e 65 77 3b  fileEntry *pNew;
5400: 0a 0a 20 20 20 20 69 6e 74 20 6e 46 69 6c 65 20  ..    int nFile 
5410: 3d 20 7a 69 70 66 69 6c 65 47 65 74 55 31 36 28  = zipfileGetU16(
5420: 26 61 52 65 61 64 5b 5a 49 50 46 49 4c 45 5f 43  &aRead[ZIPFILE_C
5430: 44 53 5f 4e 46 49 4c 45 5f 4f 46 46 5d 29 3b 0a  DS_NFILE_OFF]);.
5440: 20 20 20 20 69 6e 74 20 6e 45 78 74 72 61 20 3d      int nExtra =
5450: 20 7a 69 70 66 69 6c 65 47 65 74 55 31 36 28 26   zipfileGetU16(&
5460: 61 52 65 61 64 5b 5a 49 50 46 49 4c 45 5f 43 44  aRead[ZIPFILE_CD
5470: 53 5f 4e 46 49 4c 45 5f 4f 46 46 2b 32 5d 29 3b  S_NFILE_OFF+2]);
5480: 0a 20 20 20 20 6e 45 78 74 72 61 20 2b 3d 20 7a  .    nExtra += z
5490: 69 70 66 69 6c 65 47 65 74 55 31 36 28 26 61 52  ipfileGetU16(&aR
54a0: 65 61 64 5b 5a 49 50 46 49 4c 45 5f 43 44 53 5f  ead[ZIPFILE_CDS_
54b0: 4e 46 49 4c 45 5f 4f 46 46 2b 34 5d 29 3b 0a 0a  NFILE_OFF+4]);..
54c0: 20 20 20 20 6e 41 6c 6c 6f 63 20 3d 20 73 69 7a      nAlloc = siz
54d0: 65 6f 66 28 5a 69 70 66 69 6c 65 45 6e 74 72 79  eof(ZipfileEntry
54e0: 29 20 2b 20 6e 45 78 74 72 61 3b 0a 20 20 20 20  ) + nExtra;.    
54f0: 69 66 28 20 61 42 6c 6f 62 20 29 7b 0a 20 20 20  if( aBlob ){.   
5500: 20 20 20 6e 41 6c 6c 6f 63 20 2b 3d 20 7a 69 70     nAlloc += zip
5510: 66 69 6c 65 47 65 74 55 33 32 28 26 61 52 65 61  fileGetU32(&aRea
5520: 64 5b 5a 49 50 46 49 4c 45 5f 43 44 53 5f 53 5a  d[ZIPFILE_CDS_SZ
5530: 43 4f 4d 50 52 45 53 53 45 44 5f 4f 46 46 5d 29  COMPRESSED_OFF])
5540: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 70 4e 65  ;.    }..    pNe
5550: 77 20 3d 20 28 5a 69 70 66 69 6c 65 45 6e 74 72  w = (ZipfileEntr
5560: 79 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  y*)sqlite3_mallo
5570: 63 28 6e 41 6c 6c 6f 63 29 3b 0a 20 20 20 20 69  c(nAlloc);.    i
5580: 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b 0a 20 20  f( pNew==0 ){.  
5590: 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f      rc = SQLITE_
55a0: 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 65 6c 73 65  NOMEM;.    }else
55b0: 7b 0a 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70  {.      memset(p
55c0: 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66 28 5a  New, 0, sizeof(Z
55d0: 69 70 66 69 6c 65 45 6e 74 72 79 29 29 3b 0a 20  ipfileEntry));. 
55e0: 20 20 20 20 20 72 63 20 3d 20 7a 69 70 66 69 6c       rc = zipfil
55f0: 65 52 65 61 64 43 44 53 28 61 52 65 61 64 2c 20  eReadCDS(aRead, 
5600: 26 70 4e 65 77 2d 3e 63 64 73 29 3b 0a 20 20 20  &pNew->cds);.   
5610: 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54     if( rc!=SQLIT
5620: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20 20  E_OK ){.        
5630: 2a 70 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33  *pzErr = sqlite3
5640: 5f 6d 70 72 69 6e 74 66 28 22 66 61 69 6c 65 64  _mprintf("failed
5650: 20 74 6f 20 72 65 61 64 20 43 44 53 20 61 74 20   to read CDS at 
5660: 6f 66 66 73 65 74 20 25 6c 6c 64 22 2c 20 69 4f  offset %lld", iO
5670: 66 66 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  ff);.      }else
5680: 20 69 66 28 20 61 42 6c 6f 62 3d 3d 30 20 29 7b   if( aBlob==0 ){
5690: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 7a 69  .        rc = zi
56a0: 70 66 69 6c 65 52 65 61 64 44 61 74 61 28 0a 20  pfileReadData(. 
56b0: 20 20 20 20 20 20 20 20 20 20 20 70 46 69 6c 65             pFile
56c0: 2c 20 61 52 65 61 64 2c 20 6e 45 78 74 72 61 2b  , aRead, nExtra+
56d0: 6e 46 69 6c 65 2c 20 69 4f 66 66 2b 5a 49 50 46  nFile, iOff+ZIPF
56e0: 49 4c 45 5f 43 44 53 5f 46 49 58 45 44 5f 53 5a  ILE_CDS_FIXED_SZ
56f0: 2c 20 70 7a 45 72 72 0a 20 20 20 20 20 20 20 20  , pzErr.        
5700: 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  );.      }else{.
5710: 20 20 20 20 20 20 20 20 61 52 65 61 64 20 3d 20          aRead = 
5720: 28 75 38 2a 29 26 61 42 6c 6f 62 5b 69 4f 66 66  (u8*)&aBlob[iOff
5730: 20 2b 20 5a 49 50 46 49 4c 45 5f 43 44 53 5f 46   + ZIPFILE_CDS_F
5740: 49 58 45 44 5f 53 5a 5d 3b 0a 20 20 20 20 20 20  IXED_SZ];.      
5750: 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 28  }.    }..    if(
5760: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
5770: 7b 0a 20 20 20 20 20 20 75 33 32 20 2a 70 74 20  {.      u32 *pt 
5780: 3d 20 26 70 4e 65 77 2d 3e 6d 55 6e 69 78 54 69  = &pNew->mUnixTi
5790: 6d 65 3b 0a 20 20 20 20 20 20 70 4e 65 77 2d 3e  me;.      pNew->
57a0: 63 64 73 2e 7a 46 69 6c 65 20 3d 20 73 71 6c 69  cds.zFile = sqli
57b0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 2e 2a  te3_mprintf("%.*
57c0: 73 22 2c 20 6e 46 69 6c 65 2c 20 61 52 65 61 64  s", nFile, aRead
57d0: 29 3b 20 0a 20 20 20 20 20 20 70 4e 65 77 2d 3e  ); .      pNew->
57e0: 61 45 78 74 72 61 20 3d 20 28 75 38 2a 29 26 70  aExtra = (u8*)&p
57f0: 4e 65 77 5b 31 5d 3b 0a 20 20 20 20 20 20 6d 65  New[1];.      me
5800: 6d 63 70 79 28 70 4e 65 77 2d 3e 61 45 78 74 72  mcpy(pNew->aExtr
5810: 61 2c 20 26 61 52 65 61 64 5b 6e 46 69 6c 65 5d  a, &aRead[nFile]
5820: 2c 20 6e 45 78 74 72 61 29 3b 0a 20 20 20 20 20  , nExtra);.     
5830: 20 69 66 28 20 70 4e 65 77 2d 3e 63 64 73 2e 7a   if( pNew->cds.z
5840: 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20  File==0 ){.     
5850: 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e     rc = SQLITE_N
5860: 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 7d 65 6c 73  OMEM;.      }els
5870: 65 20 69 66 28 20 30 3d 3d 7a 69 70 66 69 6c 65  e if( 0==zipfile
5880: 53 63 61 6e 45 78 74 72 61 28 26 61 52 65 61 64  ScanExtra(&aRead
5890: 5b 6e 46 69 6c 65 5d 2c 20 70 4e 65 77 2d 3e 63  [nFile], pNew->c
58a0: 64 73 2e 6e 45 78 74 72 61 2c 20 70 74 29 20 29  ds.nExtra, pt) )
58b0: 7b 0a 20 20 20 20 20 20 20 20 70 4e 65 77 2d 3e  {.        pNew->
58c0: 6d 55 6e 69 78 54 69 6d 65 20 3d 20 7a 69 70 66  mUnixTime = zipf
58d0: 69 6c 65 4d 74 69 6d 65 28 26 70 4e 65 77 2d 3e  ileMtime(&pNew->
58e0: 63 64 73 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  cds);.      }.  
58f0: 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d    }..    if( rc=
5900: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20  =SQLITE_OK ){.  
5910: 20 20 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74      static const
5920: 20 69 6e 74 20 73 7a 46 69 78 20 3d 20 5a 49 50   int szFix = ZIP
5930: 46 49 4c 45 5f 4c 46 48 5f 46 49 58 45 44 5f 53  FILE_LFH_FIXED_S
5940: 5a 3b 0a 20 20 20 20 20 20 5a 69 70 66 69 6c 65  Z;.      Zipfile
5950: 4c 46 48 20 6c 66 68 3b 0a 20 20 20 20 20 20 69  LFH lfh;.      i
5960: 66 28 20 70 46 69 6c 65 20 29 7b 0a 20 20 20 20  f( pFile ){.    
5970: 20 20 20 20 72 63 20 3d 20 7a 69 70 66 69 6c 65      rc = zipfile
5980: 52 65 61 64 44 61 74 61 28 70 46 69 6c 65 2c 20  ReadData(pFile, 
5990: 61 52 65 61 64 2c 20 73 7a 46 69 78 2c 20 70 4e  aRead, szFix, pN
59a0: 65 77 2d 3e 63 64 73 2e 69 4f 66 66 73 65 74 2c  ew->cds.iOffset,
59b0: 20 70 7a 45 72 72 29 3b 0a 20 20 20 20 20 20 7d   pzErr);.      }
59c0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 61 52  else{.        aR
59d0: 65 61 64 20 3d 20 28 75 38 2a 29 26 61 42 6c 6f  ead = (u8*)&aBlo
59e0: 62 5b 70 4e 65 77 2d 3e 63 64 73 2e 69 4f 66 66  b[pNew->cds.iOff
59f0: 73 65 74 5d 3b 0a 20 20 20 20 20 20 7d 0a 0a 20  set];.      }.. 
5a00: 20 20 20 20 20 72 63 20 3d 20 7a 69 70 66 69 6c       rc = zipfil
5a10: 65 52 65 61 64 4c 46 48 28 61 52 65 61 64 2c 20  eReadLFH(aRead, 
5a20: 26 6c 66 68 29 3b 0a 20 20 20 20 20 20 69 66 28  &lfh);.      if(
5a30: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
5a40: 7b 0a 20 20 20 20 20 20 20 20 70 4e 65 77 2d 3e  {.        pNew->
5a50: 69 44 61 74 61 4f 66 66 20 3d 20 20 70 4e 65 77  iDataOff =  pNew
5a60: 2d 3e 63 64 73 2e 69 4f 66 66 73 65 74 20 2b 20  ->cds.iOffset + 
5a70: 5a 49 50 46 49 4c 45 5f 4c 46 48 5f 46 49 58 45  ZIPFILE_LFH_FIXE
5a80: 44 5f 53 5a 3b 0a 20 20 20 20 20 20 20 20 70 4e  D_SZ;.        pN
5a90: 65 77 2d 3e 69 44 61 74 61 4f 66 66 20 2b 3d 20  ew->iDataOff += 
5aa0: 6c 66 68 2e 6e 46 69 6c 65 20 2b 20 6c 66 68 2e  lfh.nFile + lfh.
5ab0: 6e 45 78 74 72 61 3b 0a 20 20 20 20 20 20 20 20  nExtra;.        
5ac0: 69 66 28 20 61 42 6c 6f 62 20 26 26 20 70 4e 65  if( aBlob && pNe
5ad0: 77 2d 3e 63 64 73 2e 73 7a 43 6f 6d 70 72 65 73  w->cds.szCompres
5ae0: 73 65 64 20 29 7b 0a 20 20 20 20 20 20 20 20 20  sed ){.         
5af0: 20 70 4e 65 77 2d 3e 61 44 61 74 61 20 3d 20 26   pNew->aData = &
5b00: 70 4e 65 77 2d 3e 61 45 78 74 72 61 5b 6e 45 78  pNew->aExtra[nEx
5b10: 74 72 61 5d 3b 0a 20 20 20 20 20 20 20 20 20 20  tra];.          
5b20: 6d 65 6d 63 70 79 28 70 4e 65 77 2d 3e 61 44 61  memcpy(pNew->aDa
5b30: 74 61 2c 20 26 61 42 6c 6f 62 5b 70 4e 65 77 2d  ta, &aBlob[pNew-
5b40: 3e 69 44 61 74 61 4f 66 66 5d 2c 20 70 4e 65 77  >iDataOff], pNew
5b50: 2d 3e 63 64 73 2e 73 7a 43 6f 6d 70 72 65 73 73  ->cds.szCompress
5b60: 65 64 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  ed);.        }. 
5b70: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
5b80: 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73 71 6c      *pzErr = sql
5b90: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 66 61  ite3_mprintf("fa
5ba0: 69 6c 65 64 20 74 6f 20 72 65 61 64 20 4c 46 48  iled to read LFH
5bb0: 20 61 74 20 6f 66 66 73 65 74 20 25 64 22 2c 20   at offset %d", 
5bc0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 28 69 6e  .            (in
5bd0: 74 29 70 4e 65 77 2d 3e 63 64 73 2e 69 4f 66 66  t)pNew->cds.iOff
5be0: 73 65 74 0a 20 20 20 20 20 20 20 20 29 3b 0a 20  set.        );. 
5bf0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20       }.    }..  
5c00: 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49 54 45    if( rc!=SQLITE
5c10: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 7a 69 70  _OK ){.      zip
5c20: 66 69 6c 65 45 6e 74 72 79 46 72 65 65 28 70 4e  fileEntryFree(pN
5c30: 65 77 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  ew);.    }else{.
5c40: 20 20 20 20 20 20 2a 70 70 45 6e 74 72 79 20 3d        *ppEntry =
5c50: 20 70 4e 65 77 3b 0a 20 20 20 20 7d 0a 20 20 7d   pNew;.    }.  }
5c60: 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  ..  return rc;.}
5c70: 0a 0a 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20  ../*.** Advance 
5c80: 61 6e 20 5a 69 70 66 69 6c 65 43 73 72 20 74 6f  an ZipfileCsr to
5c90: 20 69 74 73 20 6e 65 78 74 20 72 6f 77 20 6f 66   its next row of
5ca0: 20 6f 75 74 70 75 74 2e 0a 2a 2f 0a 73 74 61 74   output..*/.stat
5cb0: 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 4e 65  ic int zipfileNe
5cc0: 78 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  xt(sqlite3_vtab_
5cd0: 63 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20  cursor *cur){.  
5ce0: 5a 69 70 66 69 6c 65 43 73 72 20 2a 70 43 73 72  ZipfileCsr *pCsr
5cf0: 20 3d 20 28 5a 69 70 66 69 6c 65 43 73 72 2a 29   = (ZipfileCsr*)
5d00: 63 75 72 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20  cur;.  int rc = 
5d10: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 69 66  SQLITE_OK;..  if
5d20: 28 20 70 43 73 72 2d 3e 70 46 69 6c 65 20 29 7b  ( pCsr->pFile ){
5d30: 0a 20 20 20 20 69 36 34 20 69 45 6f 66 20 3d 20  .    i64 iEof = 
5d40: 70 43 73 72 2d 3e 65 6f 63 64 2e 69 4f 66 66 73  pCsr->eocd.iOffs
5d50: 65 74 20 2b 20 70 43 73 72 2d 3e 65 6f 63 64 2e  et + pCsr->eocd.
5d60: 6e 53 69 7a 65 3b 0a 20 20 20 20 7a 69 70 66 69  nSize;.    zipfi
5d70: 6c 65 45 6e 74 72 79 46 72 65 65 28 70 43 73 72  leEntryFree(pCsr
5d80: 2d 3e 70 43 75 72 72 65 6e 74 29 3b 0a 20 20 20  ->pCurrent);.   
5d90: 20 70 43 73 72 2d 3e 70 43 75 72 72 65 6e 74 20   pCsr->pCurrent 
5da0: 3d 20 30 3b 0a 20 20 20 20 69 66 28 20 70 43 73  = 0;.    if( pCs
5db0: 72 2d 3e 69 4e 65 78 74 4f 66 66 3e 3d 69 45 6f  r->iNextOff>=iEo
5dc0: 66 20 29 7b 0a 20 20 20 20 20 20 70 43 73 72 2d  f ){.      pCsr-
5dd0: 3e 62 45 6f 66 20 3d 20 31 3b 0a 20 20 20 20 7d  >bEof = 1;.    }
5de0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 5a 69 70 66  else{.      Zipf
5df0: 69 6c 65 45 6e 74 72 79 20 2a 70 20 3d 20 30 3b  ileEntry *p = 0;
5e00: 0a 20 20 20 20 20 20 5a 69 70 66 69 6c 65 54 61  .      ZipfileTa
5e10: 62 20 2a 70 54 61 62 20 3d 20 28 5a 69 70 66 69  b *pTab = (Zipfi
5e20: 6c 65 54 61 62 2a 29 28 63 75 72 2d 3e 70 56 74  leTab*)(cur->pVt
5e30: 61 62 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20  ab);.      rc = 
5e40: 7a 69 70 66 69 6c 65 47 65 74 45 6e 74 72 79 28  zipfileGetEntry(
5e50: 70 54 61 62 2c 20 30 2c 20 30 2c 20 70 43 73 72  pTab, 0, 0, pCsr
5e60: 2d 3e 70 46 69 6c 65 2c 20 70 43 73 72 2d 3e 69  ->pFile, pCsr->i
5e70: 4e 65 78 74 4f 66 66 2c 20 26 70 29 3b 0a 20 20  NextOff, &p);.  
5e80: 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49      if( rc==SQLI
5e90: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 20  TE_OK ){.       
5ea0: 20 70 43 73 72 2d 3e 69 4e 65 78 74 4f 66 66 20   pCsr->iNextOff 
5eb0: 2b 3d 20 5a 49 50 46 49 4c 45 5f 43 44 53 5f 46  += ZIPFILE_CDS_F
5ec0: 49 58 45 44 5f 53 5a 3b 0a 20 20 20 20 20 20 20  IXED_SZ;.       
5ed0: 20 70 43 73 72 2d 3e 69 4e 65 78 74 4f 66 66 20   pCsr->iNextOff 
5ee0: 2b 3d 20 28 69 6e 74 29 70 2d 3e 63 64 73 2e 6e  += (int)p->cds.n
5ef0: 45 78 74 72 61 20 2b 20 70 2d 3e 63 64 73 2e 6e  Extra + p->cds.n
5f00: 46 69 6c 65 20 2b 20 70 2d 3e 63 64 73 2e 6e 43  File + p->cds.nC
5f10: 6f 6d 6d 65 6e 74 3b 0a 20 20 20 20 20 20 7d 0a  omment;.      }.
5f20: 20 20 20 20 20 20 70 43 73 72 2d 3e 70 43 75 72        pCsr->pCur
5f30: 72 65 6e 74 20 3d 20 70 3b 0a 20 20 20 20 7d 0a  rent = p;.    }.
5f40: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66 28    }else{.    if(
5f50: 20 21 70 43 73 72 2d 3e 62 4e 6f 6f 70 20 29 7b   !pCsr->bNoop ){
5f60: 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 70 43 75  .      pCsr->pCu
5f70: 72 72 65 6e 74 20 3d 20 70 43 73 72 2d 3e 70 43  rrent = pCsr->pC
5f80: 75 72 72 65 6e 74 2d 3e 70 4e 65 78 74 3b 0a 20  urrent->pNext;. 
5f90: 20 20 20 7d 0a 20 20 20 20 69 66 28 20 70 43 73     }.    if( pCs
5fa0: 72 2d 3e 70 43 75 72 72 65 6e 74 3d 3d 30 20 29  r->pCurrent==0 )
5fb0: 7b 0a 20 20 20 20 20 20 70 43 73 72 2d 3e 62 45  {.      pCsr->bE
5fc0: 6f 66 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20  of = 1;.    }.  
5fd0: 7d 0a 0a 20 20 70 43 73 72 2d 3e 62 4e 6f 6f 70  }..  pCsr->bNoop
5fe0: 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 72   = 0;.  return r
5ff0: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69  c;.}..static voi
6000: 64 20 7a 69 70 66 69 6c 65 46 72 65 65 28 76 6f  d zipfileFree(vo
6010: 69 64 20 2a 70 29 20 7b 20 0a 20 20 73 71 6c 69  id *p) { .  sqli
6020: 74 65 33 5f 66 72 65 65 28 70 29 3b 20 0a 7d 0a  te3_free(p); .}.
6030: 0a 2f 2a 0a 2a 2a 20 42 75 66 66 65 72 20 61 49  ./*.** Buffer aI
6040: 6e 20 28 73 69 7a 65 20 6e 49 6e 20 62 79 74 65  n (size nIn byte
6050: 73 29 20 63 6f 6e 74 61 69 6e 73 20 63 6f 6d 70  s) contains comp
6060: 72 65 73 73 65 64 20 64 61 74 61 2e 20 55 6e 63  ressed data. Unc
6070: 6f 6d 70 72 65 73 73 65 64 2c 20 74 68 65 0a 2a  ompressed, the.*
6080: 2a 20 73 69 7a 65 20 69 73 20 6e 4f 75 74 20 62  * size is nOut b
6090: 79 74 65 73 2e 20 54 68 69 73 20 66 75 6e 63 74  ytes. This funct
60a0: 69 6f 6e 20 75 6e 63 6f 6d 70 72 65 73 73 65 73  ion uncompresses
60b0: 20 74 68 65 20 64 61 74 61 20 61 6e 64 20 73 65   the data and se
60c0: 74 73 20 74 68 65 0a 2a 2a 20 72 65 74 75 72 6e  ts the.** return
60d0: 20 76 61 6c 75 65 20 69 6e 20 63 6f 6e 74 65 78   value in contex
60e0: 74 20 70 43 74 78 20 74 6f 20 74 68 65 20 72 65  t pCtx to the re
60f0: 73 75 6c 74 20 28 61 20 62 6c 6f 62 29 2e 0a 2a  sult (a blob)..*
6100: 2a 0a 2a 2a 20 49 66 20 61 6e 20 65 72 72 6f 72  *.** If an error
6110: 20 6f 63 63 75 72 73 2c 20 61 6e 20 65 72 72 6f   occurs, an erro
6120: 72 20 63 6f 64 65 20 69 73 20 6c 65 66 74 20 69  r code is left i
6130: 6e 20 70 43 74 78 20 69 6e 73 74 65 61 64 2e 0a  n pCtx instead..
6140: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 7a  */.static void z
6150: 69 70 66 69 6c 65 49 6e 66 6c 61 74 65 28 0a 20  ipfileInflate(. 
6160: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
6170: 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20 20   *pCtx,         
6180: 20 2f 2a 20 53 74 6f 72 65 20 65 72 72 6f 72 20   /* Store error 
6190: 68 65 72 65 2c 20 69 66 20 61 6e 79 20 2a 2f 0a  here, if any */.
61a0: 20 20 63 6f 6e 73 74 20 75 38 20 2a 61 49 6e 2c    const u8 *aIn,
61b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61c0: 20 20 2f 2a 20 43 6f 6d 70 72 65 73 73 65 64 20    /* Compressed 
61d0: 64 61 74 61 20 2a 2f 0a 20 20 69 6e 74 20 6e 49  data */.  int nI
61e0: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n,              
61f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
6200: 65 20 6f 66 20 62 75 66 66 65 72 20 61 49 6e 5b  e of buffer aIn[
6210: 5d 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a 20 20  ] in bytes */.  
6220: 69 6e 74 20 6e 4f 75 74 20 20 20 20 20 20 20 20  int nOut        
6230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6240: 2f 2a 20 45 78 70 65 63 74 65 64 20 6f 75 74 70  /* Expected outp
6250: 75 74 20 73 69 7a 65 20 2a 2f 0a 29 7b 0a 20 20  ut size */.){.  
6260: 75 38 20 2a 61 52 65 73 20 3d 20 73 71 6c 69 74  u8 *aRes = sqlit
6270: 65 33 5f 6d 61 6c 6c 6f 63 28 6e 4f 75 74 29 3b  e3_malloc(nOut);
6280: 0a 20 20 69 66 28 20 61 52 65 73 3d 3d 30 20 29  .  if( aRes==0 )
6290: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65  {.    sqlite3_re
62a0: 73 75 6c 74 5f 65 72 72 6f 72 5f 6e 6f 6d 65 6d  sult_error_nomem
62b0: 28 70 43 74 78 29 3b 0a 20 20 7d 65 6c 73 65 7b  (pCtx);.  }else{
62c0: 0a 20 20 20 20 69 6e 74 20 65 72 72 3b 0a 20 20  .    int err;.  
62d0: 20 20 7a 5f 73 74 72 65 61 6d 20 73 74 72 3b 0a    z_stream str;.
62e0: 20 20 20 20 6d 65 6d 73 65 74 28 26 73 74 72 2c      memset(&str,
62f0: 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72 29 29   0, sizeof(str))
6300: 3b 0a 0a 20 20 20 20 73 74 72 2e 6e 65 78 74 5f  ;..    str.next_
6310: 69 6e 20 3d 20 28 42 79 74 65 2a 29 61 49 6e 3b  in = (Byte*)aIn;
6320: 0a 20 20 20 20 73 74 72 2e 61 76 61 69 6c 5f 69  .    str.avail_i
6330: 6e 20 3d 20 6e 49 6e 3b 0a 20 20 20 20 73 74 72  n = nIn;.    str
6340: 2e 6e 65 78 74 5f 6f 75 74 20 3d 20 28 42 79 74  .next_out = (Byt
6350: 65 2a 29 61 52 65 73 3b 0a 20 20 20 20 73 74 72  e*)aRes;.    str
6360: 2e 61 76 61 69 6c 5f 6f 75 74 20 3d 20 6e 4f 75  .avail_out = nOu
6370: 74 3b 0a 0a 20 20 20 20 65 72 72 20 3d 20 69 6e  t;..    err = in
6380: 66 6c 61 74 65 49 6e 69 74 32 28 26 73 74 72 2c  flateInit2(&str,
6390: 20 2d 31 35 29 3b 0a 20 20 20 20 69 66 28 20 65   -15);.    if( e
63a0: 72 72 21 3d 5a 5f 4f 4b 20 29 7b 0a 20 20 20 20  rr!=Z_OK ){.    
63b0: 20 20 7a 69 70 66 69 6c 65 43 74 78 45 72 72 6f    zipfileCtxErro
63c0: 72 4d 73 67 28 70 43 74 78 2c 20 22 69 6e 66 6c  rMsg(pCtx, "infl
63d0: 61 74 65 49 6e 69 74 32 28 29 20 66 61 69 6c 65  ateInit2() faile
63e0: 64 20 28 25 64 29 22 2c 20 65 72 72 29 3b 0a 20  d (%d)", err);. 
63f0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6400: 65 72 72 20 3d 20 69 6e 66 6c 61 74 65 28 26 73  err = inflate(&s
6410: 74 72 2c 20 5a 5f 4e 4f 5f 46 4c 55 53 48 29 3b  tr, Z_NO_FLUSH);
6420: 0a 20 20 20 20 20 20 69 66 28 20 65 72 72 21 3d  .      if( err!=
6430: 5a 5f 53 54 52 45 41 4d 5f 45 4e 44 20 29 7b 0a  Z_STREAM_END ){.
6440: 20 20 20 20 20 20 20 20 7a 69 70 66 69 6c 65 43          zipfileC
6450: 74 78 45 72 72 6f 72 4d 73 67 28 70 43 74 78 2c  txErrorMsg(pCtx,
6460: 20 22 69 6e 66 6c 61 74 65 28 29 20 66 61 69 6c   "inflate() fail
6470: 65 64 20 28 25 64 29 22 2c 20 65 72 72 29 3b 0a  ed (%d)", err);.
6480: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
6490: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73       sqlite3_res
64a0: 75 6c 74 5f 62 6c 6f 62 28 70 43 74 78 2c 20 61  ult_blob(pCtx, a
64b0: 52 65 73 2c 20 6e 4f 75 74 2c 20 7a 69 70 66 69  Res, nOut, zipfi
64c0: 6c 65 46 72 65 65 29 3b 0a 20 20 20 20 20 20 20  leFree);.       
64d0: 20 61 52 65 73 20 3d 20 30 3b 0a 20 20 20 20 20   aRes = 0;.     
64e0: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c   }.    }.    sql
64f0: 69 74 65 33 5f 66 72 65 65 28 61 52 65 73 29 3b  ite3_free(aRes);
6500: 0a 20 20 20 20 69 6e 66 6c 61 74 65 45 6e 64 28  .    inflateEnd(
6510: 26 73 74 72 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  &str);.  }.}../*
6520: 0a 2a 2a 20 42 75 66 66 65 72 20 61 49 6e 20 28  .** Buffer aIn (
6530: 73 69 7a 65 20 6e 49 6e 20 62 79 74 65 73 29 20  size nIn bytes) 
6540: 63 6f 6e 74 61 69 6e 73 20 75 6e 63 6f 6d 70 72  contains uncompr
6550: 65 73 73 65 64 20 64 61 74 61 2e 20 54 68 69 73  essed data. This
6560: 20 66 75 6e 63 74 69 6f 6e 0a 2a 2a 20 63 6f 6d   function.** com
6570: 70 72 65 73 73 65 73 20 69 74 20 61 6e 64 20 73  presses it and s
6580: 65 74 73 20 28 2a 70 70 4f 75 74 29 20 74 6f 20  ets (*ppOut) to 
6590: 70 6f 69 6e 74 20 74 6f 20 61 20 62 75 66 66 65  point to a buffe
65a0: 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65  r containing the
65b0: 0a 2a 2a 20 63 6f 6d 70 72 65 73 73 65 64 20 64  .** compressed d
65c0: 61 74 61 2e 20 54 68 65 20 63 61 6c 6c 65 72 20  ata. The caller 
65d0: 69 73 20 72 65 73 70 6f 6e 73 69 62 6c 65 20 66  is responsible f
65e0: 6f 72 20 65 76 65 6e 74 75 61 6c 6c 79 20 63 61  or eventually ca
65f0: 6c 6c 69 6e 67 0a 2a 2a 20 73 71 6c 69 74 65 33  lling.** sqlite3
6600: 5f 66 72 65 65 28 29 20 74 6f 20 72 65 6c 65 61  _free() to relea
6610: 73 65 20 62 75 66 66 65 72 20 28 2a 70 70 4f 75  se buffer (*ppOu
6620: 74 29 2e 20 42 65 66 6f 72 65 20 72 65 74 75 72  t). Before retur
6630: 6e 69 6e 67 2c 20 28 2a 70 6e 4f 75 74 29 20 0a  ning, (*pnOut) .
6640: 2a 2a 20 69 73 20 73 65 74 20 74 6f 20 74 68 65  ** is set to the
6650: 20 73 69 7a 65 20 6f 66 20 62 75 66 66 65 72 20   size of buffer 
6660: 28 2a 70 70 4f 75 74 29 20 69 6e 20 62 79 74 65  (*ppOut) in byte
6670: 73 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 6e 6f 20 65  s..**.** If no e
6680: 72 72 6f 72 20 6f 63 63 75 72 73 2c 20 53 51 4c  rror occurs, SQL
6690: 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
66a0: 65 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 20 61  ed. Otherwise, a
66b0: 6e 20 53 51 4c 69 74 65 20 65 72 72 6f 72 0a 2a  n SQLite error.*
66c0: 2a 20 63 6f 64 65 20 69 73 20 72 65 74 75 72 6e  * code is return
66d0: 65 64 20 61 6e 64 20 61 6e 20 65 72 72 6f 72 20  ed and an error 
66e0: 6d 65 73 73 61 67 65 20 6c 65 66 74 20 69 6e 20  message left in 
66f0: 76 69 72 74 75 61 6c 2d 74 61 62 6c 65 20 68 61  virtual-table ha
6700: 6e 64 6c 65 0a 2a 2a 20 70 54 61 62 2e 20 54 68  ndle.** pTab. Th
6710: 65 20 76 61 6c 75 65 73 20 6f 66 20 28 2a 70 70  e values of (*pp
6720: 4f 75 74 29 20 61 6e 64 20 28 2a 70 6e 4f 75 74  Out) and (*pnOut
6730: 29 20 61 72 65 20 6c 65 66 74 20 75 6e 63 68 61  ) are left uncha
6740: 6e 67 65 64 20 69 6e 20 74 68 69 73 0a 2a 2a 20  nged in this.** 
6750: 63 61 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  case..*/.static 
6760: 69 6e 74 20 7a 69 70 66 69 6c 65 44 65 66 6c 61  int zipfileDefla
6770: 74 65 28 0a 20 20 63 6f 6e 73 74 20 75 38 20 2a  te(.  const u8 *
6780: 61 49 6e 2c 20 69 6e 74 20 6e 49 6e 2c 20 20 20  aIn, int nIn,   
6790: 20 20 20 20 20 20 2f 2a 20 49 6e 70 75 74 20 2a        /* Input *
67a0: 2f 0a 20 20 75 38 20 2a 2a 70 70 4f 75 74 2c 20  /.  u8 **ppOut, 
67b0: 69 6e 74 20 2a 70 6e 4f 75 74 2c 20 20 20 20 20  int *pnOut,     
67c0: 20 20 20 20 2f 2a 20 4f 75 74 70 75 74 20 2a 2f      /* Output */
67d0: 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 20  .  char **pzErr 
67e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
67f0: 20 20 20 2f 2a 20 4f 55 54 3a 20 45 72 72 6f 72     /* OUT: Error
6800: 20 6d 65 73 73 61 67 65 20 2a 2f 0a 29 7b 0a 20   message */.){. 
6810: 20 69 6e 74 20 6e 41 6c 6c 6f 63 20 3d 20 28 69   int nAlloc = (i
6820: 6e 74 29 63 6f 6d 70 72 65 73 73 42 6f 75 6e 64  nt)compressBound
6830: 28 6e 49 6e 29 3b 0a 20 20 75 38 20 2a 61 4f 75  (nIn);.  u8 *aOu
6840: 74 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  t;.  int rc = SQ
6850: 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 61 4f 75 74  LITE_OK;..  aOut
6860: 20 3d 20 28 75 38 2a 29 73 71 6c 69 74 65 33 5f   = (u8*)sqlite3_
6870: 6d 61 6c 6c 6f 63 28 6e 41 6c 6c 6f 63 29 3b 0a  malloc(nAlloc);.
6880: 20 20 69 66 28 20 61 4f 75 74 3d 3d 30 20 29 7b    if( aOut==0 ){
6890: 0a 20 20 20 20 72 63 20 3d 20 53 51 4c 49 54 45  .    rc = SQLITE
68a0: 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b  _NOMEM;.  }else{
68b0: 0a 20 20 20 20 69 6e 74 20 72 65 73 3b 0a 20 20  .    int res;.  
68c0: 20 20 7a 5f 73 74 72 65 61 6d 20 73 74 72 3b 0a    z_stream str;.
68d0: 20 20 20 20 6d 65 6d 73 65 74 28 26 73 74 72 2c      memset(&str,
68e0: 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72 29 29   0, sizeof(str))
68f0: 3b 0a 20 20 20 20 73 74 72 2e 6e 65 78 74 5f 69  ;.    str.next_i
6900: 6e 20 3d 20 28 42 79 74 65 66 2a 29 61 49 6e 3b  n = (Bytef*)aIn;
6910: 0a 20 20 20 20 73 74 72 2e 61 76 61 69 6c 5f 69  .    str.avail_i
6920: 6e 20 3d 20 6e 49 6e 3b 0a 20 20 20 20 73 74 72  n = nIn;.    str
6930: 2e 6e 65 78 74 5f 6f 75 74 20 3d 20 61 4f 75 74  .next_out = aOut
6940: 3b 0a 20 20 20 20 73 74 72 2e 61 76 61 69 6c 5f  ;.    str.avail_
6950: 6f 75 74 20 3d 20 6e 41 6c 6c 6f 63 3b 0a 0a 20  out = nAlloc;.. 
6960: 20 20 20 64 65 66 6c 61 74 65 49 6e 69 74 32 28     deflateInit2(
6970: 26 73 74 72 2c 20 39 2c 20 5a 5f 44 45 46 4c 41  &str, 9, Z_DEFLA
6980: 54 45 44 2c 20 2d 31 35 2c 20 38 2c 20 5a 5f 44  TED, -15, 8, Z_D
6990: 45 46 41 55 4c 54 5f 53 54 52 41 54 45 47 59 29  EFAULT_STRATEGY)
69a0: 3b 0a 20 20 20 20 72 65 73 20 3d 20 64 65 66 6c  ;.    res = defl
69b0: 61 74 65 28 26 73 74 72 2c 20 5a 5f 46 49 4e 49  ate(&str, Z_FINI
69c0: 53 48 29 3b 0a 0a 20 20 20 20 69 66 28 20 72 65  SH);..    if( re
69d0: 73 3d 3d 5a 5f 53 54 52 45 41 4d 5f 45 4e 44 20  s==Z_STREAM_END 
69e0: 29 7b 0a 20 20 20 20 20 20 2a 70 70 4f 75 74 20  ){.      *ppOut 
69f0: 3d 20 61 4f 75 74 3b 0a 20 20 20 20 20 20 2a 70  = aOut;.      *p
6a00: 6e 4f 75 74 20 3d 20 28 69 6e 74 29 73 74 72 2e  nOut = (int)str.
6a10: 74 6f 74 61 6c 5f 6f 75 74 3b 0a 20 20 20 20 7d  total_out;.    }
6a20: 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69  else{.      sqli
6a30: 74 65 33 5f 66 72 65 65 28 61 4f 75 74 29 3b 0a  te3_free(aOut);.
6a40: 20 20 20 20 20 20 2a 70 7a 45 72 72 20 3d 20 73        *pzErr = s
6a50: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
6a60: 7a 69 70 66 69 6c 65 3a 20 64 65 66 6c 61 74 65  zipfile: deflate
6a70: 28 29 20 65 72 72 6f 72 22 29 3b 0a 20 20 20 20  () error");.    
6a80: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52    rc = SQLITE_ER
6a90: 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64  ROR;.    }.    d
6aa0: 65 66 6c 61 74 65 45 6e 64 28 26 73 74 72 29 3b  eflateEnd(&str);
6ab0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
6ac0: 63 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  c;.}.../*.** Ret
6ad0: 75 72 6e 20 76 61 6c 75 65 73 20 6f 66 20 63 6f  urn values of co
6ae0: 6c 75 6d 6e 73 20 66 6f 72 20 74 68 65 20 72 6f  lumns for the ro
6af0: 77 20 61 74 20 77 68 69 63 68 20 74 68 65 20 73  w at which the s
6b00: 65 72 69 65 73 5f 63 75 72 73 6f 72 0a 2a 2a 20  eries_cursor.** 
6b10: 69 73 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69  is currently poi
6b20: 6e 74 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  nting..*/.static
6b30: 20 69 6e 74 20 7a 69 70 66 69 6c 65 43 6f 6c 75   int zipfileColu
6b40: 6d 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  mn(.  sqlite3_vt
6b50: 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c 20  ab_cursor *cur, 
6b60: 20 20 2f 2a 20 54 68 65 20 63 75 72 73 6f 72 20    /* The cursor 
6b70: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e  */.  sqlite3_con
6b80: 74 65 78 74 20 2a 63 74 78 2c 20 20 20 20 20 20  text *ctx,      
6b90: 20 2f 2a 20 46 69 72 73 74 20 61 72 67 75 6d 65   /* First argume
6ba0: 6e 74 20 74 6f 20 73 71 6c 69 74 65 33 5f 72 65  nt to sqlite3_re
6bb0: 73 75 6c 74 5f 2e 2e 2e 28 29 20 2a 2f 0a 20 20  sult_...() */.  
6bc0: 69 6e 74 20 69 20 20 20 20 20 20 20 20 20 20 20  int i           
6bd0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
6be0: 68 69 63 68 20 63 6f 6c 75 6d 6e 20 74 6f 20 72  hich column to r
6bf0: 65 74 75 72 6e 20 2a 2f 0a 29 7b 0a 20 20 5a 69  eturn */.){.  Zi
6c00: 70 66 69 6c 65 43 73 72 20 2a 70 43 73 72 20 3d  pfileCsr *pCsr =
6c10: 20 28 5a 69 70 66 69 6c 65 43 73 72 2a 29 63 75   (ZipfileCsr*)cu
6c20: 72 3b 0a 20 20 5a 69 70 66 69 6c 65 43 44 53 20  r;.  ZipfileCDS 
6c30: 2a 70 43 44 53 20 3d 20 26 70 43 73 72 2d 3e 70  *pCDS = &pCsr->p
6c40: 43 75 72 72 65 6e 74 2d 3e 63 64 73 3b 0a 20 20  Current->cds;.  
6c50: 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  int rc = SQLITE_
6c60: 4f 4b 3b 0a 20 20 73 77 69 74 63 68 28 20 69 20  OK;.  switch( i 
6c70: 29 7b 0a 20 20 20 20 63 61 73 65 20 30 3a 20 20  ){.    case 0:  
6c80: 20 2f 2a 20 6e 61 6d 65 20 2a 2f 0a 20 20 20 20   /* name */.    
6c90: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
6ca0: 5f 74 65 78 74 28 63 74 78 2c 20 70 43 44 53 2d  _text(ctx, pCDS-
6cb0: 3e 7a 46 69 6c 65 2c 20 2d 31 2c 20 53 51 4c 49  >zFile, -1, SQLI
6cc0: 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20  TE_TRANSIENT);. 
6cd0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
6ce0: 63 61 73 65 20 31 3a 20 20 20 2f 2a 20 6d 6f 64  case 1:   /* mod
6cf0: 65 20 2a 2f 0a 20 20 20 20 20 20 2f 2a 20 54 4f  e */.      /* TO
6d00: 44 4f 3a 20 57 68 65 74 68 65 72 20 6f 72 20 6e  DO: Whether or n
6d10: 6f 74 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67  ot the following
6d20: 20 69 73 20 63 6f 72 72 65 63 74 20 73 75 72 65   is correct sure
6d30: 6c 79 20 64 65 70 65 6e 64 73 20 6f 6e 0a 20 20  ly depends on.  
6d40: 20 20 20 20 2a 2a 20 74 68 65 20 70 6c 61 74 66      ** the platf
6d50: 6f 72 6d 20 6f 6e 20 77 68 69 63 68 20 74 68 65  orm on which the
6d60: 20 61 72 63 68 69 76 65 20 77 61 73 20 63 72 65   archive was cre
6d70: 61 74 65 64 2e 20 20 2a 2f 0a 20 20 20 20 20 20  ated.  */.      
6d80: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 69  sqlite3_result_i
6d90: 6e 74 28 63 74 78 2c 20 70 43 44 53 2d 3e 69 45  nt(ctx, pCDS->iE
6da0: 78 74 65 72 6e 61 6c 41 74 74 72 20 3e 3e 20 31  xternalAttr >> 1
6db0: 36 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b  6);.      break;
6dc0: 0a 20 20 20 20 63 61 73 65 20 32 3a 20 7b 20 2f  .    case 2: { /
6dd0: 2a 20 6d 74 69 6d 65 20 2a 2f 0a 20 20 20 20 20  * mtime */.     
6de0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
6df0: 69 6e 74 36 34 28 63 74 78 2c 20 70 43 73 72 2d  int64(ctx, pCsr-
6e00: 3e 70 43 75 72 72 65 6e 74 2d 3e 6d 55 6e 69 78  >pCurrent->mUnix
6e10: 54 69 6d 65 29 3b 0a 20 20 20 20 20 20 62 72 65  Time);.      bre
6e20: 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 61  ak;.    }.    ca
6e30: 73 65 20 33 3a 20 7b 20 2f 2a 20 73 7a 20 2a 2f  se 3: { /* sz */
6e40: 0a 20 20 20 20 20 20 69 66 28 20 73 71 6c 69 74  .      if( sqlit
6e50: 65 33 5f 76 74 61 62 5f 6e 6f 63 68 61 6e 67 65  e3_vtab_nochange
6e60: 28 63 74 78 29 3d 3d 30 20 29 7b 0a 20 20 20 20  (ctx)==0 ){.    
6e70: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
6e80: 6c 74 5f 69 6e 74 36 34 28 63 74 78 2c 20 70 43  lt_int64(ctx, pC
6e90: 44 53 2d 3e 73 7a 55 6e 63 6f 6d 70 72 65 73 73  DS->szUncompress
6ea0: 65 64 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ed);.      }.   
6eb0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
6ec0: 20 20 20 20 63 61 73 65 20 34 3a 20 20 20 2f 2a      case 4:   /*
6ed0: 20 72 61 77 64 61 74 61 20 2a 2f 0a 20 20 20 20   rawdata */.    
6ee0: 20 20 69 66 28 20 73 71 6c 69 74 65 33 5f 76 74    if( sqlite3_vt
6ef0: 61 62 5f 6e 6f 63 68 61 6e 67 65 28 63 74 78 29  ab_nochange(ctx)
6f00: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 63 61   ) break;.    ca
6f10: 73 65 20 35 3a 20 7b 20 2f 2a 20 64 61 74 61 20  se 5: { /* data 
6f20: 2a 2f 0a 20 20 20 20 20 20 69 66 28 20 69 3d 3d  */.      if( i==
6f30: 34 20 7c 7c 20 70 43 44 53 2d 3e 69 43 6f 6d 70  4 || pCDS->iComp
6f40: 72 65 73 73 69 6f 6e 3d 3d 30 20 7c 7c 20 70 43  ression==0 || pC
6f50: 44 53 2d 3e 69 43 6f 6d 70 72 65 73 73 69 6f 6e  DS->iCompression
6f60: 3d 3d 38 20 29 7b 0a 20 20 20 20 20 20 20 20 69  ==8 ){.        i
6f70: 6e 74 20 73 7a 20 3d 20 70 43 44 53 2d 3e 73 7a  nt sz = pCDS->sz
6f80: 43 6f 6d 70 72 65 73 73 65 64 3b 0a 20 20 20 20  Compressed;.    
6f90: 20 20 20 20 69 6e 74 20 73 7a 46 69 6e 61 6c 20      int szFinal 
6fa0: 3d 20 70 43 44 53 2d 3e 73 7a 55 6e 63 6f 6d 70  = pCDS->szUncomp
6fb0: 72 65 73 73 65 64 3b 0a 20 20 20 20 20 20 20 20  ressed;.        
6fc0: 69 66 28 20 73 7a 46 69 6e 61 6c 3e 30 20 29 7b  if( szFinal>0 ){
6fd0: 0a 20 20 20 20 20 20 20 20 20 20 75 38 20 2a 61  .          u8 *a
6fe0: 42 75 66 3b 0a 20 20 20 20 20 20 20 20 20 20 75  Buf;.          u
6ff0: 38 20 2a 61 46 72 65 65 20 3d 20 30 3b 0a 20 20  8 *aFree = 0;.  
7000: 20 20 20 20 20 20 20 20 69 66 28 20 70 43 73 72          if( pCsr
7010: 2d 3e 70 43 75 72 72 65 6e 74 2d 3e 61 44 61 74  ->pCurrent->aDat
7020: 61 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  a ){.           
7030: 20 61 42 75 66 20 3d 20 70 43 73 72 2d 3e 70 43   aBuf = pCsr->pC
7040: 75 72 72 65 6e 74 2d 3e 61 44 61 74 61 3b 0a 20  urrent->aData;. 
7050: 20 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a           }else{.
7060: 20 20 20 20 20 20 20 20 20 20 20 20 61 42 75 66              aBuf
7070: 20 3d 20 61 46 72 65 65 20 3d 20 73 71 6c 69 74   = aFree = sqlit
7080: 65 33 5f 6d 61 6c 6c 6f 63 28 73 7a 29 3b 0a 20  e3_malloc(sz);. 
7090: 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20 61             if( a
70a0: 42 75 66 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  Buf==0 ){.      
70b0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
70c0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
70d0: 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20         }else{.  
70e0: 20 20 20 20 20 20 20 20 20 20 20 20 46 49 4c 45              FILE
70f0: 20 2a 70 46 69 6c 65 20 3d 20 70 43 73 72 2d 3e   *pFile = pCsr->
7100: 70 46 69 6c 65 3b 0a 20 20 20 20 20 20 20 20 20  pFile;.         
7110: 20 20 20 20 20 69 66 28 20 70 46 69 6c 65 3d 3d       if( pFile==
7120: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  0 ){.           
7130: 20 20 20 20 20 70 46 69 6c 65 20 3d 20 28 28 5a       pFile = ((Z
7140: 69 70 66 69 6c 65 54 61 62 2a 29 28 70 43 73 72  ipfileTab*)(pCsr
7150: 2d 3e 62 61 73 65 2e 70 56 74 61 62 29 29 2d 3e  ->base.pVtab))->
7160: 70 57 72 69 74 65 46 64 3b 0a 20 20 20 20 20 20  pWriteFd;.      
7170: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
7180: 20 20 20 20 20 20 20 20 72 63 20 3d 20 7a 69 70          rc = zip
7190: 66 69 6c 65 52 65 61 64 44 61 74 61 28 70 46 69  fileReadData(pFi
71a0: 6c 65 2c 20 61 42 75 66 2c 20 73 7a 2c 20 70 43  le, aBuf, sz, pC
71b0: 73 72 2d 3e 70 43 75 72 72 65 6e 74 2d 3e 69 44  sr->pCurrent->iD
71c0: 61 74 61 4f 66 66 2c 0a 20 20 20 20 20 20 20 20  ataOff,.        
71d0: 20 20 20 20 20 20 20 20 20 20 26 70 43 73 72 2d            &pCsr-
71e0: 3e 62 61 73 65 2e 70 56 74 61 62 2d 3e 7a 45 72  >base.pVtab->zEr
71f0: 72 4d 73 67 0a 20 20 20 20 20 20 20 20 20 20 20  rMsg.           
7200: 20 20 20 29 3b 0a 20 20 20 20 20 20 20 20 20 20     );.          
7210: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 7d 0a    }.          }.
7220: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72 63            if( rc
7230: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
7240: 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20 69             if( i
7250: 3d 3d 35 20 26 26 20 70 43 44 53 2d 3e 69 43 6f  ==5 && pCDS->iCo
7260: 6d 70 72 65 73 73 69 6f 6e 20 29 7b 0a 20 20 20  mpression ){.   
7270: 20 20 20 20 20 20 20 20 20 20 20 7a 69 70 66 69             zipfi
7280: 6c 65 49 6e 66 6c 61 74 65 28 63 74 78 2c 20 61  leInflate(ctx, a
7290: 42 75 66 2c 20 73 7a 2c 20 73 7a 46 69 6e 61 6c  Buf, sz, szFinal
72a0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d  );.            }
72b0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
72c0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
72d0: 6c 74 5f 62 6c 6f 62 28 63 74 78 2c 20 61 42 75  lt_blob(ctx, aBu
72e0: 66 2c 20 73 7a 2c 20 53 51 4c 49 54 45 5f 54 52  f, sz, SQLITE_TR
72f0: 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20 20 20 20  ANSIENT);.      
7300: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
7310: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 73 71    }.          sq
7320: 6c 69 74 65 33 5f 66 72 65 65 28 61 46 72 65 65  lite3_free(aFree
7330: 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  );.        }else
7340: 7b 0a 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46  {.          /* F
7350: 69 67 75 72 65 20 6f 75 74 20 69 66 20 74 68 69  igure out if thi
7360: 73 20 69 73 20 61 20 64 69 72 65 63 74 6f 72 79  s is a directory
7370: 20 6f 72 20 61 20 7a 65 72 6f 2d 73 69 7a 65 64   or a zero-sized
7380: 20 66 69 6c 65 2e 20 43 6f 6e 73 69 64 65 72 0a   file. Consider.
7390: 20 20 20 20 20 20 20 20 20 20 2a 2a 20 69 74 20            ** it 
73a0: 74 6f 20 62 65 20 61 20 64 69 72 65 63 74 6f 72  to be a director
73b0: 79 20 65 69 74 68 65 72 20 69 66 20 74 68 65 20  y either if the 
73c0: 6d 6f 64 65 20 73 75 67 67 65 73 74 73 20 73 6f  mode suggests so
73d0: 2c 20 6f 72 20 69 66 0a 20 20 20 20 20 20 20 20  , or if.        
73e0: 20 20 2a 2a 20 74 68 65 20 66 69 6e 61 6c 20 63    ** the final c
73f0: 68 61 72 61 63 74 65 72 20 69 6e 20 74 68 65 20  haracter in the 
7400: 6e 61 6d 65 20 69 73 20 27 2f 27 2e 20 20 2a 2f  name is '/'.  */
7410: 0a 20 20 20 20 20 20 20 20 20 20 75 33 32 20 6d  .          u32 m
7420: 6f 64 65 20 3d 20 70 43 44 53 2d 3e 69 45 78 74  ode = pCDS->iExt
7430: 65 72 6e 61 6c 41 74 74 72 20 3e 3e 20 31 36 3b  ernalAttr >> 16;
7440: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 21  .          if( !
7450: 28 6d 6f 64 65 20 26 20 53 5f 49 46 44 49 52 29  (mode & S_IFDIR)
7460: 20 26 26 20 70 43 44 53 2d 3e 7a 46 69 6c 65 5b   && pCDS->zFile[
7470: 70 43 44 53 2d 3e 6e 46 69 6c 65 2d 31 5d 21 3d  pCDS->nFile-1]!=
7480: 27 2f 27 20 29 7b 0a 20 20 20 20 20 20 20 20 20  '/' ){.         
7490: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
74a0: 74 5f 62 6c 6f 62 28 63 74 78 2c 20 22 22 2c 20  t_blob(ctx, "", 
74b0: 30 2c 20 53 51 4c 49 54 45 5f 53 54 41 54 49 43  0, SQLITE_STATIC
74c0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  );.          }. 
74d0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
74e0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
74f0: 20 20 7d 0a 20 20 20 20 63 61 73 65 20 36 3a 20    }.    case 6: 
7500: 20 20 2f 2a 20 6d 65 74 68 6f 64 20 2a 2f 0a 20    /* method */. 
7510: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73       sqlite3_res
7520: 75 6c 74 5f 69 6e 74 28 63 74 78 2c 20 70 43 44  ult_int(ctx, pCD
7530: 53 2d 3e 69 43 6f 6d 70 72 65 73 73 69 6f 6e 29  S->iCompression)
7540: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
7550: 20 20 20 63 61 73 65 20 37 3a 20 20 20 2f 2a 20     case 7:   /* 
7560: 7a 20 2a 2f 0a 20 20 20 20 20 20 73 71 6c 69 74  z */.      sqlit
7570: 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74 36 34 28  e3_result_int64(
7580: 63 74 78 2c 20 70 43 73 72 2d 3e 69 49 64 29 3b  ctx, pCsr->iId);
7590: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
75a0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  }..  return rc;.
75b0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
75c0: 54 52 55 45 20 69 66 20 74 68 65 20 63 75 72 73  TRUE if the curs
75d0: 6f 72 20 69 73 20 61 74 20 45 4f 46 2e 0a 2a 2f  or is at EOF..*/
75e0: 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70 66  .static int zipf
75f0: 69 6c 65 45 6f 66 28 73 71 6c 69 74 65 33 5f 76  ileEof(sqlite3_v
7600: 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 29  tab_cursor *cur)
7610: 7b 0a 20 20 5a 69 70 66 69 6c 65 43 73 72 20 2a  {.  ZipfileCsr *
7620: 70 43 73 72 20 3d 20 28 5a 69 70 66 69 6c 65 43  pCsr = (ZipfileC
7630: 73 72 2a 29 63 75 72 3b 0a 20 20 72 65 74 75 72  sr*)cur;.  retur
7640: 6e 20 70 43 73 72 2d 3e 62 45 6f 66 3b 0a 7d 0a  n pCsr->bEof;.}.
7650: 0a 2f 2a 0a 2a 2a 20 49 66 20 61 42 6c 6f 62 20  ./*.** If aBlob 
7660: 69 73 20 6e 6f 74 20 4e 55 4c 4c 2c 20 74 68 65  is not NULL, the
7670: 6e 20 69 74 20 70 6f 69 6e 74 73 20 74 6f 20 61  n it points to a
7680: 20 62 75 66 66 65 72 20 6e 42 6c 6f 62 20 62 79   buffer nBlob by
7690: 74 65 73 20 69 6e 20 73 69 7a 65 0a 2a 2a 20 63  tes in size.** c
76a0: 6f 6e 74 61 69 6e 69 6e 67 20 61 6e 20 65 6e 74  ontaining an ent
76b0: 69 72 65 20 7a 69 70 20 61 72 63 68 69 76 65 20  ire zip archive 
76c0: 69 6d 61 67 65 2e 20 4f 72 2c 20 69 66 20 61 42  image. Or, if aB
76d0: 6c 6f 62 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65  lob is NULL, the
76e0: 6e 20 70 46 69 6c 65 0a 2a 2a 20 69 73 20 67 75  n pFile.** is gu
76f0: 61 72 61 6e 74 65 65 64 20 74 6f 20 62 65 20 61  aranteed to be a
7700: 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 6f 70 65   file-handle ope
7710: 6e 20 6f 6e 20 61 20 7a 69 70 20 66 69 6c 65 2e  n on a zip file.
7720: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  .**.** This func
7730: 74 69 6f 6e 20 61 74 74 65 6d 70 74 73 20 74 6f  tion attempts to
7740: 20 6c 6f 63 61 74 65 20 74 68 65 20 45 4f 43 44   locate the EOCD
7750: 20 72 65 63 6f 72 64 20 77 69 74 68 69 6e 20 74   record within t
7760: 68 65 20 7a 69 70 20 61 72 63 68 69 76 65 0a 2a  he zip archive.*
7770: 2a 20 61 6e 64 20 70 6f 70 75 6c 61 74 65 20 2a  * and populate *
7780: 70 45 4f 43 44 20 77 69 74 68 20 74 68 65 20 72  pEOCD with the r
7790: 65 73 75 6c 74 73 20 6f 66 20 64 65 63 6f 64 69  esults of decodi
77a0: 6e 67 20 69 74 2e 20 53 51 4c 49 54 45 5f 4f 4b  ng it. SQLITE_OK
77b0: 20 69 73 0a 2a 2a 20 72 65 74 75 72 6e 65 64 20   is.** returned 
77c0: 69 66 20 73 75 63 63 65 73 73 66 75 6c 2e 20 4f  if successful. O
77d0: 74 68 65 72 77 69 73 65 2c 20 61 6e 20 53 51 4c  therwise, an SQL
77e0: 69 74 65 20 65 72 72 6f 72 20 63 6f 64 65 20 69  ite error code i
77f0: 73 20 72 65 74 75 72 6e 65 64 20 61 6e 64 0a 2a  s returned and.*
7800: 2a 20 61 6e 20 45 6e 67 6c 69 73 68 20 6c 61 6e  * an English lan
7810: 67 75 61 67 65 20 65 72 72 6f 72 20 6d 65 73 73  guage error mess
7820: 61 67 65 20 6d 61 79 20 62 65 20 6c 65 66 74 20  age may be left 
7830: 69 6e 20 76 69 72 74 75 61 6c 2d 74 61 62 6c 65  in virtual-table
7840: 20 70 54 61 62 2e 0a 2a 2f 0a 73 74 61 74 69 63   pTab..*/.static
7850: 20 69 6e 74 20 7a 69 70 66 69 6c 65 52 65 61 64   int zipfileRead
7860: 45 4f 43 44 28 0a 20 20 5a 69 70 66 69 6c 65 54  EOCD(.  ZipfileT
7870: 61 62 20 2a 70 54 61 62 2c 20 20 20 20 20 20 20  ab *pTab,       
7880: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 74 75 72          /* Retur
7890: 6e 20 65 72 72 6f 72 73 20 68 65 72 65 20 2a 2f  n errors here */
78a0: 0a 20 20 63 6f 6e 73 74 20 75 38 20 2a 61 42 6c  .  const u8 *aBl
78b0: 6f 62 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ob,             
78c0: 20 20 20 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f     /* Pointer to
78d0: 20 69 6e 2d 6d 65 6d 6f 72 79 20 66 69 6c 65 20   in-memory file 
78e0: 69 6d 61 67 65 20 2a 2f 0a 20 20 69 6e 74 20 6e  image */.  int n
78f0: 42 6c 6f 62 2c 20 20 20 20 20 20 20 20 20 20 20  Blob,           
7900: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
7910: 7a 65 20 6f 66 20 61 42 6c 6f 62 5b 5d 20 69 6e  ze of aBlob[] in
7920: 20 62 79 74 65 73 20 2a 2f 0a 20 20 46 49 4c 45   bytes */.  FILE
7930: 20 2a 70 46 69 6c 65 2c 20 20 20 20 20 20 20 20   *pFile,        
7940: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
7950: 65 61 64 20 66 72 6f 6d 20 74 68 69 73 20 66 69  ead from this fi
7960: 6c 65 20 69 66 20 61 42 6c 6f 62 3d 3d 30 20 2a  le if aBlob==0 *
7970: 2f 0a 20 20 5a 69 70 66 69 6c 65 45 4f 43 44 20  /.  ZipfileEOCD 
7980: 2a 70 45 4f 43 44 20 20 20 20 20 20 20 20 20 20  *pEOCD          
7990: 20 20 20 20 2f 2a 20 4f 62 6a 65 63 74 20 74 6f      /* Object to
79a0: 20 70 6f 70 75 6c 61 74 65 20 2a 2f 0a 29 7b 0a   populate */.){.
79b0: 20 20 75 38 20 2a 61 52 65 61 64 20 3d 20 70 54    u8 *aRead = pT
79c0: 61 62 2d 3e 61 42 75 66 66 65 72 3b 20 20 20 20  ab->aBuffer;    
79d0: 20 20 2f 2a 20 54 65 6d 70 6f 72 61 72 79 20 62    /* Temporary b
79e0: 75 66 66 65 72 20 2a 2f 0a 20 20 69 6e 74 20 6e  uffer */.  int n
79f0: 52 65 61 64 3b 20 20 20 20 20 20 20 20 20 20 20  Read;           
7a00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 79             /* By
7a10: 74 65 73 20 74 6f 20 72 65 61 64 20 66 72 6f 6d  tes to read from
7a20: 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 72   file */.  int r
7a30: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a  c = SQLITE_OK;..
7a40: 20 20 69 66 28 20 61 42 6c 6f 62 3d 3d 30 20 29    if( aBlob==0 )
7a50: 7b 0a 20 20 20 20 69 36 34 20 69 4f 66 66 3b 20  {.    i64 iOff; 
7a60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7a70: 20 20 20 20 2f 2a 20 4f 66 66 73 65 74 20 74 6f      /* Offset to
7a80: 20 72 65 61 64 20 66 72 6f 6d 20 2a 2f 0a 20 20   read from */.  
7a90: 20 20 69 36 34 20 73 7a 46 69 6c 65 3b 20 20 20    i64 szFile;   
7aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7ab0: 2f 2a 20 54 6f 74 61 6c 20 73 69 7a 65 20 6f 66  /* Total size of
7ac0: 20 66 69 6c 65 20 69 6e 20 62 79 74 65 73 20 2a   file in bytes *
7ad0: 2f 0a 20 20 20 20 66 73 65 65 6b 28 70 46 69 6c  /.    fseek(pFil
7ae0: 65 2c 20 30 2c 20 53 45 45 4b 5f 45 4e 44 29 3b  e, 0, SEEK_END);
7af0: 0a 20 20 20 20 73 7a 46 69 6c 65 20 3d 20 28 69  .    szFile = (i
7b00: 36 34 29 66 74 65 6c 6c 28 70 46 69 6c 65 29 3b  64)ftell(pFile);
7b10: 0a 20 20 20 20 69 66 28 20 73 7a 46 69 6c 65 3d  .    if( szFile=
7b20: 3d 30 20 29 7b 0a 20 20 20 20 20 20 6d 65 6d 73  =0 ){.      mems
7b30: 65 74 28 70 45 4f 43 44 2c 20 30 2c 20 73 69 7a  et(pEOCD, 0, siz
7b40: 65 6f 66 28 5a 69 70 66 69 6c 65 45 4f 43 44 29  eof(ZipfileEOCD)
7b50: 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20  );.      return 
7b60: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d  SQLITE_OK;.    }
7b70: 0a 20 20 20 20 6e 52 65 61 64 20 3d 20 28 69 6e  .    nRead = (in
7b80: 74 29 28 4d 49 4e 28 73 7a 46 69 6c 65 2c 20 5a  t)(MIN(szFile, Z
7b90: 49 50 46 49 4c 45 5f 42 55 46 46 45 52 5f 53 49  IPFILE_BUFFER_SI
7ba0: 5a 45 29 29 3b 0a 20 20 20 20 69 4f 66 66 20 3d  ZE));.    iOff =
7bb0: 20 73 7a 46 69 6c 65 20 2d 20 6e 52 65 61 64 3b   szFile - nRead;
7bc0: 0a 20 20 20 20 72 63 20 3d 20 7a 69 70 66 69 6c  .    rc = zipfil
7bd0: 65 52 65 61 64 44 61 74 61 28 70 46 69 6c 65 2c  eReadData(pFile,
7be0: 20 61 52 65 61 64 2c 20 6e 52 65 61 64 2c 20 69   aRead, nRead, i
7bf0: 4f 66 66 2c 20 26 70 54 61 62 2d 3e 62 61 73 65  Off, &pTab->base
7c00: 2e 7a 45 72 72 4d 73 67 29 3b 0a 20 20 7d 65 6c  .zErrMsg);.  }el
7c10: 73 65 7b 0a 20 20 20 20 6e 52 65 61 64 20 3d 20  se{.    nRead = 
7c20: 28 69 6e 74 29 28 4d 49 4e 28 6e 42 6c 6f 62 2c  (int)(MIN(nBlob,
7c30: 20 5a 49 50 46 49 4c 45 5f 42 55 46 46 45 52 5f   ZIPFILE_BUFFER_
7c40: 53 49 5a 45 29 29 3b 0a 20 20 20 20 61 52 65 61  SIZE));.    aRea
7c50: 64 20 3d 20 28 75 38 2a 29 26 61 42 6c 6f 62 5b  d = (u8*)&aBlob[
7c60: 6e 42 6c 6f 62 2d 6e 52 65 61 64 5d 3b 0a 20 20  nBlob-nRead];.  
7c70: 7d 0a 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  }..  if( rc==SQL
7c80: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 69 6e  ITE_OK ){.    in
7c90: 74 20 69 3b 0a 0a 20 20 20 20 2f 2a 20 53 63 61  t i;..    /* Sca
7ca0: 6e 20 62 61 63 6b 77 61 72 64 73 20 6c 6f 6f 6b  n backwards look
7cb0: 69 6e 67 20 66 6f 72 20 74 68 65 20 73 69 67 6e  ing for the sign
7cc0: 61 74 75 72 65 20 62 79 74 65 73 20 2a 2f 0a 20  ature bytes */. 
7cd0: 20 20 20 66 6f 72 28 69 3d 6e 52 65 61 64 2d 32     for(i=nRead-2
7ce0: 30 3b 20 69 3e 3d 30 3b 20 69 2d 2d 29 7b 0a 20  0; i>=0; i--){. 
7cf0: 20 20 20 20 20 69 66 28 20 61 52 65 61 64 5b 69       if( aRead[i
7d00: 5d 3d 3d 30 78 35 30 20 26 26 20 61 52 65 61 64  ]==0x50 && aRead
7d10: 5b 69 2b 31 5d 3d 3d 30 78 34 62 20 0a 20 20 20  [i+1]==0x4b .   
7d20: 20 20 20 20 26 26 20 61 52 65 61 64 5b 69 2b 32      && aRead[i+2
7d30: 5d 3d 3d 30 78 30 35 20 26 26 20 61 52 65 61 64  ]==0x05 && aRead
7d40: 5b 69 2b 33 5d 3d 3d 30 78 30 36 20 0a 20 20 20  [i+3]==0x06 .   
7d50: 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 62 72     ){.        br
7d60: 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  eak;.      }.   
7d70: 20 7d 0a 20 20 20 20 69 66 28 20 69 3c 30 20 29   }.    if( i<0 )
7d80: 7b 0a 20 20 20 20 20 20 70 54 61 62 2d 3e 62 61  {.      pTab->ba
7d90: 73 65 2e 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c  se.zErrMsg = sql
7da0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20  ite3_mprintf(.  
7db0: 20 20 20 20 20 20 20 20 22 63 61 6e 6e 6f 74 20          "cannot 
7dc0: 66 69 6e 64 20 65 6e 64 20 6f 66 20 63 65 6e 74  find end of cent
7dd0: 72 61 6c 20 64 69 72 65 63 74 6f 72 79 20 72 65  ral directory re
7de0: 63 6f 72 64 22 0a 20 20 20 20 20 20 29 3b 0a 20  cord".      );. 
7df0: 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
7e00: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a  TE_ERROR;.    }.
7e10: 0a 20 20 20 20 61 52 65 61 64 20 2b 3d 20 69 2b  .    aRead += i+
7e20: 34 3b 0a 20 20 20 20 70 45 4f 43 44 2d 3e 69 44  4;.    pEOCD->iD
7e30: 69 73 6b 20 3d 20 7a 69 70 66 69 6c 65 52 65 61  isk = zipfileRea
7e40: 64 31 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20  d16(aRead);.    
7e50: 70 45 4f 43 44 2d 3e 69 46 69 72 73 74 44 69 73  pEOCD->iFirstDis
7e60: 6b 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 31  k = zipfileRead1
7e70: 36 28 61 52 65 61 64 29 3b 0a 20 20 20 20 70 45  6(aRead);.    pE
7e80: 4f 43 44 2d 3e 6e 45 6e 74 72 79 20 3d 20 7a 69  OCD->nEntry = zi
7e90: 70 66 69 6c 65 52 65 61 64 31 36 28 61 52 65 61  pfileRead16(aRea
7ea0: 64 29 3b 0a 20 20 20 20 70 45 4f 43 44 2d 3e 6e  d);.    pEOCD->n
7eb0: 45 6e 74 72 79 54 6f 74 61 6c 20 3d 20 7a 69 70  EntryTotal = zip
7ec0: 66 69 6c 65 52 65 61 64 31 36 28 61 52 65 61 64  fileRead16(aRead
7ed0: 29 3b 0a 20 20 20 20 70 45 4f 43 44 2d 3e 6e 53  );.    pEOCD->nS
7ee0: 69 7a 65 20 3d 20 7a 69 70 66 69 6c 65 52 65 61  ize = zipfileRea
7ef0: 64 33 32 28 61 52 65 61 64 29 3b 0a 20 20 20 20  d32(aRead);.    
7f00: 70 45 4f 43 44 2d 3e 69 4f 66 66 73 65 74 20 3d  pEOCD->iOffset =
7f10: 20 7a 69 70 66 69 6c 65 52 65 61 64 33 32 28 61   zipfileRead32(a
7f20: 52 65 61 64 29 3b 0a 20 20 7d 0a 0a 20 20 72 65  Read);.  }..  re
7f30: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
7f40: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 6f 62 6a  }../*.** Add obj
7f50: 65 63 74 20 70 4e 65 77 20 74 6f 20 74 68 65 20  ect pNew to the 
7f60: 6c 69 6e 6b 65 64 20 6c 69 73 74 20 74 68 61 74  linked list that
7f70: 20 62 65 67 69 6e 73 20 61 74 20 5a 69 70 66 69   begins at Zipfi
7f80: 6c 65 54 61 62 2e 70 46 69 72 73 74 45 6e 74 72  leTab.pFirstEntr
7f90: 79 20 0a 2a 2a 20 61 6e 64 20 65 6e 64 73 20 77  y .** and ends w
7fa0: 69 74 68 20 70 4c 61 73 74 45 6e 74 72 79 2e 20  ith pLastEntry. 
7fb0: 49 66 20 61 72 67 75 6d 65 6e 74 20 70 42 65 66  If argument pBef
7fc0: 6f 72 65 20 69 73 20 4e 55 4c 4c 2c 20 74 68 65  ore is NULL, the
7fd0: 6e 20 70 4e 65 77 20 69 73 20 61 64 64 65 64 0a  n pNew is added.
7fe0: 2a 2a 20 74 6f 20 74 68 65 20 65 6e 64 20 6f 66  ** to the end of
7ff0: 20 74 68 65 20 6c 69 73 74 2e 20 4f 74 68 65 72   the list. Other
8000: 77 69 73 65 2c 20 69 74 20 69 73 20 61 64 64 65  wise, it is adde
8010: 64 20 74 6f 20 74 68 65 20 6c 69 73 74 20 69 6d  d to the list im
8020: 6d 65 64 69 61 74 65 6c 79 0a 2a 2a 20 62 65 66  mediately.** bef
8030: 6f 72 65 20 70 42 65 66 6f 72 65 20 28 77 68 69  ore pBefore (whi
8040: 63 68 20 69 73 20 67 75 61 72 61 6e 74 65 65 64  ch is guaranteed
8050: 20 74 6f 20 62 65 20 61 20 70 61 72 74 20 6f 66   to be a part of
8060: 20 73 61 69 64 20 6c 69 73 74 29 2e 0a 2a 2f 0a   said list)..*/.
8070: 73 74 61 74 69 63 20 76 6f 69 64 20 7a 69 70 66  static void zipf
8080: 69 6c 65 41 64 64 45 6e 74 72 79 28 0a 20 20 5a  ileAddEntry(.  Z
8090: 69 70 66 69 6c 65 54 61 62 20 2a 70 54 61 62 2c  ipfileTab *pTab,
80a0: 20 0a 20 20 5a 69 70 66 69 6c 65 45 6e 74 72 79   .  ZipfileEntry
80b0: 20 2a 70 42 65 66 6f 72 65 2c 20 0a 20 20 5a 69   *pBefore, .  Zi
80c0: 70 66 69 6c 65 45 6e 74 72 79 20 2a 70 4e 65 77  pfileEntry *pNew
80d0: 0a 29 7b 0a 20 20 61 73 73 65 72 74 28 20 28 70  .){.  assert( (p
80e0: 54 61 62 2d 3e 70 46 69 72 73 74 45 6e 74 72 79  Tab->pFirstEntry
80f0: 3d 3d 30 29 3d 3d 28 70 54 61 62 2d 3e 70 4c 61  ==0)==(pTab->pLa
8100: 73 74 45 6e 74 72 79 3d 3d 30 29 20 29 3b 0a 20  stEntry==0) );. 
8110: 20 61 73 73 65 72 74 28 20 70 4e 65 77 2d 3e 70   assert( pNew->p
8120: 4e 65 78 74 3d 3d 30 20 29 3b 0a 20 20 69 66 28  Next==0 );.  if(
8130: 20 70 42 65 66 6f 72 65 3d 3d 30 20 29 7b 0a 20   pBefore==0 ){. 
8140: 20 20 20 69 66 28 20 70 54 61 62 2d 3e 70 46 69     if( pTab->pFi
8150: 72 73 74 45 6e 74 72 79 3d 3d 30 20 29 7b 0a 20  rstEntry==0 ){. 
8160: 20 20 20 20 20 70 54 61 62 2d 3e 70 46 69 72 73       pTab->pFirs
8170: 74 45 6e 74 72 79 20 3d 20 70 54 61 62 2d 3e 70  tEntry = pTab->p
8180: 4c 61 73 74 45 6e 74 72 79 20 3d 20 70 4e 65 77  LastEntry = pNew
8190: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
81a0: 20 20 20 61 73 73 65 72 74 28 20 70 54 61 62 2d     assert( pTab-
81b0: 3e 70 4c 61 73 74 45 6e 74 72 79 2d 3e 70 4e 65  >pLastEntry->pNe
81c0: 78 74 3d 3d 30 20 29 3b 0a 20 20 20 20 20 20 70  xt==0 );.      p
81d0: 54 61 62 2d 3e 70 4c 61 73 74 45 6e 74 72 79 2d  Tab->pLastEntry-
81e0: 3e 70 4e 65 78 74 20 3d 20 70 4e 65 77 3b 0a 20  >pNext = pNew;. 
81f0: 20 20 20 20 20 70 54 61 62 2d 3e 70 4c 61 73 74       pTab->pLast
8200: 45 6e 74 72 79 20 3d 20 70 4e 65 77 3b 0a 20 20  Entry = pNew;.  
8210: 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20    }.  }else{.   
8220: 20 5a 69 70 66 69 6c 65 45 6e 74 72 79 20 2a 2a   ZipfileEntry **
8230: 70 70 3b 0a 20 20 20 20 66 6f 72 28 70 70 3d 26  pp;.    for(pp=&
8240: 70 54 61 62 2d 3e 70 46 69 72 73 74 45 6e 74 72  pTab->pFirstEntr
8250: 79 3b 20 2a 70 70 21 3d 70 42 65 66 6f 72 65 3b  y; *pp!=pBefore;
8260: 20 70 70 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65   pp=&((*pp)->pNe
8270: 78 74 29 29 3b 0a 20 20 20 20 70 4e 65 77 2d 3e  xt));.    pNew->
8280: 70 4e 65 78 74 20 3d 20 70 42 65 66 6f 72 65 3b  pNext = pBefore;
8290: 0a 20 20 20 20 2a 70 70 20 3d 20 70 4e 65 77 3b  .    *pp = pNew;
82a0: 0a 20 20 7d 0a 7d 0a 0a 73 74 61 74 69 63 20 69  .  }.}..static i
82b0: 6e 74 20 7a 69 70 66 69 6c 65 4c 6f 61 64 44 69  nt zipfileLoadDi
82c0: 72 65 63 74 6f 72 79 28 5a 69 70 66 69 6c 65 54  rectory(ZipfileT
82d0: 61 62 20 2a 70 54 61 62 2c 20 63 6f 6e 73 74 20  ab *pTab, const 
82e0: 75 38 20 2a 61 42 6c 6f 62 2c 20 69 6e 74 20 6e  u8 *aBlob, int n
82f0: 42 6c 6f 62 29 7b 0a 20 20 5a 69 70 66 69 6c 65  Blob){.  Zipfile
8300: 45 4f 43 44 20 65 6f 63 64 3b 0a 20 20 69 6e 74  EOCD eocd;.  int
8310: 20 72 63 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20   rc;.  int i;.  
8320: 69 36 34 20 69 4f 66 66 3b 0a 0a 20 20 72 63 20  i64 iOff;..  rc 
8330: 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 45 4f 43  = zipfileReadEOC
8340: 44 28 70 54 61 62 2c 20 61 42 6c 6f 62 2c 20 6e  D(pTab, aBlob, n
8350: 42 6c 6f 62 2c 20 70 54 61 62 2d 3e 70 57 72 69  Blob, pTab->pWri
8360: 74 65 46 64 2c 20 26 65 6f 63 64 29 3b 0a 20 20  teFd, &eocd);.  
8370: 69 4f 66 66 20 3d 20 65 6f 63 64 2e 69 4f 66 66  iOff = eocd.iOff
8380: 73 65 74 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  set;.  for(i=0; 
8390: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26  rc==SQLITE_OK &&
83a0: 20 69 3c 65 6f 63 64 2e 6e 45 6e 74 72 79 3b 20   i<eocd.nEntry; 
83b0: 69 2b 2b 29 7b 0a 20 20 20 20 5a 69 70 66 69 6c  i++){.    Zipfil
83c0: 65 45 6e 74 72 79 20 2a 70 4e 65 77 20 3d 20 30  eEntry *pNew = 0
83d0: 3b 0a 20 20 20 20 72 63 20 3d 20 7a 69 70 66 69  ;.    rc = zipfi
83e0: 6c 65 47 65 74 45 6e 74 72 79 28 70 54 61 62 2c  leGetEntry(pTab,
83f0: 20 61 42 6c 6f 62 2c 20 6e 42 6c 6f 62 2c 20 70   aBlob, nBlob, p
8400: 54 61 62 2d 3e 70 57 72 69 74 65 46 64 2c 20 69  Tab->pWriteFd, i
8410: 4f 66 66 2c 20 26 70 4e 65 77 29 3b 0a 0a 20 20  Off, &pNew);..  
8420: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
8430: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 7a 69 70  _OK ){.      zip
8440: 66 69 6c 65 41 64 64 45 6e 74 72 79 28 70 54 61  fileAddEntry(pTa
8450: 62 2c 20 30 2c 20 70 4e 65 77 29 3b 0a 20 20 20  b, 0, pNew);.   
8460: 20 20 20 69 4f 66 66 20 2b 3d 20 5a 49 50 46 49     iOff += ZIPFI
8470: 4c 45 5f 43 44 53 5f 46 49 58 45 44 5f 53 5a 3b  LE_CDS_FIXED_SZ;
8480: 0a 20 20 20 20 20 20 69 4f 66 66 20 2b 3d 20 28  .      iOff += (
8490: 69 6e 74 29 70 4e 65 77 2d 3e 63 64 73 2e 6e 45  int)pNew->cds.nE
84a0: 78 74 72 61 20 2b 20 70 4e 65 77 2d 3e 63 64 73  xtra + pNew->cds
84b0: 2e 6e 46 69 6c 65 20 2b 20 70 4e 65 77 2d 3e 63  .nFile + pNew->c
84c0: 64 73 2e 6e 43 6f 6d 6d 65 6e 74 3b 0a 20 20 20  ds.nComment;.   
84d0: 20 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20   }.  }.  return 
84e0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 46 69  rc;.}../*.** xFi
84f0: 6c 74 65 72 20 63 61 6c 6c 62 61 63 6b 2e 0a 2a  lter callback..*
8500: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70  /.static int zip
8510: 66 69 6c 65 46 69 6c 74 65 72 28 0a 20 20 73 71  fileFilter(.  sq
8520: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
8530: 72 20 2a 63 75 72 2c 20 0a 20 20 69 6e 74 20 69  r *cur, .  int i
8540: 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61  dxNum, const cha
8550: 72 20 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e 74  r *idxStr,.  int
8560: 20 61 72 67 63 2c 20 73 71 6c 69 74 65 33 5f 76   argc, sqlite3_v
8570: 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20  alue **argv.){. 
8580: 20 5a 69 70 66 69 6c 65 54 61 62 20 2a 70 54 61   ZipfileTab *pTa
8590: 62 20 3d 20 28 5a 69 70 66 69 6c 65 54 61 62 2a  b = (ZipfileTab*
85a0: 29 63 75 72 2d 3e 70 56 74 61 62 3b 0a 20 20 5a  )cur->pVtab;.  Z
85b0: 69 70 66 69 6c 65 43 73 72 20 2a 70 43 73 72 20  ipfileCsr *pCsr 
85c0: 3d 20 28 5a 69 70 66 69 6c 65 43 73 72 2a 29 63  = (ZipfileCsr*)c
85d0: 75 72 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  ur;.  const char
85e0: 20 2a 7a 46 69 6c 65 3b 20 20 20 20 20 20 20 20   *zFile;        
85f0: 20 20 20 20 20 20 2f 2a 20 5a 69 70 20 66 69 6c        /* Zip fil
8600: 65 20 74 6f 20 73 63 61 6e 20 2a 2f 0a 20 20 69  e to scan */.  i
8610: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
8620: 4b 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  K;             /
8630: 2a 20 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f  * Return Code */
8640: 0a 20 20 69 6e 74 20 62 49 6e 4d 65 6d 6f 72 79  .  int bInMemory
8650: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
8660: 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 61     /* True for a
8670: 6e 20 69 6e 2d 6d 65 6d 6f 72 79 20 7a 69 70 66  n in-memory zipf
8680: 69 6c 65 20 2a 2f 0a 0a 20 20 7a 69 70 66 69 6c  ile */..  zipfil
8690: 65 52 65 73 65 74 43 75 72 73 6f 72 28 70 43 73  eResetCursor(pCs
86a0: 72 29 3b 0a 0a 20 20 69 66 28 20 70 54 61 62 2d  r);..  if( pTab-
86b0: 3e 7a 46 69 6c 65 20 29 7b 0a 20 20 20 20 7a 46  >zFile ){.    zF
86c0: 69 6c 65 20 3d 20 70 54 61 62 2d 3e 7a 46 69 6c  ile = pTab->zFil
86d0: 65 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 69  e;.  }else if( i
86e0: 64 78 4e 75 6d 3d 3d 30 20 29 7b 0a 20 20 20 20  dxNum==0 ){.    
86f0: 62 49 6e 4d 65 6d 6f 72 79 20 3d 20 31 3b 0a 20  bInMemory = 1;. 
8700: 20 7d 65 6c 73 65 20 69 66 28 20 73 71 6c 69 74   }else if( sqlit
8710: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 72  e3_value_type(ar
8720: 67 76 5b 30 5d 29 3d 3d 53 51 4c 49 54 45 5f 42  gv[0])==SQLITE_B
8730: 4c 4f 42 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74  LOB ){.    const
8740: 20 75 38 20 2a 61 42 6c 6f 62 20 3d 20 28 63 6f   u8 *aBlob = (co
8750: 6e 73 74 20 75 38 2a 29 73 71 6c 69 74 65 33 5f  nst u8*)sqlite3_
8760: 76 61 6c 75 65 5f 62 6c 6f 62 28 61 72 67 76 5b  value_blob(argv[
8770: 30 5d 29 3b 0a 20 20 20 20 69 6e 74 20 6e 42 6c  0]);.    int nBl
8780: 6f 62 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c  ob = sqlite3_val
8790: 75 65 5f 62 79 74 65 73 28 61 72 67 76 5b 30 5d  ue_bytes(argv[0]
87a0: 29 3b 0a 20 20 20 20 61 73 73 65 72 74 28 20 70  );.    assert( p
87b0: 54 61 62 2d 3e 70 46 69 72 73 74 45 6e 74 72 79  Tab->pFirstEntry
87c0: 3d 3d 30 20 29 3b 0a 20 20 20 20 72 63 20 3d 20  ==0 );.    rc = 
87d0: 7a 69 70 66 69 6c 65 4c 6f 61 64 44 69 72 65 63  zipfileLoadDirec
87e0: 74 6f 72 79 28 70 54 61 62 2c 20 61 42 6c 6f 62  tory(pTab, aBlob
87f0: 2c 20 6e 42 6c 6f 62 29 3b 0a 20 20 20 20 70 43  , nBlob);.    pC
8800: 73 72 2d 3e 70 46 72 65 65 45 6e 74 72 79 20 3d  sr->pFreeEntry =
8810: 20 70 54 61 62 2d 3e 70 46 69 72 73 74 45 6e 74   pTab->pFirstEnt
8820: 72 79 3b 0a 20 20 20 20 70 54 61 62 2d 3e 70 46  ry;.    pTab->pF
8830: 69 72 73 74 45 6e 74 72 79 20 3d 20 70 54 61 62  irstEntry = pTab
8840: 2d 3e 70 4c 61 73 74 45 6e 74 72 79 20 3d 20 30  ->pLastEntry = 0
8850: 3b 0a 20 20 20 20 69 66 28 20 72 63 21 3d 53 51  ;.    if( rc!=SQ
8860: 4c 49 54 45 5f 4f 4b 20 29 20 72 65 74 75 72 6e  LITE_OK ) return
8870: 20 72 63 3b 0a 20 20 20 20 62 49 6e 4d 65 6d 6f   rc;.    bInMemo
8880: 72 79 20 3d 20 31 3b 0a 20 20 7d 65 6c 73 65 7b  ry = 1;.  }else{
8890: 0a 20 20 20 20 7a 46 69 6c 65 20 3d 20 28 63 6f  .    zFile = (co
88a0: 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65  nst char*)sqlite
88b0: 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67  3_value_text(arg
88c0: 76 5b 30 5d 29 3b 0a 20 20 7d 0a 0a 20 20 69 66  v[0]);.  }..  if
88d0: 28 20 30 3d 3d 70 54 61 62 2d 3e 70 57 72 69 74  ( 0==pTab->pWrit
88e0: 65 46 64 20 26 26 20 30 3d 3d 62 49 6e 4d 65 6d  eFd && 0==bInMem
88f0: 6f 72 79 20 29 7b 0a 20 20 20 20 70 43 73 72 2d  ory ){.    pCsr-
8900: 3e 70 46 69 6c 65 20 3d 20 66 6f 70 65 6e 28 7a  >pFile = fopen(z
8910: 46 69 6c 65 2c 20 22 72 62 22 29 3b 0a 20 20 20  File, "rb");.   
8920: 20 69 66 28 20 70 43 73 72 2d 3e 70 46 69 6c 65   if( pCsr->pFile
8930: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 7a 69 70  ==0 ){.      zip
8940: 66 69 6c 65 53 65 74 45 72 72 6d 73 67 28 70 43  fileSetErrmsg(pC
8950: 73 72 2c 20 22 63 61 6e 6e 6f 74 20 6f 70 65 6e  sr, "cannot open
8960: 20 66 69 6c 65 3a 20 25 73 22 2c 20 7a 46 69 6c   file: %s", zFil
8970: 65 29 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 53  e);.      rc = S
8980: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20  QLITE_ERROR;.   
8990: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 63   }else{.      rc
89a0: 20 3d 20 7a 69 70 66 69 6c 65 52 65 61 64 45 4f   = zipfileReadEO
89b0: 43 44 28 70 54 61 62 2c 20 30 2c 20 30 2c 20 70  CD(pTab, 0, 0, p
89c0: 43 73 72 2d 3e 70 46 69 6c 65 2c 20 26 70 43 73  Csr->pFile, &pCs
89d0: 72 2d 3e 65 6f 63 64 29 3b 0a 20 20 20 20 20 20  r->eocd);.      
89e0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
89f0: 4b 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  K ){.        if(
8a00: 20 70 43 73 72 2d 3e 65 6f 63 64 2e 6e 45 6e 74   pCsr->eocd.nEnt
8a10: 72 79 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  ry==0 ){.       
8a20: 20 20 20 70 43 73 72 2d 3e 62 45 6f 66 20 3d 20     pCsr->bEof = 
8a30: 31 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  1;.        }else
8a40: 7b 0a 20 20 20 20 20 20 20 20 20 20 70 43 73 72  {.          pCsr
8a50: 2d 3e 69 4e 65 78 74 4f 66 66 20 3d 20 70 43 73  ->iNextOff = pCs
8a60: 72 2d 3e 65 6f 63 64 2e 69 4f 66 66 73 65 74 3b  r->eocd.iOffset;
8a70: 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
8a80: 7a 69 70 66 69 6c 65 4e 65 78 74 28 63 75 72 29  zipfileNext(cur)
8a90: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
8aa0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73    }.    }.  }els
8ab0: 65 7b 0a 20 20 20 20 70 43 73 72 2d 3e 62 4e 6f  e{.    pCsr->bNo
8ac0: 6f 70 20 3d 20 31 3b 0a 20 20 20 20 70 43 73 72  op = 1;.    pCsr
8ad0: 2d 3e 70 43 75 72 72 65 6e 74 20 3d 20 70 43 73  ->pCurrent = pCs
8ae0: 72 2d 3e 70 46 72 65 65 45 6e 74 72 79 20 3f 20  r->pFreeEntry ? 
8af0: 70 43 73 72 2d 3e 70 46 72 65 65 45 6e 74 72 79  pCsr->pFreeEntry
8b00: 20 3a 20 70 54 61 62 2d 3e 70 46 69 72 73 74 45   : pTab->pFirstE
8b10: 6e 74 72 79 3b 0a 20 20 20 20 72 63 20 3d 20 7a  ntry;.    rc = z
8b20: 69 70 66 69 6c 65 4e 65 78 74 28 63 75 72 29 3b  ipfileNext(cur);
8b30: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
8b40: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 42 65 73  c;.}../*.** xBes
8b50: 74 49 6e 64 65 78 20 63 61 6c 6c 62 61 63 6b 2e  tIndex callback.
8b60: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 7a  .*/.static int z
8b70: 69 70 66 69 6c 65 42 65 73 74 49 6e 64 65 78 28  ipfileBestIndex(
8b80: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20  .  sqlite3_vtab 
8b90: 2a 74 61 62 2c 0a 20 20 73 71 6c 69 74 65 33 5f  *tab,.  sqlite3_
8ba0: 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70 49 64 78  index_info *pIdx
8bb0: 49 6e 66 6f 0a 29 7b 0a 20 20 69 6e 74 20 69 3b  Info.){.  int i;
8bc0: 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70  ..  for(i=0; i<p
8bd0: 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72  IdxInfo->nConstr
8be0: 61 69 6e 74 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  aint; i++){.    
8bf0: 63 6f 6e 73 74 20 73 74 72 75 63 74 20 73 71 6c  const struct sql
8c00: 69 74 65 33 5f 69 6e 64 65 78 5f 63 6f 6e 73 74  ite3_index_const
8c10: 72 61 69 6e 74 20 2a 70 43 6f 6e 73 20 3d 20 26  raint *pCons = &
8c20: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  pIdxInfo->aConst
8c30: 72 61 69 6e 74 5b 69 5d 3b 0a 20 20 20 20 69 66  raint[i];.    if
8c40: 28 20 70 43 6f 6e 73 2d 3e 75 73 61 62 6c 65 3d  ( pCons->usable=
8c50: 3d 30 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20  =0 ) continue;. 
8c60: 20 20 20 69 66 28 20 70 43 6f 6e 73 2d 3e 6f 70     if( pCons->op
8c70: 21 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43  !=SQLITE_INDEX_C
8c80: 4f 4e 53 54 52 41 49 4e 54 5f 45 51 20 29 20 63  ONSTRAINT_EQ ) c
8c90: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 69 66 28  ontinue;.    if(
8ca0: 20 70 43 6f 6e 73 2d 3e 69 43 6f 6c 75 6d 6e 21   pCons->iColumn!
8cb0: 3d 5a 49 50 46 49 4c 45 5f 46 5f 43 4f 4c 55 4d  =ZIPFILE_F_COLUM
8cc0: 4e 5f 49 44 58 20 29 20 63 6f 6e 74 69 6e 75 65  N_IDX ) continue
8cd0: 3b 0a 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 7d  ;.    break;.  }
8ce0: 0a 0a 20 20 69 66 28 20 69 3c 70 49 64 78 49 6e  ..  if( i<pIdxIn
8cf0: 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e 74 20  fo->nConstraint 
8d00: 29 7b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d  ){.    pIdxInfo-
8d10: 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61 67  >aConstraintUsag
8d20: 65 5b 69 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d  e[i].argvIndex =
8d30: 20 31 3b 0a 20 20 20 20 70 49 64 78 49 6e 66 6f   1;.    pIdxInfo
8d40: 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73 61  ->aConstraintUsa
8d50: 67 65 5b 69 5d 2e 6f 6d 69 74 20 3d 20 31 3b 0a  ge[i].omit = 1;.
8d60: 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73      pIdxInfo->es
8d70: 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 30  timatedCost = 10
8d80: 30 30 2e 30 3b 0a 20 20 20 20 70 49 64 78 49 6e  00.0;.    pIdxIn
8d90: 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 31 3b 0a  fo->idxNum = 1;.
8da0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 49 64    }else{.    pId
8db0: 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64  xInfo->estimated
8dc0: 43 6f 73 74 20 3d 20 28 64 6f 75 62 6c 65 29 28  Cost = (double)(
8dd0: 28 28 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 29  ((sqlite3_int64)
8de0: 31 29 20 3c 3c 20 35 30 29 3b 0a 20 20 20 20 70  1) << 50);.    p
8df0: 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20  IdxInfo->idxNum 
8e00: 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  = 0;.  }..  retu
8e10: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
8e20: 0a 73 74 61 74 69 63 20 5a 69 70 66 69 6c 65 45  .static ZipfileE
8e30: 6e 74 72 79 20 2a 7a 69 70 66 69 6c 65 4e 65 77  ntry *zipfileNew
8e40: 45 6e 74 72 79 28 63 6f 6e 73 74 20 63 68 61 72  Entry(const char
8e50: 20 2a 7a 50 61 74 68 2c 20 69 6e 74 20 6e 44 61   *zPath, int nDa
8e60: 74 61 29 7b 0a 20 20 5a 69 70 66 69 6c 65 45 6e  ta){.  ZipfileEn
8e70: 74 72 79 20 2a 70 4e 65 77 3b 0a 20 20 70 4e 65  try *pNew;.  pNe
8e80: 77 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  w = sqlite3_mall
8e90: 6f 63 28 73 69 7a 65 6f 66 28 5a 69 70 66 69 6c  oc(sizeof(Zipfil
8ea0: 65 45 6e 74 72 79 29 20 2b 20 6e 44 61 74 61 29  eEntry) + nData)
8eb0: 3b 0a 20 20 69 66 28 20 70 4e 65 77 20 29 7b 0a  ;.  if( pNew ){.
8ec0: 20 20 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c      memset(pNew,
8ed0: 20 30 2c 20 73 69 7a 65 6f 66 28 5a 69 70 66 69   0, sizeof(Zipfi
8ee0: 6c 65 45 6e 74 72 79 29 29 3b 0a 20 20 20 20 69  leEntry));.    i
8ef0: 66 28 20 6e 44 61 74 61 20 29 7b 0a 20 20 20 20  f( nData ){.    
8f00: 20 20 70 4e 65 77 2d 3e 61 44 61 74 61 20 3d 20    pNew->aData = 
8f10: 28 75 38 2a 29 26 70 4e 65 77 5b 31 5d 3b 0a 20  (u8*)&pNew[1];. 
8f20: 20 20 20 7d 0a 20 20 20 20 70 4e 65 77 2d 3e 63     }.    pNew->c
8f30: 64 73 2e 7a 46 69 6c 65 20 3d 20 73 71 6c 69 74  ds.zFile = sqlit
8f40: 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 22 2c  e3_mprintf("%s",
8f50: 20 7a 50 61 74 68 29 3b 0a 20 20 20 20 69 66 28   zPath);.    if(
8f60: 20 70 4e 65 77 2d 3e 63 64 73 2e 7a 46 69 6c 65   pNew->cds.zFile
8f70: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 73 71 6c  ==0 ){.      sql
8f80: 69 74 65 33 5f 66 72 65 65 28 70 4e 65 77 29 3b  ite3_free(pNew);
8f90: 0a 20 20 20 20 20 20 70 4e 65 77 20 3d 20 30 3b  .      pNew = 0;
8fa0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
8fb0: 75 72 6e 20 70 4e 65 77 3b 0a 7d 0a 0a 73 74 61  urn pNew;.}..sta
8fc0: 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 53  tic int zipfileS
8fd0: 65 72 69 61 6c 69 7a 65 4c 46 48 28 5a 69 70 66  erializeLFH(Zipf
8fe0: 69 6c 65 45 6e 74 72 79 20 2a 70 45 6e 74 72 79  ileEntry *pEntry
8ff0: 2c 20 75 38 20 2a 61 42 75 66 29 7b 0a 20 20 5a  , u8 *aBuf){.  Z
9000: 69 70 66 69 6c 65 43 44 53 20 2a 70 43 64 73 20  ipfileCDS *pCds 
9010: 3d 20 26 70 45 6e 74 72 79 2d 3e 63 64 73 3b 0a  = &pEntry->cds;.
9020: 20 20 75 38 20 2a 61 20 3d 20 61 42 75 66 3b 0a    u8 *a = aBuf;.
9030: 0a 20 20 70 43 64 73 2d 3e 6e 45 78 74 72 61 20  .  pCds->nExtra 
9040: 3d 20 39 3b 0a 0a 20 20 2f 2a 20 57 72 69 74 65  = 9;..  /* Write
9050: 20 74 68 65 20 4c 46 48 20 69 74 73 65 6c 66 20   the LFH itself 
9060: 2a 2f 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74  */.  zipfileWrit
9070: 65 33 32 28 61 2c 20 5a 49 50 46 49 4c 45 5f 53  e32(a, ZIPFILE_S
9080: 49 47 4e 41 54 55 52 45 5f 4c 46 48 29 3b 0a 20  IGNATURE_LFH);. 
9090: 20 7a 69 70 66 69 6c 65 57 72 69 74 65 31 36 28   zipfileWrite16(
90a0: 61 2c 20 70 43 64 73 2d 3e 69 56 65 72 73 69 6f  a, pCds->iVersio
90b0: 6e 45 78 74 72 61 63 74 29 3b 0a 20 20 7a 69 70  nExtract);.  zip
90c0: 66 69 6c 65 57 72 69 74 65 31 36 28 61 2c 20 70  fileWrite16(a, p
90d0: 43 64 73 2d 3e 66 6c 61 67 73 29 3b 0a 20 20 7a  Cds->flags);.  z
90e0: 69 70 66 69 6c 65 57 72 69 74 65 31 36 28 61 2c  ipfileWrite16(a,
90f0: 20 70 43 64 73 2d 3e 69 43 6f 6d 70 72 65 73 73   pCds->iCompress
9100: 69 6f 6e 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57  ion);.  zipfileW
9110: 72 69 74 65 31 36 28 61 2c 20 70 43 64 73 2d 3e  rite16(a, pCds->
9120: 6d 54 69 6d 65 29 3b 0a 20 20 7a 69 70 66 69 6c  mTime);.  zipfil
9130: 65 57 72 69 74 65 31 36 28 61 2c 20 70 43 64 73  eWrite16(a, pCds
9140: 2d 3e 6d 44 61 74 65 29 3b 0a 20 20 7a 69 70 66  ->mDate);.  zipf
9150: 69 6c 65 57 72 69 74 65 33 32 28 61 2c 20 70 43  ileWrite32(a, pC
9160: 64 73 2d 3e 63 72 63 33 32 29 3b 0a 20 20 7a 69  ds->crc32);.  zi
9170: 70 66 69 6c 65 57 72 69 74 65 33 32 28 61 2c 20  pfileWrite32(a, 
9180: 70 43 64 73 2d 3e 73 7a 43 6f 6d 70 72 65 73 73  pCds->szCompress
9190: 65 64 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72  ed);.  zipfileWr
91a0: 69 74 65 33 32 28 61 2c 20 70 43 64 73 2d 3e 73  ite32(a, pCds->s
91b0: 7a 55 6e 63 6f 6d 70 72 65 73 73 65 64 29 3b 0a  zUncompressed);.
91c0: 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65 31 36    zipfileWrite16
91d0: 28 61 2c 20 28 75 31 36 29 70 43 64 73 2d 3e 6e  (a, (u16)pCds->n
91e0: 46 69 6c 65 29 3b 0a 20 20 7a 69 70 66 69 6c 65  File);.  zipfile
91f0: 57 72 69 74 65 31 36 28 61 2c 20 70 43 64 73 2d  Write16(a, pCds-
9200: 3e 6e 45 78 74 72 61 29 3b 0a 20 20 61 73 73 65  >nExtra);.  asse
9210: 72 74 28 20 61 3d 3d 26 61 42 75 66 5b 5a 49 50  rt( a==&aBuf[ZIP
9220: 46 49 4c 45 5f 4c 46 48 5f 46 49 58 45 44 5f 53  FILE_LFH_FIXED_S
9230: 5a 5d 20 29 3b 0a 0a 20 20 2f 2a 20 41 64 64 20  Z] );..  /* Add 
9240: 74 68 65 20 66 69 6c 65 20 6e 61 6d 65 20 2a 2f  the file name */
9250: 0a 20 20 6d 65 6d 63 70 79 28 61 2c 20 70 43 64  .  memcpy(a, pCd
9260: 73 2d 3e 7a 46 69 6c 65 2c 20 28 69 6e 74 29 70  s->zFile, (int)p
9270: 43 64 73 2d 3e 6e 46 69 6c 65 29 3b 0a 20 20 61  Cds->nFile);.  a
9280: 20 2b 3d 20 28 69 6e 74 29 70 43 64 73 2d 3e 6e   += (int)pCds->n
9290: 46 69 6c 65 3b 0a 0a 20 20 2f 2a 20 54 68 65 20  File;..  /* The 
92a0: 22 65 78 74 72 61 22 20 64 61 74 61 20 2a 2f 0a  "extra" data */.
92b0: 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65 31 36    zipfileWrite16
92c0: 28 61 2c 20 5a 49 50 46 49 4c 45 5f 45 58 54 52  (a, ZIPFILE_EXTR
92d0: 41 5f 54 49 4d 45 53 54 41 4d 50 29 3b 0a 20 20  A_TIMESTAMP);.  
92e0: 7a 69 70 66 69 6c 65 57 72 69 74 65 31 36 28 61  zipfileWrite16(a
92f0: 2c 20 35 29 3b 0a 20 20 2a 61 2b 2b 20 3d 20 30  , 5);.  *a++ = 0
9300: 78 30 31 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72  x01;.  zipfileWr
9310: 69 74 65 33 32 28 61 2c 20 70 45 6e 74 72 79 2d  ite32(a, pEntry-
9320: 3e 6d 55 6e 69 78 54 69 6d 65 29 3b 0a 0a 20 20  >mUnixTime);..  
9330: 72 65 74 75 72 6e 20 61 2d 61 42 75 66 3b 0a 7d  return a-aBuf;.}
9340: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70  ..static int zip
9350: 66 69 6c 65 41 70 70 65 6e 64 45 6e 74 72 79 28  fileAppendEntry(
9360: 0a 20 20 5a 69 70 66 69 6c 65 54 61 62 20 2a 70  .  ZipfileTab *p
9370: 54 61 62 2c 0a 20 20 5a 69 70 66 69 6c 65 45 6e  Tab,.  ZipfileEn
9380: 74 72 79 20 2a 70 45 6e 74 72 79 2c 0a 20 20 63  try *pEntry,.  c
9390: 6f 6e 73 74 20 75 38 20 2a 70 44 61 74 61 2c 0a  onst u8 *pData,.
93a0: 20 20 69 6e 74 20 6e 44 61 74 61 0a 29 7b 0a 20    int nData.){. 
93b0: 20 75 38 20 2a 61 42 75 66 20 3d 20 70 54 61 62   u8 *aBuf = pTab
93c0: 2d 3e 61 42 75 66 66 65 72 3b 0a 20 20 69 6e 74  ->aBuffer;.  int
93d0: 20 6e 42 75 66 3b 0a 20 20 69 6e 74 20 72 63 3b   nBuf;.  int rc;
93e0: 0a 0a 20 20 6e 42 75 66 20 3d 20 7a 69 70 66 69  ..  nBuf = zipfi
93f0: 6c 65 53 65 72 69 61 6c 69 7a 65 4c 46 48 28 70  leSerializeLFH(p
9400: 45 6e 74 72 79 2c 20 61 42 75 66 29 3b 0a 20 20  Entry, aBuf);.  
9410: 72 63 20 3d 20 7a 69 70 66 69 6c 65 41 70 70 65  rc = zipfileAppe
9420: 6e 64 44 61 74 61 28 70 54 61 62 2c 20 61 42 75  ndData(pTab, aBu
9430: 66 2c 20 6e 42 75 66 29 3b 0a 20 20 69 66 28 20  f, nBuf);.  if( 
9440: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
9450: 0a 20 20 20 20 72 63 20 3d 20 7a 69 70 66 69 6c  .    rc = zipfil
9460: 65 41 70 70 65 6e 64 44 61 74 61 28 70 54 61 62  eAppendData(pTab
9470: 2c 20 70 44 61 74 61 2c 20 6e 44 61 74 61 29 3b  , pData, nData);
9480: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72  .  }..  return r
9490: 63 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  c;.}..static int
94a0: 20 7a 69 70 66 69 6c 65 47 65 74 4d 6f 64 65 28   zipfileGetMode(
94b0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  .  sqlite3_value
94c0: 20 2a 70 56 61 6c 2c 20 0a 20 20 69 6e 74 20 62   *pVal, .  int b
94d0: 49 73 44 69 72 2c 20 20 20 20 20 20 20 20 20 20  IsDir,          
94e0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 66             /* If
94f0: 20 74 72 75 65 2c 20 64 65 66 61 75 6c 74 20 74   true, default t
9500: 6f 20 64 69 72 65 63 74 6f 72 79 20 2a 2f 0a 20  o directory */. 
9510: 20 75 33 32 20 2a 70 4d 6f 64 65 2c 20 20 20 20   u32 *pMode,    
9520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9530: 20 2f 2a 20 4f 55 54 3a 20 4d 6f 64 65 20 76 61   /* OUT: Mode va
9540: 6c 75 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a 2a  lue */.  char **
9550: 70 7a 45 72 72 20 20 20 20 20 20 20 20 20 20 20  pzErr           
9560: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
9570: 20 45 72 72 6f 72 20 6d 65 73 73 61 67 65 20 2a   Error message *
9580: 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61  /.){.  const cha
9590: 72 20 2a 7a 20 3d 20 28 63 6f 6e 73 74 20 63 68  r *z = (const ch
95a0: 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
95b0: 65 5f 74 65 78 74 28 70 56 61 6c 29 3b 0a 20 20  e_text(pVal);.  
95c0: 75 33 32 20 6d 6f 64 65 20 3d 20 30 3b 0a 20 20  u32 mode = 0;.  
95d0: 69 66 28 20 7a 3d 3d 30 20 29 7b 0a 20 20 20 20  if( z==0 ){.    
95e0: 6d 6f 64 65 20 3d 20 28 62 49 73 44 69 72 20 3f  mode = (bIsDir ?
95f0: 20 28 53 5f 49 46 44 49 52 20 2b 20 30 37 35 35   (S_IFDIR + 0755
9600: 29 20 3a 20 28 53 5f 49 46 52 45 47 20 2b 20 30  ) : (S_IFREG + 0
9610: 36 34 34 29 29 3b 0a 20 20 7d 65 6c 73 65 20 69  644));.  }else i
9620: 66 28 20 7a 5b 30 5d 3e 3d 27 30 27 20 26 26 20  f( z[0]>='0' && 
9630: 7a 5b 30 5d 3c 3d 27 39 27 20 29 7b 0a 20 20 20  z[0]<='9' ){.   
9640: 20 6d 6f 64 65 20 3d 20 28 75 6e 73 69 67 6e 65   mode = (unsigne
9650: 64 20 69 6e 74 29 73 71 6c 69 74 65 33 5f 76 61  d int)sqlite3_va
9660: 6c 75 65 5f 69 6e 74 28 70 56 61 6c 29 3b 0a 20  lue_int(pVal);. 
9670: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 63 6f 6e 73   }else{.    cons
9680: 74 20 63 68 61 72 20 7a 54 65 6d 70 6c 61 74 65  t char zTemplate
9690: 5b 31 31 5d 20 3d 20 22 2d 72 77 78 72 77 78 72  [11] = "-rwxrwxr
96a0: 77 78 22 3b 0a 20 20 20 20 69 6e 74 20 69 3b 0a  wx";.    int i;.
96b0: 20 20 20 20 69 66 28 20 73 74 72 6c 65 6e 28 7a      if( strlen(z
96c0: 29 21 3d 31 30 20 29 20 67 6f 74 6f 20 70 61 72  )!=10 ) goto par
96d0: 73 65 5f 65 72 72 6f 72 3b 0a 20 20 20 20 73 77  se_error;.    sw
96e0: 69 74 63 68 28 20 7a 5b 30 5d 20 29 7b 0a 20 20  itch( z[0] ){.  
96f0: 20 20 20 20 63 61 73 65 20 27 2d 27 3a 20 6d 6f      case '-': mo
9700: 64 65 20 7c 3d 20 53 5f 49 46 52 45 47 3b 20 62  de |= S_IFREG; b
9710: 72 65 61 6b 3b 0a 20 20 20 20 20 20 63 61 73 65  reak;.      case
9720: 20 27 64 27 3a 20 6d 6f 64 65 20 7c 3d 20 53 5f   'd': mode |= S_
9730: 49 46 44 49 52 3b 20 62 72 65 61 6b 3b 0a 23 69  IFDIR; break;.#i
9740: 66 20 21 64 65 66 69 6e 65 64 28 5f 57 49 4e 33  f !defined(_WIN3
9750: 32 29 20 26 26 20 21 64 65 66 69 6e 65 64 28 57  2) && !defined(W
9760: 49 4e 33 32 29 0a 20 20 20 20 20 20 63 61 73 65  IN32).      case
9770: 20 27 6c 27 3a 20 6d 6f 64 65 20 7c 3d 20 53 5f   'l': mode |= S_
9780: 49 46 4c 4e 4b 3b 20 62 72 65 61 6b 3b 0a 23 65  IFLNK; break;.#e
9790: 6e 64 69 66 0a 20 20 20 20 20 20 64 65 66 61 75  ndif.      defau
97a0: 6c 74 3a 20 67 6f 74 6f 20 70 61 72 73 65 5f 65  lt: goto parse_e
97b0: 72 72 6f 72 3b 0a 20 20 20 20 7d 0a 20 20 20 20  rror;.    }.    
97c0: 66 6f 72 28 69 3d 31 3b 20 69 3c 31 30 3b 20 69  for(i=1; i<10; i
97d0: 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 7a  ++){.      if( z
97e0: 5b 69 5d 3d 3d 7a 54 65 6d 70 6c 61 74 65 5b 69  [i]==zTemplate[i
97f0: 5d 20 29 20 6d 6f 64 65 20 7c 3d 20 31 20 3c 3c  ] ) mode |= 1 <<
9800: 20 28 39 2d 69 29 3b 0a 20 20 20 20 20 20 65 6c   (9-i);.      el
9810: 73 65 20 69 66 28 20 7a 5b 69 5d 21 3d 27 2d 27  se if( z[i]!='-'
9820: 20 29 20 67 6f 74 6f 20 70 61 72 73 65 5f 65 72   ) goto parse_er
9830: 72 6f 72 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  ror;.    }.  }. 
9840: 20 69 66 28 20 28 62 49 73 44 69 72 20 3d 3d 20   if( (bIsDir == 
9850: 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 44 49 52  ((mode & S_IFDIR
9860: 29 3d 3d 30 29 29 20 29 7b 0a 20 20 20 20 2f 2a  )==0)) ){.    /*
9870: 20 54 68 65 20 22 6d 6f 64 65 22 20 61 74 74 72   The "mode" attr
9880: 69 62 75 74 65 20 69 73 20 61 20 64 69 72 65 63  ibute is a direc
9890: 74 6f 72 79 2c 20 62 75 74 20 64 61 74 61 20 68  tory, but data h
98a0: 61 73 20 62 65 65 6e 20 73 70 65 63 69 66 69 65  as been specifie
98b0: 64 2e 0a 20 20 20 20 2a 2a 20 4f 72 20 76 69 63  d..    ** Or vic
98c0: 65 2d 76 65 72 73 61 20 2d 20 6e 6f 20 64 61 74  e-versa - no dat
98d0: 61 20 62 75 74 20 22 6d 6f 64 65 22 20 69 73 20  a but "mode" is 
98e0: 61 20 66 69 6c 65 20 6f 72 20 73 79 6d 6c 69 6e  a file or symlin
98f0: 6b 2e 20 20 2a 2f 0a 20 20 20 20 72 65 74 75 72  k.  */.    retur
9900: 6e 20 53 51 4c 49 54 45 5f 43 4f 4e 53 54 52 41  n SQLITE_CONSTRA
9910: 49 4e 54 3b 0a 20 20 7d 0a 20 20 2a 70 4d 6f 64  INT;.  }.  *pMod
9920: 65 20 3d 20 6d 6f 64 65 3b 0a 20 20 72 65 74 75  e = mode;.  retu
9930: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20  rn SQLITE_OK;.. 
9940: 70 61 72 73 65 5f 65 72 72 6f 72 3a 0a 20 20 2a  parse_error:.  *
9950: 70 7a 45 72 72 20 3d 20 73 71 6c 69 74 65 33 5f  pzErr = sqlite3_
9960: 6d 70 72 69 6e 74 66 28 22 7a 69 70 66 69 6c 65  mprintf("zipfile
9970: 3a 20 70 61 72 73 65 20 65 72 72 6f 72 20 69 6e  : parse error in
9980: 20 6d 6f 64 65 3a 20 25 73 22 2c 20 7a 29 3b 0a   mode: %s", z);.
9990: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
99a0: 45 52 52 4f 52 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  ERROR;.}../*.** 
99b0: 42 6f 74 68 20 28 63 6f 6e 73 74 20 63 68 61 72  Both (const char
99c0: 2a 29 20 61 72 67 75 6d 65 6e 74 73 20 70 6f 69  *) arguments poi
99d0: 6e 74 20 74 6f 20 6e 75 6c 2d 74 65 72 6d 69 6e  nt to nul-termin
99e0: 61 74 65 64 20 73 74 72 69 6e 67 73 2e 20 41 72  ated strings. Ar
99f0: 67 75 6d 65 6e 74 0a 2a 2a 20 6e 42 20 69 73 20  gument.** nB is 
9a00: 74 68 65 20 76 61 6c 75 65 20 6f 66 20 73 74 72  the value of str
9a10: 6c 65 6e 28 7a 42 29 2e 20 54 68 69 73 20 66 75  len(zB). This fu
9a20: 6e 63 74 69 6f 6e 20 72 65 74 75 72 6e 73 20 30  nction returns 0
9a30: 20 69 66 20 74 68 65 20 73 74 72 69 6e 67 73 20   if the strings 
9a40: 61 72 65 0a 2a 2a 20 69 64 65 6e 74 69 63 61 6c  are.** identical
9a50: 2c 20 69 67 6e 6f 72 69 6e 67 20 61 6e 79 20 74  , ignoring any t
9a60: 72 61 69 6c 69 6e 67 20 27 2f 27 20 63 68 61 72  railing '/' char
9a70: 61 63 74 65 72 20 69 6e 20 65 69 74 68 65 72 20  acter in either 
9a80: 70 61 74 68 2e 20 20 2a 2f 0a 73 74 61 74 69 63  path.  */.static
9a90: 20 69 6e 74 20 7a 69 70 66 69 6c 65 43 6f 6d 70   int zipfileComp
9aa0: 61 72 65 50 61 74 68 28 63 6f 6e 73 74 20 63 68  arePath(const ch
9ab0: 61 72 20 2a 7a 41 2c 20 63 6f 6e 73 74 20 63 68  ar *zA, const ch
9ac0: 61 72 20 2a 7a 42 2c 20 69 6e 74 20 6e 42 29 7b  ar *zB, int nB){
9ad0: 0a 20 20 69 6e 74 20 6e 41 20 3d 20 28 69 6e 74  .  int nA = (int
9ae0: 29 73 74 72 6c 65 6e 28 7a 41 29 3b 0a 20 20 69  )strlen(zA);.  i
9af0: 66 28 20 7a 41 5b 6e 41 2d 31 5d 3d 3d 27 2f 27  f( zA[nA-1]=='/'
9b00: 20 29 20 6e 41 2d 2d 3b 0a 20 20 69 66 28 20 7a   ) nA--;.  if( z
9b10: 42 5b 6e 42 2d 31 5d 3d 3d 27 2f 27 20 29 20 6e  B[nB-1]=='/' ) n
9b20: 42 2d 2d 3b 0a 20 20 69 66 28 20 6e 41 3d 3d 6e  B--;.  if( nA==n
9b30: 42 20 26 26 20 6d 65 6d 63 6d 70 28 7a 41 2c 20  B && memcmp(zA, 
9b40: 7a 42 2c 20 6e 41 29 3d 3d 30 20 29 20 72 65 74  zB, nA)==0 ) ret
9b50: 75 72 6e 20 30 3b 0a 20 20 72 65 74 75 72 6e 20  urn 0;.  return 
9b60: 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 55 70 64  1;.}../*.** xUpd
9b70: 61 74 65 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a 73  ate method..*/.s
9b80: 74 61 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c  tatic int zipfil
9b90: 65 55 70 64 61 74 65 28 0a 20 20 73 71 6c 69 74  eUpdate(.  sqlit
9ba0: 65 33 5f 76 74 61 62 20 2a 70 56 74 61 62 2c 20  e3_vtab *pVtab, 
9bb0: 0a 20 20 69 6e 74 20 6e 56 61 6c 2c 20 0a 20 20  .  int nVal, .  
9bc0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
9bd0: 61 70 56 61 6c 2c 20 0a 20 20 73 71 6c 69 74 65  apVal, .  sqlite
9be0: 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 0a 29  _int64 *pRowid.)
9bf0: 7b 0a 20 20 5a 69 70 66 69 6c 65 54 61 62 20 2a  {.  ZipfileTab *
9c00: 70 54 61 62 20 3d 20 28 5a 69 70 66 69 6c 65 54  pTab = (ZipfileT
9c10: 61 62 2a 29 70 56 74 61 62 3b 0a 20 20 69 6e 74  ab*)pVtab;.  int
9c20: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
9c30: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9c40: 52 65 74 75 72 6e 20 43 6f 64 65 20 2a 2f 0a 20  Return Code */. 
9c50: 20 5a 69 70 66 69 6c 65 45 6e 74 72 79 20 2a 70   ZipfileEntry *p
9c60: 4e 65 77 20 3d 20 30 3b 20 20 20 20 20 20 20 20  New = 0;        
9c70: 20 2f 2a 20 4e 65 77 20 69 6e 2d 6d 65 6d 6f 72   /* New in-memor
9c80: 79 20 43 44 53 20 65 6e 74 72 79 20 2a 2f 0a 0a  y CDS entry */..
9c90: 20 20 75 33 32 20 6d 6f 64 65 20 3d 20 30 3b 20    u32 mode = 0; 
9ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9cb0: 20 20 2f 2a 20 4d 6f 64 65 20 66 6f 72 20 6e 65    /* Mode for ne
9cc0: 77 20 65 6e 74 72 79 20 2a 2f 0a 20 20 69 36 34  w entry */.  i64
9cd0: 20 6d 54 69 6d 65 20 3d 20 30 3b 20 20 20 20 20   mTime = 0;     
9ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9cf0: 4d 6f 64 69 66 69 63 61 74 69 6f 6e 20 74 69 6d  Modification tim
9d00: 65 20 66 6f 72 20 6e 65 77 20 65 6e 74 72 79 20  e for new entry 
9d10: 2a 2f 0a 20 20 69 36 34 20 73 7a 20 3d 20 30 3b  */.  i64 sz = 0;
9d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9d30: 20 20 20 20 20 2f 2a 20 55 6e 63 6f 6d 70 72 65       /* Uncompre
9d40: 73 73 65 64 20 73 69 7a 65 20 2a 2f 0a 20 20 63  ssed size */.  c
9d50: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68  onst char *zPath
9d60: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 2f   = 0;          /
9d70: 2a 20 50 61 74 68 20 66 6f 72 20 6e 65 77 20 65  * Path for new e
9d80: 6e 74 72 79 20 2a 2f 0a 20 20 69 6e 74 20 6e 50  ntry */.  int nP
9d90: 61 74 68 20 3d 20 30 3b 20 20 20 20 20 20 20 20  ath = 0;        
9da0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73 74 72            /* str
9db0: 6c 65 6e 28 7a 50 61 74 68 29 20 2a 2f 0a 20 20  len(zPath) */.  
9dc0: 63 6f 6e 73 74 20 75 38 20 2a 70 44 61 74 61 20  const u8 *pData 
9dd0: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  = 0;            
9de0: 2f 2a 20 50 6f 69 6e 74 65 72 20 74 6f 20 62 75  /* Pointer to bu
9df0: 66 66 65 72 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ffer containing 
9e00: 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 69 6e 74  content */.  int
9e10: 20 6e 44 61 74 61 20 3d 20 30 3b 20 20 20 20 20   nData = 0;     
9e20: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
9e30: 53 69 7a 65 20 6f 66 20 70 44 61 74 61 20 62 75  Size of pData bu
9e40: 66 66 65 72 20 69 6e 20 62 79 74 65 73 20 2a 2f  ffer in bytes */
9e50: 0a 20 20 69 6e 74 20 69 4d 65 74 68 6f 64 20 3d  .  int iMethod =
9e60: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   0;             
9e70: 20 20 20 2f 2a 20 43 6f 6d 70 72 65 73 73 69 6f     /* Compressio
9e80: 6e 20 6d 65 74 68 6f 64 20 66 6f 72 20 6e 65 77  n method for new
9e90: 20 65 6e 74 72 79 20 2a 2f 0a 20 20 75 38 20 2a   entry */.  u8 *
9ea0: 70 46 72 65 65 20 3d 20 30 3b 20 20 20 20 20 20  pFree = 0;      
9eb0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
9ec0: 72 65 65 20 74 68 69 73 20 2a 2f 0a 20 20 63 68  ree this */.  ch
9ed0: 61 72 20 2a 7a 46 72 65 65 20 3d 20 30 3b 20 20  ar *zFree = 0;  
9ee0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9ef0: 20 41 6c 73 6f 20 66 72 65 65 20 74 68 69 73 20   Also free this 
9f00: 2a 2f 0a 20 20 5a 69 70 66 69 6c 65 45 6e 74 72  */.  ZipfileEntr
9f10: 79 20 2a 70 4f 6c 64 20 3d 20 30 3b 0a 20 20 69  y *pOld = 0;.  i
9f20: 6e 74 20 62 49 73 44 69 72 20 3d 20 30 3b 0a 20  nt bIsDir = 0;. 
9f30: 20 75 33 32 20 69 43 72 63 33 32 20 3d 20 30 3b   u32 iCrc32 = 0;
9f40: 0a 0a 20 20 61 73 73 65 72 74 28 20 28 70 54 61  ..  assert( (pTa
9f50: 62 2d 3e 7a 46 69 6c 65 3d 3d 30 29 3d 3d 28 70  b->zFile==0)==(p
9f60: 54 61 62 2d 3e 70 57 72 69 74 65 46 64 3d 3d 30  Tab->pWriteFd==0
9f70: 29 20 29 3b 0a 0a 20 20 2f 2a 20 49 66 20 74 68  ) );..  /* If th
9f80: 69 73 20 69 73 20 61 20 44 45 4c 45 54 45 20 6f  is is a DELETE o
9f90: 72 20 55 50 44 41 54 45 2c 20 66 69 6e 64 20 74  r UPDATE, find t
9fa0: 68 65 20 61 72 63 68 69 76 65 20 65 6e 74 72 79  he archive entry
9fb0: 20 74 6f 20 64 65 6c 65 74 65 2e 20 2a 2f 0a 20   to delete. */. 
9fc0: 20 69 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c   if( sqlite3_val
9fd0: 75 65 5f 74 79 70 65 28 61 70 56 61 6c 5b 30 5d  ue_type(apVal[0]
9fe0: 29 21 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29  )!=SQLITE_NULL )
9ff0: 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  {.    const char
a000: 20 2a 7a 44 65 6c 65 74 65 20 3d 20 28 63 6f 6e   *zDelete = (con
a010: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
a020: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70 56 61  _value_text(apVa
a030: 6c 5b 30 5d 29 3b 0a 20 20 20 20 69 6e 74 20 6e  l[0]);.    int n
a040: 44 65 6c 65 74 65 20 3d 20 28 69 6e 74 29 73 74  Delete = (int)st
a050: 72 6c 65 6e 28 7a 44 65 6c 65 74 65 29 3b 0a 20  rlen(zDelete);. 
a060: 20 20 20 66 6f 72 28 70 4f 6c 64 3d 70 54 61 62     for(pOld=pTab
a070: 2d 3e 70 46 69 72 73 74 45 6e 74 72 79 3b 20 31  ->pFirstEntry; 1
a080: 3b 20 70 4f 6c 64 3d 70 4f 6c 64 2d 3e 70 4e 65  ; pOld=pOld->pNe
a090: 78 74 29 7b 0a 20 20 20 20 20 20 69 66 28 20 7a  xt){.      if( z
a0a0: 69 70 66 69 6c 65 43 6f 6d 70 61 72 65 50 61 74  ipfileComparePat
a0b0: 68 28 70 4f 6c 64 2d 3e 63 64 73 2e 7a 46 69 6c  h(pOld->cds.zFil
a0c0: 65 2c 20 7a 44 65 6c 65 74 65 2c 20 6e 44 65 6c  e, zDelete, nDel
a0d0: 65 74 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  ete)==0 ){.     
a0e0: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20     break;.      
a0f0: 7d 0a 20 20 20 20 20 20 61 73 73 65 72 74 28 20  }.      assert( 
a100: 70 4f 6c 64 2d 3e 70 4e 65 78 74 20 29 3b 0a 20  pOld->pNext );. 
a110: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
a120: 6e 56 61 6c 3e 31 20 29 7b 0a 20 20 20 20 2f 2a  nVal>1 ){.    /*
a130: 20 43 68 65 63 6b 20 74 68 61 74 20 22 73 7a 22   Check that "sz"
a140: 20 61 6e 64 20 22 72 61 77 64 61 74 61 22 20 61   and "rawdata" a
a150: 72 65 20 62 6f 74 68 20 4e 55 4c 4c 3a 20 2a 2f  re both NULL: */
a160: 0a 20 20 20 20 69 66 28 20 73 71 6c 69 74 65 33  .    if( sqlite3
a170: 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70 56 61  _value_type(apVa
a180: 6c 5b 35 5d 29 21 3d 53 51 4c 49 54 45 5f 4e 55  l[5])!=SQLITE_NU
a190: 4c 4c 0a 20 20 20 20 20 7c 7c 20 73 71 6c 69 74  LL.     || sqlit
a1a0: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 61 70  e3_value_type(ap
a1b0: 56 61 6c 5b 36 5d 29 21 3d 53 51 4c 49 54 45 5f  Val[6])!=SQLITE_
a1c0: 4e 55 4c 4c 0a 20 20 20 20 29 7b 0a 20 20 20 20  NULL.    ){.    
a1d0: 20 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43 4f    rc = SQLITE_CO
a1e0: 4e 53 54 52 41 49 4e 54 3b 0a 20 20 20 20 7d 0a  NSTRAINT;.    }.
a1f0: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
a200: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
a210: 69 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  if( sqlite3_valu
a220: 65 5f 74 79 70 65 28 61 70 56 61 6c 5b 37 5d 29  e_type(apVal[7])
a230: 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b  ==SQLITE_NULL ){
a240: 0a 20 20 20 20 20 20 20 20 2f 2a 20 64 61 74 61  .        /* data
a250: 3d 4e 55 4c 4c 2e 20 41 20 64 69 72 65 63 74 6f  =NULL. A directo
a260: 72 79 20 2a 2f 0a 20 20 20 20 20 20 20 20 62 49  ry */.        bI
a270: 73 44 69 72 20 3d 20 31 3b 0a 20 20 20 20 20 20  sDir = 1;.      
a280: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 2f  }else{.        /
a290: 2a 20 56 61 6c 75 65 20 73 70 65 63 69 66 69 65  * Value specifie
a2a0: 64 20 66 6f 72 20 22 64 61 74 61 22 2c 20 61 6e  d for "data", an
a2b0: 64 20 70 6f 73 73 69 62 6c 79 20 22 6d 65 74 68  d possibly "meth
a2c0: 6f 64 22 2e 20 54 68 69 73 20 6d 75 73 74 20 62  od". This must b
a2d0: 65 0a 20 20 20 20 20 20 20 20 2a 2a 20 61 20 72  e.        ** a r
a2e0: 65 67 75 6c 61 72 20 66 69 6c 65 20 6f 72 20 61  egular file or a
a2f0: 20 73 79 6d 6c 69 6e 6b 2e 20 2a 2f 0a 20 20 20   symlink. */.   
a300: 20 20 20 20 20 63 6f 6e 73 74 20 75 38 20 2a 61       const u8 *a
a310: 49 6e 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c  In = sqlite3_val
a320: 75 65 5f 62 6c 6f 62 28 61 70 56 61 6c 5b 37 5d  ue_blob(apVal[7]
a330: 29 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e  );.        int n
a340: 49 6e 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c  In = sqlite3_val
a350: 75 65 5f 62 79 74 65 73 28 61 70 56 61 6c 5b 37  ue_bytes(apVal[7
a360: 5d 29 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  ]);.        int 
a370: 62 41 75 74 6f 20 3d 20 73 71 6c 69 74 65 33 5f  bAuto = sqlite3_
a380: 76 61 6c 75 65 5f 74 79 70 65 28 61 70 56 61 6c  value_type(apVal
a390: 5b 38 5d 29 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c  [8])==SQLITE_NUL
a3a0: 4c 3b 0a 0a 20 20 20 20 20 20 20 20 69 4d 65 74  L;..        iMet
a3b0: 68 6f 64 20 3d 20 73 71 6c 69 74 65 33 5f 76 61  hod = sqlite3_va
a3c0: 6c 75 65 5f 69 6e 74 28 61 70 56 61 6c 5b 38 5d  lue_int(apVal[8]
a3d0: 29 3b 0a 20 20 20 20 20 20 20 20 73 7a 20 3d 20  );.        sz = 
a3e0: 6e 49 6e 3b 0a 20 20 20 20 20 20 20 20 70 44 61  nIn;.        pDa
a3f0: 74 61 20 3d 20 61 49 6e 3b 0a 20 20 20 20 20 20  ta = aIn;.      
a400: 20 20 6e 44 61 74 61 20 3d 20 6e 49 6e 3b 0a 20    nData = nIn;. 
a410: 20 20 20 20 20 20 20 69 66 28 20 69 4d 65 74 68         if( iMeth
a420: 6f 64 21 3d 30 20 26 26 20 69 4d 65 74 68 6f 64  od!=0 && iMethod
a430: 21 3d 38 20 29 7b 0a 20 20 20 20 20 20 20 20 20  !=8 ){.         
a440: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 43 4f 4e   rc = SQLITE_CON
a450: 53 54 52 41 49 4e 54 3b 0a 20 20 20 20 20 20 20  STRAINT;.       
a460: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
a470: 20 20 69 66 28 20 62 41 75 74 6f 20 7c 7c 20 69    if( bAuto || i
a480: 4d 65 74 68 6f 64 20 29 7b 0a 20 20 20 20 20 20  Method ){.      
a490: 20 20 20 20 20 20 69 6e 74 20 6e 43 6d 70 3b 0a        int nCmp;.
a4a0: 20 20 20 20 20 20 20 20 20 20 20 20 72 63 20 3d              rc =
a4b0: 20 7a 69 70 66 69 6c 65 44 65 66 6c 61 74 65 28   zipfileDeflate(
a4c0: 61 49 6e 2c 20 6e 49 6e 2c 20 26 70 46 72 65 65  aIn, nIn, &pFree
a4d0: 2c 20 26 6e 43 6d 70 2c 20 26 70 54 61 62 2d 3e  , &nCmp, &pTab->
a4e0: 62 61 73 65 2e 7a 45 72 72 4d 73 67 29 3b 0a 20  base.zErrMsg);. 
a4f0: 20 20 20 20 20 20 20 20 20 20 20 69 66 28 20 72             if( r
a500: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
a510: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
a520: 28 20 69 4d 65 74 68 6f 64 20 7c 7c 20 6e 43 6d  ( iMethod || nCm
a530: 70 3c 6e 49 6e 20 29 7b 0a 20 20 20 20 20 20 20  p<nIn ){.       
a540: 20 20 20 20 20 20 20 20 20 69 4d 65 74 68 6f 64           iMethod
a550: 20 3d 20 38 3b 0a 20 20 20 20 20 20 20 20 20 20   = 8;.          
a560: 20 20 20 20 20 20 70 44 61 74 61 20 3d 20 70 46        pData = pF
a570: 72 65 65 3b 0a 20 20 20 20 20 20 20 20 20 20 20  ree;.           
a580: 20 20 20 20 20 6e 44 61 74 61 20 3d 20 6e 43 6d       nData = nCm
a590: 70 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  p;.             
a5a0: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d   }.            }
a5b0: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
a5c0: 20 20 20 20 20 20 20 69 43 72 63 33 32 20 3d 20         iCrc32 = 
a5d0: 63 72 63 33 32 28 30 2c 20 61 49 6e 2c 20 6e 49  crc32(0, aIn, nI
a5e0: 6e 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  n);.        }.  
a5f0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20      }.    }..   
a600: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
a610: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 63 20 3d  OK ){.      rc =
a620: 20 7a 69 70 66 69 6c 65 47 65 74 4d 6f 64 65 28   zipfileGetMode(
a630: 61 70 56 61 6c 5b 33 5d 2c 20 62 49 73 44 69 72  apVal[3], bIsDir
a640: 2c 20 26 6d 6f 64 65 2c 20 26 70 54 61 62 2d 3e  , &mode, &pTab->
a650: 62 61 73 65 2e 7a 45 72 72 4d 73 67 29 3b 0a 20  base.zErrMsg);. 
a660: 20 20 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63     }..    if( rc
a670: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
a680: 20 20 20 20 20 7a 50 61 74 68 20 3d 20 28 63 6f       zPath = (co
a690: 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65  nst char*)sqlite
a6a0: 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 70 56  3_value_text(apV
a6b0: 61 6c 5b 32 5d 29 3b 0a 20 20 20 20 20 20 6e 50  al[2]);.      nP
a6c0: 61 74 68 20 3d 20 28 69 6e 74 29 73 74 72 6c 65  ath = (int)strle
a6d0: 6e 28 7a 50 61 74 68 29 3b 0a 20 20 20 20 20 20  n(zPath);.      
a6e0: 69 66 28 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  if( sqlite3_valu
a6f0: 65 5f 74 79 70 65 28 61 70 56 61 6c 5b 34 5d 29  e_type(apVal[4])
a700: 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c 20 29 7b  ==SQLITE_NULL ){
a710: 0a 20 20 20 20 20 20 20 20 6d 54 69 6d 65 20 3d  .        mTime =
a720: 20 28 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 29   (sqlite3_int64)
a730: 74 69 6d 65 28 30 29 3b 0a 20 20 20 20 20 20 7d  time(0);.      }
a740: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 6d 54  else{.        mT
a750: 69 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f 76 61  ime = sqlite3_va
a760: 6c 75 65 5f 69 6e 74 36 34 28 61 70 56 61 6c 5b  lue_int64(apVal[
a770: 34 5d 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  4]);.      }.   
a780: 20 7d 0a 0a 20 20 20 20 69 66 28 20 72 63 3d 3d   }..    if( rc==
a790: 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 62 49 73  SQLITE_OK && bIs
a7a0: 44 69 72 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  Dir ){.      /* 
a7b0: 46 6f 72 20 61 20 64 69 72 65 63 74 6f 72 79 2c  For a directory,
a7c0: 20 63 68 65 63 6b 20 74 68 61 74 20 74 68 65 20   check that the 
a7d0: 6c 61 73 74 20 63 68 61 72 61 63 74 65 72 20 69  last character i
a7e0: 6e 20 74 68 65 20 70 61 74 68 20 69 73 20 61 0a  n the path is a.
a7f0: 20 20 20 20 20 20 2a 2a 20 27 2f 27 2e 20 54 68        ** '/'. Th
a800: 69 73 20 61 70 70 65 61 72 73 20 74 6f 20 62 65  is appears to be
a810: 20 72 65 71 75 69 72 65 64 20 66 6f 72 20 63 6f   required for co
a820: 6d 70 61 74 69 62 69 6c 69 74 79 20 77 69 74 68  mpatibility with
a830: 20 69 6e 66 6f 2d 7a 69 70 0a 20 20 20 20 20 20   info-zip.      
a840: 2a 2a 20 28 74 68 65 20 75 6e 7a 69 70 20 63 6f  ** (the unzip co
a850: 6d 6d 61 6e 64 20 6f 6e 20 75 6e 69 78 29 2e 20  mmand on unix). 
a860: 49 74 20 64 6f 65 73 20 6e 6f 74 20 63 72 65 61  It does not crea
a870: 74 65 20 64 69 72 65 63 74 6f 72 69 65 73 0a 20  te directories. 
a880: 20 20 20 20 20 2a 2a 20 6f 74 68 65 72 77 69 73       ** otherwis
a890: 65 2e 20 20 2a 2f 0a 20 20 20 20 20 20 69 66 28  e.  */.      if(
a8a0: 20 7a 50 61 74 68 5b 6e 50 61 74 68 2d 31 5d 21   zPath[nPath-1]!
a8b0: 3d 27 2f 27 20 29 7b 0a 20 20 20 20 20 20 20 20  ='/' ){.        
a8c0: 7a 46 72 65 65 20 3d 20 73 71 6c 69 74 65 33 5f  zFree = sqlite3_
a8d0: 6d 70 72 69 6e 74 66 28 22 25 73 2f 22 2c 20 7a  mprintf("%s/", z
a8e0: 50 61 74 68 29 3b 0a 20 20 20 20 20 20 20 20 69  Path);.        i
a8f0: 66 28 20 7a 46 72 65 65 3d 3d 30 20 29 7b 20 72  f( zFree==0 ){ r
a900: 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  c = SQLITE_NOMEM
a910: 3b 20 7d 0a 20 20 20 20 20 20 20 20 7a 50 61 74  ; }.        zPat
a920: 68 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a  h = (const char*
a930: 29 7a 46 72 65 65 3b 0a 20 20 20 20 20 20 20 20  )zFree;.        
a940: 6e 50 61 74 68 2b 2b 3b 0a 20 20 20 20 20 20 7d  nPath++;.      }
a950: 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 43  .    }..    /* C
a960: 68 65 63 6b 20 74 68 61 74 20 77 65 27 72 65 20  heck that we're 
a970: 6e 6f 74 20 69 6e 73 65 72 74 69 6e 67 20 61 20  not inserting a 
a980: 64 75 70 6c 69 63 61 74 65 20 65 6e 74 72 79 20  duplicate entry 
a990: 2a 2f 0a 20 20 20 20 69 66 28 20 70 4f 6c 64 3d  */.    if( pOld=
a9a0: 3d 30 20 26 26 20 72 63 3d 3d 53 51 4c 49 54 45  =0 && rc==SQLITE
a9b0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 5a 69 70  _OK ){.      Zip
a9c0: 66 69 6c 65 45 6e 74 72 79 20 2a 70 3b 0a 20 20  fileEntry *p;.  
a9d0: 20 20 20 20 66 6f 72 28 70 3d 70 54 61 62 2d 3e      for(p=pTab->
a9e0: 70 46 69 72 73 74 45 6e 74 72 79 3b 20 70 3b 20  pFirstEntry; p; 
a9f0: 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  p=p->pNext){.   
aa00: 20 20 20 20 20 69 66 28 20 7a 69 70 66 69 6c 65       if( zipfile
aa10: 43 6f 6d 70 61 72 65 50 61 74 68 28 70 2d 3e 63  ComparePath(p->c
aa20: 64 73 2e 7a 46 69 6c 65 2c 20 7a 50 61 74 68 2c  ds.zFile, zPath,
aa30: 20 6e 50 61 74 68 29 3d 3d 30 20 29 7b 0a 20 20   nPath)==0 ){.  
aa40: 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51 4c          rc = SQL
aa50: 49 54 45 5f 43 4f 4e 53 54 52 41 49 4e 54 3b 0a  ITE_CONSTRAINT;.
aa60: 20 20 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b            break;
aa70: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
aa80: 20 7d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66   }.    }..    if
aa90: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
aaa0: 29 7b 0a 20 20 20 20 20 20 2f 2a 20 43 72 65 61  ){.      /* Crea
aab0: 74 65 20 74 68 65 20 6e 65 77 20 43 44 53 20 72  te the new CDS r
aac0: 65 63 6f 72 64 2e 20 2a 2f 0a 20 20 20 20 20 20  ecord. */.      
aad0: 70 4e 65 77 20 3d 20 7a 69 70 66 69 6c 65 4e 65  pNew = zipfileNe
aae0: 77 45 6e 74 72 79 28 7a 50 61 74 68 2c 20 70 54  wEntry(zPath, pT
aaf0: 61 62 2d 3e 7a 46 69 6c 65 20 3f 20 30 20 3a 20  ab->zFile ? 0 : 
ab00: 28 6e 44 61 74 61 2b 31 29 29 3b 0a 20 20 20 20  (nData+1));.    
ab10: 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20 29 7b    if( pNew==0 ){
ab20: 0a 20 20 20 20 20 20 20 20 72 63 20 3d 20 53 51  .        rc = SQ
ab30: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
ab40: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
ab50: 20 70 4e 65 77 2d 3e 63 64 73 2e 69 56 65 72 73   pNew->cds.iVers
ab60: 69 6f 6e 4d 61 64 65 42 79 20 3d 20 5a 49 50 46  ionMadeBy = ZIPF
ab70: 49 4c 45 5f 4e 45 57 45 4e 54 52 59 5f 4d 41 44  ILE_NEWENTRY_MAD
ab80: 45 42 59 3b 0a 20 20 20 20 20 20 20 20 70 4e 65  EBY;.        pNe
ab90: 77 2d 3e 63 64 73 2e 69 56 65 72 73 69 6f 6e 45  w->cds.iVersionE
aba0: 78 74 72 61 63 74 20 3d 20 5a 49 50 46 49 4c 45  xtract = ZIPFILE
abb0: 5f 4e 45 57 45 4e 54 52 59 5f 52 45 51 55 49 52  _NEWENTRY_REQUIR
abc0: 45 44 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 77  ED;.        pNew
abd0: 2d 3e 63 64 73 2e 66 6c 61 67 73 20 3d 20 5a 49  ->cds.flags = ZI
abe0: 50 46 49 4c 45 5f 4e 45 57 45 4e 54 52 59 5f 46  PFILE_NEWENTRY_F
abf0: 4c 41 47 53 3b 0a 20 20 20 20 20 20 20 20 70 4e  LAGS;.        pN
ac00: 65 77 2d 3e 63 64 73 2e 69 43 6f 6d 70 72 65 73  ew->cds.iCompres
ac10: 73 69 6f 6e 20 3d 20 28 75 31 36 29 69 4d 65 74  sion = (u16)iMet
ac20: 68 6f 64 3b 0a 20 20 20 20 20 20 20 20 7a 69 70  hod;.        zip
ac30: 66 69 6c 65 4d 74 69 6d 65 54 6f 44 6f 73 28 26  fileMtimeToDos(&
ac40: 70 4e 65 77 2d 3e 63 64 73 2c 20 28 75 33 32 29  pNew->cds, (u32)
ac50: 6d 54 69 6d 65 29 3b 0a 20 20 20 20 20 20 20 20  mTime);.        
ac60: 70 4e 65 77 2d 3e 63 64 73 2e 63 72 63 33 32 20  pNew->cds.crc32 
ac70: 3d 20 69 43 72 63 33 32 3b 0a 20 20 20 20 20 20  = iCrc32;.      
ac80: 20 20 70 4e 65 77 2d 3e 63 64 73 2e 73 7a 43 6f    pNew->cds.szCo
ac90: 6d 70 72 65 73 73 65 64 20 3d 20 6e 44 61 74 61  mpressed = nData
aca0: 3b 0a 20 20 20 20 20 20 20 20 70 4e 65 77 2d 3e  ;.        pNew->
acb0: 63 64 73 2e 73 7a 55 6e 63 6f 6d 70 72 65 73 73  cds.szUncompress
acc0: 65 64 20 3d 20 28 75 33 32 29 73 7a 3b 0a 20 20  ed = (u32)sz;.  
acd0: 20 20 20 20 20 20 70 4e 65 77 2d 3e 63 64 73 2e        pNew->cds.
ace0: 69 45 78 74 65 72 6e 61 6c 41 74 74 72 20 3d 20  iExternalAttr = 
acf0: 28 6d 6f 64 65 3c 3c 31 36 29 3b 0a 20 20 20 20  (mode<<16);.    
ad00: 20 20 20 20 70 4e 65 77 2d 3e 63 64 73 2e 69 4f      pNew->cds.iO
ad10: 66 66 73 65 74 20 3d 20 28 75 33 32 29 70 54 61  ffset = (u32)pTa
ad20: 62 2d 3e 73 7a 43 75 72 72 65 6e 74 3b 0a 20 20  b->szCurrent;.  
ad30: 20 20 20 20 20 20 70 4e 65 77 2d 3e 63 64 73 2e        pNew->cds.
ad40: 6e 46 69 6c 65 20 3d 20 6e 50 61 74 68 3b 0a 20  nFile = nPath;. 
ad50: 20 20 20 20 20 20 20 70 4e 65 77 2d 3e 6d 55 6e         pNew->mUn
ad60: 69 78 54 69 6d 65 20 3d 20 28 75 33 32 29 6d 54  ixTime = (u32)mT
ad70: 69 6d 65 3b 0a 20 20 20 20 20 20 20 20 69 66 28  ime;.        if(
ad80: 20 70 54 61 62 2d 3e 7a 46 69 6c 65 20 29 7b 0a   pTab->zFile ){.
ad90: 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 7a            rc = z
ada0: 69 70 66 69 6c 65 41 70 70 65 6e 64 45 6e 74 72  ipfileAppendEntr
adb0: 79 28 70 54 61 62 2c 20 70 4e 65 77 2c 20 70 44  y(pTab, pNew, pD
adc0: 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a 20 20 20  ata, nData);.   
add0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
ade0: 20 20 20 20 20 20 6d 65 6d 63 70 79 28 70 4e 65        memcpy(pNe
adf0: 77 2d 3e 61 44 61 74 61 2c 20 70 44 61 74 61 2c  w->aData, pData,
ae00: 20 6e 44 61 74 61 29 3b 0a 20 20 20 20 20 20 20   nData);.       
ae10: 20 7d 0a 20 20 20 20 20 20 20 20 7a 69 70 66 69   }.        zipfi
ae20: 6c 65 41 64 64 45 6e 74 72 79 28 70 54 61 62 2c  leAddEntry(pTab,
ae30: 20 70 4f 6c 64 2c 20 70 4e 65 77 29 3b 0a 20 20   pOld, pNew);.  
ae40: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
ae50: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
ae60: 45 5f 4f 4b 20 26 26 20 70 4f 6c 64 20 29 7b 0a  E_OK && pOld ){.
ae70: 20 20 20 20 5a 69 70 66 69 6c 65 45 6e 74 72 79      ZipfileEntry
ae80: 20 2a 2a 70 70 3b 0a 20 20 20 20 5a 69 70 66 69   **pp;.    Zipfi
ae90: 6c 65 43 73 72 20 2a 70 43 73 72 3b 0a 20 20 20  leCsr *pCsr;.   
aea0: 20 66 6f 72 28 70 43 73 72 3d 70 54 61 62 2d 3e   for(pCsr=pTab->
aeb0: 70 43 73 72 4c 69 73 74 3b 20 70 43 73 72 3b 20  pCsrList; pCsr; 
aec0: 70 43 73 72 3d 70 43 73 72 2d 3e 70 43 73 72 4e  pCsr=pCsr->pCsrN
aed0: 65 78 74 29 7b 0a 20 20 20 20 20 20 69 66 28 20  ext){.      if( 
aee0: 70 43 73 72 2d 3e 70 43 75 72 72 65 6e 74 3d 3d  pCsr->pCurrent==
aef0: 70 4f 6c 64 20 29 7b 0a 20 20 20 20 20 20 20 20  pOld ){.        
af00: 70 43 73 72 2d 3e 70 43 75 72 72 65 6e 74 20 3d  pCsr->pCurrent =
af10: 20 70 4f 6c 64 2d 3e 70 4e 65 78 74 3b 0a 20 20   pOld->pNext;.  
af20: 20 20 20 20 20 20 70 43 73 72 2d 3e 62 4e 6f 6f        pCsr->bNoo
af30: 70 20 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20  p = 1;.      }. 
af40: 20 20 20 7d 0a 20 20 20 20 66 6f 72 28 70 70 3d     }.    for(pp=
af50: 26 70 54 61 62 2d 3e 70 46 69 72 73 74 45 6e 74  &pTab->pFirstEnt
af60: 72 79 3b 20 28 2a 70 70 29 21 3d 70 4f 6c 64 3b  ry; (*pp)!=pOld;
af70: 20 70 70 3d 26 28 28 2a 70 70 29 2d 3e 70 4e 65   pp=&((*pp)->pNe
af80: 78 74 29 29 3b 0a 20 20 20 20 2a 70 70 20 3d 20  xt));.    *pp = 
af90: 28 2a 70 70 29 2d 3e 70 4e 65 78 74 3b 0a 20 20  (*pp)->pNext;.  
afa0: 20 20 7a 69 70 66 69 6c 65 45 6e 74 72 79 46 72    zipfileEntryFr
afb0: 65 65 28 70 4f 6c 64 29 3b 0a 20 20 7d 0a 0a 20  ee(pOld);.  }.. 
afc0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 46   sqlite3_free(pF
afd0: 72 65 65 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  ree);.  sqlite3_
afe0: 66 72 65 65 28 7a 46 72 65 65 29 3b 0a 20 20 72  free(zFree);.  r
aff0: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 73 74 61  eturn rc;.}..sta
b000: 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 53  tic int zipfileS
b010: 65 72 69 61 6c 69 7a 65 45 4f 43 44 28 5a 69 70  erializeEOCD(Zip
b020: 66 69 6c 65 45 4f 43 44 20 2a 70 2c 20 75 38 20  fileEOCD *p, u8 
b030: 2a 61 42 75 66 29 7b 0a 20 20 75 38 20 2a 61 20  *aBuf){.  u8 *a 
b040: 3d 20 61 42 75 66 3b 0a 20 20 7a 69 70 66 69 6c  = aBuf;.  zipfil
b050: 65 57 72 69 74 65 33 32 28 61 2c 20 5a 49 50 46  eWrite32(a, ZIPF
b060: 49 4c 45 5f 53 49 47 4e 41 54 55 52 45 5f 45 4f  ILE_SIGNATURE_EO
b070: 43 44 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72  CD);.  zipfileWr
b080: 69 74 65 31 36 28 61 2c 20 70 2d 3e 69 44 69 73  ite16(a, p->iDis
b090: 6b 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69  k);.  zipfileWri
b0a0: 74 65 31 36 28 61 2c 20 70 2d 3e 69 46 69 72 73  te16(a, p->iFirs
b0b0: 74 44 69 73 6b 29 3b 0a 20 20 7a 69 70 66 69 6c  tDisk);.  zipfil
b0c0: 65 57 72 69 74 65 31 36 28 61 2c 20 70 2d 3e 6e  eWrite16(a, p->n
b0d0: 45 6e 74 72 79 29 3b 0a 20 20 7a 69 70 66 69 6c  Entry);.  zipfil
b0e0: 65 57 72 69 74 65 31 36 28 61 2c 20 70 2d 3e 6e  eWrite16(a, p->n
b0f0: 45 6e 74 72 79 54 6f 74 61 6c 29 3b 0a 20 20 7a  EntryTotal);.  z
b100: 69 70 66 69 6c 65 57 72 69 74 65 33 32 28 61 2c  ipfileWrite32(a,
b110: 20 70 2d 3e 6e 53 69 7a 65 29 3b 0a 20 20 7a 69   p->nSize);.  zi
b120: 70 66 69 6c 65 57 72 69 74 65 33 32 28 61 2c 20  pfileWrite32(a, 
b130: 70 2d 3e 69 4f 66 66 73 65 74 29 3b 0a 20 20 7a  p->iOffset);.  z
b140: 69 70 66 69 6c 65 57 72 69 74 65 31 36 28 61 2c  ipfileWrite16(a,
b150: 20 30 29 3b 20 20 20 20 20 20 20 20 2f 2a 20 53   0);        /* S
b160: 69 7a 65 20 6f 66 20 74 72 61 69 6c 69 6e 67 20  ize of trailing 
b170: 63 6f 6d 6d 65 6e 74 20 69 6e 20 62 79 74 65 73  comment in bytes
b180: 2a 2f 0a 0a 20 20 72 65 74 75 72 6e 20 61 2d 61  */..  return a-a
b190: 42 75 66 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  Buf;.}..static i
b1a0: 6e 74 20 7a 69 70 66 69 6c 65 41 70 70 65 6e 64  nt zipfileAppend
b1b0: 45 4f 43 44 28 5a 69 70 66 69 6c 65 54 61 62 20  EOCD(ZipfileTab 
b1c0: 2a 70 54 61 62 2c 20 5a 69 70 66 69 6c 65 45 4f  *pTab, ZipfileEO
b1d0: 43 44 20 2a 70 29 7b 0a 20 20 69 6e 74 20 6e 42  CD *p){.  int nB
b1e0: 75 66 20 3d 20 7a 69 70 66 69 6c 65 53 65 72 69  uf = zipfileSeri
b1f0: 61 6c 69 7a 65 45 4f 43 44 28 70 2c 20 70 54 61  alizeEOCD(p, pTa
b200: 62 2d 3e 61 42 75 66 66 65 72 29 3b 0a 20 20 61  b->aBuffer);.  a
b210: 73 73 65 72 74 28 20 6e 42 75 66 3d 3d 5a 49 50  ssert( nBuf==ZIP
b220: 46 49 4c 45 5f 45 4f 43 44 5f 46 49 58 45 44 5f  FILE_EOCD_FIXED_
b230: 53 5a 20 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a  SZ );.  return z
b240: 69 70 66 69 6c 65 41 70 70 65 6e 64 44 61 74 61  ipfileAppendData
b250: 28 70 54 61 62 2c 20 70 54 61 62 2d 3e 61 42 75  (pTab, pTab->aBu
b260: 66 66 65 72 2c 20 6e 42 75 66 29 3b 0a 7d 0a 0a  ffer, nBuf);.}..
b270: 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70 66 69  static int zipfi
b280: 6c 65 42 65 67 69 6e 28 73 71 6c 69 74 65 33 5f  leBegin(sqlite3_
b290: 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20 20  vtab *pVtab){.  
b2a0: 5a 69 70 66 69 6c 65 54 61 62 20 2a 70 54 61 62  ZipfileTab *pTab
b2b0: 20 3d 20 28 5a 69 70 66 69 6c 65 54 61 62 2a 29   = (ZipfileTab*)
b2c0: 70 56 74 61 62 3b 0a 20 20 69 6e 74 20 72 63 20  pVtab;.  int rc 
b2d0: 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20  = SQLITE_OK;..  
b2e0: 61 73 73 65 72 74 28 20 70 54 61 62 2d 3e 70 57  assert( pTab->pW
b2f0: 72 69 74 65 46 64 3d 3d 30 20 29 3b 0a 20 20 69  riteFd==0 );.  i
b300: 66 28 20 70 54 61 62 2d 3e 7a 46 69 6c 65 20 29  f( pTab->zFile )
b310: 7b 0a 20 20 20 20 2f 2a 20 4f 70 65 6e 20 61 20  {.    /* Open a 
b320: 77 72 69 74 65 20 66 64 20 6f 6e 20 74 68 65 20  write fd on the 
b330: 66 69 6c 65 2e 20 41 6c 73 6f 20 6c 6f 61 64 20  file. Also load 
b340: 74 68 65 20 65 6e 74 69 72 65 20 63 65 6e 74 72  the entire centr
b350: 61 6c 20 64 69 72 65 63 74 6f 72 79 0a 20 20 20  al directory.   
b360: 20 2a 2a 20 73 74 72 75 63 74 75 72 65 20 69 6e   ** structure in
b370: 74 6f 20 6d 65 6d 6f 72 79 2e 20 44 75 72 69 6e  to memory. Durin
b380: 67 20 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f  g the transactio
b390: 6e 20 61 6e 79 20 6e 65 77 20 66 69 6c 65 20 64  n any new file d
b3a0: 61 74 61 20 69 73 20 0a 20 20 20 20 2a 2a 20 61  ata is .    ** a
b3b0: 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 61  ppended to the a
b3c0: 72 63 68 69 76 65 20 66 69 6c 65 2c 20 62 75 74  rchive file, but
b3d0: 20 74 68 65 20 63 65 6e 74 72 61 6c 20 64 69 72   the central dir
b3e0: 65 63 74 6f 72 79 20 69 73 20 61 63 63 75 6d 75  ectory is accumu
b3f0: 6c 61 74 65 64 0a 20 20 20 20 2a 2a 20 69 6e 20  lated.    ** in 
b400: 6d 61 69 6e 2d 6d 65 6d 6f 72 79 20 75 6e 74 69  main-memory unti
b410: 6c 20 74 68 65 20 74 72 61 6e 73 61 63 74 69 6f  l the transactio
b420: 6e 20 69 73 20 63 6f 6d 6d 69 74 74 65 64 2e 20  n is committed. 
b430: 20 2a 2f 0a 20 20 20 20 70 54 61 62 2d 3e 70 57   */.    pTab->pW
b440: 72 69 74 65 46 64 20 3d 20 66 6f 70 65 6e 28 70  riteFd = fopen(p
b450: 54 61 62 2d 3e 7a 46 69 6c 65 2c 20 22 61 62 2b  Tab->zFile, "ab+
b460: 22 29 3b 0a 20 20 20 20 69 66 28 20 70 54 61 62  ");.    if( pTab
b470: 2d 3e 70 57 72 69 74 65 46 64 3d 3d 30 20 29 7b  ->pWriteFd==0 ){
b480: 0a 20 20 20 20 20 20 70 54 61 62 2d 3e 62 61 73  .      pTab->bas
b490: 65 2e 7a 45 72 72 4d 73 67 20 3d 20 73 71 6c 69  e.zErrMsg = sqli
b4a0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 0a 20 20 20  te3_mprintf(.   
b4b0: 20 20 20 20 20 20 20 22 7a 69 70 66 69 6c 65 3a         "zipfile:
b4c0: 20 66 61 69 6c 65 64 20 74 6f 20 6f 70 65 6e 20   failed to open 
b4d0: 66 69 6c 65 20 25 73 20 66 6f 72 20 77 72 69 74  file %s for writ
b4e0: 69 6e 67 22 2c 20 70 54 61 62 2d 3e 7a 46 69 6c  ing", pTab->zFil
b4f0: 65 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 20  e.      );.     
b500: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52   rc = SQLITE_ERR
b510: 4f 52 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  OR;.    }else{. 
b520: 20 20 20 20 20 66 73 65 65 6b 28 70 54 61 62 2d       fseek(pTab-
b530: 3e 70 57 72 69 74 65 46 64 2c 20 30 2c 20 53 45  >pWriteFd, 0, SE
b540: 45 4b 5f 45 4e 44 29 3b 0a 20 20 20 20 20 20 70  EK_END);.      p
b550: 54 61 62 2d 3e 73 7a 43 75 72 72 65 6e 74 20 3d  Tab->szCurrent =
b560: 20 70 54 61 62 2d 3e 73 7a 4f 72 69 67 20 3d 20   pTab->szOrig = 
b570: 28 69 36 34 29 66 74 65 6c 6c 28 70 54 61 62 2d  (i64)ftell(pTab-
b580: 3e 70 57 72 69 74 65 46 64 29 3b 0a 20 20 20 20  >pWriteFd);.    
b590: 20 20 72 63 20 3d 20 7a 69 70 66 69 6c 65 4c 6f    rc = zipfileLo
b5a0: 61 64 44 69 72 65 63 74 6f 72 79 28 70 54 61 62  adDirectory(pTab
b5b0: 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 7d 0a 0a  , 0, 0);.    }..
b5c0: 20 20 20 20 69 66 28 20 72 63 21 3d 53 51 4c 49      if( rc!=SQLI
b5d0: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 7a  TE_OK ){.      z
b5e0: 69 70 66 69 6c 65 43 6c 65 61 6e 75 70 54 72 61  ipfileCleanupTra
b5f0: 6e 73 61 63 74 69 6f 6e 28 70 54 61 62 29 3b 0a  nsaction(pTab);.
b600: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74      }.  }..  ret
b610: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
b620: 20 53 65 72 69 61 6c 69 7a 65 20 74 68 65 20 43   Serialize the C
b630: 44 53 20 73 74 72 75 63 74 75 72 65 20 69 6e 74  DS structure int
b640: 6f 20 62 75 66 66 65 72 20 61 42 75 66 5b 5d 2e  o buffer aBuf[].
b650: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62   Return the numb
b660: 65 72 0a 2a 2a 20 6f 66 20 62 79 74 65 73 20 77  er.** of bytes w
b670: 72 69 74 74 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69  ritten..*/.stati
b680: 63 20 69 6e 74 20 7a 69 70 66 69 6c 65 53 65 72  c int zipfileSer
b690: 69 61 6c 69 7a 65 43 44 53 28 5a 69 70 66 69 6c  ializeCDS(Zipfil
b6a0: 65 45 6e 74 72 79 20 2a 70 45 6e 74 72 79 2c 20  eEntry *pEntry, 
b6b0: 75 38 20 2a 61 42 75 66 29 7b 0a 20 20 75 38 20  u8 *aBuf){.  u8 
b6c0: 2a 61 20 3d 20 61 42 75 66 3b 0a 20 20 5a 69 70  *a = aBuf;.  Zip
b6d0: 66 69 6c 65 43 44 53 20 2a 70 43 44 53 20 3d 20  fileCDS *pCDS = 
b6e0: 26 70 45 6e 74 72 79 2d 3e 63 64 73 3b 0a 0a 20  &pEntry->cds;.. 
b6f0: 20 69 66 28 20 70 45 6e 74 72 79 2d 3e 61 45 78   if( pEntry->aEx
b700: 74 72 61 3d 3d 30 20 29 7b 0a 20 20 20 20 70 43  tra==0 ){.    pC
b710: 44 53 2d 3e 6e 45 78 74 72 61 20 3d 20 39 3b 0a  DS->nExtra = 9;.
b720: 20 20 7d 0a 0a 20 20 7a 69 70 66 69 6c 65 57 72    }..  zipfileWr
b730: 69 74 65 33 32 28 61 2c 20 5a 49 50 46 49 4c 45  ite32(a, ZIPFILE
b740: 5f 53 49 47 4e 41 54 55 52 45 5f 43 44 53 29 3b  _SIGNATURE_CDS);
b750: 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65 31  .  zipfileWrite1
b760: 36 28 61 2c 20 70 43 44 53 2d 3e 69 56 65 72 73  6(a, pCDS->iVers
b770: 69 6f 6e 4d 61 64 65 42 79 29 3b 0a 20 20 7a 69  ionMadeBy);.  zi
b780: 70 66 69 6c 65 57 72 69 74 65 31 36 28 61 2c 20  pfileWrite16(a, 
b790: 70 43 44 53 2d 3e 69 56 65 72 73 69 6f 6e 45 78  pCDS->iVersionEx
b7a0: 74 72 61 63 74 29 3b 0a 20 20 7a 69 70 66 69 6c  tract);.  zipfil
b7b0: 65 57 72 69 74 65 31 36 28 61 2c 20 70 43 44 53  eWrite16(a, pCDS
b7c0: 2d 3e 66 6c 61 67 73 29 3b 0a 20 20 7a 69 70 66  ->flags);.  zipf
b7d0: 69 6c 65 57 72 69 74 65 31 36 28 61 2c 20 70 43  ileWrite16(a, pC
b7e0: 44 53 2d 3e 69 43 6f 6d 70 72 65 73 73 69 6f 6e  DS->iCompression
b7f0: 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74  );.  zipfileWrit
b800: 65 31 36 28 61 2c 20 70 43 44 53 2d 3e 6d 54 69  e16(a, pCDS->mTi
b810: 6d 65 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72  me);.  zipfileWr
b820: 69 74 65 31 36 28 61 2c 20 70 43 44 53 2d 3e 6d  ite16(a, pCDS->m
b830: 44 61 74 65 29 3b 0a 20 20 7a 69 70 66 69 6c 65  Date);.  zipfile
b840: 57 72 69 74 65 33 32 28 61 2c 20 70 43 44 53 2d  Write32(a, pCDS-
b850: 3e 63 72 63 33 32 29 3b 0a 20 20 7a 69 70 66 69  >crc32);.  zipfi
b860: 6c 65 57 72 69 74 65 33 32 28 61 2c 20 70 43 44  leWrite32(a, pCD
b870: 53 2d 3e 73 7a 43 6f 6d 70 72 65 73 73 65 64 29  S->szCompressed)
b880: 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65  ;.  zipfileWrite
b890: 33 32 28 61 2c 20 70 43 44 53 2d 3e 73 7a 55 6e  32(a, pCDS->szUn
b8a0: 63 6f 6d 70 72 65 73 73 65 64 29 3b 0a 20 20 61  compressed);.  a
b8b0: 73 73 65 72 74 28 20 61 3d 3d 26 61 42 75 66 5b  ssert( a==&aBuf[
b8c0: 5a 49 50 46 49 4c 45 5f 43 44 53 5f 4e 46 49 4c  ZIPFILE_CDS_NFIL
b8d0: 45 5f 4f 46 46 5d 20 29 3b 0a 20 20 7a 69 70 66  E_OFF] );.  zipf
b8e0: 69 6c 65 57 72 69 74 65 31 36 28 61 2c 20 70 43  ileWrite16(a, pC
b8f0: 44 53 2d 3e 6e 46 69 6c 65 29 3b 0a 20 20 7a 69  DS->nFile);.  zi
b900: 70 66 69 6c 65 57 72 69 74 65 31 36 28 61 2c 20  pfileWrite16(a, 
b910: 70 43 44 53 2d 3e 6e 45 78 74 72 61 29 3b 0a 20  pCDS->nExtra);. 
b920: 20 7a 69 70 66 69 6c 65 57 72 69 74 65 31 36 28   zipfileWrite16(
b930: 61 2c 20 70 43 44 53 2d 3e 6e 43 6f 6d 6d 65 6e  a, pCDS->nCommen
b940: 74 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72 69  t);.  zipfileWri
b950: 74 65 31 36 28 61 2c 20 70 43 44 53 2d 3e 69 44  te16(a, pCDS->iD
b960: 69 73 6b 53 74 61 72 74 29 3b 0a 20 20 7a 69 70  iskStart);.  zip
b970: 66 69 6c 65 57 72 69 74 65 31 36 28 61 2c 20 70  fileWrite16(a, p
b980: 43 44 53 2d 3e 69 49 6e 74 65 72 6e 61 6c 41 74  CDS->iInternalAt
b990: 74 72 29 3b 0a 20 20 7a 69 70 66 69 6c 65 57 72  tr);.  zipfileWr
b9a0: 69 74 65 33 32 28 61 2c 20 70 43 44 53 2d 3e 69  ite32(a, pCDS->i
b9b0: 45 78 74 65 72 6e 61 6c 41 74 74 72 29 3b 0a 20  ExternalAttr);. 
b9c0: 20 7a 69 70 66 69 6c 65 57 72 69 74 65 33 32 28   zipfileWrite32(
b9d0: 61 2c 20 70 43 44 53 2d 3e 69 4f 66 66 73 65 74  a, pCDS->iOffset
b9e0: 29 3b 0a 0a 20 20 6d 65 6d 63 70 79 28 61 2c 20  );..  memcpy(a, 
b9f0: 70 43 44 53 2d 3e 7a 46 69 6c 65 2c 20 70 43 44  pCDS->zFile, pCD
ba00: 53 2d 3e 6e 46 69 6c 65 29 3b 0a 20 20 61 20 2b  S->nFile);.  a +
ba10: 3d 20 70 43 44 53 2d 3e 6e 46 69 6c 65 3b 0a 0a  = pCDS->nFile;..
ba20: 20 20 69 66 28 20 70 45 6e 74 72 79 2d 3e 61 45    if( pEntry->aE
ba30: 78 74 72 61 20 29 7b 0a 20 20 20 20 69 6e 74 20  xtra ){.    int 
ba40: 6e 20 3d 20 28 69 6e 74 29 70 43 44 53 2d 3e 6e  n = (int)pCDS->n
ba50: 45 78 74 72 61 20 2b 20 28 69 6e 74 29 70 43 44  Extra + (int)pCD
ba60: 53 2d 3e 6e 43 6f 6d 6d 65 6e 74 3b 0a 20 20 20  S->nComment;.   
ba70: 20 6d 65 6d 63 70 79 28 61 2c 20 70 45 6e 74 72   memcpy(a, pEntr
ba80: 79 2d 3e 61 45 78 74 72 61 2c 20 6e 29 3b 0a 20  y->aExtra, n);. 
ba90: 20 20 20 61 20 2b 3d 20 6e 3b 0a 20 20 7d 65 6c     a += n;.  }el
baa0: 73 65 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20  se{.    assert( 
bab0: 70 43 44 53 2d 3e 6e 45 78 74 72 61 3d 3d 39 20  pCDS->nExtra==9 
bac0: 29 3b 0a 20 20 20 20 7a 69 70 66 69 6c 65 57 72  );.    zipfileWr
bad0: 69 74 65 31 36 28 61 2c 20 5a 49 50 46 49 4c 45  ite16(a, ZIPFILE
bae0: 5f 45 58 54 52 41 5f 54 49 4d 45 53 54 41 4d 50  _EXTRA_TIMESTAMP
baf0: 29 3b 0a 20 20 20 20 7a 69 70 66 69 6c 65 57 72  );.    zipfileWr
bb00: 69 74 65 31 36 28 61 2c 20 35 29 3b 0a 20 20 20  ite16(a, 5);.   
bb10: 20 2a 61 2b 2b 20 3d 20 30 78 30 31 3b 0a 20 20   *a++ = 0x01;.  
bb20: 20 20 7a 69 70 66 69 6c 65 57 72 69 74 65 33 32    zipfileWrite32
bb30: 28 61 2c 20 70 45 6e 74 72 79 2d 3e 6d 55 6e 69  (a, pEntry->mUni
bb40: 78 54 69 6d 65 29 3b 0a 20 20 7d 0a 0a 20 20 72  xTime);.  }..  r
bb50: 65 74 75 72 6e 20 61 2d 61 42 75 66 3b 0a 7d 0a  eturn a-aBuf;.}.
bb60: 0a 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70 66  .static int zipf
bb70: 69 6c 65 43 6f 6d 6d 69 74 28 73 71 6c 69 74 65  ileCommit(sqlite
bb80: 33 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a  3_vtab *pVtab){.
bb90: 20 20 5a 69 70 66 69 6c 65 54 61 62 20 2a 70 54    ZipfileTab *pT
bba0: 61 62 20 3d 20 28 5a 69 70 66 69 6c 65 54 61 62  ab = (ZipfileTab
bbb0: 2a 29 70 56 74 61 62 3b 0a 20 20 69 6e 74 20 72  *)pVtab;.  int r
bbc0: 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20  c = SQLITE_OK;. 
bbd0: 20 69 66 28 20 70 54 61 62 2d 3e 70 57 72 69 74   if( pTab->pWrit
bbe0: 65 46 64 20 29 7b 0a 20 20 20 20 69 36 34 20 69  eFd ){.    i64 i
bbf0: 4f 66 66 73 65 74 20 3d 20 70 54 61 62 2d 3e 73  Offset = pTab->s
bc00: 7a 43 75 72 72 65 6e 74 3b 0a 20 20 20 20 5a 69  zCurrent;.    Zi
bc10: 70 66 69 6c 65 45 6e 74 72 79 20 2a 70 3b 0a 20  pfileEntry *p;. 
bc20: 20 20 20 5a 69 70 66 69 6c 65 45 4f 43 44 20 65     ZipfileEOCD e
bc30: 6f 63 64 3b 0a 20 20 20 20 69 6e 74 20 6e 45 6e  ocd;.    int nEn
bc40: 74 72 79 20 3d 20 30 3b 0a 0a 20 20 20 20 2f 2a  try = 0;..    /*
bc50: 20 57 72 69 74 65 20 6f 75 74 20 61 6c 6c 20 65   Write out all e
bc60: 6e 74 72 69 65 73 20 2a 2f 0a 20 20 20 20 66 6f  ntries */.    fo
bc70: 72 28 70 3d 70 54 61 62 2d 3e 70 46 69 72 73 74  r(p=pTab->pFirst
bc80: 45 6e 74 72 79 3b 20 72 63 3d 3d 53 51 4c 49 54  Entry; rc==SQLIT
bc90: 45 5f 4f 4b 20 26 26 20 70 3b 20 70 3d 70 2d 3e  E_OK && p; p=p->
bca0: 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 69 6e  pNext){.      in
bcb0: 74 20 6e 20 3d 20 7a 69 70 66 69 6c 65 53 65 72  t n = zipfileSer
bcc0: 69 61 6c 69 7a 65 43 44 53 28 70 2c 20 70 54 61  ializeCDS(p, pTa
bcd0: 62 2d 3e 61 42 75 66 66 65 72 29 3b 0a 20 20 20  b->aBuffer);.   
bce0: 20 20 20 72 63 20 3d 20 7a 69 70 66 69 6c 65 41     rc = zipfileA
bcf0: 70 70 65 6e 64 44 61 74 61 28 70 54 61 62 2c 20  ppendData(pTab, 
bd00: 70 54 61 62 2d 3e 61 42 75 66 66 65 72 2c 20 6e  pTab->aBuffer, n
bd10: 29 3b 0a 20 20 20 20 20 20 6e 45 6e 74 72 79 2b  );.      nEntry+
bd20: 2b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a  +;.    }..    /*
bd30: 20 57 72 69 74 65 20 6f 75 74 20 74 68 65 20 45   Write out the E
bd40: 4f 43 44 20 72 65 63 6f 72 64 20 2a 2f 0a 20 20  OCD record */.  
bd50: 20 20 65 6f 63 64 2e 69 44 69 73 6b 20 3d 20 30    eocd.iDisk = 0
bd60: 3b 0a 20 20 20 20 65 6f 63 64 2e 69 46 69 72 73  ;.    eocd.iFirs
bd70: 74 44 69 73 6b 20 3d 20 30 3b 0a 20 20 20 20 65  tDisk = 0;.    e
bd80: 6f 63 64 2e 6e 45 6e 74 72 79 20 3d 20 28 75 31  ocd.nEntry = (u1
bd90: 36 29 6e 45 6e 74 72 79 3b 0a 20 20 20 20 65 6f  6)nEntry;.    eo
bda0: 63 64 2e 6e 45 6e 74 72 79 54 6f 74 61 6c 20 3d  cd.nEntryTotal =
bdb0: 20 28 75 31 36 29 6e 45 6e 74 72 79 3b 0a 20 20   (u16)nEntry;.  
bdc0: 20 20 65 6f 63 64 2e 6e 53 69 7a 65 20 3d 20 28    eocd.nSize = (
bdd0: 75 33 32 29 28 70 54 61 62 2d 3e 73 7a 43 75 72  u32)(pTab->szCur
bde0: 72 65 6e 74 20 2d 20 69 4f 66 66 73 65 74 29 3b  rent - iOffset);
bdf0: 0a 20 20 20 20 65 6f 63 64 2e 69 4f 66 66 73 65  .    eocd.iOffse
be00: 74 20 3d 20 28 75 33 32 29 69 4f 66 66 73 65 74  t = (u32)iOffset
be10: 3b 0a 20 20 20 20 72 63 20 3d 20 7a 69 70 66 69  ;.    rc = zipfi
be20: 6c 65 41 70 70 65 6e 64 45 4f 43 44 28 70 54 61  leAppendEOCD(pTa
be30: 62 2c 20 26 65 6f 63 64 29 3b 0a 0a 20 20 20 20  b, &eocd);..    
be40: 7a 69 70 66 69 6c 65 43 6c 65 61 6e 75 70 54 72  zipfileCleanupTr
be50: 61 6e 73 61 63 74 69 6f 6e 28 70 54 61 62 29 3b  ansaction(pTab);
be60: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
be70: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
be80: 7a 69 70 66 69 6c 65 52 6f 6c 6c 62 61 63 6b 28  zipfileRollback(
be90: 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56  sqlite3_vtab *pV
bea0: 74 61 62 29 7b 0a 20 20 72 65 74 75 72 6e 20 7a  tab){.  return z
beb0: 69 70 66 69 6c 65 43 6f 6d 6d 69 74 28 70 56 74  ipfileCommit(pVt
bec0: 61 62 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 5a  ab);.}..static Z
bed0: 69 70 66 69 6c 65 43 73 72 20 2a 7a 69 70 66 69  ipfileCsr *zipfi
bee0: 6c 65 46 69 6e 64 43 75 72 73 6f 72 28 5a 69 70  leFindCursor(Zip
bef0: 66 69 6c 65 54 61 62 20 2a 70 54 61 62 2c 20 69  fileTab *pTab, i
bf00: 36 34 20 69 49 64 29 7b 0a 20 20 5a 69 70 66 69  64 iId){.  Zipfi
bf10: 6c 65 43 73 72 20 2a 70 43 73 72 3b 0a 20 20 66  leCsr *pCsr;.  f
bf20: 6f 72 28 70 43 73 72 3d 70 54 61 62 2d 3e 70 43  or(pCsr=pTab->pC
bf30: 73 72 4c 69 73 74 3b 20 70 43 73 72 3b 20 70 43  srList; pCsr; pC
bf40: 73 72 3d 70 43 73 72 2d 3e 70 43 73 72 4e 65 78  sr=pCsr->pCsrNex
bf50: 74 29 7b 0a 20 20 20 20 69 66 28 20 69 49 64 3d  t){.    if( iId=
bf60: 3d 70 43 73 72 2d 3e 69 49 64 20 29 20 62 72 65  =pCsr->iId ) bre
bf70: 61 6b 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ak;.  }.  return
bf80: 20 70 43 73 72 3b 0a 7d 0a 0a 73 74 61 74 69 63   pCsr;.}..static
bf90: 20 76 6f 69 64 20 7a 69 70 66 69 6c 65 46 75 6e   void zipfileFun
bfa0: 63 74 69 6f 6e 43 64 73 28 0a 20 20 73 71 6c 69  ctionCds(.  sqli
bfb0: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e  te3_context *con
bfc0: 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63  text,.  int argc
bfd0: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  ,.  sqlite3_valu
bfe0: 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 5a 69  e **argv.){.  Zi
bff0: 70 66 69 6c 65 43 73 72 20 2a 70 43 73 72 3b 0a  pfileCsr *pCsr;.
c000: 20 20 5a 69 70 66 69 6c 65 54 61 62 20 2a 70 54    ZipfileTab *pT
c010: 61 62 20 3d 20 28 5a 69 70 66 69 6c 65 54 61 62  ab = (ZipfileTab
c020: 2a 29 73 71 6c 69 74 65 33 5f 75 73 65 72 5f 64  *)sqlite3_user_d
c030: 61 74 61 28 63 6f 6e 74 65 78 74 29 3b 0a 20 20  ata(context);.  
c040: 61 73 73 65 72 74 28 20 61 72 67 63 3e 30 20 29  assert( argc>0 )
c050: 3b 0a 0a 20 20 70 43 73 72 20 3d 20 7a 69 70 66  ;..  pCsr = zipf
c060: 69 6c 65 46 69 6e 64 43 75 72 73 6f 72 28 70 54  ileFindCursor(pT
c070: 61 62 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  ab, sqlite3_valu
c080: 65 5f 69 6e 74 36 34 28 61 72 67 76 5b 30 5d 29  e_int64(argv[0])
c090: 29 3b 0a 20 20 69 66 28 20 70 43 73 72 20 29 7b  );.  if( pCsr ){
c0a0: 0a 20 20 20 20 5a 69 70 66 69 6c 65 43 44 53 20  .    ZipfileCDS 
c0b0: 2a 70 20 3d 20 26 70 43 73 72 2d 3e 70 43 75 72  *p = &pCsr->pCur
c0c0: 72 65 6e 74 2d 3e 63 64 73 3b 0a 20 20 20 20 63  rent->cds;.    c
c0d0: 68 61 72 20 2a 7a 52 65 73 20 3d 20 73 71 6c 69  har *zRes = sqli
c0e0: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 7b 22 0a  te3_mprintf("{".
c0f0: 20 20 20 20 20 20 20 20 22 5c 22 76 65 72 73 69          "\"versi
c100: 6f 6e 2d 6d 61 64 65 2d 62 79 5c 22 20 3a 20 25  on-made-by\" : %
c110: 75 2c 20 22 0a 20 20 20 20 20 20 20 20 22 5c 22  u, ".        "\"
c120: 76 65 72 73 69 6f 6e 2d 74 6f 2d 65 78 74 72 61  version-to-extra
c130: 63 74 5c 22 20 3a 20 25 75 2c 20 22 0a 20 20 20  ct\" : %u, ".   
c140: 20 20 20 20 20 22 5c 22 66 6c 61 67 73 5c 22 20       "\"flags\" 
c150: 3a 20 25 75 2c 20 22 0a 20 20 20 20 20 20 20 20  : %u, ".        
c160: 22 5c 22 63 6f 6d 70 72 65 73 73 69 6f 6e 5c 22  "\"compression\"
c170: 20 3a 20 25 75 2c 20 22 0a 20 20 20 20 20 20 20   : %u, ".       
c180: 20 22 5c 22 74 69 6d 65 5c 22 20 3a 20 25 75 2c   "\"time\" : %u,
c190: 20 22 0a 20 20 20 20 20 20 20 20 22 5c 22 64 61   ".        "\"da
c1a0: 74 65 5c 22 20 3a 20 25 75 2c 20 22 0a 20 20 20  te\" : %u, ".   
c1b0: 20 20 20 20 20 22 5c 22 63 72 63 33 32 5c 22 20       "\"crc32\" 
c1c0: 3a 20 25 75 2c 20 22 0a 20 20 20 20 20 20 20 20  : %u, ".        
c1d0: 22 5c 22 63 6f 6d 70 72 65 73 73 65 64 2d 73 69  "\"compressed-si
c1e0: 7a 65 5c 22 20 3a 20 25 75 2c 20 22 0a 20 20 20  ze\" : %u, ".   
c1f0: 20 20 20 20 20 22 5c 22 75 6e 63 6f 6d 70 72 65       "\"uncompre
c200: 73 73 65 64 2d 73 69 7a 65 5c 22 20 3a 20 25 75  ssed-size\" : %u
c210: 2c 20 22 0a 20 20 20 20 20 20 20 20 22 5c 22 66  , ".        "\"f
c220: 69 6c 65 2d 6e 61 6d 65 2d 6c 65 6e 67 74 68 5c  ile-name-length\
c230: 22 20 3a 20 25 75 2c 20 22 0a 20 20 20 20 20 20  " : %u, ".      
c240: 20 20 22 5c 22 65 78 74 72 61 2d 66 69 65 6c 64    "\"extra-field
c250: 2d 6c 65 6e 67 74 68 5c 22 20 3a 20 25 75 2c 20  -length\" : %u, 
c260: 22 0a 20 20 20 20 20 20 20 20 22 5c 22 66 69 6c  ".        "\"fil
c270: 65 2d 63 6f 6d 6d 65 6e 74 2d 6c 65 6e 67 74 68  e-comment-length
c280: 5c 22 20 3a 20 25 75 2c 20 22 0a 20 20 20 20 20  \" : %u, ".     
c290: 20 20 20 22 5c 22 64 69 73 6b 2d 6e 75 6d 62 65     "\"disk-numbe
c2a0: 72 2d 73 74 61 72 74 5c 22 20 3a 20 25 75 2c 20  r-start\" : %u, 
c2b0: 22 0a 20 20 20 20 20 20 20 20 22 5c 22 69 6e 74  ".        "\"int
c2c0: 65 72 6e 61 6c 2d 61 74 74 72 5c 22 20 3a 20 25  ernal-attr\" : %
c2d0: 75 2c 20 22 0a 20 20 20 20 20 20 20 20 22 5c 22  u, ".        "\"
c2e0: 65 78 74 65 72 6e 61 6c 2d 61 74 74 72 5c 22 20  external-attr\" 
c2f0: 3a 20 25 75 2c 20 22 0a 20 20 20 20 20 20 20 20  : %u, ".        
c300: 22 5c 22 6f 66 66 73 65 74 5c 22 20 3a 20 25 75  "\"offset\" : %u
c310: 20 7d 22 2c 0a 20 20 20 20 20 20 20 20 28 75 33   }",.        (u3
c320: 32 29 70 2d 3e 69 56 65 72 73 69 6f 6e 4d 61 64  2)p->iVersionMad
c330: 65 42 79 2c 20 28 75 33 32 29 70 2d 3e 69 56 65  eBy, (u32)p->iVe
c340: 72 73 69 6f 6e 45 78 74 72 61 63 74 2c 0a 20 20  rsionExtract,.  
c350: 20 20 20 20 20 20 28 75 33 32 29 70 2d 3e 66 6c        (u32)p->fl
c360: 61 67 73 2c 20 28 75 33 32 29 70 2d 3e 69 43 6f  ags, (u32)p->iCo
c370: 6d 70 72 65 73 73 69 6f 6e 2c 0a 20 20 20 20 20  mpression,.     
c380: 20 20 20 28 75 33 32 29 70 2d 3e 6d 54 69 6d 65     (u32)p->mTime
c390: 2c 20 28 75 33 32 29 70 2d 3e 6d 44 61 74 65 2c  , (u32)p->mDate,
c3a0: 0a 20 20 20 20 20 20 20 20 28 75 33 32 29 70 2d  .        (u32)p-
c3b0: 3e 63 72 63 33 32 2c 20 28 75 33 32 29 70 2d 3e  >crc32, (u32)p->
c3c0: 73 7a 43 6f 6d 70 72 65 73 73 65 64 2c 0a 20 20  szCompressed,.  
c3d0: 20 20 20 20 20 20 28 75 33 32 29 70 2d 3e 73 7a        (u32)p->sz
c3e0: 55 6e 63 6f 6d 70 72 65 73 73 65 64 2c 20 28 75  Uncompressed, (u
c3f0: 33 32 29 70 2d 3e 6e 46 69 6c 65 2c 0a 20 20 20  32)p->nFile,.   
c400: 20 20 20 20 20 28 75 33 32 29 70 2d 3e 6e 45 78       (u32)p->nEx
c410: 74 72 61 2c 20 28 75 33 32 29 70 2d 3e 6e 43 6f  tra, (u32)p->nCo
c420: 6d 6d 65 6e 74 2c 0a 20 20 20 20 20 20 20 20 28  mment,.        (
c430: 75 33 32 29 70 2d 3e 69 44 69 73 6b 53 74 61 72  u32)p->iDiskStar
c440: 74 2c 20 28 75 33 32 29 70 2d 3e 69 49 6e 74 65  t, (u32)p->iInte
c450: 72 6e 61 6c 41 74 74 72 2c 0a 20 20 20 20 20 20  rnalAttr,.      
c460: 20 20 28 75 33 32 29 70 2d 3e 69 45 78 74 65 72    (u32)p->iExter
c470: 6e 61 6c 41 74 74 72 2c 20 28 75 33 32 29 70 2d  nalAttr, (u32)p-
c480: 3e 69 4f 66 66 73 65 74 0a 20 20 20 20 29 3b 0a  >iOffset.    );.
c490: 0a 20 20 20 20 69 66 28 20 7a 52 65 73 3d 3d 30  .    if( zRes==0
c4a0: 20 29 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65   ){.      sqlite
c4b0: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f 6e  3_result_error_n
c4c0: 6f 6d 65 6d 28 63 6f 6e 74 65 78 74 29 3b 0a 20  omem(context);. 
c4d0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
c4e0: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74  sqlite3_result_t
c4f0: 65 78 74 28 63 6f 6e 74 65 78 74 2c 20 7a 52 65  ext(context, zRe
c500: 73 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52  s, -1, SQLITE_TR
c510: 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20 20 20 20  ANSIENT);.      
c520: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 52 65  sqlite3_free(zRe
c530: 73 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a  s);.    }.  }.}.
c540: 0a 2f 2a 0a 2a 2a 20 78 46 69 6e 64 46 75 6e 63  ./*.** xFindFunc
c550: 74 69 6f 6e 20 6d 65 74 68 6f 64 2e 0a 2a 2f 0a  tion method..*/.
c560: 73 74 61 74 69 63 20 69 6e 74 20 7a 69 70 66 69  static int zipfi
c570: 6c 65 46 69 6e 64 46 75 6e 63 74 69 6f 6e 28 0a  leFindFunction(.
c580: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
c590: 70 56 74 61 62 2c 20 20 20 20 20 20 20 20 20 20  pVtab,          
c5a0: 20 20 2f 2a 20 56 69 72 74 75 61 6c 20 74 61 62    /* Virtual tab
c5b0: 6c 65 20 68 61 6e 64 6c 65 20 2a 2f 0a 20 20 69  le handle */.  i
c5c0: 6e 74 20 6e 41 72 67 2c 20 20 20 20 20 20 20 20  nt nArg,        
c5d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
c5e0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 53 51 4c 20  * Number of SQL 
c5f0: 66 75 6e 63 74 69 6f 6e 20 61 72 67 75 6d 65 6e  function argumen
c600: 74 73 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ts */.  const ch
c610: 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20 20  ar *zName,      
c620: 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20          /* Name 
c630: 6f 66 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e 20  of SQL function 
c640: 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 2a 70 78 46  */.  void (**pxF
c650: 75 6e 63 29 28 73 71 6c 69 74 65 33 5f 63 6f 6e  unc)(sqlite3_con
c660: 74 65 78 74 2a 2c 69 6e 74 2c 73 71 6c 69 74 65  text*,int,sqlite
c670: 33 5f 76 61 6c 75 65 2a 2a 29 2c 20 2f 2a 20 4f  3_value**), /* O
c680: 55 54 3a 20 52 65 73 75 6c 74 20 2a 2f 0a 20 20  UT: Result */.  
c690: 76 6f 69 64 20 2a 2a 70 70 41 72 67 20 20 20 20  void **ppArg    
c6a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c6b0: 2f 2a 20 4f 55 54 3a 20 55 73 65 72 20 64 61 74  /* OUT: User dat
c6c0: 61 20 66 6f 72 20 2a 70 78 46 75 6e 63 20 2a 2f  a for *pxFunc */
c6d0: 0a 29 7b 0a 20 20 69 66 28 20 6e 41 72 67 3e 30  .){.  if( nArg>0
c6e0: 20 29 7b 0a 20 20 20 20 69 66 28 20 73 71 6c 69   ){.    if( sqli
c6f0: 74 65 33 5f 73 74 72 69 63 6d 70 28 22 7a 69 70  te3_stricmp("zip
c700: 66 69 6c 65 5f 63 64 73 22 2c 20 7a 4e 61 6d 65  file_cds", zName
c710: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 2a 70  )==0 ){.      *p
c720: 78 46 75 6e 63 20 3d 20 7a 69 70 66 69 6c 65 46  xFunc = zipfileF
c730: 75 6e 63 74 69 6f 6e 43 64 73 3b 0a 20 20 20 20  unctionCds;.    
c740: 20 20 2a 70 70 41 72 67 20 3d 20 28 76 6f 69 64    *ppArg = (void
c750: 2a 29 70 56 74 61 62 3b 0a 20 20 20 20 20 20 72  *)pVtab;.      r
c760: 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d 0a 20  eturn 1;.    }. 
c770: 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a   }..  return 0;.
c780: 7d 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  }..typedef struc
c790: 74 20 5a 69 70 66 69 6c 65 42 75 66 66 65 72 20  t ZipfileBuffer 
c7a0: 5a 69 70 66 69 6c 65 42 75 66 66 65 72 3b 0a 73  ZipfileBuffer;.s
c7b0: 74 72 75 63 74 20 5a 69 70 66 69 6c 65 42 75 66  truct ZipfileBuf
c7c0: 66 65 72 20 7b 0a 20 20 75 38 20 2a 61 3b 20 20  fer {.  u8 *a;  
c7d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c7e0: 20 20 20 20 20 20 20 20 2f 2a 20 50 6f 69 6e 74          /* Point
c7f0: 65 72 20 74 6f 20 62 75 66 66 65 72 20 2a 2f 0a  er to buffer */.
c800: 20 20 69 6e 74 20 6e 3b 20 20 20 20 20 20 20 20    int n;        
c810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c820: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 62 75 66    /* Size of buf
c830: 66 65 72 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  fer in bytes */.
c840: 20 20 69 6e 74 20 6e 41 6c 6c 6f 63 3b 20 20 20    int nAlloc;   
c850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
c860: 20 20 2f 2a 20 42 79 74 65 20 61 6c 6c 6f 63 61    /* Byte alloca
c870: 74 65 64 20 61 74 20 61 5b 5d 20 2a 2f 0a 7d 3b  ted at a[] */.};
c880: 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74  ..typedef struct
c890: 20 5a 69 70 66 69 6c 65 43 74 78 20 5a 69 70 66   ZipfileCtx Zipf
c8a0: 69 6c 65 43 74 78 3b 0a 73 74 72 75 63 74 20 5a  ileCtx;.struct Z
c8b0: 69 70 66 69 6c 65 43 74 78 20 7b 0a 20 20 69 6e  ipfileCtx {.  in
c8c0: 74 20 6e 45 6e 74 72 79 3b 0a 20 20 5a 69 70 66  t nEntry;.  Zipf
c8d0: 69 6c 65 42 75 66 66 65 72 20 62 6f 64 79 3b 0a  ileBuffer body;.
c8e0: 20 20 5a 69 70 66 69 6c 65 42 75 66 66 65 72 20    ZipfileBuffer 
c8f0: 63 64 73 3b 0a 7d 3b 0a 0a 73 74 61 74 69 63 20  cds;.};..static 
c900: 69 6e 74 20 7a 69 70 66 69 6c 65 42 75 66 66 65  int zipfileBuffe
c910: 72 47 72 6f 77 28 5a 69 70 66 69 6c 65 42 75 66  rGrow(ZipfileBuf
c920: 66 65 72 20 2a 70 42 75 66 2c 20 69 6e 74 20 6e  fer *pBuf, int n
c930: 42 79 74 65 29 7b 0a 20 20 69 66 28 20 70 42 75  Byte){.  if( pBu
c940: 66 2d 3e 6e 2b 6e 42 79 74 65 3e 70 42 75 66 2d  f->n+nByte>pBuf-
c950: 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20 20 20 20 75  >nAlloc ){.    u
c960: 38 20 2a 61 4e 65 77 3b 0a 20 20 20 20 69 6e 74  8 *aNew;.    int
c970: 20 6e 4e 65 77 20 3d 20 70 42 75 66 2d 3e 6e 20   nNew = pBuf->n 
c980: 3f 20 70 42 75 66 2d 3e 6e 2a 32 20 3a 20 35 31  ? pBuf->n*2 : 51
c990: 32 3b 0a 20 20 20 20 69 6e 74 20 6e 52 65 71 20  2;.    int nReq 
c9a0: 3d 20 70 42 75 66 2d 3e 6e 20 2b 20 6e 42 79 74  = pBuf->n + nByt
c9b0: 65 3b 0a 0a 20 20 20 20 77 68 69 6c 65 28 20 6e  e;..    while( n
c9c0: 4e 65 77 3c 6e 52 65 71 20 29 20 6e 4e 65 77 20  New<nReq ) nNew 
c9d0: 3d 20 6e 4e 65 77 2a 32 3b 0a 20 20 20 20 61 4e  = nNew*2;.    aN
c9e0: 65 77 20 3d 20 73 71 6c 69 74 65 33 5f 72 65 61  ew = sqlite3_rea
c9f0: 6c 6c 6f 63 28 70 42 75 66 2d 3e 61 2c 20 6e 4e  lloc(pBuf->a, nN
ca00: 65 77 29 3b 0a 20 20 20 20 69 66 28 20 61 4e 65  ew);.    if( aNe
ca10: 77 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  w==0 ) return SQ
ca20: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
ca30: 70 42 75 66 2d 3e 61 20 3d 20 61 4e 65 77 3b 0a  pBuf->a = aNew;.
ca40: 20 20 20 20 70 42 75 66 2d 3e 6e 41 6c 6c 6f 63      pBuf->nAlloc
ca50: 20 3d 20 6e 4e 65 77 3b 0a 20 20 7d 0a 20 20 72   = nNew;.  }.  r
ca60: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
ca70: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 53 74 65 70 28  .}../*.** xStep(
ca80: 29 20 63 61 6c 6c 62 61 63 6b 20 66 6f 72 20 74  ) callback for t
ca90: 68 65 20 7a 69 70 66 69 6c 65 28 29 20 61 67 67  he zipfile() agg
caa0: 72 65 67 61 74 65 2e 20 54 68 69 73 20 63 61 6e  regate. This can
cab0: 20 62 65 20 63 61 6c 6c 65 64 20 69 6e 0a 2a 2a   be called in.**
cac0: 20 61 6e 79 20 6f 66 20 74 68 65 20 66 6f 6c 6c   any of the foll
cad0: 6f 77 69 6e 67 20 77 61 79 73 3a 0a 2a 2a 0a 2a  owing ways:.**.*
cae0: 2a 20 20 20 53 45 4c 45 43 54 20 7a 69 70 66 69  *   SELECT zipfi
caf0: 6c 65 28 6e 61 6d 65 2c 64 61 74 61 29 20 2e 2e  le(name,data) ..
cb00: 2e 0a 2a 2a 20 20 20 53 45 4c 45 43 54 20 7a 69  ..**   SELECT zi
cb10: 70 66 69 6c 65 28 6e 61 6d 65 2c 6d 6f 64 65 2c  pfile(name,mode,
cb20: 6d 74 69 6d 65 2c 64 61 74 61 29 20 2e 2e 2e 0a  mtime,data) ....
cb30: 2a 2a 20 20 20 53 45 4c 45 43 54 20 7a 69 70 66  **   SELECT zipf
cb40: 69 6c 65 28 6e 61 6d 65 2c 6d 6f 64 65 2c 6d 74  ile(name,mode,mt
cb50: 69 6d 65 2c 64 61 74 61 2c 6d 65 74 68 6f 64 29  ime,data,method)
cb60: 20 2e 2e 2e 0a 2a 2f 0a 76 6f 69 64 20 7a 69 70   ....*/.void zip
cb70: 66 69 6c 65 53 74 65 70 28 73 71 6c 69 74 65 33  fileStep(sqlite3
cb80: 5f 63 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20  _context *pCtx, 
cb90: 69 6e 74 20 6e 56 61 6c 2c 20 73 71 6c 69 74 65  int nVal, sqlite
cba0: 33 5f 76 61 6c 75 65 20 2a 2a 61 70 56 61 6c 29  3_value **apVal)
cbb0: 7b 0a 20 20 5a 69 70 66 69 6c 65 43 74 78 20 2a  {.  ZipfileCtx *
cbc0: 70 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  p;              
cbd0: 20 20 20 20 2f 2a 20 41 67 67 72 65 67 61 74 65      /* Aggregate
cbe0: 20 66 75 6e 63 74 69 6f 6e 20 63 6f 6e 74 65 78   function contex
cbf0: 74 20 2a 2f 0a 20 20 5a 69 70 66 69 6c 65 45 6e  t */.  ZipfileEn
cc00: 74 72 79 20 65 3b 20 20 20 20 20 20 20 20 20 20  try e;          
cc10: 20 20 20 20 20 20 20 2f 2a 20 4e 65 77 20 65 6e         /* New en
cc20: 74 72 79 20 74 6f 20 61 64 64 20 74 6f 20 7a 69  try to add to zi
cc30: 70 20 61 72 63 68 69 76 65 20 2a 2f 0a 0a 20 20  p archive */..  
cc40: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70  sqlite3_value *p
cc50: 4e 61 6d 65 20 3d 20 30 3b 0a 20 20 73 71 6c 69  Name = 0;.  sqli
cc60: 74 65 33 5f 76 61 6c 75 65 20 2a 70 4d 6f 64 65  te3_value *pMode
cc70: 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f   = 0;.  sqlite3_
cc80: 76 61 6c 75 65 20 2a 70 4d 74 69 6d 65 20 3d 20  value *pMtime = 
cc90: 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c  0;.  sqlite3_val
cca0: 75 65 20 2a 70 44 61 74 61 20 3d 20 30 3b 0a 20  ue *pData = 0;. 
ccb0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
ccc0: 70 4d 65 74 68 6f 64 20 3d 20 30 3b 0a 0a 20 20  pMethod = 0;..  
ccd0: 69 6e 74 20 62 49 73 44 69 72 20 3d 20 30 3b 0a  int bIsDir = 0;.
cce0: 20 20 75 33 32 20 6d 6f 64 65 3b 0a 20 20 69 6e    u32 mode;.  in
ccf0: 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b  t rc = SQLITE_OK
cd00: 3b 0a 20 20 63 68 61 72 20 2a 7a 45 72 72 20 3d  ;.  char *zErr =
cd10: 20 30 3b 0a 0a 20 20 69 6e 74 20 69 4d 65 74 68   0;..  int iMeth
cd20: 6f 64 20 3d 20 2d 31 3b 20 20 20 20 20 20 20 20  od = -1;        
cd30: 20 20 20 20 20 20 20 2f 2a 20 43 6f 6d 70 72 65         /* Compre
cd40: 73 73 69 6f 6e 20 6d 65 74 68 6f 64 20 74 6f 20  ssion method to 
cd50: 75 73 65 20 28 30 20 6f 72 20 38 29 20 2a 2f 0a  use (0 or 8) */.
cd60: 0a 20 20 63 6f 6e 73 74 20 75 38 20 2a 61 44 61  .  const u8 *aDa
cd70: 74 61 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20  ta = 0;         
cd80: 20 20 20 2f 2a 20 50 6f 73 73 69 62 6c 79 20 63     /* Possibly c
cd90: 6f 6d 70 72 65 73 73 65 64 20 64 61 74 61 20 66  ompressed data f
cda0: 6f 72 20 6e 65 77 20 65 6e 74 72 79 20 2a 2f 0a  or new entry */.
cdb0: 20 20 69 6e 74 20 6e 44 61 74 61 20 3d 20 30 3b    int nData = 0;
cdc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
cdd0: 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 61 44 61    /* Size of aDa
cde0: 74 61 5b 5d 20 69 6e 20 62 79 74 65 73 20 2a 2f  ta[] in bytes */
cdf0: 0a 20 20 69 6e 74 20 73 7a 55 6e 63 6f 6d 70 72  .  int szUncompr
ce00: 65 73 73 65 64 20 3d 20 30 3b 20 20 20 20 20 20  essed = 0;      
ce10: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 64 61     /* Size of da
ce20: 74 61 20 62 65 66 6f 72 65 20 63 6f 6d 70 72 65  ta before compre
ce30: 73 73 69 6f 6e 20 2a 2f 0a 20 20 75 38 20 2a 61  ssion */.  u8 *a
ce40: 46 72 65 65 20 3d 20 30 3b 20 20 20 20 20 20 20  Free = 0;       
ce50: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 72             /* Fr
ce60: 65 65 20 74 68 69 73 20 62 65 66 6f 72 65 20 72  ee this before r
ce70: 65 74 75 72 6e 69 6e 67 20 2a 2f 0a 20 20 75 33  eturning */.  u3
ce80: 32 20 69 43 72 63 33 32 20 3d 20 30 3b 20 20 20  2 iCrc32 = 0;   
ce90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
cea0: 20 63 72 63 33 32 20 6f 66 20 75 6e 63 6f 6d 70   crc32 of uncomp
ceb0: 72 65 73 73 65 64 20 64 61 74 61 20 2a 2f 0a 0a  ressed data */..
cec0: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20    char *zName = 
ced0: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
cee0: 20 20 2f 2a 20 50 61 74 68 20 28 6e 61 6d 65 29    /* Path (name)
cef0: 20 6f 66 20 6e 65 77 20 65 6e 74 72 79 20 2a 2f   of new entry */
cf00: 0a 20 20 69 6e 74 20 6e 4e 61 6d 65 20 3d 20 30  .  int nName = 0
cf10: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
cf20: 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20 7a 4e     /* Size of zN
cf30: 61 6d 65 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ame in bytes */.
cf40: 20 20 63 68 61 72 20 2a 7a 46 72 65 65 20 3d 20    char *zFree = 
cf50: 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0;              
cf60: 20 20 2f 2a 20 46 72 65 65 20 74 68 69 73 20 62    /* Free this b
cf70: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 20  efore returning 
cf80: 2a 2f 0a 20 20 69 6e 74 20 6e 42 79 74 65 3b 0a  */.  int nByte;.
cf90: 0a 20 20 6d 65 6d 73 65 74 28 26 65 2c 20 30 2c  .  memset(&e, 0,
cfa0: 20 73 69 7a 65 6f 66 28 65 29 29 3b 0a 20 20 70   sizeof(e));.  p
cfb0: 20 3d 20 28 5a 69 70 66 69 6c 65 43 74 78 2a 29   = (ZipfileCtx*)
cfc0: 73 71 6c 69 74 65 33 5f 61 67 67 72 65 67 61 74  sqlite3_aggregat
cfd0: 65 5f 63 6f 6e 74 65 78 74 28 70 43 74 78 2c 20  e_context(pCtx, 
cfe0: 73 69 7a 65 6f 66 28 5a 69 70 66 69 6c 65 43 74  sizeof(ZipfileCt
cff0: 78 29 29 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20  x));.  if( p==0 
d000: 29 20 72 65 74 75 72 6e 3b 0a 0a 20 20 2f 2a 20  ) return;..  /* 
d010: 4d 61 72 74 69 61 6c 20 74 68 65 20 61 72 67 75  Martial the argu
d020: 6d 65 6e 74 73 20 69 6e 74 6f 20 73 74 61 63 6b  ments into stack
d030: 20 76 61 72 69 61 62 6c 65 73 20 2a 2f 0a 20 20   variables */.  
d040: 69 66 28 20 6e 56 61 6c 21 3d 32 20 26 26 20 6e  if( nVal!=2 && n
d050: 56 61 6c 21 3d 34 20 26 26 20 6e 56 61 6c 21 3d  Val!=4 && nVal!=
d060: 35 20 29 7b 0a 20 20 20 20 7a 45 72 72 20 3d 20  5 ){.    zErr = 
d070: 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28  sqlite3_mprintf(
d080: 22 77 72 6f 6e 67 20 6e 75 6d 62 65 72 20 6f 66  "wrong number of
d090: 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 66 75   arguments to fu
d0a0: 6e 63 74 69 6f 6e 20 7a 69 70 66 69 6c 65 28 29  nction zipfile()
d0b0: 22 29 3b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c  ");.    rc = SQL
d0c0: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 67  ITE_ERROR;.    g
d0d0: 6f 74 6f 20 7a 69 70 66 69 6c 65 5f 73 74 65 70  oto zipfile_step
d0e0: 5f 6f 75 74 3b 0a 20 20 7d 0a 20 20 70 4e 61 6d  _out;.  }.  pNam
d0f0: 65 20 3d 20 61 70 56 61 6c 5b 30 5d 3b 0a 20 20  e = apVal[0];.  
d100: 69 66 28 20 6e 56 61 6c 3d 3d 32 20 29 7b 0a 20  if( nVal==2 ){. 
d110: 20 20 20 70 44 61 74 61 20 3d 20 61 70 56 61 6c     pData = apVal
d120: 5b 31 5d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  [1];.  }else{.  
d130: 20 20 70 4d 6f 64 65 20 3d 20 61 70 56 61 6c 5b    pMode = apVal[
d140: 31 5d 3b 0a 20 20 20 20 70 4d 74 69 6d 65 20 3d  1];.    pMtime =
d150: 20 61 70 56 61 6c 5b 32 5d 3b 0a 20 20 20 20 70   apVal[2];.    p
d160: 44 61 74 61 20 3d 20 61 70 56 61 6c 5b 33 5d 3b  Data = apVal[3];
d170: 0a 20 20 20 20 69 66 28 20 6e 56 61 6c 3d 3d 35  .    if( nVal==5
d180: 20 29 7b 0a 20 20 20 20 20 20 70 4d 65 74 68 6f   ){.      pMetho
d190: 64 20 3d 20 61 70 56 61 6c 5b 34 5d 3b 0a 20 20  d = apVal[4];.  
d1a0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 68    }.  }..  /* Ch
d1b0: 65 63 6b 20 74 68 61 74 20 74 68 65 20 27 6e 61  eck that the 'na
d1c0: 6d 65 27 20 70 61 72 61 6d 65 74 65 72 20 6c 6f  me' parameter lo
d1d0: 6f 6b 73 20 6f 6b 2e 20 2a 2f 0a 20 20 7a 4e 61  oks ok. */.  zNa
d1e0: 6d 65 20 3d 20 28 63 68 61 72 2a 29 73 71 6c 69  me = (char*)sqli
d1f0: 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 70  te3_value_text(p
d200: 4e 61 6d 65 29 3b 0a 20 20 6e 4e 61 6d 65 20 3d  Name);.  nName =
d210: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62   sqlite3_value_b
d220: 79 74 65 73 28 70 4e 61 6d 65 29 3b 0a 20 20 69  ytes(pName);.  i
d230: 66 28 20 7a 4e 61 6d 65 3d 3d 30 20 29 7b 0a 20  f( zName==0 ){. 
d240: 20 20 20 7a 45 72 72 20 3d 20 73 71 6c 69 74 65     zErr = sqlite
d250: 33 5f 6d 70 72 69 6e 74 66 28 22 66 69 72 73 74  3_mprintf("first
d260: 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 7a 69 70   argument to zip
d270: 66 69 6c 65 28 29 20 6d 75 73 74 20 62 65 20 6e  file() must be n
d280: 6f 6e 2d 4e 55 4c 4c 22 29 3b 0a 20 20 20 20 72  on-NULL");.    r
d290: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
d2a0: 3b 0a 20 20 20 20 67 6f 74 6f 20 7a 69 70 66 69  ;.    goto zipfi
d2b0: 6c 65 5f 73 74 65 70 5f 6f 75 74 3b 0a 20 20 7d  le_step_out;.  }
d2c0: 0a 0a 20 20 2f 2a 20 49 6e 73 70 65 63 74 20 74  ..  /* Inspect t
d2d0: 68 65 20 27 6d 65 74 68 6f 64 27 20 70 61 72 61  he 'method' para
d2e0: 6d 65 74 65 72 2e 20 54 68 69 73 20 6d 75 73 74  meter. This must
d2f0: 20 62 65 20 65 69 74 68 65 72 20 30 20 28 73 74   be either 0 (st
d300: 6f 72 65 29 2c 20 38 20 28 75 73 65 0a 20 20 2a  ore), 8 (use.  *
d310: 2a 20 64 65 66 6c 61 74 65 20 63 6f 6d 70 72 65  * deflate compre
d320: 73 73 69 6f 6e 29 20 6f 72 20 4e 55 4c 4c 20 28  ssion) or NULL (
d330: 63 68 6f 6f 73 65 20 61 75 74 6f 6d 61 74 69 63  choose automatic
d340: 61 6c 6c 79 29 2e 20 20 2a 2f 0a 20 20 69 66 28  ally).  */.  if(
d350: 20 70 4d 65 74 68 6f 64 20 26 26 20 53 51 4c 49   pMethod && SQLI
d360: 54 45 5f 4e 55 4c 4c 21 3d 73 71 6c 69 74 65 33  TE_NULL!=sqlite3
d370: 5f 76 61 6c 75 65 5f 74 79 70 65 28 70 4d 65 74  _value_type(pMet
d380: 68 6f 64 29 20 29 7b 0a 20 20 20 20 69 4d 65 74  hod) ){.    iMet
d390: 68 6f 64 20 3d 20 73 71 6c 69 74 65 33 5f 76 61  hod = sqlite3_va
d3a0: 6c 75 65 5f 69 6e 74 36 34 28 70 4d 65 74 68 6f  lue_int64(pMetho
d3b0: 64 29 3b 0a 20 20 20 20 69 66 28 20 69 4d 65 74  d);.    if( iMet
d3c0: 68 6f 64 21 3d 30 20 26 26 20 69 4d 65 74 68 6f  hod!=0 && iMetho
d3d0: 64 21 3d 38 20 29 7b 0a 20 20 20 20 20 20 7a 45  d!=8 ){.      zE
d3e0: 72 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  rr = sqlite3_mpr
d3f0: 69 6e 74 66 28 22 69 6c 6c 65 67 61 6c 20 6d 65  intf("illegal me
d400: 74 68 6f 64 20 76 61 6c 75 65 3a 20 25 64 22 2c  thod value: %d",
d410: 20 69 4d 65 74 68 6f 64 29 3b 0a 20 20 20 20 20   iMethod);.     
d420: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52   rc = SQLITE_ERR
d430: 4f 52 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 7a  OR;.      goto z
d440: 69 70 66 69 6c 65 5f 73 74 65 70 5f 6f 75 74 3b  ipfile_step_out;
d450: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a  .    }.  }..  /*
d460: 20 4e 6f 77 20 69 6e 73 70 65 63 74 20 74 68 65   Now inspect the
d470: 20 64 61 74 61 2e 20 49 66 20 74 68 69 73 20 69   data. If this i
d480: 73 20 4e 55 4c 4c 2c 20 74 68 65 6e 20 74 68 65  s NULL, then the
d490: 20 6e 65 77 20 65 6e 74 72 79 20 6d 75 73 74 20   new entry must 
d4a0: 62 65 20 61 0a 20 20 2a 2a 20 64 69 72 65 63 74  be a.  ** direct
d4b0: 6f 72 79 2e 20 20 4f 74 68 65 72 77 69 73 65 2c  ory.  Otherwise,
d4c0: 20 66 69 67 75 72 65 20 6f 75 74 20 77 68 65 74   figure out whet
d4d0: 68 65 72 20 6f 72 20 6e 6f 74 20 74 68 65 20 64  her or not the d
d4e0: 61 74 61 20 73 68 6f 75 6c 64 0a 20 20 2a 2a 20  ata should.  ** 
d4f0: 62 65 20 64 65 66 6c 61 74 65 64 20 6f 72 20 73  be deflated or s
d500: 69 6d 70 6c 79 20 73 74 6f 72 65 64 20 69 6e 20  imply stored in 
d510: 74 68 65 20 7a 69 70 20 61 72 63 68 69 76 65 2e  the zip archive.
d520: 20 2a 2f 0a 20 20 69 66 28 20 73 71 6c 69 74 65   */.  if( sqlite
d530: 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 70 44 61  3_value_type(pDa
d540: 74 61 29 3d 3d 53 51 4c 49 54 45 5f 4e 55 4c 4c  ta)==SQLITE_NULL
d550: 20 29 7b 0a 20 20 20 20 62 49 73 44 69 72 20 3d   ){.    bIsDir =
d560: 20 31 3b 0a 20 20 20 20 69 4d 65 74 68 6f 64 20   1;.    iMethod 
d570: 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  = 0;.  }else{.  
d580: 20 20 61 44 61 74 61 20 3d 20 73 71 6c 69 74 65    aData = sqlite
d590: 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28 70 44 61  3_value_blob(pDa
d5a0: 74 61 29 3b 0a 20 20 20 20 73 7a 55 6e 63 6f 6d  ta);.    szUncom
d5b0: 70 72 65 73 73 65 64 20 3d 20 6e 44 61 74 61 20  pressed = nData 
d5c0: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
d5d0: 62 79 74 65 73 28 70 44 61 74 61 29 3b 0a 20 20  bytes(pData);.  
d5e0: 20 20 69 43 72 63 33 32 20 3d 20 63 72 63 33 32    iCrc32 = crc32
d5f0: 28 30 2c 20 61 44 61 74 61 2c 20 6e 44 61 74 61  (0, aData, nData
d600: 29 3b 0a 20 20 20 20 69 66 28 20 69 4d 65 74 68  );.    if( iMeth
d610: 6f 64 3c 30 20 7c 7c 20 69 4d 65 74 68 6f 64 3d  od<0 || iMethod=
d620: 3d 38 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20  =8 ){.      int 
d630: 6e 4f 75 74 20 3d 20 30 3b 0a 20 20 20 20 20 20  nOut = 0;.      
d640: 72 63 20 3d 20 7a 69 70 66 69 6c 65 44 65 66 6c  rc = zipfileDefl
d650: 61 74 65 28 61 44 61 74 61 2c 20 6e 44 61 74 61  ate(aData, nData
d660: 2c 20 26 61 46 72 65 65 2c 20 26 6e 4f 75 74 2c  , &aFree, &nOut,
d670: 20 26 7a 45 72 72 29 3b 0a 20 20 20 20 20 20 69   &zErr);.      i
d680: 66 28 20 72 63 21 3d 53 51 4c 49 54 45 5f 4f 4b  f( rc!=SQLITE_OK
d690: 20 29 7b 0a 20 20 20 20 20 20 20 20 67 6f 74 6f   ){.        goto
d6a0: 20 7a 69 70 66 69 6c 65 5f 73 74 65 70 5f 6f 75   zipfile_step_ou
d6b0: 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  t;.      }.     
d6c0: 20 69 66 28 20 69 4d 65 74 68 6f 64 3d 3d 38 20   if( iMethod==8 
d6d0: 7c 7c 20 6e 4f 75 74 3c 6e 44 61 74 61 20 29 7b  || nOut<nData ){
d6e0: 0a 20 20 20 20 20 20 20 20 61 44 61 74 61 20 3d  .        aData =
d6f0: 20 61 46 72 65 65 3b 0a 20 20 20 20 20 20 20 20   aFree;.        
d700: 6e 44 61 74 61 20 3d 20 6e 4f 75 74 3b 0a 20 20  nData = nOut;.  
d710: 20 20 20 20 20 20 69 4d 65 74 68 6f 64 20 3d 20        iMethod = 
d720: 38 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  8;.      }else{.
d730: 20 20 20 20 20 20 20 20 69 4d 65 74 68 6f 64 20          iMethod 
d740: 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 0;.      }.   
d750: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 65 63   }.  }..  /* Dec
d760: 6f 64 65 20 74 68 65 20 22 6d 6f 64 65 22 20 61  ode the "mode" a
d770: 72 67 75 6d 65 6e 74 2e 20 2a 2f 0a 20 20 72 63  rgument. */.  rc
d780: 20 3d 20 7a 69 70 66 69 6c 65 47 65 74 4d 6f 64   = zipfileGetMod
d790: 65 28 70 4d 6f 64 65 2c 20 62 49 73 44 69 72 2c  e(pMode, bIsDir,
d7a0: 20 26 6d 6f 64 65 2c 20 26 7a 45 72 72 29 3b 0a   &mode, &zErr);.
d7b0: 20 20 69 66 28 20 72 63 20 29 20 67 6f 74 6f 20    if( rc ) goto 
d7c0: 7a 69 70 66 69 6c 65 5f 73 74 65 70 5f 6f 75 74  zipfile_step_out
d7d0: 3b 0a 0a 20 20 2f 2a 20 44 65 63 6f 64 65 20 74  ;..  /* Decode t
d7e0: 68 65 20 22 6d 74 69 6d 65 22 20 61 72 67 75 6d  he "mtime" argum
d7f0: 65 6e 74 2e 20 2a 2f 0a 20 20 69 66 28 20 70 4d  ent. */.  if( pM
d800: 74 69 6d 65 3d 3d 30 20 7c 7c 20 73 71 6c 69 74  time==0 || sqlit
d810: 65 33 5f 76 61 6c 75 65 5f 74 79 70 65 28 70 4d  e3_value_type(pM
d820: 74 69 6d 65 29 3d 3d 53 51 4c 49 54 45 5f 4e 55  time)==SQLITE_NU
d830: 4c 4c 20 29 7b 0a 20 20 20 20 65 2e 6d 55 6e 69  LL ){.    e.mUni
d840: 78 54 69 6d 65 20 3d 20 28 75 33 32 29 74 69 6d  xTime = (u32)tim
d850: 65 28 30 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  e(0);.  }else{. 
d860: 20 20 20 65 2e 6d 55 6e 69 78 54 69 6d 65 20 3d     e.mUnixTime =
d870: 20 28 75 33 32 29 73 71 6c 69 74 65 33 5f 76 61   (u32)sqlite3_va
d880: 6c 75 65 5f 69 6e 74 36 34 28 70 4d 74 69 6d 65  lue_int64(pMtime
d890: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20  );.  }..  /* If 
d8a0: 74 68 69 73 20 69 73 20 61 20 64 69 72 65 63 74  this is a direct
d8b0: 6f 72 79 20 65 6e 74 72 79 2c 20 65 6e 73 75 72  ory entry, ensur
d8c0: 65 20 74 68 61 74 20 74 68 65 72 65 20 69 73 20  e that there is 
d8d0: 65 78 61 63 74 6c 79 20 6f 6e 65 20 27 2f 27 0a  exactly one '/'.
d8e0: 20 20 2a 2a 20 61 74 20 74 68 65 20 65 6e 64 20    ** at the end 
d8f0: 6f 66 20 74 68 65 20 70 61 74 68 2e 20 4f 72 2c  of the path. Or,
d900: 20 69 66 20 74 68 69 73 20 69 73 20 6e 6f 74 20   if this is not 
d910: 61 20 64 69 72 65 63 74 6f 72 79 20 61 6e 64 20  a directory and 
d920: 74 68 65 20 70 61 74 68 0a 20 20 2a 2a 20 65 6e  the path.  ** en
d930: 64 73 20 69 6e 20 27 2f 27 20 69 74 20 69 73 20  ds in '/' it is 
d940: 61 6e 20 65 72 72 6f 72 2e 20 2a 2f 0a 20 20 69  an error. */.  i
d950: 66 28 20 62 49 73 44 69 72 3d 3d 30 20 29 7b 0a  f( bIsDir==0 ){.
d960: 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b 6e 4e      if( zName[nN
d970: 61 6d 65 2d 31 5d 3d 3d 27 2f 27 20 29 7b 0a 20  ame-1]=='/' ){. 
d980: 20 20 20 20 20 7a 45 72 72 20 3d 20 73 71 6c 69       zErr = sqli
d990: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 6e 6f 6e  te3_mprintf("non
d9a0: 2d 64 69 72 65 63 74 6f 72 79 20 6e 61 6d 65 20  -directory name 
d9b0: 6d 75 73 74 20 6e 6f 74 20 65 6e 64 20 77 69 74  must not end wit
d9c0: 68 20 2f 22 29 3b 0a 20 20 20 20 20 20 72 63 20  h /");.      rc 
d9d0: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
d9e0: 20 20 20 20 20 20 67 6f 74 6f 20 7a 69 70 66 69        goto zipfi
d9f0: 6c 65 5f 73 74 65 70 5f 6f 75 74 3b 0a 20 20 20  le_step_out;.   
da00: 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20   }.  }else{.    
da10: 69 66 28 20 7a 4e 61 6d 65 5b 6e 4e 61 6d 65 2d  if( zName[nName-
da20: 31 5d 21 3d 27 2f 27 20 29 7b 0a 20 20 20 20 20  1]!='/' ){.     
da30: 20 7a 4e 61 6d 65 20 3d 20 7a 46 72 65 65 20 3d   zName = zFree =
da40: 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66   sqlite3_mprintf
da50: 28 22 25 73 2f 22 2c 20 7a 4e 61 6d 65 29 3b 0a  ("%s/", zName);.
da60: 20 20 20 20 20 20 6e 4e 61 6d 65 2b 2b 3b 0a 20        nName++;. 
da70: 20 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 3d 3d       if( zName==
da80: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  0 ){.        rc 
da90: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
daa0: 20 20 20 20 20 20 20 20 67 6f 74 6f 20 7a 69 70          goto zip
dab0: 66 69 6c 65 5f 73 74 65 70 5f 6f 75 74 3b 0a 20  file_step_out;. 
dac0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65       }.    }else
dad0: 7b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 6e  {.      while( n
dae0: 4e 61 6d 65 3e 31 20 26 26 20 7a 4e 61 6d 65 5b  Name>1 && zName[
daf0: 6e 4e 61 6d 65 2d 32 5d 3d 3d 27 2f 27 20 29 20  nName-2]=='/' ) 
db00: 6e 4e 61 6d 65 2d 2d 3b 0a 20 20 20 20 7d 0a 20  nName--;.    }. 
db10: 20 7d 0a 0a 20 20 2f 2a 20 41 73 73 65 6d 62 6c   }..  /* Assembl
db20: 65 20 74 68 65 20 5a 69 70 66 69 6c 65 45 6e 74  e the ZipfileEnt
db30: 72 79 20 6f 62 6a 65 63 74 20 66 6f 72 20 74 68  ry object for th
db40: 65 20 6e 65 77 20 7a 69 70 20 61 72 63 68 69 76  e new zip archiv
db50: 65 20 65 6e 74 72 79 20 2a 2f 0a 20 20 65 2e 63  e entry */.  e.c
db60: 64 73 2e 69 56 65 72 73 69 6f 6e 4d 61 64 65 42  ds.iVersionMadeB
db70: 79 20 3d 20 5a 49 50 46 49 4c 45 5f 4e 45 57 45  y = ZIPFILE_NEWE
db80: 4e 54 52 59 5f 4d 41 44 45 42 59 3b 0a 20 20 65  NTRY_MADEBY;.  e
db90: 2e 63 64 73 2e 69 56 65 72 73 69 6f 6e 45 78 74  .cds.iVersionExt
dba0: 72 61 63 74 20 3d 20 5a 49 50 46 49 4c 45 5f 4e  ract = ZIPFILE_N
dbb0: 45 57 45 4e 54 52 59 5f 52 45 51 55 49 52 45 44  EWENTRY_REQUIRED
dbc0: 3b 0a 20 20 65 2e 63 64 73 2e 66 6c 61 67 73 20  ;.  e.cds.flags 
dbd0: 3d 20 5a 49 50 46 49 4c 45 5f 4e 45 57 45 4e 54  = ZIPFILE_NEWENT
dbe0: 52 59 5f 46 4c 41 47 53 3b 0a 20 20 65 2e 63 64  RY_FLAGS;.  e.cd
dbf0: 73 2e 69 43 6f 6d 70 72 65 73 73 69 6f 6e 20 3d  s.iCompression =
dc00: 20 69 4d 65 74 68 6f 64 3b 0a 20 20 7a 69 70 66   iMethod;.  zipf
dc10: 69 6c 65 4d 74 69 6d 65 54 6f 44 6f 73 28 26 65  ileMtimeToDos(&e
dc20: 2e 63 64 73 2c 20 28 75 33 32 29 65 2e 6d 55 6e  .cds, (u32)e.mUn
dc30: 69 78 54 69 6d 65 29 3b 0a 20 20 65 2e 63 64 73  ixTime);.  e.cds
dc40: 2e 63 72 63 33 32 20 3d 20 69 43 72 63 33 32 3b  .crc32 = iCrc32;
dc50: 0a 20 20 65 2e 63 64 73 2e 73 7a 43 6f 6d 70 72  .  e.cds.szCompr
dc60: 65 73 73 65 64 20 3d 20 6e 44 61 74 61 3b 0a 20  essed = nData;. 
dc70: 20 65 2e 63 64 73 2e 73 7a 55 6e 63 6f 6d 70 72   e.cds.szUncompr
dc80: 65 73 73 65 64 20 3d 20 73 7a 55 6e 63 6f 6d 70  essed = szUncomp
dc90: 72 65 73 73 65 64 3b 0a 20 20 65 2e 63 64 73 2e  ressed;.  e.cds.
dca0: 69 45 78 74 65 72 6e 61 6c 41 74 74 72 20 3d 20  iExternalAttr = 
dcb0: 28 6d 6f 64 65 3c 3c 31 36 29 3b 0a 20 20 65 2e  (mode<<16);.  e.
dcc0: 63 64 73 2e 69 4f 66 66 73 65 74 20 3d 20 70 2d  cds.iOffset = p-
dcd0: 3e 62 6f 64 79 2e 6e 3b 0a 20 20 65 2e 63 64 73  >body.n;.  e.cds
dce0: 2e 6e 46 69 6c 65 20 3d 20 6e 4e 61 6d 65 3b 0a  .nFile = nName;.
dcf0: 20 20 65 2e 63 64 73 2e 7a 46 69 6c 65 20 3d 20    e.cds.zFile = 
dd00: 7a 4e 61 6d 65 3b 0a 0a 20 20 2f 2a 20 41 70 70  zName;..  /* App
dd10: 65 6e 64 20 74 68 65 20 4c 46 48 20 74 6f 20 74  end the LFH to t
dd20: 68 65 20 62 6f 64 79 20 6f 66 20 74 68 65 20 6e  he body of the n
dd30: 65 77 20 61 72 63 68 69 76 65 20 2a 2f 0a 20 20  ew archive */.  
dd40: 6e 42 79 74 65 20 3d 20 5a 49 50 46 49 4c 45 5f  nByte = ZIPFILE_
dd50: 4c 46 48 5f 46 49 58 45 44 5f 53 5a 20 2b 20 65  LFH_FIXED_SZ + e
dd60: 2e 63 64 73 2e 6e 46 69 6c 65 20 2b 20 39 3b 0a  .cds.nFile + 9;.
dd70: 20 20 69 66 28 20 28 72 63 20 3d 20 7a 69 70 66    if( (rc = zipf
dd80: 69 6c 65 42 75 66 66 65 72 47 72 6f 77 28 26 70  ileBufferGrow(&p
dd90: 2d 3e 62 6f 64 79 2c 20 6e 42 79 74 65 29 29 20  ->body, nByte)) 
dda0: 29 20 67 6f 74 6f 20 7a 69 70 66 69 6c 65 5f 73  ) goto zipfile_s
ddb0: 74 65 70 5f 6f 75 74 3b 0a 20 20 70 2d 3e 62 6f  tep_out;.  p->bo
ddc0: 64 79 2e 6e 20 2b 3d 20 7a 69 70 66 69 6c 65 53  dy.n += zipfileS
ddd0: 65 72 69 61 6c 69 7a 65 4c 46 48 28 26 65 2c 20  erializeLFH(&e, 
dde0: 26 70 2d 3e 62 6f 64 79 2e 61 5b 70 2d 3e 62 6f  &p->body.a[p->bo
ddf0: 64 79 2e 6e 5d 29 3b 0a 0a 20 20 2f 2a 20 41 70  dy.n]);..  /* Ap
de00: 70 65 6e 64 20 74 68 65 20 64 61 74 61 20 74 6f  pend the data to
de10: 20 74 68 65 20 62 6f 64 79 20 6f 66 20 74 68 65   the body of the
de20: 20 6e 65 77 20 61 72 63 68 69 76 65 20 2a 2f 0a   new archive */.
de30: 20 20 69 66 28 20 28 72 63 20 3d 20 7a 69 70 66    if( (rc = zipf
de40: 69 6c 65 42 75 66 66 65 72 47 72 6f 77 28 26 70  ileBufferGrow(&p
de50: 2d 3e 62 6f 64 79 2c 20 6e 44 61 74 61 29 29 20  ->body, nData)) 
de60: 29 20 67 6f 74 6f 20 7a 69 70 66 69 6c 65 5f 73  ) goto zipfile_s
de70: 74 65 70 5f 6f 75 74 3b 0a 20 20 6d 65 6d 63 70  tep_out;.  memcp
de80: 79 28 26 70 2d 3e 62 6f 64 79 2e 61 5b 70 2d 3e  y(&p->body.a[p->
de90: 62 6f 64 79 2e 6e 5d 2c 20 61 44 61 74 61 2c 20  body.n], aData, 
dea0: 6e 44 61 74 61 29 3b 0a 20 20 70 2d 3e 62 6f 64  nData);.  p->bod
deb0: 79 2e 6e 20 2b 3d 20 6e 44 61 74 61 3b 0a 0a 20  y.n += nData;.. 
dec0: 20 2f 2a 20 41 70 70 65 6e 64 20 74 68 65 20 43   /* Append the C
ded0: 44 53 20 72 65 63 6f 72 64 20 74 6f 20 74 68 65  DS record to the
dee0: 20 64 69 72 65 63 74 6f 72 79 20 6f 66 20 74 68   directory of th
def0: 65 20 6e 65 77 20 61 72 63 68 69 76 65 20 2a 2f  e new archive */
df00: 0a 20 20 6e 42 79 74 65 20 3d 20 5a 49 50 46 49  .  nByte = ZIPFI
df10: 4c 45 5f 43 44 53 5f 46 49 58 45 44 5f 53 5a 20  LE_CDS_FIXED_SZ 
df20: 2b 20 65 2e 63 64 73 2e 6e 46 69 6c 65 20 2b 20  + e.cds.nFile + 
df30: 39 3b 0a 20 20 69 66 28 20 28 72 63 20 3d 20 7a  9;.  if( (rc = z
df40: 69 70 66 69 6c 65 42 75 66 66 65 72 47 72 6f 77  ipfileBufferGrow
df50: 28 26 70 2d 3e 63 64 73 2c 20 6e 42 79 74 65 29  (&p->cds, nByte)
df60: 29 20 29 20 67 6f 74 6f 20 7a 69 70 66 69 6c 65  ) ) goto zipfile
df70: 5f 73 74 65 70 5f 6f 75 74 3b 0a 20 20 70 2d 3e  _step_out;.  p->
df80: 63 64 73 2e 6e 20 2b 3d 20 7a 69 70 66 69 6c 65  cds.n += zipfile
df90: 53 65 72 69 61 6c 69 7a 65 43 44 53 28 26 65 2c  SerializeCDS(&e,
dfa0: 20 26 70 2d 3e 63 64 73 2e 61 5b 70 2d 3e 63 64   &p->cds.a[p->cd
dfb0: 73 2e 6e 5d 29 3b 0a 0a 20 20 2f 2a 20 49 6e 63  s.n]);..  /* Inc
dfc0: 72 65 6d 65 6e 74 20 74 68 65 20 63 6f 75 6e 74  rement the count
dfd0: 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20 74   of entries in t
dfe0: 68 65 20 61 72 63 68 69 76 65 20 2a 2f 0a 20 20  he archive */.  
dff0: 70 2d 3e 6e 45 6e 74 72 79 2b 2b 3b 0a 0a 20 7a  p->nEntry++;.. z
e000: 69 70 66 69 6c 65 5f 73 74 65 70 5f 6f 75 74 3a  ipfile_step_out:
e010: 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28  .  sqlite3_free(
e020: 61 46 72 65 65 29 3b 0a 20 20 73 71 6c 69 74 65  aFree);.  sqlite
e030: 33 5f 66 72 65 65 28 7a 46 72 65 65 29 3b 0a 20  3_free(zFree);. 
e040: 20 69 66 28 20 72 63 20 29 7b 0a 20 20 20 20 69   if( rc ){.    i
e050: 66 28 20 7a 45 72 72 20 29 7b 0a 20 20 20 20 20  f( zErr ){.     
e060: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
e070: 65 72 72 6f 72 28 70 43 74 78 2c 20 7a 45 72 72  error(pCtx, zErr
e080: 2c 20 2d 31 29 3b 0a 20 20 20 20 7d 65 6c 73 65  , -1);.    }else
e090: 7b 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  {.      sqlite3_
e0a0: 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f 63 6f 64  result_error_cod
e0b0: 65 28 70 43 74 78 2c 20 72 63 29 3b 0a 20 20 20  e(pCtx, rc);.   
e0c0: 20 7d 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65 33   }.  }.  sqlite3
e0d0: 5f 66 72 65 65 28 7a 45 72 72 29 3b 0a 7d 0a 0a  _free(zErr);.}..
e0e0: 2f 2a 0a 2a 2a 20 78 46 69 6e 61 6c 69 7a 65 28  /*.** xFinalize(
e0f0: 29 20 63 61 6c 6c 62 61 63 6b 20 66 6f 72 20 7a  ) callback for z
e100: 69 70 66 69 6c 65 20 61 67 67 72 65 67 61 74 65  ipfile aggregate
e110: 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a 76 6f   function..*/.vo
e120: 69 64 20 7a 69 70 66 69 6c 65 46 69 6e 61 6c 28  id zipfileFinal(
e130: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
e140: 2a 70 43 74 78 29 7b 0a 20 20 5a 69 70 66 69 6c  *pCtx){.  Zipfil
e150: 65 43 74 78 20 2a 70 3b 0a 20 20 5a 69 70 66 69  eCtx *p;.  Zipfi
e160: 6c 65 45 4f 43 44 20 65 6f 63 64 3b 0a 20 20 69  leEOCD eocd;.  i
e170: 6e 74 20 6e 5a 69 70 3b 0a 20 20 75 38 20 2a 61  nt nZip;.  u8 *a
e180: 5a 69 70 3b 0a 0a 20 20 70 20 3d 20 28 5a 69 70  Zip;..  p = (Zip
e190: 66 69 6c 65 43 74 78 2a 29 73 71 6c 69 74 65 33  fileCtx*)sqlite3
e1a0: 5f 61 67 67 72 65 67 61 74 65 5f 63 6f 6e 74 65  _aggregate_conte
e1b0: 78 74 28 70 43 74 78 2c 20 73 69 7a 65 6f 66 28  xt(pCtx, sizeof(
e1c0: 5a 69 70 66 69 6c 65 43 74 78 29 29 3b 0a 20 20  ZipfileCtx));.  
e1d0: 69 66 28 20 70 3d 3d 30 20 7c 7c 20 70 2d 3e 6e  if( p==0 || p->n
e1e0: 45 6e 74 72 79 3d 3d 30 20 29 20 72 65 74 75 72  Entry==0 ) retur
e1f0: 6e 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 65 6f  n;..  memset(&eo
e200: 63 64 2c 20 30 2c 20 73 69 7a 65 6f 66 28 65 6f  cd, 0, sizeof(eo
e210: 63 64 29 29 3b 0a 20 20 65 6f 63 64 2e 6e 45 6e  cd));.  eocd.nEn
e220: 74 72 79 20 3d 20 70 2d 3e 6e 45 6e 74 72 79 3b  try = p->nEntry;
e230: 0a 20 20 65 6f 63 64 2e 6e 45 6e 74 72 79 54 6f  .  eocd.nEntryTo
e240: 74 61 6c 20 3d 20 70 2d 3e 6e 45 6e 74 72 79 3b  tal = p->nEntry;
e250: 0a 20 20 65 6f 63 64 2e 6e 53 69 7a 65 20 3d 20  .  eocd.nSize = 
e260: 70 2d 3e 63 64 73 2e 6e 3b 0a 20 20 65 6f 63 64  p->cds.n;.  eocd
e270: 2e 69 4f 66 66 73 65 74 20 3d 20 70 2d 3e 62 6f  .iOffset = p->bo
e280: 64 79 2e 6e 3b 0a 0a 20 20 6e 5a 69 70 20 3d 20  dy.n;..  nZip = 
e290: 70 2d 3e 62 6f 64 79 2e 6e 20 2b 20 70 2d 3e 63  p->body.n + p->c
e2a0: 64 73 2e 6e 20 2b 20 5a 49 50 46 49 4c 45 5f 45  ds.n + ZIPFILE_E
e2b0: 4f 43 44 5f 46 49 58 45 44 5f 53 5a 3b 0a 20 20  OCD_FIXED_SZ;.  
e2c0: 61 5a 69 70 20 3d 20 28 75 38 2a 29 73 71 6c 69  aZip = (u8*)sqli
e2d0: 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 5a 69 70 29  te3_malloc(nZip)
e2e0: 3b 0a 20 20 69 66 28 20 61 5a 69 70 3d 3d 30 20  ;.  if( aZip==0 
e2f0: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  ){.    sqlite3_r
e300: 65 73 75 6c 74 5f 65 72 72 6f 72 5f 6e 6f 6d 65  esult_error_nome
e310: 6d 28 70 43 74 78 29 3b 0a 20 20 7d 65 6c 73 65  m(pCtx);.  }else
e320: 7b 0a 20 20 20 20 6d 65 6d 63 70 79 28 61 5a 69  {.    memcpy(aZi
e330: 70 2c 20 70 2d 3e 62 6f 64 79 2e 61 2c 20 70 2d  p, p->body.a, p-
e340: 3e 62 6f 64 79 2e 6e 29 3b 0a 20 20 20 20 6d 65  >body.n);.    me
e350: 6d 63 70 79 28 26 61 5a 69 70 5b 70 2d 3e 62 6f  mcpy(&aZip[p->bo
e360: 64 79 2e 6e 5d 2c 20 70 2d 3e 63 64 73 2e 61 2c  dy.n], p->cds.a,
e370: 20 70 2d 3e 63 64 73 2e 6e 29 3b 0a 20 20 20 20   p->cds.n);.    
e380: 7a 69 70 66 69 6c 65 53 65 72 69 61 6c 69 7a 65  zipfileSerialize
e390: 45 4f 43 44 28 26 65 6f 63 64 2c 20 26 61 5a 69  EOCD(&eocd, &aZi
e3a0: 70 5b 70 2d 3e 62 6f 64 79 2e 6e 20 2b 20 70 2d  p[p->body.n + p-
e3b0: 3e 63 64 73 2e 6e 5d 29 3b 0a 20 20 20 20 73 71  >cds.n]);.    sq
e3c0: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 62 6c 6f  lite3_result_blo
e3d0: 62 28 70 43 74 78 2c 20 61 5a 69 70 2c 20 6e 5a  b(pCtx, aZip, nZ
e3e0: 69 70 2c 20 7a 69 70 66 69 6c 65 46 72 65 65 29  ip, zipfileFree)
e3f0: 3b 0a 20 20 7d 0a 0a 20 20 73 71 6c 69 74 65 33  ;.  }..  sqlite3
e400: 5f 66 72 65 65 28 70 2d 3e 62 6f 64 79 2e 61 29  _free(p->body.a)
e410: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
e420: 28 70 2d 3e 63 64 73 2e 61 29 3b 0a 7d 0a 0a 0a  (p->cds.a);.}...
e430: 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20 74  /*.** Register t
e440: 68 65 20 22 7a 69 70 66 69 6c 65 22 20 76 69 72  he "zipfile" vir
e450: 74 75 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73  tual table..*/.s
e460: 74 61 74 69 63 20 69 6e 74 20 7a 69 70 66 69 6c  tatic int zipfil
e470: 65 52 65 67 69 73 74 65 72 28 73 71 6c 69 74 65  eRegister(sqlite
e480: 33 20 2a 64 62 29 7b 0a 20 20 73 74 61 74 69 63  3 *db){.  static
e490: 20 73 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20   sqlite3_module 
e4a0: 7a 69 70 66 69 6c 65 4d 6f 64 75 6c 65 20 3d 20  zipfileModule = 
e4b0: 7b 0a 20 20 20 20 31 2c 20 20 20 20 20 20 20 20  {.    1,        
e4c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e4d0: 20 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a   /* iVersion */.
e4e0: 20 20 20 20 7a 69 70 66 69 6c 65 43 6f 6e 6e 65      zipfileConne
e4f0: 63 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 2f  ct,            /
e500: 2a 20 78 43 72 65 61 74 65 20 2a 2f 0a 20 20 20  * xCreate */.   
e510: 20 7a 69 70 66 69 6c 65 43 6f 6e 6e 65 63 74 2c   zipfileConnect,
e520: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
e530: 43 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20 20 20 7a  Connect */.    z
e540: 69 70 66 69 6c 65 42 65 73 74 49 6e 64 65 78 2c  ipfileBestIndex,
e550: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65            /* xBe
e560: 73 74 49 6e 64 65 78 20 2a 2f 0a 20 20 20 20 7a  stIndex */.    z
e570: 69 70 66 69 6c 65 44 69 73 63 6f 6e 6e 65 63 74  ipfileDisconnect
e580: 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 69  ,         /* xDi
e590: 73 63 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20 20 20  sconnect */.    
e5a0: 7a 69 70 66 69 6c 65 44 69 73 63 6f 6e 6e 65 63  zipfileDisconnec
e5b0: 74 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44  t,         /* xD
e5c0: 65 73 74 72 6f 79 20 2a 2f 0a 20 20 20 20 7a 69  estroy */.    zi
e5d0: 70 66 69 6c 65 4f 70 65 6e 2c 20 20 20 20 20 20  pfileOpen,      
e5e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65           /* xOpe
e5f0: 6e 20 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f  n - open a curso
e600: 72 20 2a 2f 0a 20 20 20 20 7a 69 70 66 69 6c 65  r */.    zipfile
e610: 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20  Close,          
e620: 20 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20      /* xClose - 
e630: 63 6c 6f 73 65 20 61 20 63 75 72 73 6f 72 20 2a  close a cursor *
e640: 2f 0a 20 20 20 20 7a 69 70 66 69 6c 65 46 69 6c  /.    zipfileFil
e650: 74 65 72 2c 20 20 20 20 20 20 20 20 20 20 20 20  ter,            
e660: 20 2f 2a 20 78 46 69 6c 74 65 72 20 2d 20 63 6f   /* xFilter - co
e670: 6e 66 69 67 75 72 65 20 73 63 61 6e 20 63 6f 6e  nfigure scan con
e680: 73 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20 20 20  straints */.    
e690: 7a 69 70 66 69 6c 65 4e 65 78 74 2c 20 20 20 20  zipfileNext,    
e6a0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4e             /* xN
e6b0: 65 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61 20  ext - advance a 
e6c0: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 20 20 7a 69  cursor */.    zi
e6d0: 70 66 69 6c 65 45 6f 66 2c 20 20 20 20 20 20 20  pfileEof,       
e6e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66           /* xEof
e6f0: 20 2d 20 63 68 65 63 6b 20 66 6f 72 20 65 6e 64   - check for end
e700: 20 6f 66 20 73 63 61 6e 20 2a 2f 0a 20 20 20 20   of scan */.    
e710: 7a 69 70 66 69 6c 65 43 6f 6c 75 6d 6e 2c 20 20  zipfileColumn,  
e720: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
e730: 6f 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 74  olumn - read dat
e740: 61 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  a */.    0,     
e750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e760: 20 20 20 20 2f 2a 20 78 52 6f 77 69 64 20 2d 20      /* xRowid - 
e770: 72 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 20  read data */.   
e780: 20 7a 69 70 66 69 6c 65 55 70 64 61 74 65 2c 20   zipfileUpdate, 
e790: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
e7a0: 55 70 64 61 74 65 20 2a 2f 0a 20 20 20 20 7a 69  Update */.    zi
e7b0: 70 66 69 6c 65 42 65 67 69 6e 2c 20 20 20 20 20  pfileBegin,     
e7c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67           /* xBeg
e7d0: 69 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20  in */.    0,    
e7e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
e7f0: 20 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f       /* xSync */
e800: 0a 20 20 20 20 7a 69 70 66 69 6c 65 43 6f 6d 6d  .    zipfileComm
e810: 69 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  it,             
e820: 2f 2a 20 78 43 6f 6d 6d 69 74 20 2a 2f 0a 20 20  /* xCommit */.  
e830: 20 20 7a 69 70 66 69 6c 65 52 6f 6c 6c 62 61 63    zipfileRollbac
e840: 6b 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  k,           /* 
e850: 78 52 6f 6c 6c 62 61 63 6b 20 2a 2f 0a 20 20 20  xRollback */.   
e860: 20 7a 69 70 66 69 6c 65 46 69 6e 64 46 75 6e 63   zipfileFindFunc
e870: 74 69 6f 6e 2c 20 20 20 20 20 20 20 2f 2a 20 78  tion,       /* x
e880: 46 69 6e 64 4d 65 74 68 6f 64 20 2a 2f 0a 20 20  FindMethod */.  
e890: 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20    0,            
e8a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
e8b0: 78 52 65 6e 61 6d 65 20 2a 2f 0a 20 20 7d 3b 0a  xRename */.  };.
e8c0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69  .  int rc = sqli
e8d0: 74 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c  te3_create_modul
e8e0: 65 28 64 62 2c 20 22 7a 69 70 66 69 6c 65 22 20  e(db, "zipfile" 
e8f0: 20 2c 20 26 7a 69 70 66 69 6c 65 4d 6f 64 75 6c   , &zipfileModul
e900: 65 2c 20 30 29 3b 0a 20 20 69 66 28 20 72 63 3d  e, 0);.  if( rc=
e910: 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 20 72 63 20  =SQLITE_OK ) rc 
e920: 3d 20 73 71 6c 69 74 65 33 5f 6f 76 65 72 6c 6f  = sqlite3_overlo
e930: 61 64 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20  ad_function(db, 
e940: 22 7a 69 70 66 69 6c 65 5f 63 64 73 22 2c 20 2d  "zipfile_cds", -
e950: 31 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51  1);.  if( rc==SQ
e960: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
e970: 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61  c = sqlite3_crea
e980: 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20  te_function(db, 
e990: 22 7a 69 70 66 69 6c 65 22 2c 20 2d 31 2c 20 53  "zipfile", -1, S
e9a0: 51 4c 49 54 45 5f 55 54 46 38 2c 20 30 2c 20 30  QLITE_UTF8, 0, 0
e9b0: 2c 20 0a 20 20 20 20 20 20 20 20 7a 69 70 66 69  , .        zipfi
e9c0: 6c 65 53 74 65 70 2c 20 7a 69 70 66 69 6c 65 46  leStep, zipfileF
e9d0: 69 6e 61 6c 0a 20 20 20 20 29 3b 0a 20 20 7d 0a  inal.    );.  }.
e9e0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 23    return rc;.}.#
e9f0: 65 6c 73 65 20 20 20 20 20 20 20 20 20 2f 2a 20  else         /* 
ea00: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54  SQLITE_OMIT_VIRT
ea10: 55 41 4c 54 41 42 4c 45 20 2a 2f 0a 23 20 64 65  UALTABLE */.# de
ea20: 66 69 6e 65 20 7a 69 70 66 69 6c 65 52 65 67 69  fine zipfileRegi
ea30: 73 74 65 72 28 78 29 20 53 51 4c 49 54 45 5f 4f  ster(x) SQLITE_O
ea40: 4b 0a 23 65 6e 64 69 66 0a 0a 23 69 66 64 65 66  K.#endif..#ifdef
ea50: 20 5f 57 49 4e 33 32 0a 5f 5f 64 65 63 6c 73 70   _WIN32.__declsp
ea60: 65 63 28 64 6c 6c 65 78 70 6f 72 74 29 0a 23 65  ec(dllexport).#e
ea70: 6e 64 69 66 0a 69 6e 74 20 73 71 6c 69 74 65 33  ndif.int sqlite3
ea80: 5f 7a 69 70 66 69 6c 65 5f 69 6e 69 74 28 0a 20  _zipfile_init(. 
ea90: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20   sqlite3 *db, . 
eaa0: 20 63 68 61 72 20 2a 2a 70 7a 45 72 72 4d 73 67   char **pzErrMsg
eab0: 2c 20 0a 20 20 63 6f 6e 73 74 20 73 71 6c 69 74  , .  const sqlit
eac0: 65 33 5f 61 70 69 5f 72 6f 75 74 69 6e 65 73 20  e3_api_routines 
ead0: 2a 70 41 70 69 0a 29 7b 0a 20 20 53 51 4c 49 54  *pApi.){.  SQLIT
eae0: 45 5f 45 58 54 45 4e 53 49 4f 4e 5f 49 4e 49 54  E_EXTENSION_INIT
eaf0: 32 28 70 41 70 69 29 3b 0a 20 20 28 76 6f 69 64  2(pApi);.  (void
eb00: 29 70 7a 45 72 72 4d 73 67 3b 20 20 2f 2a 20 55  )pzErrMsg;  /* U
eb10: 6e 75 73 65 64 20 70 61 72 61 6d 65 74 65 72 20  nused parameter 
eb20: 2a 2f 0a 20 20 72 65 74 75 72 6e 20 7a 69 70 66  */.  return zipf
eb30: 69 6c 65 52 65 67 69 73 74 65 72 28 64 62 29 3b  ileRegister(db);
eb40: 0a 7d 0a                                         .}.