Hex Artifact Content
Not logged in

Artifact dd5cb8b3ef02d69632c75c49ea17c8da1b0b825b:

File src/zip.c part of check-in [90048e0b30] - Add an "extended timestamp" field to generated ZIP archives. The extended timestamp is in UTC so it does not mangle the time when the server and client are in different timezones. Ticket 28044ab5a42b75 by drh on 2009-08-15 02:17:27.

0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20  /*.** Copyright 
0010: 28 63 29 20 32 30 30 37 20 44 2e 20 52 69 63 68  (c) 2007 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54  ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66  his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f  ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75  u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20  te it and/or.** 
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20  modify it under 
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65  the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62   GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76  lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c  ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65  ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73  s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20  tributed in the 
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c  hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20  l be useful,.** 
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20  but WITHOUT ANY 
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75  WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69  t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a  ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54  * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52  Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55   A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20  RPOSE.  See the 
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50  GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f  ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a  r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c  ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20  d have received 
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e  a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63  U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e  .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72  g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69  ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65  te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20  ation, Inc., 59 
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53  Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73  uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31  ton, MA  02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20  307, USA..**.** 
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69  Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20  nformation:.**  
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a   drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68  *   http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a  waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0360: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65  .**.** This file
0370: 20 63 6f 6e 74 61 69 6e 73 20 63 6f 64 65 20 75   contains code u
0380: 73 65 64 20 74 6f 20 67 65 6e 65 72 61 74 65 20  sed to generate 
0390: 5a 49 50 20 61 72 63 68 69 76 65 73 2e 0a 2a 2f  ZIP archives..*/
03a0: 0a 23 69 6e 63 6c 75 64 65 20 3c 61 73 73 65 72  .#include <asser
03b0: 74 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 7a  t.h>.#include <z
03c0: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  lib.h>.#include 
03d0: 22 63 6f 6e 66 69 67 2e 68 22 0a 23 69 6e 63 6c  "config.h".#incl
03e0: 75 64 65 20 22 7a 69 70 2e 68 22 0a 0a 2f 2a 0a  ude "zip.h"../*.
03f0: 2a 2a 20 57 72 69 74 65 20 61 20 31 36 2d 20 6f  ** Write a 16- o
0400: 72 20 33 32 2d 62 69 74 20 69 6e 74 65 67 65 72  r 32-bit integer
0410: 20 61 73 20 6c 69 74 74 6c 65 2d 65 6e 64 69 61   as little-endia
0420: 6e 20 69 6e 74 6f 20 74 68 65 20 67 69 76 65 6e  n into the given
0430: 20 62 75 66 66 65 72 2e 0a 2a 2f 0a 73 74 61 74   buffer..*/.stat
0440: 69 63 20 76 6f 69 64 20 70 75 74 31 36 28 63 68  ic void put16(ch
0450: 61 72 20 2a 7a 2c 20 69 6e 74 20 76 29 7b 0a 20  ar *z, int v){. 
0460: 20 7a 5b 30 5d 20 3d 20 76 20 26 20 30 78 66 66   z[0] = v & 0xff
0470: 3b 0a 20 20 7a 5b 31 5d 20 3d 20 28 76 3e 3e 38  ;.  z[1] = (v>>8
0480: 29 20 26 20 30 78 66 66 3b 0a 7d 0a 73 74 61 74  ) & 0xff;.}.stat
0490: 69 63 20 76 6f 69 64 20 70 75 74 33 32 28 63 68  ic void put32(ch
04a0: 61 72 20 2a 7a 2c 20 69 6e 74 20 76 29 7b 0a 20  ar *z, int v){. 
04b0: 20 7a 5b 30 5d 20 3d 20 76 20 26 20 30 78 66 66   z[0] = v & 0xff
04c0: 3b 0a 20 20 7a 5b 31 5d 20 3d 20 28 76 3e 3e 38  ;.  z[1] = (v>>8
04d0: 29 20 26 20 30 78 66 66 3b 0a 20 20 7a 5b 32 5d  ) & 0xff;.  z[2]
04e0: 20 3d 20 28 76 3e 3e 31 36 29 20 26 20 30 78 66   = (v>>16) & 0xf
04f0: 66 3b 0a 20 20 7a 5b 33 5d 20 3d 20 28 76 3e 3e  f;.  z[3] = (v>>
0500: 32 34 29 20 26 20 30 78 66 66 3b 0a 7d 0a 0a 2f  24) & 0xff;.}../
0510: 2a 0a 2a 2a 20 56 61 72 69 61 62 6c 65 73 20 69  *.** Variables i
0520: 6e 20 77 68 69 63 68 20 74 6f 20 61 63 63 75 6d  n which to accum
0530: 75 6c 61 74 65 20 61 20 67 72 6f 77 69 6e 67 20  ulate a growing 
0540: 5a 49 50 20 61 72 63 68 69 76 65 2e 0a 2a 2f 0a  ZIP archive..*/.
0550: 73 74 61 74 69 63 20 42 6c 6f 62 20 62 6f 64 79  static Blob body
0560: 3b 20 20 20 20 2f 2a 20 54 68 65 20 62 6f 64 79  ;    /* The body
0570: 20 6f 66 20 74 68 65 20 5a 49 50 20 61 72 63 68   of the ZIP arch
0580: 69 76 65 20 2a 2f 0a 73 74 61 74 69 63 20 42 6c  ive */.static Bl
0590: 6f 62 20 74 6f 63 3b 20 20 20 20 20 2f 2a 20 54  ob toc;     /* T
05a0: 68 65 20 74 61 62 6c 65 20 6f 66 20 63 6f 6e 74  he table of cont
05b0: 65 6e 74 73 20 2a 2f 0a 73 74 61 74 69 63 20 69  ents */.static i
05c0: 6e 74 20 6e 45 6e 74 72 79 3b 20 20 20 2f 2a 20  nt nEntry;   /* 
05d0: 4e 75 6d 62 65 72 20 6f 66 20 66 69 6c 65 73 20  Number of files 
05e0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 64 6f  */.static int do
05f0: 73 54 69 6d 65 3b 20 20 2f 2a 20 44 4f 53 2d 66  sTime;  /* DOS-f
0600: 6f 72 6d 61 74 20 74 69 6d 65 20 2a 2f 0a 73 74  ormat time */.st
0610: 61 74 69 63 20 69 6e 74 20 64 6f 73 44 61 74 65  atic int dosDate
0620: 3b 20 20 2f 2a 20 44 4f 53 2d 66 6f 72 6d 61 74  ;  /* DOS-format
0630: 20 64 61 74 65 20 2a 2f 0a 73 74 61 74 69 63 20   date */.static 
0640: 69 6e 74 20 75 6e 69 78 54 69 6d 65 3b 20 2f 2a  int unixTime; /*
0650: 20 53 65 63 6f 6e 64 73 20 73 69 6e 63 65 20 31   Seconds since 1
0660: 39 37 30 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  970 */.static in
0670: 74 20 6e 44 69 72 3b 20 20 20 20 20 2f 2a 20 4e  t nDir;     /* N
0680: 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65 73  umber of entries
0690: 20 69 6e 20 61 7a 44 69 72 5b 5d 20 2a 2f 0a 73   in azDir[] */.s
06a0: 74 61 74 69 63 20 63 68 61 72 20 2a 2a 61 7a 44  tatic char **azD
06b0: 69 72 3b 20 2f 2a 20 44 69 72 65 63 74 6f 72 79  ir; /* Directory
06c0: 20 6e 61 6d 65 73 20 61 6c 72 65 61 64 79 20 61   names already a
06d0: 64 64 65 64 20 74 6f 20 74 68 65 20 61 72 63 68  dded to the arch
06e0: 69 76 65 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 49 6e  ive */../*.** In
06f0: 69 74 69 61 6c 69 7a 65 20 61 20 6e 65 77 20 5a  itialize a new Z
0700: 49 50 20 61 72 63 68 69 76 65 2e 0a 2a 2f 0a 76  IP archive..*/.v
0710: 6f 69 64 20 7a 69 70 5f 6f 70 65 6e 28 76 6f 69  oid zip_open(voi
0720: 64 29 7b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28  d){.  blob_zero(
0730: 26 62 6f 64 79 29 3b 0a 20 20 62 6c 6f 62 5f 7a  &body);.  blob_z
0740: 65 72 6f 28 26 74 6f 63 29 3b 0a 20 20 6e 45 6e  ero(&toc);.  nEn
0750: 74 72 79 20 3d 20 30 3b 0a 20 20 64 6f 73 54 69  try = 0;.  dosTi
0760: 6d 65 20 3d 20 30 3b 0a 20 20 64 6f 73 44 61 74  me = 0;.  dosDat
0770: 65 20 3d 20 30 3b 0a 20 20 75 6e 69 78 54 69 6d  e = 0;.  unixTim
0780: 65 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  e = 0;.}../*.** 
0790: 53 65 74 20 74 68 65 20 64 61 74 65 20 61 6e 64  Set the date and
07a0: 20 74 69 6d 65 20 76 61 6c 75 65 73 20 66 72 6f   time values fro
07b0: 6d 20 61 6e 20 49 53 4f 38 36 30 31 20 64 61 74  m an ISO8601 dat
07c0: 65 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 76 6f 69  e string..*/.voi
07d0: 64 20 7a 69 70 5f 73 65 74 5f 74 69 6d 65 64 61  d zip_set_timeda
07e0: 74 65 5f 66 72 6f 6d 5f 73 74 72 28 63 6f 6e 73  te_from_str(cons
07f0: 74 20 63 68 61 72 20 2a 7a 44 61 74 65 29 7b 0a  t char *zDate){.
0800: 20 20 69 6e 74 20 79 2c 20 6d 2c 20 64 3b 0a 20    int y, m, d;. 
0810: 20 69 6e 74 20 48 2c 20 4d 2c 20 53 3b 0a 0a 20   int H, M, S;.. 
0820: 20 79 20 3d 20 61 74 6f 69 28 7a 44 61 74 65 29   y = atoi(zDate)
0830: 3b 0a 20 20 6d 20 3d 20 61 74 6f 69 28 26 7a 44  ;.  m = atoi(&zD
0840: 61 74 65 5b 35 5d 29 3b 0a 20 20 64 20 3d 20 61  ate[5]);.  d = a
0850: 74 6f 69 28 26 7a 44 61 74 65 5b 38 5d 29 3b 0a  toi(&zDate[8]);.
0860: 20 20 48 20 3d 20 61 74 6f 69 28 26 7a 44 61 74    H = atoi(&zDat
0870: 65 5b 31 31 5d 29 3b 0a 20 20 4d 20 3d 20 61 74  e[11]);.  M = at
0880: 6f 69 28 26 7a 44 61 74 65 5b 31 34 5d 29 3b 0a  oi(&zDate[14]);.
0890: 20 20 53 20 3d 20 61 74 6f 69 28 26 7a 44 61 74    S = atoi(&zDat
08a0: 65 5b 31 37 5d 29 3b 0a 20 20 64 6f 73 54 69 6d  e[17]);.  dosTim
08b0: 65 20 3d 20 28 48 3c 3c 31 31 29 20 2b 20 28 4d  e = (H<<11) + (M
08c0: 3c 3c 35 29 20 2b 20 28 53 3e 3e 31 29 3b 0a 20  <<5) + (S>>1);. 
08d0: 20 64 6f 73 44 61 74 65 20 3d 20 28 28 79 2d 31   dosDate = ((y-1
08e0: 39 38 30 29 3c 3c 39 29 20 2b 20 28 6d 3c 3c 35  980)<<9) + (m<<5
08f0: 29 20 2b 20 64 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  ) + d;.}../*.** 
0900: 53 65 74 20 74 68 65 20 64 61 74 65 20 61 6e 64  Set the date and
0910: 20 74 69 6d 65 20 66 72 6f 6d 20 61 20 6a 75 6c   time from a jul
0920: 69 61 6e 20 64 61 79 20 6e 75 6d 62 65 72 2e 0a  ian day number..
0930: 2a 2f 0a 76 6f 69 64 20 7a 69 70 5f 73 65 74 5f  */.void zip_set_
0940: 74 69 6d 65 64 61 74 65 28 64 6f 75 62 6c 65 20  timedate(double 
0950: 72 44 61 74 65 29 7b 0a 20 20 63 68 61 72 20 2a  rDate){.  char *
0960: 7a 44 61 74 65 20 3d 20 64 62 5f 74 65 78 74 28  zDate = db_text(
0970: 30 2c 20 22 53 45 4c 45 43 54 20 64 61 74 65 74  0, "SELECT datet
0980: 69 6d 65 28 25 2e 31 37 67 29 22 2c 20 72 44 61  ime(%.17g)", rDa
0990: 74 65 29 3b 0a 20 20 7a 69 70 5f 73 65 74 5f 74  te);.  zip_set_t
09a0: 69 6d 65 64 61 74 65 5f 66 72 6f 6d 5f 73 74 72  imedate_from_str
09b0: 28 7a 44 61 74 65 29 3b 0a 20 20 66 72 65 65 28  (zDate);.  free(
09c0: 7a 44 61 74 65 29 3b 0a 20 20 75 6e 69 78 54 69  zDate);.  unixTi
09d0: 6d 65 20 3d 20 28 72 44 61 74 65 20 2d 20 32 34  me = (rDate - 24
09e0: 34 30 35 38 37 2e 35 29 2a 38 36 34 30 30 2e 30  40587.5)*86400.0
09f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68  ;.}../*.** If th
0a00: 65 20 67 69 76 65 6e 20 66 69 6c 65 6e 61 6d 65  e given filename
0a10: 20 69 6e 63 6c 75 64 65 73 20 6f 6e 65 20 6f 72   includes one or
0a20: 20 6d 6f 72 65 20 64 69 72 65 63 74 6f 72 79 20   more directory 
0a30: 65 6e 74 72 69 65 73 2c 20 6d 61 6b 65 0a 2a 2a  entries, make.**
0a40: 20 73 75 72 65 20 74 68 65 20 64 69 72 65 63 74   sure the direct
0a50: 6f 72 69 65 73 20 61 72 65 20 61 6c 72 65 61 64  ories are alread
0a60: 79 20 69 6e 20 74 68 65 20 61 72 63 68 69 76 65  y in the archive
0a70: 2e 20 20 49 66 20 74 68 65 79 20 61 72 65 20 6e  .  If they are n
0a80: 6f 74 0a 2a 2a 20 69 6e 20 74 68 65 20 61 72 63  ot.** in the arc
0a90: 68 69 76 65 2c 20 61 64 64 20 74 68 65 6d 2e 0a  hive, add them..
0aa0: 2a 2f 0a 76 6f 69 64 20 7a 69 70 5f 61 64 64 5f  */.void zip_add_
0ab0: 66 6f 6c 64 65 72 73 28 63 68 61 72 20 2a 7a 4e  folders(char *zN
0ac0: 61 6d 65 29 7b 0a 20 20 69 6e 74 20 69 2c 20 63  ame){.  int i, c
0ad0: 3b 0a 20 20 69 6e 74 20 6a 3b 0a 20 20 66 6f 72  ;.  int j;.  for
0ae0: 28 69 3d 30 3b 20 7a 4e 61 6d 65 5b 69 5d 3b 20  (i=0; zName[i]; 
0af0: 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a 4e  i++){.    if( zN
0b00: 61 6d 65 5b 69 5d 3d 3d 27 2f 27 20 29 7b 0a 20  ame[i]=='/' ){. 
0b10: 20 20 20 20 20 63 20 3d 20 7a 4e 61 6d 65 5b 69       c = zName[i
0b20: 2b 31 5d 3b 0a 20 20 20 20 20 20 7a 4e 61 6d 65  +1];.      zName
0b30: 5b 69 2b 31 5d 20 3d 20 30 3b 0a 20 20 20 20 20  [i+1] = 0;.     
0b40: 20 66 6f 72 28 6a 3d 30 3b 20 6a 3c 6e 44 69 72   for(j=0; j<nDir
0b50: 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20  ; j++){.        
0b60: 69 66 28 20 73 74 72 63 6d 70 28 7a 4e 61 6d 65  if( strcmp(zName
0b70: 2c 20 61 7a 44 69 72 5b 6a 5d 29 3d 3d 30 20 29  , azDir[j])==0 )
0b80: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a   break;.      }.
0b90: 20 20 20 20 20 20 69 66 28 20 6a 3e 3d 6e 44 69        if( j>=nDi
0ba0: 72 20 29 7b 0a 20 20 20 20 20 20 20 20 6e 44 69  r ){.        nDi
0bb0: 72 2b 2b 3b 0a 20 20 20 20 20 20 20 20 61 7a 44  r++;.        azD
0bc0: 69 72 20 3d 20 72 65 61 6c 6c 6f 63 28 61 7a 44  ir = realloc(azD
0bd0: 69 72 2c 20 6e 44 69 72 29 3b 0a 20 20 20 20 20  ir, nDir);.     
0be0: 20 20 20 61 7a 44 69 72 5b 6a 5d 20 3d 20 73 71     azDir[j] = sq
0bf0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25  lite3_mprintf("%
0c00: 73 22 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20  s", zName);.    
0c10: 20 20 20 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65      zip_add_file
0c20: 28 7a 4e 61 6d 65 2c 20 30 29 3b 0a 20 20 20 20  (zName, 0);.    
0c30: 20 20 7d 0a 20 20 20 20 20 20 7a 4e 61 6d 65 5b    }.      zName[
0c40: 69 2b 31 5d 20 3d 20 63 3b 0a 20 20 20 20 7d 0a  i+1] = c;.    }.
0c50: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70    }.}../*.** App
0c60: 65 6e 64 20 61 20 73 69 6e 67 6c 65 20 66 69 6c  end a single fil
0c70: 65 20 74 6f 20 61 20 67 72 6f 77 69 6e 67 20 5a  e to a growing Z
0c80: 49 50 20 61 72 63 68 69 76 65 2e 0a 2a 2a 0a 2a  IP archive..**.*
0c90: 2a 20 70 46 69 6c 65 20 69 73 20 74 68 65 20 66  * pFile is the f
0ca0: 69 6c 65 20 74 6f 20 62 65 20 61 70 70 65 6e 64  ile to be append
0cb0: 65 64 2e 20 20 7a 4e 61 6d 65 20 69 73 20 74 68  ed.  zName is th
0cc0: 65 20 6e 61 6d 65 0a 2a 2a 20 74 68 61 74 20 74  e name.** that t
0cd0: 68 65 20 66 69 6c 65 20 73 68 6f 75 6c 64 20 62  he file should b
0ce0: 65 20 73 61 76 65 64 20 61 73 2e 0a 2a 2f 0a 76  e saved as..*/.v
0cf0: 6f 69 64 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65  oid zip_add_file
0d00: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61  (const char *zNa
0d10: 6d 65 2c 20 63 6f 6e 73 74 20 42 6c 6f 62 20 2a  me, const Blob *
0d20: 70 46 69 6c 65 29 7b 0a 20 20 7a 5f 73 74 72 65  pFile){.  z_stre
0d30: 61 6d 20 73 74 72 65 61 6d 3b 0a 20 20 69 6e 74  am stream;.  int
0d40: 20 6e 61 6d 65 4c 65 6e 3b 0a 20 20 69 6e 74 20   nameLen;.  int 
0d50: 73 6b 69 70 3b 0a 20 20 69 6e 74 20 74 6f 4f 75  skip;.  int toOu
0d60: 74 3b 0a 20 20 69 6e 74 20 69 53 74 61 72 74 3b  t;.  int iStart;
0d70: 0a 20 20 69 6e 74 20 69 43 52 43 20 3d 20 30 3b  .  int iCRC = 0;
0d80: 0a 20 20 69 6e 74 20 6e 42 79 74 65 20 3d 20 30  .  int nByte = 0
0d90: 3b 0a 20 20 69 6e 74 20 6e 42 79 74 65 43 6f 6d  ;.  int nByteCom
0da0: 70 72 20 3d 20 30 3b 0a 20 20 69 6e 74 20 6e 42  pr = 0;.  int nB
0db0: 6c 6f 62 3b 20 20 20 20 20 20 20 20 20 20 20 20  lob;            
0dc0: 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f 66 20       /* Size of 
0dd0: 74 68 65 20 62 6c 6f 62 20 2a 2f 0a 20 20 69 6e  the blob */.  in
0de0: 74 20 69 4d 65 74 68 6f 64 3b 20 20 20 20 20 20  t iMethod;      
0df0: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6d 70           /* Comp
0e00: 72 65 73 73 69 6f 6e 20 6d 65 74 68 6f 64 2e 20  ression method. 
0e10: 2a 2f 0a 20 20 69 6e 74 20 69 4d 6f 64 65 20 3d  */.  int iMode =
0e20: 20 30 36 34 34 3b 20 20 20 20 20 20 20 20 20 20   0644;          
0e30: 2f 2a 20 41 63 63 65 73 73 20 70 65 72 6d 69 73  /* Access permis
0e40: 73 69 6f 6e 73 20 2a 2f 0a 20 20 63 68 61 72 20  sions */.  char 
0e50: 2a 7a 3b 0a 20 20 63 68 61 72 20 7a 48 64 72 5b  *z;.  char zHdr[
0e60: 33 30 5d 3b 0a 20 20 63 68 61 72 20 7a 45 78 54  30];.  char zExT
0e70: 69 6d 65 5b 31 33 5d 3b 0a 20 20 63 68 61 72 20  ime[13];.  char 
0e80: 7a 42 75 66 5b 31 30 30 5d 3b 0a 20 20 63 68 61  zBuf[100];.  cha
0e90: 72 20 7a 4f 75 74 42 75 66 5b 31 30 30 30 30 30  r zOutBuf[100000
0ea0: 5d 3b 0a 0a 20 20 2f 2a 20 46 69 6c 6c 20 69 6e  ];..  /* Fill in
0eb0: 20 61 73 20 6d 75 63 68 20 6f 66 20 74 68 65 20   as much of the 
0ec0: 68 65 61 64 65 72 20 61 73 20 77 65 20 6b 6e 6f  header as we kno
0ed0: 77 2e 0a 20 20 2a 2f 0a 20 20 6e 42 6c 6f 62 20  w..  */.  nBlob 
0ee0: 3d 20 70 46 69 6c 65 20 3f 20 62 6c 6f 62 5f 73  = pFile ? blob_s
0ef0: 69 7a 65 28 70 46 69 6c 65 29 20 3a 20 30 3b 0a  ize(pFile) : 0;.
0f00: 20 20 69 66 28 20 6e 42 6c 6f 62 3e 30 20 29 7b    if( nBlob>0 ){
0f10: 0a 20 20 20 20 69 4d 65 74 68 6f 64 20 3d 20 38  .    iMethod = 8
0f20: 3b 0a 20 20 20 20 69 4d 6f 64 65 20 3d 20 30 31  ;.    iMode = 01
0f30: 30 30 36 34 34 3b 0a 20 20 7d 65 6c 73 65 7b 0a  00644;.  }else{.
0f40: 20 20 20 20 69 4d 65 74 68 6f 64 20 3d 20 30 3b      iMethod = 0;
0f50: 0a 20 20 20 20 69 4d 6f 64 65 20 3d 20 30 34 30  .    iMode = 040
0f60: 37 35 35 3b 0a 20 20 7d 0a 20 20 6e 61 6d 65 4c  755;.  }.  nameL
0f70: 65 6e 20 3d 20 73 74 72 6c 65 6e 28 7a 4e 61 6d  en = strlen(zNam
0f80: 65 29 3b 0a 20 20 6d 65 6d 73 65 74 28 7a 48 64  e);.  memset(zHd
0f90: 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 7a 48 64  r, 0, sizeof(zHd
0fa0: 72 29 29 3b 0a 20 20 70 75 74 33 32 28 26 7a 48  r));.  put32(&zH
0fb0: 64 72 5b 30 5d 2c 20 30 78 30 34 30 33 34 62 35  dr[0], 0x04034b5
0fc0: 30 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 48 64  0);.  put16(&zHd
0fd0: 72 5b 34 5d 2c 20 30 78 30 30 30 61 29 3b 0a 20  r[4], 0x000a);. 
0fe0: 20 70 75 74 31 36 28 26 7a 48 64 72 5b 36 5d 2c   put16(&zHdr[6],
0ff0: 20 30 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 48   0);.  put16(&zH
1000: 64 72 5b 38 5d 2c 20 69 4d 65 74 68 6f 64 29 3b  dr[8], iMethod);
1010: 0a 20 20 70 75 74 31 36 28 26 7a 48 64 72 5b 31  .  put16(&zHdr[1
1020: 30 5d 2c 20 64 6f 73 54 69 6d 65 29 3b 0a 20 20  0], dosTime);.  
1030: 70 75 74 31 36 28 26 7a 48 64 72 5b 31 32 5d 2c  put16(&zHdr[12],
1040: 20 64 6f 73 44 61 74 65 29 3b 0a 20 20 70 75 74   dosDate);.  put
1050: 31 36 28 26 7a 48 64 72 5b 32 36 5d 2c 20 6e 61  16(&zHdr[26], na
1060: 6d 65 4c 65 6e 29 3b 0a 20 20 70 75 74 31 36 28  meLen);.  put16(
1070: 26 7a 48 64 72 5b 32 38 5d 2c 20 31 33 29 3b 0a  &zHdr[28], 13);.
1080: 20 20 0a 20 20 70 75 74 31 36 28 26 7a 45 78 54    .  put16(&zExT
1090: 69 6d 65 5b 30 5d 2c 20 30 78 35 34 35 35 29 3b  ime[0], 0x5455);
10a0: 0a 20 20 70 75 74 31 36 28 26 7a 45 78 54 69 6d  .  put16(&zExTim
10b0: 65 5b 32 5d 2c 20 39 29 3b 0a 20 20 7a 45 78 54  e[2], 9);.  zExT
10c0: 69 6d 65 5b 34 5d 20 3d 20 33 3b 0a 20 20 70 75  ime[4] = 3;.  pu
10d0: 74 33 32 28 26 7a 45 78 54 69 6d 65 5b 35 5d 2c  t32(&zExTime[5],
10e0: 20 75 6e 69 78 54 69 6d 65 29 3b 0a 20 20 70 75   unixTime);.  pu
10f0: 74 33 32 28 26 7a 45 78 54 69 6d 65 5b 39 5d 2c  t32(&zExTime[9],
1100: 20 75 6e 69 78 54 69 6d 65 29 3b 0a 20 20 0a 0a   unixTime);.  ..
1110: 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 68    /* Write the h
1120: 65 61 64 65 72 20 61 6e 64 20 66 69 6c 65 6e 61  eader and filena
1130: 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 53 74 61 72  me..  */.  iStar
1140: 74 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 26 62  t = blob_size(&b
1150: 6f 64 79 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70  ody);.  blob_app
1160: 65 6e 64 28 26 62 6f 64 79 2c 20 7a 48 64 72 2c  end(&body, zHdr,
1170: 20 33 30 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70   30);.  blob_app
1180: 65 6e 64 28 26 62 6f 64 79 2c 20 7a 4e 61 6d 65  end(&body, zName
1190: 2c 20 6e 61 6d 65 4c 65 6e 29 3b 0a 20 20 62 6c  , nameLen);.  bl
11a0: 6f 62 5f 61 70 70 65 6e 64 28 26 62 6f 64 79 2c  ob_append(&body,
11b0: 20 7a 45 78 54 69 6d 65 2c 20 31 33 29 3b 0a 0a   zExTime, 13);..
11c0: 20 20 69 66 28 20 6e 42 6c 6f 62 3e 30 20 29 7b    if( nBlob>0 ){
11d0: 0a 20 20 20 20 2f 2a 20 54 68 65 20 66 69 72 73  .    /* The firs
11e0: 74 20 74 77 6f 20 62 79 74 65 73 20 74 68 61 74  t two bytes that
11f0: 20 63 6f 6d 65 20 6f 75 74 20 6f 66 20 74 68 65   come out of the
1200: 20 64 65 66 6c 61 74 65 20 63 6f 6d 70 72 65 73   deflate compres
1210: 73 6f 72 20 61 72 65 0a 20 20 20 20 2a 2a 20 73  sor are.    ** s
1220: 6f 6d 65 20 6b 69 6e 64 20 6f 66 20 68 65 61 64  ome kind of head
1230: 65 72 20 74 68 61 74 20 5a 49 50 20 64 6f 65 73  er that ZIP does
1240: 20 6e 6f 74 20 75 73 65 2e 20 20 53 6f 20 73 6b   not use.  So sk
1250: 69 70 20 74 68 65 20 66 69 72 73 74 20 74 77 6f  ip the first two
1260: 0a 20 20 20 20 2a 2a 20 6f 75 74 70 75 74 20 62  .    ** output b
1270: 79 74 65 73 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  ytes..    */.   
1280: 20 73 6b 69 70 20 3d 20 32 3b 0a 20 20 0a 20 20   skip = 2;.  .  
1290: 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 63    /* Write the c
12a0: 6f 6d 70 72 65 73 73 65 64 20 66 69 6c 65 2e 20  ompressed file. 
12b0: 20 43 6f 6d 70 75 74 65 20 74 68 65 20 43 52 43   Compute the CRC
12c0: 20 61 73 20 77 65 20 70 72 6f 67 72 65 73 73 2e   as we progress.
12d0: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 73 74 72 65  .    */.    stre
12e0: 61 6d 2e 7a 61 6c 6c 6f 63 20 3d 20 28 61 6c 6c  am.zalloc = (all
12f0: 6f 63 5f 66 75 6e 63 29 30 3b 0a 20 20 20 20 73  oc_func)0;.    s
1300: 74 72 65 61 6d 2e 7a 66 72 65 65 20 3d 20 28 66  tream.zfree = (f
1310: 72 65 65 5f 66 75 6e 63 29 30 3b 0a 20 20 20 20  ree_func)0;.    
1320: 73 74 72 65 61 6d 2e 6f 70 61 71 75 65 20 3d 20  stream.opaque = 
1330: 30 3b 0a 20 20 20 20 73 74 72 65 61 6d 2e 61 76  0;.    stream.av
1340: 61 69 6c 5f 69 6e 20 3d 20 62 6c 6f 62 5f 73 69  ail_in = blob_si
1350: 7a 65 28 70 46 69 6c 65 29 3b 0a 20 20 20 20 73  ze(pFile);.    s
1360: 74 72 65 61 6d 2e 6e 65 78 74 5f 69 6e 20 3d 20  tream.next_in = 
1370: 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 2a 29  (unsigned char*)
1380: 62 6c 6f 62 5f 62 75 66 66 65 72 28 70 46 69 6c  blob_buffer(pFil
1390: 65 29 3b 0a 20 20 20 20 73 74 72 65 61 6d 2e 61  e);.    stream.a
13a0: 76 61 69 6c 5f 6f 75 74 20 3d 20 73 69 7a 65 6f  vail_out = sizeo
13b0: 66 28 7a 4f 75 74 42 75 66 29 3b 0a 20 20 20 20  f(zOutBuf);.    
13c0: 73 74 72 65 61 6d 2e 6e 65 78 74 5f 6f 75 74 20  stream.next_out 
13d0: 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72  = (unsigned char
13e0: 2a 29 7a 4f 75 74 42 75 66 3b 0a 20 20 20 20 64  *)zOutBuf;.    d
13f0: 65 66 6c 61 74 65 49 6e 69 74 28 26 73 74 72 65  eflateInit(&stre
1400: 61 6d 2c 20 39 29 3b 0a 20 20 20 20 69 43 52 43  am, 9);.    iCRC
1410: 20 3d 20 63 72 63 33 32 28 30 2c 20 73 74 72 65   = crc32(0, stre
1420: 61 6d 2e 6e 65 78 74 5f 69 6e 2c 20 73 74 72 65  am.next_in, stre
1430: 61 6d 2e 61 76 61 69 6c 5f 69 6e 29 3b 0a 20 20  am.avail_in);.  
1440: 20 20 77 68 69 6c 65 28 20 73 74 72 65 61 6d 2e    while( stream.
1450: 61 76 61 69 6c 5f 69 6e 3e 30 20 29 7b 0a 20 20  avail_in>0 ){.  
1460: 20 20 20 20 64 65 66 6c 61 74 65 28 26 73 74 72      deflate(&str
1470: 65 61 6d 2c 20 30 29 3b 0a 20 20 20 20 20 20 74  eam, 0);.      t
1480: 6f 4f 75 74 20 3d 20 73 69 7a 65 6f 66 28 7a 4f  oOut = sizeof(zO
1490: 75 74 42 75 66 29 20 2d 20 73 74 72 65 61 6d 2e  utBuf) - stream.
14a0: 61 76 61 69 6c 5f 6f 75 74 3b 0a 20 20 20 20 20  avail_out;.     
14b0: 20 69 66 28 20 74 6f 4f 75 74 3e 73 6b 69 70 20   if( toOut>skip 
14c0: 29 7b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f  ){.        blob_
14d0: 61 70 70 65 6e 64 28 26 62 6f 64 79 2c 20 26 7a  append(&body, &z
14e0: 4f 75 74 42 75 66 5b 73 6b 69 70 5d 2c 20 74 6f  OutBuf[skip], to
14f0: 4f 75 74 20 2d 20 73 6b 69 70 29 3b 0a 20 20 20  Out - skip);.   
1500: 20 20 20 20 20 73 6b 69 70 20 3d 20 30 3b 0a 20       skip = 0;. 
1510: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
1520: 20 20 20 20 73 6b 69 70 20 2d 3d 20 74 6f 4f 75      skip -= toOu
1530: 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  t;.      }.     
1540: 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f 75   stream.avail_ou
1550: 74 20 3d 20 73 69 7a 65 6f 66 28 7a 4f 75 74 42  t = sizeof(zOutB
1560: 75 66 29 3b 0a 20 20 20 20 20 20 73 74 72 65 61  uf);.      strea
1570: 6d 2e 6e 65 78 74 5f 6f 75 74 20 3d 20 28 75 6e  m.next_out = (un
1580: 73 69 67 6e 65 64 20 63 68 61 72 2a 29 7a 4f 75  signed char*)zOu
1590: 74 42 75 66 3b 0a 20 20 20 20 7d 0a 20 20 20 20  tBuf;.    }.    
15a0: 64 6f 7b 0a 20 20 20 20 20 20 73 74 72 65 61 6d  do{.      stream
15b0: 2e 61 76 61 69 6c 5f 6f 75 74 20 3d 20 73 69 7a  .avail_out = siz
15c0: 65 6f 66 28 7a 4f 75 74 42 75 66 29 3b 0a 20 20  eof(zOutBuf);.  
15d0: 20 20 20 20 73 74 72 65 61 6d 2e 6e 65 78 74 5f      stream.next_
15e0: 6f 75 74 20 3d 20 28 75 6e 73 69 67 6e 65 64 20  out = (unsigned 
15f0: 63 68 61 72 2a 29 7a 4f 75 74 42 75 66 3b 0a 20  char*)zOutBuf;. 
1600: 20 20 20 20 20 64 65 66 6c 61 74 65 28 26 73 74       deflate(&st
1610: 72 65 61 6d 2c 20 5a 5f 46 49 4e 49 53 48 29 3b  ream, Z_FINISH);
1620: 0a 20 20 20 20 20 20 74 6f 4f 75 74 20 3d 20 73  .      toOut = s
1630: 69 7a 65 6f 66 28 7a 4f 75 74 42 75 66 29 20 2d  izeof(zOutBuf) -
1640: 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f 75   stream.avail_ou
1650: 74 3b 0a 20 20 20 20 20 20 69 66 28 20 74 6f 4f  t;.      if( toO
1660: 75 74 3e 73 6b 69 70 20 29 7b 0a 20 20 20 20 20  ut>skip ){.     
1670: 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26     blob_append(&
1680: 62 6f 64 79 2c 20 26 7a 4f 75 74 42 75 66 5b 73  body, &zOutBuf[s
1690: 6b 69 70 5d 2c 20 74 6f 4f 75 74 20 2d 20 73 6b  kip], toOut - sk
16a0: 69 70 29 3b 0a 20 20 20 20 20 20 20 20 73 6b 69  ip);.        ski
16b0: 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c  p = 0;.      }el
16c0: 73 65 7b 0a 20 20 20 20 20 20 20 20 73 6b 69 70  se{.        skip
16d0: 20 2d 3d 20 74 6f 4f 75 74 3b 0a 20 20 20 20 20   -= toOut;.     
16e0: 20 7d 0a 20 20 20 20 7d 77 68 69 6c 65 28 20 73   }.    }while( s
16f0: 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f 75 74 3d  tream.avail_out=
1700: 3d 30 20 29 3b 0a 20 20 20 20 6e 42 79 74 65 20  =0 );.    nByte 
1710: 3d 20 73 74 72 65 61 6d 2e 74 6f 74 61 6c 5f 69  = stream.total_i
1720: 6e 3b 0a 20 20 20 20 6e 42 79 74 65 43 6f 6d 70  n;.    nByteComp
1730: 72 20 3d 20 73 74 72 65 61 6d 2e 74 6f 74 61 6c  r = stream.total
1740: 5f 6f 75 74 20 2d 20 32 3b 0a 20 20 20 20 64 65  _out - 2;.    de
1750: 66 6c 61 74 65 45 6e 64 28 26 73 74 72 65 61 6d  flateEnd(&stream
1760: 29 3b 0a 20 20 0a 20 20 20 20 2f 2a 20 47 6f 20  );.  .    /* Go 
1770: 62 61 63 6b 20 61 6e 64 20 77 72 69 74 65 20 74  back and write t
1780: 68 65 20 68 65 61 64 65 72 2c 20 6e 6f 77 20 74  he header, now t
1790: 68 61 74 20 77 65 20 6b 6e 6f 77 20 74 68 65 20  hat we know the 
17a0: 63 6f 6d 70 72 65 73 73 65 64 20 66 69 6c 65 20  compressed file 
17b0: 73 69 7a 65 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  size..    */.   
17c0: 20 7a 20 3d 20 26 62 6c 6f 62 5f 62 75 66 66 65   z = &blob_buffe
17d0: 72 28 26 62 6f 64 79 29 5b 69 53 74 61 72 74 5d  r(&body)[iStart]
17e0: 3b 0a 20 20 20 20 70 75 74 33 32 28 26 7a 5b 31  ;.    put32(&z[1
17f0: 34 5d 2c 20 69 43 52 43 29 3b 0a 20 20 20 20 70  4], iCRC);.    p
1800: 75 74 33 32 28 26 7a 5b 31 38 5d 2c 20 6e 42 79  ut32(&z[18], nBy
1810: 74 65 43 6f 6d 70 72 29 3b 0a 20 20 20 20 70 75  teCompr);.    pu
1820: 74 33 32 28 26 7a 5b 32 32 5d 2c 20 6e 42 79 74  t32(&z[22], nByt
1830: 65 29 3b 0a 20 20 7d 0a 20 20 0a 20 20 2f 2a 20  e);.  }.  .  /* 
1840: 4d 61 6b 65 20 61 6e 20 65 6e 74 72 79 20 69 6e  Make an entry in
1850: 20 74 68 65 20 74 61 62 6c 65 73 20 6f 66 20 63   the tables of c
1860: 6f 6e 74 65 6e 74 73 0a 20 20 2a 2f 0a 20 20 6d  ontents.  */.  m
1870: 65 6d 73 65 74 28 7a 42 75 66 2c 20 30 2c 20 73  emset(zBuf, 0, s
1880: 69 7a 65 6f 66 28 7a 42 75 66 29 29 3b 0a 20 20  izeof(zBuf));.  
1890: 70 75 74 33 32 28 26 7a 42 75 66 5b 30 5d 2c 20  put32(&zBuf[0], 
18a0: 30 78 30 32 30 31 34 62 35 30 29 3b 0a 20 20 70  0x02014b50);.  p
18b0: 75 74 31 36 28 26 7a 42 75 66 5b 34 5d 2c 20 30  ut16(&zBuf[4], 0
18c0: 78 30 33 31 37 29 3b 0a 20 20 70 75 74 31 36 28  x0317);.  put16(
18d0: 26 7a 42 75 66 5b 36 5d 2c 20 30 78 30 30 30 61  &zBuf[6], 0x000a
18e0: 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66  );.  put16(&zBuf
18f0: 5b 38 5d 2c 20 30 29 3b 0a 20 20 70 75 74 31 36  [8], 0);.  put16
1900: 28 26 7a 42 75 66 5b 31 30 5d 2c 20 69 4d 65 74  (&zBuf[10], iMet
1910: 68 6f 64 29 3b 0a 20 20 70 75 74 31 36 28 26 7a  hod);.  put16(&z
1920: 42 75 66 5b 31 32 5d 2c 20 64 6f 73 54 69 6d 65  Buf[12], dosTime
1930: 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66  );.  put16(&zBuf
1940: 5b 31 34 5d 2c 20 64 6f 73 44 61 74 65 29 3b 0a  [14], dosDate);.
1950: 20 20 70 75 74 33 32 28 26 7a 42 75 66 5b 31 36    put32(&zBuf[16
1960: 5d 2c 20 69 43 52 43 29 3b 0a 20 20 70 75 74 33  ], iCRC);.  put3
1970: 32 28 26 7a 42 75 66 5b 32 30 5d 2c 20 6e 42 79  2(&zBuf[20], nBy
1980: 74 65 43 6f 6d 70 72 29 3b 0a 20 20 70 75 74 33  teCompr);.  put3
1990: 32 28 26 7a 42 75 66 5b 32 34 5d 2c 20 6e 42 79  2(&zBuf[24], nBy
19a0: 74 65 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 42  te);.  put16(&zB
19b0: 75 66 5b 32 38 5d 2c 20 6e 61 6d 65 4c 65 6e 29  uf[28], nameLen)
19c0: 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b  ;.  put16(&zBuf[
19d0: 33 30 5d 2c 20 39 29 3b 0a 20 20 70 75 74 31 36  30], 9);.  put16
19e0: 28 26 7a 42 75 66 5b 33 32 5d 2c 20 30 29 3b 0a  (&zBuf[32], 0);.
19f0: 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 33 34    put16(&zBuf[34
1a00: 5d 2c 20 30 29 3b 0a 20 20 70 75 74 31 36 28 26  ], 0);.  put16(&
1a10: 7a 42 75 66 5b 33 36 5d 2c 20 30 29 3b 0a 20 20  zBuf[36], 0);.  
1a20: 70 75 74 33 32 28 26 7a 42 75 66 5b 33 38 5d 2c  put32(&zBuf[38],
1a30: 20 28 28 75 6e 73 69 67 6e 65 64 29 69 4d 6f 64   ((unsigned)iMod
1a40: 65 29 3c 3c 31 36 29 3b 0a 20 20 70 75 74 33 32  e)<<16);.  put32
1a50: 28 26 7a 42 75 66 5b 34 32 5d 2c 20 69 53 74 61  (&zBuf[42], iSta
1a60: 72 74 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70 65  rt);.  blob_appe
1a70: 6e 64 28 26 74 6f 63 2c 20 7a 42 75 66 2c 20 34  nd(&toc, zBuf, 4
1a80: 36 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e  6);.  blob_appen
1a90: 64 28 26 74 6f 63 2c 20 7a 4e 61 6d 65 2c 20 6e  d(&toc, zName, n
1aa0: 61 6d 65 4c 65 6e 29 3b 0a 20 20 70 75 74 31 36  ameLen);.  put16
1ab0: 28 26 7a 45 78 54 69 6d 65 5b 32 5d 2c 20 35 29  (&zExTime[2], 5)
1ac0: 3b 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28  ;.  blob_append(
1ad0: 26 74 6f 63 2c 20 7a 45 78 54 69 6d 65 2c 20 39  &toc, zExTime, 9
1ae0: 29 3b 0a 20 20 6e 45 6e 74 72 79 2b 2b 3b 0a 7d  );.  nEntry++;.}
1af0: 0a 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74  .../*.** Write t
1b00: 68 65 20 5a 49 50 20 61 72 63 68 69 76 65 20 69  he ZIP archive i
1b10: 6e 74 6f 20 74 68 65 20 67 69 76 65 6e 20 42 4c  nto the given BL
1b20: 4f 42 2e 0a 2a 2f 0a 76 6f 69 64 20 7a 69 70 5f  OB..*/.void zip_
1b30: 63 6c 6f 73 65 28 42 6c 6f 62 20 2a 70 5a 69 70  close(Blob *pZip
1b40: 29 7b 0a 20 20 69 6e 74 20 69 54 6f 63 53 74 61  ){.  int iTocSta
1b50: 72 74 3b 0a 20 20 69 6e 74 20 69 54 6f 63 45 6e  rt;.  int iTocEn
1b60: 64 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 68  d;.  int i;.  ch
1b70: 61 72 20 7a 42 75 66 5b 33 30 5d 3b 0a 0a 20 20  ar zBuf[30];..  
1b80: 69 54 6f 63 53 74 61 72 74 20 3d 20 62 6c 6f 62  iTocStart = blob
1b90: 5f 73 69 7a 65 28 26 62 6f 64 79 29 3b 0a 20 20  _size(&body);.  
1ba0: 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 62 6f 64  blob_append(&bod
1bb0: 79 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26  y, blob_buffer(&
1bc0: 74 6f 63 29 2c 20 62 6c 6f 62 5f 73 69 7a 65 28  toc), blob_size(
1bd0: 26 74 6f 63 29 29 3b 0a 20 20 69 54 6f 63 45 6e  &toc));.  iTocEn
1be0: 64 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 26 62  d = blob_size(&b
1bf0: 6f 64 79 29 3b 0a 0a 20 20 6d 65 6d 73 65 74 28  ody);..  memset(
1c00: 7a 42 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28  zBuf, 0, sizeof(
1c10: 7a 42 75 66 29 29 3b 0a 20 20 70 75 74 33 32 28  zBuf));.  put32(
1c20: 26 7a 42 75 66 5b 30 5d 2c 20 30 78 30 36 30 35  &zBuf[0], 0x0605
1c30: 34 62 35 30 29 3b 0a 20 20 70 75 74 31 36 28 26  4b50);.  put16(&
1c40: 7a 42 75 66 5b 34 5d 2c 20 30 29 3b 0a 20 20 70  zBuf[4], 0);.  p
1c50: 75 74 31 36 28 26 7a 42 75 66 5b 36 5d 2c 20 30  ut16(&zBuf[6], 0
1c60: 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66  );.  put16(&zBuf
1c70: 5b 38 5d 2c 20 6e 45 6e 74 72 79 29 3b 0a 20 20  [8], nEntry);.  
1c80: 70 75 74 31 36 28 26 7a 42 75 66 5b 31 30 5d 2c  put16(&zBuf[10],
1c90: 20 6e 45 6e 74 72 79 29 3b 0a 20 20 70 75 74 33   nEntry);.  put3
1ca0: 32 28 26 7a 42 75 66 5b 31 32 5d 2c 20 69 54 6f  2(&zBuf[12], iTo
1cb0: 63 45 6e 64 20 2d 20 69 54 6f 63 53 74 61 72 74  cEnd - iTocStart
1cc0: 29 3b 0a 20 20 70 75 74 33 32 28 26 7a 42 75 66  );.  put32(&zBuf
1cd0: 5b 31 36 5d 2c 20 69 54 6f 63 53 74 61 72 74 29  [16], iTocStart)
1ce0: 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b  ;.  put16(&zBuf[
1cf0: 32 30 5d 2c 20 30 29 3b 0a 20 20 62 6c 6f 62 5f  20], 0);.  blob_
1d00: 61 70 70 65 6e 64 28 26 62 6f 64 79 2c 20 7a 42  append(&body, zB
1d10: 75 66 2c 20 32 32 29 3b 0a 20 20 62 6c 6f 62 5f  uf, 22);.  blob_
1d20: 72 65 73 65 74 28 26 74 6f 63 29 3b 0a 20 20 2a  reset(&toc);.  *
1d30: 70 5a 69 70 20 3d 20 62 6f 64 79 3b 0a 20 20 62  pZip = body;.  b
1d40: 6c 6f 62 5f 7a 65 72 6f 28 26 62 6f 64 79 29 3b  lob_zero(&body);
1d50: 0a 20 20 6e 45 6e 74 72 79 20 3d 20 30 3b 0a 20  .  nEntry = 0;. 
1d60: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 44 69 72   for(i=0; i<nDir
1d70: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 73 71 6c 69  ; i++){.    sqli
1d80: 74 65 33 5f 66 72 65 65 28 61 7a 44 69 72 5b 69  te3_free(azDir[i
1d90: 5d 29 3b 0a 20 20 7d 0a 20 20 66 72 65 65 28 61  ]);.  }.  free(a
1da0: 7a 44 69 72 29 3b 0a 20 20 6e 44 69 72 20 3d 20  zDir);.  nDir = 
1db0: 30 3b 0a 20 20 61 7a 44 69 72 20 3d 20 30 3b 0a  0;.  azDir = 0;.
1dc0: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e 44  }../*.** COMMAND
1dd0: 3a 20 74 65 73 74 2d 66 69 6c 65 7a 69 70 0a 2a  : test-filezip.*
1de0: 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20 61 20  *.** Generate a 
1df0: 5a 49 50 20 61 72 63 68 69 76 65 20 73 70 65 63  ZIP archive spec
1e00: 69 66 69 65 64 20 62 79 20 74 68 65 20 66 69 72  ified by the fir
1e10: 73 74 20 61 72 67 75 6d 65 6e 74 20 74 68 61 74  st argument that
1e20: 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 66 69 6c  .** contains fil
1e30: 65 73 20 67 69 76 65 6e 20 69 6e 20 74 68 65 20  es given in the 
1e40: 73 65 63 6f 6e 64 20 61 6e 64 20 73 75 62 73 65  second and subse
1e50: 71 75 65 6e 74 20 61 72 67 75 6d 65 6e 74 73 2e  quent arguments.
1e60: 0a 2a 2f 0a 76 6f 69 64 20 66 69 6c 65 7a 69 70  .*/.void filezip
1e70: 5f 63 6d 64 28 76 6f 69 64 29 7b 0a 20 20 69 6e  _cmd(void){.  in
1e80: 74 20 69 3b 0a 20 20 42 6c 6f 62 20 7a 69 70 3b  t i;.  Blob zip;
1e90: 0a 20 20 42 6c 6f 62 20 66 69 6c 65 3b 0a 20 20  .  Blob file;.  
1ea0: 69 66 28 20 67 2e 61 72 67 63 3c 33 20 29 7b 0a  if( g.argc<3 ){.
1eb0: 20 20 20 20 75 73 61 67 65 28 22 41 52 43 48 49      usage("ARCHI
1ec0: 56 45 20 46 49 4c 45 2e 2e 2e 2e 22 29 3b 0a 20  VE FILE....");. 
1ed0: 20 7d 0a 20 20 7a 69 70 5f 6f 70 65 6e 28 29 3b   }.  zip_open();
1ee0: 0a 20 20 66 6f 72 28 69 3d 33 3b 20 69 3c 67 2e  .  for(i=3; i<g.
1ef0: 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  argc; i++){.    
1f00: 62 6c 6f 62 5f 7a 65 72 6f 28 26 66 69 6c 65 29  blob_zero(&file)
1f10: 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 61 64 5f  ;.    blob_read_
1f20: 66 72 6f 6d 5f 66 69 6c 65 28 26 66 69 6c 65 2c  from_file(&file,
1f30: 20 67 2e 61 72 67 76 5b 69 5d 29 3b 0a 20 20 20   g.argv[i]);.   
1f40: 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65 28 67 2e   zip_add_file(g.
1f50: 61 72 67 76 5b 69 5d 2c 20 26 66 69 6c 65 29 3b  argv[i], &file);
1f60: 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28  .    blob_reset(
1f70: 26 66 69 6c 65 29 3b 0a 20 20 7d 0a 20 20 7a 69  &file);.  }.  zi
1f80: 70 5f 63 6c 6f 73 65 28 26 7a 69 70 29 3b 0a 20  p_close(&zip);. 
1f90: 20 62 6c 6f 62 5f 77 72 69 74 65 5f 74 6f 5f 66   blob_write_to_f
1fa0: 69 6c 65 28 26 7a 69 70 2c 20 67 2e 61 72 67 76  ile(&zip, g.argv
1fb0: 5b 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47  [2]);.}../*.** G
1fc0: 69 76 65 6e 20 74 68 65 20 52 49 44 20 66 6f 72  iven the RID for
1fd0: 20 61 20 6d 61 6e 69 66 65 73 74 2c 20 63 6f 6e   a manifest, con
1fe0: 73 74 72 75 63 74 20 61 20 5a 49 50 20 61 72 63  struct a ZIP arc
1ff0: 68 69 76 65 20 63 6f 6e 74 61 69 6e 69 6e 67 0a  hive containing.
2000: 2a 2a 20 61 6c 6c 20 66 69 6c 65 73 20 69 6e 20  ** all files in 
2010: 74 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e  the correspondin
2020: 67 20 62 61 73 65 6c 69 6e 65 2e 0a 2a 2a 0a 2a  g baseline..**.*
2030: 2a 20 49 66 20 52 49 44 20 69 73 20 66 6f 72 20  * If RID is for 
2040: 61 6e 20 6f 62 6a 65 63 74 20 74 68 61 74 20 69  an object that i
2050: 73 20 6e 6f 74 20 61 20 72 65 61 6c 20 6d 61 6e  s not a real man
2060: 69 66 65 73 74 2c 20 74 68 65 6e 20 74 68 65 0a  ifest, then the.
2070: 2a 2a 20 72 65 73 75 6c 74 69 6e 67 20 5a 49 50  ** resulting ZIP
2080: 20 61 72 63 68 69 76 65 20 63 6f 6e 74 61 69 6e   archive contain
2090: 73 20 61 20 73 69 6e 67 6c 65 20 66 69 6c 65 20  s a single file 
20a0: 77 68 69 63 68 20 69 73 20 74 68 65 20 52 49 44  which is the RID
20b0: 0a 2a 2a 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a  .** object..**.*
20c0: 2a 20 49 66 20 74 68 65 20 52 49 44 20 6f 62 6a  * If the RID obj
20d0: 65 63 74 20 64 6f 65 73 20 6e 6f 74 20 65 78 69  ect does not exi
20e0: 73 74 20 69 6e 20 74 68 65 20 72 65 70 6f 73 69  st in the reposi
20f0: 74 6f 72 79 2c 20 74 68 65 6e 0a 2a 2a 20 70 5a  tory, then.** pZ
2100: 69 70 20 69 73 20 7a 65 72 6f 65 64 2e 0a 2a 2a  ip is zeroed..**
2110: 0a 2a 2a 20 7a 44 69 72 20 69 73 20 61 20 22 73  .** zDir is a "s
2120: 79 6e 74 68 65 74 69 63 22 20 73 75 62 64 69 72  ynthetic" subdir
2130: 65 63 74 6f 72 79 20 77 68 69 63 68 20 61 6c 6c  ectory which all
2140: 20 7a 69 70 70 65 64 20 66 69 6c 65 73 20 67 65   zipped files ge
2150: 74 0a 2a 2a 20 61 64 64 65 64 20 74 6f 20 61 73  t.** added to as
2160: 20 70 61 72 74 20 6f 66 20 74 68 65 20 7a 69 70   part of the zip
2170: 20 66 69 6c 65 2e 20 49 74 20 6d 61 79 20 62 65   file. It may be
2180: 20 30 20 6f 72 20 61 6e 20 65 6d 70 74 79 20 73   0 or an empty s
2190: 74 72 69 6e 67 2c 0a 2a 2a 20 69 6e 20 77 68 69  tring,.** in whi
21a0: 63 68 20 63 61 73 65 20 69 74 20 69 73 20 69 67  ch case it is ig
21b0: 6e 6f 72 65 64 2e 20 54 68 65 20 69 6e 74 65 6e  nored. The inten
21c0: 74 69 6f 6e 20 69 73 20 74 6f 20 63 72 65 61 74  tion is to creat
21d0: 65 20 61 20 7a 69 70 20 77 68 69 63 68 0a 2a 2a  e a zip which.**
21e0: 20 70 6f 6c 69 74 65 6c 79 20 65 78 70 61 6e 64   politely expand
21f0: 73 20 69 6e 74 6f 20 61 20 73 75 62 64 69 72 20  s into a subdir 
2200: 69 6e 73 74 65 61 64 20 6f 66 20 66 69 6c 6c 69  instead of filli
2210: 6e 67 20 79 6f 75 72 20 63 75 72 72 65 6e 74 20  ng your current 
2220: 64 69 72 0a 2a 2a 20 77 69 74 68 20 73 6f 75 72  dir.** with sour
2230: 63 65 20 66 69 6c 65 73 2e 20 46 6f 72 20 65 78  ce files. For ex
2240: 61 6d 70 6c 65 2c 20 70 61 73 73 20 61 20 55 55  ample, pass a UU
2250: 49 44 20 6f 72 20 22 50 72 6f 6a 65 63 74 4e 61  ID or "ProjectNa
2260: 6d 65 22 2e 0a 2a 2a 0a 2a 2f 0a 76 6f 69 64 20  me"..**.*/.void 
2270: 7a 69 70 5f 6f 66 5f 62 61 73 65 6c 69 6e 65 28  zip_of_baseline(
2280: 69 6e 74 20 72 69 64 2c 20 42 6c 6f 62 20 2a 70  int rid, Blob *p
2290: 5a 69 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  Zip, const char 
22a0: 2a 7a 44 69 72 29 7b 0a 20 20 69 6e 74 20 69 3b  *zDir){.  int i;
22b0: 0a 20 20 42 6c 6f 62 20 6d 66 69 6c 65 2c 20 66  .  Blob mfile, f
22c0: 69 6c 65 2c 20 68 61 73 68 3b 0a 20 20 4d 61 6e  ile, hash;.  Man
22d0: 69 66 65 73 74 20 6d 3b 0a 20 20 42 6c 6f 62 20  ifest m;.  Blob 
22e0: 66 69 6c 65 6e 61 6d 65 3b 0a 20 20 69 6e 74 20  filename;.  int 
22f0: 6e 50 72 65 66 69 78 3b 0a 20 20 0a 20 20 63 6f  nPrefix;.  .  co
2300: 6e 74 65 6e 74 5f 67 65 74 28 72 69 64 2c 20 26  ntent_get(rid, &
2310: 6d 66 69 6c 65 29 3b 0a 20 20 69 66 28 20 62 6c  mfile);.  if( bl
2320: 6f 62 5f 73 69 7a 65 28 26 6d 66 69 6c 65 29 3d  ob_size(&mfile)=
2330: 3d 30 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 7a  =0 ){.    blob_z
2340: 65 72 6f 28 70 5a 69 70 29 3b 0a 20 20 20 20 72  ero(pZip);.    r
2350: 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 62 6c 6f  eturn;.  }.  blo
2360: 62 5f 7a 65 72 6f 28 26 66 69 6c 65 29 3b 0a 20  b_zero(&file);. 
2370: 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 68 61 73 68   blob_zero(&hash
2380: 29 3b 0a 20 20 62 6c 6f 62 5f 63 6f 70 79 28 26  );.  blob_copy(&
2390: 66 69 6c 65 2c 20 26 6d 66 69 6c 65 29 3b 0a 20  file, &mfile);. 
23a0: 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 66 69 6c 65   blob_zero(&file
23b0: 6e 61 6d 65 29 3b 0a 20 20 7a 69 70 5f 6f 70 65  name);.  zip_ope
23c0: 6e 28 29 3b 0a 0a 20 20 69 66 28 20 7a 44 69 72  n();..  if( zDir
23d0: 20 26 26 20 7a 44 69 72 5b 30 5d 20 29 7b 0a 20   && zDir[0] ){. 
23e0: 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28     blob_appendf(
23f0: 26 66 69 6c 65 6e 61 6d 65 2c 20 22 25 73 2f 22  &filename, "%s/"
2400: 2c 20 7a 44 69 72 29 3b 0a 20 20 7d 0a 20 20 6e  , zDir);.  }.  n
2410: 50 72 65 66 69 78 20 3d 20 62 6c 6f 62 5f 73 69  Prefix = blob_si
2420: 7a 65 28 26 66 69 6c 65 6e 61 6d 65 29 3b 0a 0a  ze(&filename);..
2430: 20 20 69 66 28 20 6d 61 6e 69 66 65 73 74 5f 70    if( manifest_p
2440: 61 72 73 65 28 26 6d 2c 20 26 6d 66 69 6c 65 29  arse(&m, &mfile)
2450: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e   ){.    char *zN
2460: 61 6d 65 3b 0a 20 20 20 20 7a 69 70 5f 73 65 74  ame;.    zip_set
2470: 5f 74 69 6d 65 64 61 74 65 28 6d 2e 72 44 61 74  _timedate(m.rDat
2480: 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70  e);.    blob_app
2490: 65 6e 64 28 26 66 69 6c 65 6e 61 6d 65 2c 20 22  end(&filename, "
24a0: 6d 61 6e 69 66 65 73 74 22 2c 20 2d 31 29 3b 0a  manifest", -1);.
24b0: 20 20 20 20 7a 4e 61 6d 65 20 3d 20 62 6c 6f 62      zName = blob
24c0: 5f 73 74 72 28 26 66 69 6c 65 6e 61 6d 65 29 3b  _str(&filename);
24d0: 0a 20 20 20 20 7a 69 70 5f 61 64 64 5f 66 6f 6c  .    zip_add_fol
24e0: 64 65 72 73 28 7a 4e 61 6d 65 29 3b 0a 20 20 20  ders(zName);.   
24f0: 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65 28 7a 4e   zip_add_file(zN
2500: 61 6d 65 2c 20 26 66 69 6c 65 29 3b 0a 20 20 20  ame, &file);.   
2510: 20 73 68 61 31 73 75 6d 5f 62 6c 6f 62 28 26 66   sha1sum_blob(&f
2520: 69 6c 65 2c 20 26 68 61 73 68 29 3b 0a 20 20 20  ile, &hash);.   
2530: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 66 69 6c   blob_reset(&fil
2540: 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70  e);.    blob_app
2550: 65 6e 64 28 26 68 61 73 68 2c 20 22 5c 6e 22 2c  end(&hash, "\n",
2560: 20 31 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65   1);.    blob_re
2570: 73 69 7a 65 28 26 66 69 6c 65 6e 61 6d 65 2c 20  size(&filename, 
2580: 6e 50 72 65 66 69 78 29 3b 0a 20 20 20 20 62 6c  nPrefix);.    bl
2590: 6f 62 5f 61 70 70 65 6e 64 28 26 66 69 6c 65 6e  ob_append(&filen
25a0: 61 6d 65 2c 20 22 6d 61 6e 69 66 65 73 74 2e 75  ame, "manifest.u
25b0: 75 69 64 22 2c 20 2d 31 29 3b 0a 20 20 20 20 7a  uid", -1);.    z
25c0: 4e 61 6d 65 20 3d 20 62 6c 6f 62 5f 73 74 72 28  Name = blob_str(
25d0: 26 66 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 20 20  &filename);.    
25e0: 7a 69 70 5f 61 64 64 5f 66 69 6c 65 28 7a 4e 61  zip_add_file(zNa
25f0: 6d 65 2c 20 26 68 61 73 68 29 3b 0a 20 20 20 20  me, &hash);.    
2600: 62 6c 6f 62 5f 72 65 73 65 74 28 26 68 61 73 68  blob_reset(&hash
2610: 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  );.    for(i=0; 
2620: 69 3c 6d 2e 6e 46 69 6c 65 3b 20 69 2b 2b 29 7b  i<m.nFile; i++){
2630: 0a 20 20 20 20 20 20 69 6e 74 20 66 69 64 20 3d  .      int fid =
2640: 20 75 75 69 64 5f 74 6f 5f 72 69 64 28 6d 2e 61   uuid_to_rid(m.a
2650: 46 69 6c 65 5b 69 5d 2e 7a 55 75 69 64 2c 20 30  File[i].zUuid, 0
2660: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 66 69 64  );.      if( fid
2670: 20 29 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e 74   ){.        cont
2680: 65 6e 74 5f 67 65 74 28 66 69 64 2c 20 26 66 69  ent_get(fid, &fi
2690: 6c 65 29 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f  le);.        blo
26a0: 62 5f 72 65 73 69 7a 65 28 26 66 69 6c 65 6e 61  b_resize(&filena
26b0: 6d 65 2c 20 6e 50 72 65 66 69 78 29 3b 0a 20 20  me, nPrefix);.  
26c0: 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e        blob_appen
26d0: 64 28 26 66 69 6c 65 6e 61 6d 65 2c 20 6d 2e 61  d(&filename, m.a
26e0: 46 69 6c 65 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 2d  File[i].zName, -
26f0: 31 29 3b 0a 20 20 20 20 20 20 20 20 7a 4e 61 6d  1);.        zNam
2700: 65 20 3d 20 62 6c 6f 62 5f 73 74 72 28 26 66 69  e = blob_str(&fi
2710: 6c 65 6e 61 6d 65 29 3b 0a 20 20 20 20 20 20 20  lename);.       
2720: 20 7a 69 70 5f 61 64 64 5f 66 6f 6c 64 65 72 73   zip_add_folders
2730: 28 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 20  (zName);.       
2740: 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65 28 7a 4e   zip_add_file(zN
2750: 61 6d 65 2c 20 26 66 69 6c 65 29 3b 0a 20 20 20  ame, &file);.   
2760: 20 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28       blob_reset(
2770: 26 66 69 6c 65 29 3b 0a 20 20 20 20 20 20 7d 0a  &file);.      }.
2780: 20 20 20 20 7d 0a 20 20 20 20 6d 61 6e 69 66 65      }.    manife
2790: 73 74 5f 63 6c 65 61 72 28 26 6d 29 3b 0a 20 20  st_clear(&m);.  
27a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 62 6c 6f 62 5f  }else{.    blob_
27b0: 72 65 73 65 74 28 26 6d 66 69 6c 65 29 3b 0a 20  reset(&mfile);. 
27c0: 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 66     blob_reset(&f
27d0: 69 6c 65 29 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62  ile);.  }.  blob
27e0: 5f 72 65 73 65 74 28 26 66 69 6c 65 6e 61 6d 65  _reset(&filename
27f0: 29 3b 0a 20 20 7a 69 70 5f 63 6c 6f 73 65 28 70  );.  zip_close(p
2800: 5a 69 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  Zip);.}../*.** C
2810: 4f 4d 4d 41 4e 44 3a 20 74 65 73 74 2d 62 61 73  OMMAND: test-bas
2820: 65 6c 69 6e 65 2d 7a 69 70 0a 2a 2a 0a 2a 2a 20  eline-zip.**.** 
2830: 47 65 6e 65 72 61 74 65 20 61 20 5a 49 50 20 61  Generate a ZIP a
2840: 72 63 68 69 76 65 20 66 6f 72 20 61 20 73 70 65  rchive for a spe
2850: 63 69 66 69 65 64 20 62 61 73 65 6c 69 6e 65 2e  cified baseline.
2860: 0a 2a 2f 0a 76 6f 69 64 20 62 61 73 65 6c 69 6e  .*/.void baselin
2870: 65 5f 7a 69 70 5f 63 6d 64 28 76 6f 69 64 29 7b  e_zip_cmd(void){
2880: 0a 20 20 69 6e 74 20 72 69 64 3b 0a 20 20 42 6c  .  int rid;.  Bl
2890: 6f 62 20 7a 69 70 3b 0a 20 20 69 66 28 20 67 2e  ob zip;.  if( g.
28a0: 61 72 67 63 21 3d 34 20 29 7b 0a 20 20 20 20 75  argc!=4 ){.    u
28b0: 73 61 67 65 28 22 55 55 49 44 20 5a 49 50 46 49  sage("UUID ZIPFI
28c0: 4c 45 22 29 3b 0a 20 20 7d 0a 20 20 64 62 5f 6d  LE");.  }.  db_m
28d0: 75 73 74 5f 62 65 5f 77 69 74 68 69 6e 5f 74 72  ust_be_within_tr
28e0: 65 65 28 29 3b 0a 20 20 72 69 64 20 3d 20 6e 61  ee();.  rid = na
28f0: 6d 65 5f 74 6f 5f 72 69 64 28 67 2e 61 72 67 76  me_to_rid(g.argv
2900: 5b 32 5d 29 3b 0a 20 20 7a 69 70 5f 6f 66 5f 62  [2]);.  zip_of_b
2910: 61 73 65 6c 69 6e 65 28 72 69 64 2c 20 26 7a 69  aseline(rid, &zi
2920: 70 2c 20 67 2e 61 72 67 76 5b 32 5d 29 3b 0a 20  p, g.argv[2]);. 
2930: 20 62 6c 6f 62 5f 77 72 69 74 65 5f 74 6f 5f 66   blob_write_to_f
2940: 69 6c 65 28 26 7a 69 70 2c 20 67 2e 61 72 67 76  ile(&zip, g.argv
2950: 5b 33 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  [3]);.}../*.** W
2960: 45 42 50 41 47 45 3a 20 7a 69 70 0a 2a 2a 20 55  EBPAGE: zip.** U
2970: 52 4c 3a 20 2f 7a 69 70 2f 52 49 44 2e 7a 69 70  RL: /zip/RID.zip
2980: 0a 2a 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20  .**.** Generate 
2990: 61 20 5a 49 50 20 61 72 63 68 69 76 65 20 66 6f  a ZIP archive fo
29a0: 72 20 74 68 65 20 62 61 73 65 6c 69 6e 65 2e 0a  r the baseline..
29b0: 2a 2a 20 52 65 74 75 72 6e 20 74 68 61 74 20 5a  ** Return that Z
29c0: 49 50 20 61 72 63 68 69 76 65 20 61 73 20 74 68  IP archive as th
29d0: 65 20 48 54 54 50 20 72 65 70 6c 79 20 63 6f 6e  e HTTP reply con
29e0: 74 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 64 20 62 61  tent..*/.void ba
29f0: 73 65 6c 69 6e 65 5f 7a 69 70 5f 70 61 67 65 28  seline_zip_page(
2a00: 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 72 69 64  void){.  int rid
2a10: 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c  ;.  char *zName,
2a20: 20 2a 7a 52 69 64 3b 0a 20 20 69 6e 74 20 6e 4e   *zRid;.  int nN
2a30: 61 6d 65 2c 20 6e 52 69 64 3b 0a 20 20 42 6c 6f  ame, nRid;.  Blo
2a40: 62 20 7a 69 70 3b 0a 0a 20 20 6c 6f 67 69 6e 5f  b zip;..  login_
2a50: 63 68 65 63 6b 5f 63 72 65 64 65 6e 74 69 61 6c  check_credential
2a60: 73 28 29 3b 0a 20 20 69 66 28 20 21 67 2e 6f 6b  s();.  if( !g.ok
2a70: 5a 69 70 20 26 26 20 28 21 67 2e 6f 6b 52 65 61  Zip && (!g.okRea
2a80: 64 20 7c 7c 20 21 67 2e 6f 6b 48 69 73 74 6f 72  d || !g.okHistor
2a90: 79 29 20 29 7b 20 6c 6f 67 69 6e 5f 6e 65 65 64  y) ){ login_need
2aa0: 65 64 28 29 3b 20 72 65 74 75 72 6e 3b 20 7d 0a  ed(); return; }.
2ab0: 20 20 7a 4e 61 6d 65 20 3d 20 6d 70 72 69 6e 74    zName = mprint
2ac0: 66 28 22 25 73 22 2c 20 50 44 28 22 6e 61 6d 65  f("%s", PD("name
2ad0: 22 2c 22 22 29 29 3b 0a 20 20 6e 4e 61 6d 65 20  ",""));.  nName 
2ae0: 3d 20 73 74 72 6c 65 6e 28 7a 4e 61 6d 65 29 3b  = strlen(zName);
2af0: 0a 20 20 7a 52 69 64 20 3d 20 6d 70 72 69 6e 74  .  zRid = mprint
2b00: 66 28 22 25 73 22 2c 20 50 44 28 22 75 75 69 64  f("%s", PD("uuid
2b10: 22 2c 22 22 29 29 3b 0a 20 20 6e 52 69 64 20 3d  ",""));.  nRid =
2b20: 20 73 74 72 6c 65 6e 28 7a 52 69 64 29 3b 0a 20   strlen(zRid);. 
2b30: 20 66 6f 72 28 6e 4e 61 6d 65 3d 73 74 72 6c 65   for(nName=strle
2b40: 6e 28 7a 4e 61 6d 65 29 2d 31 3b 20 6e 4e 61 6d  n(zName)-1; nNam
2b50: 65 3e 35 3b 20 6e 4e 61 6d 65 2d 2d 29 7b 0a 20  e>5; nName--){. 
2b60: 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b 6e 4e 61     if( zName[nNa
2b70: 6d 65 5d 3d 3d 27 2e 27 20 29 7b 0a 20 20 20 20  me]=='.' ){.    
2b80: 20 20 7a 4e 61 6d 65 5b 6e 4e 61 6d 65 5d 20 3d    zName[nName] =
2b90: 20 30 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b   0;.      break;
2ba0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 69 64  .    }.  }.  rid
2bb0: 20 3d 20 6e 61 6d 65 5f 74 6f 5f 72 69 64 28 6e   = name_to_rid(n
2bc0: 52 69 64 3f 7a 52 69 64 3a 7a 4e 61 6d 65 29 3b  Rid?zRid:zName);
2bd0: 0a 20 20 69 66 28 20 72 69 64 3d 3d 30 20 29 7b  .  if( rid==0 ){
2be0: 0a 20 20 20 20 40 20 4e 6f 74 20 66 6f 75 6e 64  .    @ Not found
2bf0: 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d  .    return;.  }
2c00: 0a 20 20 69 66 28 20 6e 52 69 64 3d 3d 30 20 26  .  if( nRid==0 &
2c10: 26 20 6e 4e 61 6d 65 3e 31 30 20 29 20 7a 4e 61  & nName>10 ) zNa
2c20: 6d 65 5b 31 30 5d 20 3d 20 30 3b 0a 20 20 7a 69  me[10] = 0;.  zi
2c30: 70 5f 6f 66 5f 62 61 73 65 6c 69 6e 65 28 72 69  p_of_baseline(ri
2c40: 64 2c 20 26 7a 69 70 2c 20 7a 4e 61 6d 65 29 3b  d, &zip, zName);
2c50: 0a 20 20 66 72 65 65 28 20 7a 4e 61 6d 65 20 29  .  free( zName )
2c60: 3b 0a 20 20 66 72 65 65 28 20 7a 52 69 64 20 29  ;.  free( zRid )
2c70: 3b 0a 20 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74  ;.  cgi_set_cont
2c80: 65 6e 74 28 26 7a 69 70 29 3b 0a 20 20 63 67 69  ent(&zip);.  cgi
2c90: 5f 73 65 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70  _set_content_typ
2ca0: 65 28 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 7a  e("application/z
2cb0: 69 70 22 29 3b 0a 7d 0a                          ip");.}.