Hex Artifact Content
Not logged in

Artifact 8c1776ca5d0addc13d2f9a926d55310bed59cafb:

File src/zip.c part of check-in [7a2c37063a] - merge trunk into creole branch by bob on 2009-09-22 07:49:39. Also file src/zip.c part of check-in [5b91887495] - Fix a memory allocation bug in the ZIP archive generator. Ticket 8d6efe4f927 by drh on 2009-08-15 13:21:45.

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 73 69 7a 65 6f 66 28 61 7a 44 69 72  ir, sizeof(azDir
0be0: 5b 30 5d 29 2a 6e 44 69 72 29 3b 0a 20 20 20 20  [0])*nDir);.    
0bf0: 20 20 20 20 61 7a 44 69 72 5b 6a 5d 20 3d 20 6d      azDir[j] = m
0c00: 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 4e 61  printf("%s", zNa
0c10: 6d 65 29 3b 0a 20 20 20 20 20 20 20 20 7a 69 70  me);.        zip
0c20: 5f 61 64 64 5f 66 69 6c 65 28 7a 4e 61 6d 65 2c  _add_file(zName,
0c30: 20 30 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20   0);.      }.   
0c40: 20 20 20 7a 4e 61 6d 65 5b 69 2b 31 5d 20 3d 20     zName[i+1] = 
0c50: 63 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a  c;.    }.  }.}..
0c60: 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 61 20 73  /*.** Append a s
0c70: 69 6e 67 6c 65 20 66 69 6c 65 20 74 6f 20 61 20  ingle file to a 
0c80: 67 72 6f 77 69 6e 67 20 5a 49 50 20 61 72 63 68  growing ZIP arch
0c90: 69 76 65 2e 0a 2a 2a 0a 2a 2a 20 70 46 69 6c 65  ive..**.** pFile
0ca0: 20 69 73 20 74 68 65 20 66 69 6c 65 20 74 6f 20   is the file to 
0cb0: 62 65 20 61 70 70 65 6e 64 65 64 2e 20 20 7a 4e  be appended.  zN
0cc0: 61 6d 65 20 69 73 20 74 68 65 20 6e 61 6d 65 0a  ame is the name.
0cd0: 2a 2a 20 74 68 61 74 20 74 68 65 20 66 69 6c 65  ** that the file
0ce0: 20 73 68 6f 75 6c 64 20 62 65 20 73 61 76 65 64   should be saved
0cf0: 20 61 73 2e 0a 2a 2f 0a 76 6f 69 64 20 7a 69 70   as..*/.void zip
0d00: 5f 61 64 64 5f 66 69 6c 65 28 63 6f 6e 73 74 20  _add_file(const 
0d10: 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e  char *zName, con
0d20: 73 74 20 42 6c 6f 62 20 2a 70 46 69 6c 65 29 7b  st Blob *pFile){
0d30: 0a 20 20 7a 5f 73 74 72 65 61 6d 20 73 74 72 65  .  z_stream stre
0d40: 61 6d 3b 0a 20 20 69 6e 74 20 6e 61 6d 65 4c 65  am;.  int nameLe
0d50: 6e 3b 0a 20 20 69 6e 74 20 73 6b 69 70 3b 0a 20  n;.  int skip;. 
0d60: 20 69 6e 74 20 74 6f 4f 75 74 3b 0a 20 20 69 6e   int toOut;.  in
0d70: 74 20 69 53 74 61 72 74 3b 0a 20 20 69 6e 74 20  t iStart;.  int 
0d80: 69 43 52 43 20 3d 20 30 3b 0a 20 20 69 6e 74 20  iCRC = 0;.  int 
0d90: 6e 42 79 74 65 20 3d 20 30 3b 0a 20 20 69 6e 74  nByte = 0;.  int
0da0: 20 6e 42 79 74 65 43 6f 6d 70 72 20 3d 20 30 3b   nByteCompr = 0;
0db0: 0a 20 20 69 6e 74 20 6e 42 6c 6f 62 3b 20 20 20  .  int nBlob;   
0dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0dd0: 20 53 69 7a 65 20 6f 66 20 74 68 65 20 62 6c 6f   Size of the blo
0de0: 62 20 2a 2f 0a 20 20 69 6e 74 20 69 4d 65 74 68  b */.  int iMeth
0df0: 6f 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  od;             
0e00: 20 20 2f 2a 20 43 6f 6d 70 72 65 73 73 69 6f 6e    /* Compression
0e10: 20 6d 65 74 68 6f 64 2e 20 2a 2f 0a 20 20 69 6e   method. */.  in
0e20: 74 20 69 4d 6f 64 65 20 3d 20 30 36 34 34 3b 20  t iMode = 0644; 
0e30: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 63 63 65           /* Acce
0e40: 73 73 20 70 65 72 6d 69 73 73 69 6f 6e 73 20 2a  ss permissions *
0e50: 2f 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 20 20 63  /.  char *z;.  c
0e60: 68 61 72 20 7a 48 64 72 5b 33 30 5d 3b 0a 20 20  har zHdr[30];.  
0e70: 63 68 61 72 20 7a 45 78 54 69 6d 65 5b 31 33 5d  char zExTime[13]
0e80: 3b 0a 20 20 63 68 61 72 20 7a 42 75 66 5b 31 30  ;.  char zBuf[10
0e90: 30 5d 3b 0a 20 20 63 68 61 72 20 7a 4f 75 74 42  0];.  char zOutB
0ea0: 75 66 5b 31 30 30 30 30 30 5d 3b 0a 0a 20 20 2f  uf[100000];..  /
0eb0: 2a 20 46 69 6c 6c 20 69 6e 20 61 73 20 6d 75 63  * Fill in as muc
0ec0: 68 20 6f 66 20 74 68 65 20 68 65 61 64 65 72 20  h of the header 
0ed0: 61 73 20 77 65 20 6b 6e 6f 77 2e 0a 20 20 2a 2f  as we know..  */
0ee0: 0a 20 20 6e 42 6c 6f 62 20 3d 20 70 46 69 6c 65  .  nBlob = pFile
0ef0: 20 3f 20 62 6c 6f 62 5f 73 69 7a 65 28 70 46 69   ? blob_size(pFi
0f00: 6c 65 29 20 3a 20 30 3b 0a 20 20 69 66 28 20 6e  le) : 0;.  if( n
0f10: 42 6c 6f 62 3e 30 20 29 7b 0a 20 20 20 20 69 4d  Blob>0 ){.    iM
0f20: 65 74 68 6f 64 20 3d 20 38 3b 0a 20 20 20 20 69  ethod = 8;.    i
0f30: 4d 6f 64 65 20 3d 20 30 31 30 30 36 34 34 3b 0a  Mode = 0100644;.
0f40: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 4d 65    }else{.    iMe
0f50: 74 68 6f 64 20 3d 20 30 3b 0a 20 20 20 20 69 4d  thod = 0;.    iM
0f60: 6f 64 65 20 3d 20 30 34 30 37 35 35 3b 0a 20 20  ode = 040755;.  
0f70: 7d 0a 20 20 6e 61 6d 65 4c 65 6e 20 3d 20 73 74  }.  nameLen = st
0f80: 72 6c 65 6e 28 7a 4e 61 6d 65 29 3b 0a 20 20 6d  rlen(zName);.  m
0f90: 65 6d 73 65 74 28 7a 48 64 72 2c 20 30 2c 20 73  emset(zHdr, 0, s
0fa0: 69 7a 65 6f 66 28 7a 48 64 72 29 29 3b 0a 20 20  izeof(zHdr));.  
0fb0: 70 75 74 33 32 28 26 7a 48 64 72 5b 30 5d 2c 20  put32(&zHdr[0], 
0fc0: 30 78 30 34 30 33 34 62 35 30 29 3b 0a 20 20 70  0x04034b50);.  p
0fd0: 75 74 31 36 28 26 7a 48 64 72 5b 34 5d 2c 20 30  ut16(&zHdr[4], 0
0fe0: 78 30 30 30 61 29 3b 0a 20 20 70 75 74 31 36 28  x000a);.  put16(
0ff0: 26 7a 48 64 72 5b 36 5d 2c 20 30 29 3b 0a 20 20  &zHdr[6], 0);.  
1000: 70 75 74 31 36 28 26 7a 48 64 72 5b 38 5d 2c 20  put16(&zHdr[8], 
1010: 69 4d 65 74 68 6f 64 29 3b 0a 20 20 70 75 74 31  iMethod);.  put1
1020: 36 28 26 7a 48 64 72 5b 31 30 5d 2c 20 64 6f 73  6(&zHdr[10], dos
1030: 54 69 6d 65 29 3b 0a 20 20 70 75 74 31 36 28 26  Time);.  put16(&
1040: 7a 48 64 72 5b 31 32 5d 2c 20 64 6f 73 44 61 74  zHdr[12], dosDat
1050: 65 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 48 64  e);.  put16(&zHd
1060: 72 5b 32 36 5d 2c 20 6e 61 6d 65 4c 65 6e 29 3b  r[26], nameLen);
1070: 0a 20 20 70 75 74 31 36 28 26 7a 48 64 72 5b 32  .  put16(&zHdr[2
1080: 38 5d 2c 20 31 33 29 3b 0a 20 20 0a 20 20 70 75  8], 13);.  .  pu
1090: 74 31 36 28 26 7a 45 78 54 69 6d 65 5b 30 5d 2c  t16(&zExTime[0],
10a0: 20 30 78 35 34 35 35 29 3b 0a 20 20 70 75 74 31   0x5455);.  put1
10b0: 36 28 26 7a 45 78 54 69 6d 65 5b 32 5d 2c 20 39  6(&zExTime[2], 9
10c0: 29 3b 0a 20 20 7a 45 78 54 69 6d 65 5b 34 5d 20  );.  zExTime[4] 
10d0: 3d 20 33 3b 0a 20 20 70 75 74 33 32 28 26 7a 45  = 3;.  put32(&zE
10e0: 78 54 69 6d 65 5b 35 5d 2c 20 75 6e 69 78 54 69  xTime[5], unixTi
10f0: 6d 65 29 3b 0a 20 20 70 75 74 33 32 28 26 7a 45  me);.  put32(&zE
1100: 78 54 69 6d 65 5b 39 5d 2c 20 75 6e 69 78 54 69  xTime[9], unixTi
1110: 6d 65 29 3b 0a 20 20 0a 0a 20 20 2f 2a 20 57 72  me);.  ..  /* Wr
1120: 69 74 65 20 74 68 65 20 68 65 61 64 65 72 20 61  ite the header a
1130: 6e 64 20 66 69 6c 65 6e 61 6d 65 2e 0a 20 20 2a  nd filename..  *
1140: 2f 0a 20 20 69 53 74 61 72 74 20 3d 20 62 6c 6f  /.  iStart = blo
1150: 62 5f 73 69 7a 65 28 26 62 6f 64 79 29 3b 0a 20  b_size(&body);. 
1160: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 62 6f   blob_append(&bo
1170: 64 79 2c 20 7a 48 64 72 2c 20 33 30 29 3b 0a 20  dy, zHdr, 30);. 
1180: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 62 6f   blob_append(&bo
1190: 64 79 2c 20 7a 4e 61 6d 65 2c 20 6e 61 6d 65 4c  dy, zName, nameL
11a0: 65 6e 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70 65  en);.  blob_appe
11b0: 6e 64 28 26 62 6f 64 79 2c 20 7a 45 78 54 69 6d  nd(&body, zExTim
11c0: 65 2c 20 31 33 29 3b 0a 0a 20 20 69 66 28 20 6e  e, 13);..  if( n
11d0: 42 6c 6f 62 3e 30 20 29 7b 0a 20 20 20 20 2f 2a  Blob>0 ){.    /*
11e0: 20 54 68 65 20 66 69 72 73 74 20 74 77 6f 20 62   The first two b
11f0: 79 74 65 73 20 74 68 61 74 20 63 6f 6d 65 20 6f  ytes that come o
1200: 75 74 20 6f 66 20 74 68 65 20 64 65 66 6c 61 74  ut of the deflat
1210: 65 20 63 6f 6d 70 72 65 73 73 6f 72 20 61 72 65  e compressor are
1220: 0a 20 20 20 20 2a 2a 20 73 6f 6d 65 20 6b 69 6e  .    ** some kin
1230: 64 20 6f 66 20 68 65 61 64 65 72 20 74 68 61 74  d of header that
1240: 20 5a 49 50 20 64 6f 65 73 20 6e 6f 74 20 75 73   ZIP does not us
1250: 65 2e 20 20 53 6f 20 73 6b 69 70 20 74 68 65 20  e.  So skip the 
1260: 66 69 72 73 74 20 74 77 6f 0a 20 20 20 20 2a 2a  first two.    **
1270: 20 6f 75 74 70 75 74 20 62 79 74 65 73 2e 0a 20   output bytes.. 
1280: 20 20 20 2a 2f 0a 20 20 20 20 73 6b 69 70 20 3d     */.    skip =
1290: 20 32 3b 0a 20 20 0a 20 20 20 20 2f 2a 20 57 72   2;.  .    /* Wr
12a0: 69 74 65 20 74 68 65 20 63 6f 6d 70 72 65 73 73  ite the compress
12b0: 65 64 20 66 69 6c 65 2e 20 20 43 6f 6d 70 75 74  ed file.  Comput
12c0: 65 20 74 68 65 20 43 52 43 20 61 73 20 77 65 20  e the CRC as we 
12d0: 70 72 6f 67 72 65 73 73 2e 0a 20 20 20 20 2a 2f  progress..    */
12e0: 0a 20 20 20 20 73 74 72 65 61 6d 2e 7a 61 6c 6c  .    stream.zall
12f0: 6f 63 20 3d 20 28 61 6c 6c 6f 63 5f 66 75 6e 63  oc = (alloc_func
1300: 29 30 3b 0a 20 20 20 20 73 74 72 65 61 6d 2e 7a  )0;.    stream.z
1310: 66 72 65 65 20 3d 20 28 66 72 65 65 5f 66 75 6e  free = (free_fun
1320: 63 29 30 3b 0a 20 20 20 20 73 74 72 65 61 6d 2e  c)0;.    stream.
1330: 6f 70 61 71 75 65 20 3d 20 30 3b 0a 20 20 20 20  opaque = 0;.    
1340: 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 69 6e 20  stream.avail_in 
1350: 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 70 46 69 6c  = blob_size(pFil
1360: 65 29 3b 0a 20 20 20 20 73 74 72 65 61 6d 2e 6e  e);.    stream.n
1370: 65 78 74 5f 69 6e 20 3d 20 28 75 6e 73 69 67 6e  ext_in = (unsign
1380: 65 64 20 63 68 61 72 2a 29 62 6c 6f 62 5f 62 75  ed char*)blob_bu
1390: 66 66 65 72 28 70 46 69 6c 65 29 3b 0a 20 20 20  ffer(pFile);.   
13a0: 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f 75   stream.avail_ou
13b0: 74 20 3d 20 73 69 7a 65 6f 66 28 7a 4f 75 74 42  t = sizeof(zOutB
13c0: 75 66 29 3b 0a 20 20 20 20 73 74 72 65 61 6d 2e  uf);.    stream.
13d0: 6e 65 78 74 5f 6f 75 74 20 3d 20 28 75 6e 73 69  next_out = (unsi
13e0: 67 6e 65 64 20 63 68 61 72 2a 29 7a 4f 75 74 42  gned char*)zOutB
13f0: 75 66 3b 0a 20 20 20 20 64 65 66 6c 61 74 65 49  uf;.    deflateI
1400: 6e 69 74 28 26 73 74 72 65 61 6d 2c 20 39 29 3b  nit(&stream, 9);
1410: 0a 20 20 20 20 69 43 52 43 20 3d 20 63 72 63 33  .    iCRC = crc3
1420: 32 28 30 2c 20 73 74 72 65 61 6d 2e 6e 65 78 74  2(0, stream.next
1430: 5f 69 6e 2c 20 73 74 72 65 61 6d 2e 61 76 61 69  _in, stream.avai
1440: 6c 5f 69 6e 29 3b 0a 20 20 20 20 77 68 69 6c 65  l_in);.    while
1450: 28 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 69  ( stream.avail_i
1460: 6e 3e 30 20 29 7b 0a 20 20 20 20 20 20 64 65 66  n>0 ){.      def
1470: 6c 61 74 65 28 26 73 74 72 65 61 6d 2c 20 30 29  late(&stream, 0)
1480: 3b 0a 20 20 20 20 20 20 74 6f 4f 75 74 20 3d 20  ;.      toOut = 
1490: 73 69 7a 65 6f 66 28 7a 4f 75 74 42 75 66 29 20  sizeof(zOutBuf) 
14a0: 2d 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f  - stream.avail_o
14b0: 75 74 3b 0a 20 20 20 20 20 20 69 66 28 20 74 6f  ut;.      if( to
14c0: 4f 75 74 3e 73 6b 69 70 20 29 7b 0a 20 20 20 20  Out>skip ){.    
14d0: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28      blob_append(
14e0: 26 62 6f 64 79 2c 20 26 7a 4f 75 74 42 75 66 5b  &body, &zOutBuf[
14f0: 73 6b 69 70 5d 2c 20 74 6f 4f 75 74 20 2d 20 73  skip], toOut - s
1500: 6b 69 70 29 3b 0a 20 20 20 20 20 20 20 20 73 6b  kip);.        sk
1510: 69 70 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 65  ip = 0;.      }e
1520: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 73 6b 69  lse{.        ski
1530: 70 20 2d 3d 20 74 6f 4f 75 74 3b 0a 20 20 20 20  p -= toOut;.    
1540: 20 20 7d 0a 20 20 20 20 20 20 73 74 72 65 61 6d    }.      stream
1550: 2e 61 76 61 69 6c 5f 6f 75 74 20 3d 20 73 69 7a  .avail_out = siz
1560: 65 6f 66 28 7a 4f 75 74 42 75 66 29 3b 0a 20 20  eof(zOutBuf);.  
1570: 20 20 20 20 73 74 72 65 61 6d 2e 6e 65 78 74 5f      stream.next_
1580: 6f 75 74 20 3d 20 28 75 6e 73 69 67 6e 65 64 20  out = (unsigned 
1590: 63 68 61 72 2a 29 7a 4f 75 74 42 75 66 3b 0a 20  char*)zOutBuf;. 
15a0: 20 20 20 7d 0a 20 20 20 20 64 6f 7b 0a 20 20 20     }.    do{.   
15b0: 20 20 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f     stream.avail_
15c0: 6f 75 74 20 3d 20 73 69 7a 65 6f 66 28 7a 4f 75  out = sizeof(zOu
15d0: 74 42 75 66 29 3b 0a 20 20 20 20 20 20 73 74 72  tBuf);.      str
15e0: 65 61 6d 2e 6e 65 78 74 5f 6f 75 74 20 3d 20 28  eam.next_out = (
15f0: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 2a 29 7a  unsigned char*)z
1600: 4f 75 74 42 75 66 3b 0a 20 20 20 20 20 20 64 65  OutBuf;.      de
1610: 66 6c 61 74 65 28 26 73 74 72 65 61 6d 2c 20 5a  flate(&stream, Z
1620: 5f 46 49 4e 49 53 48 29 3b 0a 20 20 20 20 20 20  _FINISH);.      
1630: 74 6f 4f 75 74 20 3d 20 73 69 7a 65 6f 66 28 7a  toOut = sizeof(z
1640: 4f 75 74 42 75 66 29 20 2d 20 73 74 72 65 61 6d  OutBuf) - stream
1650: 2e 61 76 61 69 6c 5f 6f 75 74 3b 0a 20 20 20 20  .avail_out;.    
1660: 20 20 69 66 28 20 74 6f 4f 75 74 3e 73 6b 69 70    if( toOut>skip
1670: 20 29 7b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62   ){.        blob
1680: 5f 61 70 70 65 6e 64 28 26 62 6f 64 79 2c 20 26  _append(&body, &
1690: 7a 4f 75 74 42 75 66 5b 73 6b 69 70 5d 2c 20 74  zOutBuf[skip], t
16a0: 6f 4f 75 74 20 2d 20 73 6b 69 70 29 3b 0a 20 20  oOut - skip);.  
16b0: 20 20 20 20 20 20 73 6b 69 70 20 3d 20 30 3b 0a        skip = 0;.
16c0: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
16d0: 20 20 20 20 20 73 6b 69 70 20 2d 3d 20 74 6f 4f       skip -= toO
16e0: 75 74 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  ut;.      }.    
16f0: 7d 77 68 69 6c 65 28 20 73 74 72 65 61 6d 2e 61  }while( stream.a
1700: 76 61 69 6c 5f 6f 75 74 3d 3d 30 20 29 3b 0a 20  vail_out==0 );. 
1710: 20 20 20 6e 42 79 74 65 20 3d 20 73 74 72 65 61     nByte = strea
1720: 6d 2e 74 6f 74 61 6c 5f 69 6e 3b 0a 20 20 20 20  m.total_in;.    
1730: 6e 42 79 74 65 43 6f 6d 70 72 20 3d 20 73 74 72  nByteCompr = str
1740: 65 61 6d 2e 74 6f 74 61 6c 5f 6f 75 74 20 2d 20  eam.total_out - 
1750: 32 3b 0a 20 20 20 20 64 65 66 6c 61 74 65 45 6e  2;.    deflateEn
1760: 64 28 26 73 74 72 65 61 6d 29 3b 0a 20 20 0a 20  d(&stream);.  . 
1770: 20 20 20 2f 2a 20 47 6f 20 62 61 63 6b 20 61 6e     /* Go back an
1780: 64 20 77 72 69 74 65 20 74 68 65 20 68 65 61 64  d write the head
1790: 65 72 2c 20 6e 6f 77 20 74 68 61 74 20 77 65 20  er, now that we 
17a0: 6b 6e 6f 77 20 74 68 65 20 63 6f 6d 70 72 65 73  know the compres
17b0: 73 65 64 20 66 69 6c 65 20 73 69 7a 65 2e 0a 20  sed file size.. 
17c0: 20 20 20 2a 2f 0a 20 20 20 20 7a 20 3d 20 26 62     */.    z = &b
17d0: 6c 6f 62 5f 62 75 66 66 65 72 28 26 62 6f 64 79  lob_buffer(&body
17e0: 29 5b 69 53 74 61 72 74 5d 3b 0a 20 20 20 20 70  )[iStart];.    p
17f0: 75 74 33 32 28 26 7a 5b 31 34 5d 2c 20 69 43 52  ut32(&z[14], iCR
1800: 43 29 3b 0a 20 20 20 20 70 75 74 33 32 28 26 7a  C);.    put32(&z
1810: 5b 31 38 5d 2c 20 6e 42 79 74 65 43 6f 6d 70 72  [18], nByteCompr
1820: 29 3b 0a 20 20 20 20 70 75 74 33 32 28 26 7a 5b  );.    put32(&z[
1830: 32 32 5d 2c 20 6e 42 79 74 65 29 3b 0a 20 20 7d  22], nByte);.  }
1840: 0a 20 20 0a 20 20 2f 2a 20 4d 61 6b 65 20 61 6e  .  .  /* Make an
1850: 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20 74 61   entry in the ta
1860: 62 6c 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74 73  bles of contents
1870: 0a 20 20 2a 2f 0a 20 20 6d 65 6d 73 65 74 28 7a  .  */.  memset(z
1880: 42 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28 7a  Buf, 0, sizeof(z
1890: 42 75 66 29 29 3b 0a 20 20 70 75 74 33 32 28 26  Buf));.  put32(&
18a0: 7a 42 75 66 5b 30 5d 2c 20 30 78 30 32 30 31 34  zBuf[0], 0x02014
18b0: 62 35 30 29 3b 0a 20 20 70 75 74 31 36 28 26 7a  b50);.  put16(&z
18c0: 42 75 66 5b 34 5d 2c 20 30 78 30 33 31 37 29 3b  Buf[4], 0x0317);
18d0: 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 36  .  put16(&zBuf[6
18e0: 5d 2c 20 30 78 30 30 30 61 29 3b 0a 20 20 70 75  ], 0x000a);.  pu
18f0: 74 31 36 28 26 7a 42 75 66 5b 38 5d 2c 20 30 29  t16(&zBuf[8], 0)
1900: 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b  ;.  put16(&zBuf[
1910: 31 30 5d 2c 20 69 4d 65 74 68 6f 64 29 3b 0a 20  10], iMethod);. 
1920: 20 70 75 74 31 36 28 26 7a 42 75 66 5b 31 32 5d   put16(&zBuf[12]
1930: 2c 20 64 6f 73 54 69 6d 65 29 3b 0a 20 20 70 75  , dosTime);.  pu
1940: 74 31 36 28 26 7a 42 75 66 5b 31 34 5d 2c 20 64  t16(&zBuf[14], d
1950: 6f 73 44 61 74 65 29 3b 0a 20 20 70 75 74 33 32  osDate);.  put32
1960: 28 26 7a 42 75 66 5b 31 36 5d 2c 20 69 43 52 43  (&zBuf[16], iCRC
1970: 29 3b 0a 20 20 70 75 74 33 32 28 26 7a 42 75 66  );.  put32(&zBuf
1980: 5b 32 30 5d 2c 20 6e 42 79 74 65 43 6f 6d 70 72  [20], nByteCompr
1990: 29 3b 0a 20 20 70 75 74 33 32 28 26 7a 42 75 66  );.  put32(&zBuf
19a0: 5b 32 34 5d 2c 20 6e 42 79 74 65 29 3b 0a 20 20  [24], nByte);.  
19b0: 70 75 74 31 36 28 26 7a 42 75 66 5b 32 38 5d 2c  put16(&zBuf[28],
19c0: 20 6e 61 6d 65 4c 65 6e 29 3b 0a 20 20 70 75 74   nameLen);.  put
19d0: 31 36 28 26 7a 42 75 66 5b 33 30 5d 2c 20 39 29  16(&zBuf[30], 9)
19e0: 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b  ;.  put16(&zBuf[
19f0: 33 32 5d 2c 20 30 29 3b 0a 20 20 70 75 74 31 36  32], 0);.  put16
1a00: 28 26 7a 42 75 66 5b 33 34 5d 2c 20 30 29 3b 0a  (&zBuf[34], 0);.
1a10: 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 33 36    put16(&zBuf[36
1a20: 5d 2c 20 30 29 3b 0a 20 20 70 75 74 33 32 28 26  ], 0);.  put32(&
1a30: 7a 42 75 66 5b 33 38 5d 2c 20 28 28 75 6e 73 69  zBuf[38], ((unsi
1a40: 67 6e 65 64 29 69 4d 6f 64 65 29 3c 3c 31 36 29  gned)iMode)<<16)
1a50: 3b 0a 20 20 70 75 74 33 32 28 26 7a 42 75 66 5b  ;.  put32(&zBuf[
1a60: 34 32 5d 2c 20 69 53 74 61 72 74 29 3b 0a 20 20  42], iStart);.  
1a70: 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 74 6f 63  blob_append(&toc
1a80: 2c 20 7a 42 75 66 2c 20 34 36 29 3b 0a 20 20 62  , zBuf, 46);.  b
1a90: 6c 6f 62 5f 61 70 70 65 6e 64 28 26 74 6f 63 2c  lob_append(&toc,
1aa0: 20 7a 4e 61 6d 65 2c 20 6e 61 6d 65 4c 65 6e 29   zName, nameLen)
1ab0: 3b 0a 20 20 70 75 74 31 36 28 26 7a 45 78 54 69  ;.  put16(&zExTi
1ac0: 6d 65 5b 32 5d 2c 20 35 29 3b 0a 20 20 62 6c 6f  me[2], 5);.  blo
1ad0: 62 5f 61 70 70 65 6e 64 28 26 74 6f 63 2c 20 7a  b_append(&toc, z
1ae0: 45 78 54 69 6d 65 2c 20 39 29 3b 0a 20 20 6e 45  ExTime, 9);.  nE
1af0: 6e 74 72 79 2b 2b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  ntry++;.}.../*.*
1b00: 2a 20 57 72 69 74 65 20 74 68 65 20 5a 49 50 20  * Write the ZIP 
1b10: 61 72 63 68 69 76 65 20 69 6e 74 6f 20 74 68 65  archive into the
1b20: 20 67 69 76 65 6e 20 42 4c 4f 42 2e 0a 2a 2f 0a   given BLOB..*/.
1b30: 76 6f 69 64 20 7a 69 70 5f 63 6c 6f 73 65 28 42  void zip_close(B
1b40: 6c 6f 62 20 2a 70 5a 69 70 29 7b 0a 20 20 69 6e  lob *pZip){.  in
1b50: 74 20 69 54 6f 63 53 74 61 72 74 3b 0a 20 20 69  t iTocStart;.  i
1b60: 6e 74 20 69 54 6f 63 45 6e 64 3b 0a 20 20 69 6e  nt iTocEnd;.  in
1b70: 74 20 69 3b 0a 20 20 63 68 61 72 20 7a 42 75 66  t i;.  char zBuf
1b80: 5b 33 30 5d 3b 0a 0a 20 20 69 54 6f 63 53 74 61  [30];..  iTocSta
1b90: 72 74 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 26  rt = blob_size(&
1ba0: 62 6f 64 79 29 3b 0a 20 20 62 6c 6f 62 5f 61 70  body);.  blob_ap
1bb0: 70 65 6e 64 28 26 62 6f 64 79 2c 20 62 6c 6f 62  pend(&body, blob
1bc0: 5f 62 75 66 66 65 72 28 26 74 6f 63 29 2c 20 62  _buffer(&toc), b
1bd0: 6c 6f 62 5f 73 69 7a 65 28 26 74 6f 63 29 29 3b  lob_size(&toc));
1be0: 0a 20 20 69 54 6f 63 45 6e 64 20 3d 20 62 6c 6f  .  iTocEnd = blo
1bf0: 62 5f 73 69 7a 65 28 26 62 6f 64 79 29 3b 0a 0a  b_size(&body);..
1c00: 20 20 6d 65 6d 73 65 74 28 7a 42 75 66 2c 20 30    memset(zBuf, 0
1c10: 2c 20 73 69 7a 65 6f 66 28 7a 42 75 66 29 29 3b  , sizeof(zBuf));
1c20: 0a 20 20 70 75 74 33 32 28 26 7a 42 75 66 5b 30  .  put32(&zBuf[0
1c30: 5d 2c 20 30 78 30 36 30 35 34 62 35 30 29 3b 0a  ], 0x06054b50);.
1c40: 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 34 5d    put16(&zBuf[4]
1c50: 2c 20 30 29 3b 0a 20 20 70 75 74 31 36 28 26 7a  , 0);.  put16(&z
1c60: 42 75 66 5b 36 5d 2c 20 30 29 3b 0a 20 20 70 75  Buf[6], 0);.  pu
1c70: 74 31 36 28 26 7a 42 75 66 5b 38 5d 2c 20 6e 45  t16(&zBuf[8], nE
1c80: 6e 74 72 79 29 3b 0a 20 20 70 75 74 31 36 28 26  ntry);.  put16(&
1c90: 7a 42 75 66 5b 31 30 5d 2c 20 6e 45 6e 74 72 79  zBuf[10], nEntry
1ca0: 29 3b 0a 20 20 70 75 74 33 32 28 26 7a 42 75 66  );.  put32(&zBuf
1cb0: 5b 31 32 5d 2c 20 69 54 6f 63 45 6e 64 20 2d 20  [12], iTocEnd - 
1cc0: 69 54 6f 63 53 74 61 72 74 29 3b 0a 20 20 70 75  iTocStart);.  pu
1cd0: 74 33 32 28 26 7a 42 75 66 5b 31 36 5d 2c 20 69  t32(&zBuf[16], i
1ce0: 54 6f 63 53 74 61 72 74 29 3b 0a 20 20 70 75 74  TocStart);.  put
1cf0: 31 36 28 26 7a 42 75 66 5b 32 30 5d 2c 20 30 29  16(&zBuf[20], 0)
1d00: 3b 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28  ;.  blob_append(
1d10: 26 62 6f 64 79 2c 20 7a 42 75 66 2c 20 32 32 29  &body, zBuf, 22)
1d20: 3b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26  ;.  blob_reset(&
1d30: 74 6f 63 29 3b 0a 20 20 2a 70 5a 69 70 20 3d 20  toc);.  *pZip = 
1d40: 62 6f 64 79 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72  body;.  blob_zer
1d50: 6f 28 26 62 6f 64 79 29 3b 0a 20 20 6e 45 6e 74  o(&body);.  nEnt
1d60: 72 79 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69 3d  ry = 0;.  for(i=
1d70: 30 3b 20 69 3c 6e 44 69 72 3b 20 69 2b 2b 29 7b  0; i<nDir; i++){
1d80: 0a 20 20 20 20 66 72 65 65 28 61 7a 44 69 72 5b  .    free(azDir[
1d90: 69 5d 29 3b 0a 20 20 7d 0a 20 20 66 72 65 65 28  i]);.  }.  free(
1da0: 61 7a 44 69 72 29 3b 0a 20 20 6e 44 69 72 20 3d  azDir);.  nDir =
1db0: 20 30 3b 0a 20 20 61 7a 44 69 72 20 3d 20 30 3b   0;.  azDir = 0;
1dc0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e  .}../*.** COMMAN
1dd0: 44 3a 20 74 65 73 74 2d 66 69 6c 65 7a 69 70 0a  D: test-filezip.
1de0: 2a 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20 61  **.** Generate a
1df0: 20 5a 49 50 20 61 72 63 68 69 76 65 20 73 70 65   ZIP archive spe
1e00: 63 69 66 69 65 64 20 62 79 20 74 68 65 20 66 69  cified by the fi
1e10: 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74 68 61  rst argument tha
1e20: 74 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 66 69  t.** contains fi
1e30: 6c 65 73 20 67 69 76 65 6e 20 69 6e 20 74 68 65  les given in the
1e40: 20 73 65 63 6f 6e 64 20 61 6e 64 20 73 75 62 73   second and subs
1e50: 65 71 75 65 6e 74 20 61 72 67 75 6d 65 6e 74 73  equent arguments
1e60: 2e 0a 2a 2f 0a 76 6f 69 64 20 66 69 6c 65 7a 69  ..*/.void filezi
1e70: 70 5f 63 6d 64 28 76 6f 69 64 29 7b 0a 20 20 69  p_cmd(void){.  i
1e80: 6e 74 20 69 3b 0a 20 20 42 6c 6f 62 20 7a 69 70  nt i;.  Blob zip
1e90: 3b 0a 20 20 42 6c 6f 62 20 66 69 6c 65 3b 0a 20  ;.  Blob file;. 
1ea0: 20 69 66 28 20 67 2e 61 72 67 63 3c 33 20 29 7b   if( g.argc<3 ){
1eb0: 0a 20 20 20 20 75 73 61 67 65 28 22 41 52 43 48  .    usage("ARCH
1ec0: 49 56 45 20 46 49 4c 45 2e 2e 2e 2e 22 29 3b 0a  IVE FILE....");.
1ed0: 20 20 7d 0a 20 20 7a 69 70 5f 6f 70 65 6e 28 29    }.  zip_open()
1ee0: 3b 0a 20 20 66 6f 72 28 69 3d 33 3b 20 69 3c 67  ;.  for(i=3; i<g
1ef0: 2e 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20  .argc; i++){.   
1f00: 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 66 69 6c 65   blob_zero(&file
1f10: 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 61 64  );.    blob_read
1f20: 5f 66 72 6f 6d 5f 66 69 6c 65 28 26 66 69 6c 65  _from_file(&file
1f30: 2c 20 67 2e 61 72 67 76 5b 69 5d 29 3b 0a 20 20  , g.argv[i]);.  
1f40: 20 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65 28 67    zip_add_file(g
1f50: 2e 61 72 67 76 5b 69 5d 2c 20 26 66 69 6c 65 29  .argv[i], &file)
1f60: 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74  ;.    blob_reset
1f70: 28 26 66 69 6c 65 29 3b 0a 20 20 7d 0a 20 20 7a  (&file);.  }.  z
1f80: 69 70 5f 63 6c 6f 73 65 28 26 7a 69 70 29 3b 0a  ip_close(&zip);.
1f90: 20 20 62 6c 6f 62 5f 77 72 69 74 65 5f 74 6f 5f    blob_write_to_
1fa0: 66 69 6c 65 28 26 7a 69 70 2c 20 67 2e 61 72 67  file(&zip, g.arg
1fb0: 76 5b 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  v[2]);.}../*.** 
1fc0: 47 69 76 65 6e 20 74 68 65 20 52 49 44 20 66 6f  Given the RID fo
1fd0: 72 20 61 20 6d 61 6e 69 66 65 73 74 2c 20 63 6f  r a manifest, co
1fe0: 6e 73 74 72 75 63 74 20 61 20 5a 49 50 20 61 72  nstruct a ZIP ar
1ff0: 63 68 69 76 65 20 63 6f 6e 74 61 69 6e 69 6e 67  chive containing
2000: 0a 2a 2a 20 61 6c 6c 20 66 69 6c 65 73 20 69 6e  .** all files in
2010: 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e 64 69   the correspondi
2020: 6e 67 20 62 61 73 65 6c 69 6e 65 2e 0a 2a 2a 0a  ng baseline..**.
2030: 2a 2a 20 49 66 20 52 49 44 20 69 73 20 66 6f 72  ** If RID is for
2040: 20 61 6e 20 6f 62 6a 65 63 74 20 74 68 61 74 20   an object that 
2050: 69 73 20 6e 6f 74 20 61 20 72 65 61 6c 20 6d 61  is not a real ma
2060: 6e 69 66 65 73 74 2c 20 74 68 65 6e 20 74 68 65  nifest, then the
2070: 0a 2a 2a 20 72 65 73 75 6c 74 69 6e 67 20 5a 49  .** resulting ZI
2080: 50 20 61 72 63 68 69 76 65 20 63 6f 6e 74 61 69  P archive contai
2090: 6e 73 20 61 20 73 69 6e 67 6c 65 20 66 69 6c 65  ns a single file
20a0: 20 77 68 69 63 68 20 69 73 20 74 68 65 20 52 49   which is the RI
20b0: 44 0a 2a 2a 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a  D.** object..**.
20c0: 2a 2a 20 49 66 20 74 68 65 20 52 49 44 20 6f 62  ** If the RID ob
20d0: 6a 65 63 74 20 64 6f 65 73 20 6e 6f 74 20 65 78  ject does not ex
20e0: 69 73 74 20 69 6e 20 74 68 65 20 72 65 70 6f 73  ist in the repos
20f0: 69 74 6f 72 79 2c 20 74 68 65 6e 0a 2a 2a 20 70  itory, then.** p
2100: 5a 69 70 20 69 73 20 7a 65 72 6f 65 64 2e 0a 2a  Zip is zeroed..*
2110: 2a 0a 2a 2a 20 7a 44 69 72 20 69 73 20 61 20 22  *.** zDir is a "
2120: 73 79 6e 74 68 65 74 69 63 22 20 73 75 62 64 69  synthetic" subdi
2130: 72 65 63 74 6f 72 79 20 77 68 69 63 68 20 61 6c  rectory which al
2140: 6c 20 7a 69 70 70 65 64 20 66 69 6c 65 73 20 67  l zipped files g
2150: 65 74 0a 2a 2a 20 61 64 64 65 64 20 74 6f 20 61  et.** added to a
2160: 73 20 70 61 72 74 20 6f 66 20 74 68 65 20 7a 69  s part of the zi
2170: 70 20 66 69 6c 65 2e 20 49 74 20 6d 61 79 20 62  p file. It may b
2180: 65 20 30 20 6f 72 20 61 6e 20 65 6d 70 74 79 20  e 0 or an empty 
2190: 73 74 72 69 6e 67 2c 0a 2a 2a 20 69 6e 20 77 68  string,.** in wh
21a0: 69 63 68 20 63 61 73 65 20 69 74 20 69 73 20 69  ich case it is i
21b0: 67 6e 6f 72 65 64 2e 20 54 68 65 20 69 6e 74 65  gnored. The inte
21c0: 6e 74 69 6f 6e 20 69 73 20 74 6f 20 63 72 65 61  ntion is to crea
21d0: 74 65 20 61 20 7a 69 70 20 77 68 69 63 68 0a 2a  te a zip which.*
21e0: 2a 20 70 6f 6c 69 74 65 6c 79 20 65 78 70 61 6e  * politely expan
21f0: 64 73 20 69 6e 74 6f 20 61 20 73 75 62 64 69 72  ds into a subdir
2200: 20 69 6e 73 74 65 61 64 20 6f 66 20 66 69 6c 6c   instead of fill
2210: 69 6e 67 20 79 6f 75 72 20 63 75 72 72 65 6e 74  ing your current
2220: 20 64 69 72 0a 2a 2a 20 77 69 74 68 20 73 6f 75   dir.** with sou
2230: 72 63 65 20 66 69 6c 65 73 2e 20 46 6f 72 20 65  rce files. For e
2240: 78 61 6d 70 6c 65 2c 20 70 61 73 73 20 61 20 55  xample, pass a U
2250: 55 49 44 20 6f 72 20 22 50 72 6f 6a 65 63 74 4e  UID or "ProjectN
2260: 61 6d 65 22 2e 0a 2a 2a 0a 2a 2f 0a 76 6f 69 64  ame"..**.*/.void
2270: 20 7a 69 70 5f 6f 66 5f 62 61 73 65 6c 69 6e 65   zip_of_baseline
2280: 28 69 6e 74 20 72 69 64 2c 20 42 6c 6f 62 20 2a  (int rid, Blob *
2290: 70 5a 69 70 2c 20 63 6f 6e 73 74 20 63 68 61 72  pZip, const char
22a0: 20 2a 7a 44 69 72 29 7b 0a 20 20 69 6e 74 20 69   *zDir){.  int i
22b0: 3b 0a 20 20 42 6c 6f 62 20 6d 66 69 6c 65 2c 20  ;.  Blob mfile, 
22c0: 66 69 6c 65 2c 20 68 61 73 68 3b 0a 20 20 4d 61  file, hash;.  Ma
22d0: 6e 69 66 65 73 74 20 6d 3b 0a 20 20 42 6c 6f 62  nifest m;.  Blob
22e0: 20 66 69 6c 65 6e 61 6d 65 3b 0a 20 20 69 6e 74   filename;.  int
22f0: 20 6e 50 72 65 66 69 78 3b 0a 20 20 0a 20 20 63   nPrefix;.  .  c
2300: 6f 6e 74 65 6e 74 5f 67 65 74 28 72 69 64 2c 20  ontent_get(rid, 
2310: 26 6d 66 69 6c 65 29 3b 0a 20 20 69 66 28 20 62  &mfile);.  if( b
2320: 6c 6f 62 5f 73 69 7a 65 28 26 6d 66 69 6c 65 29  lob_size(&mfile)
2330: 3d 3d 30 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f  ==0 ){.    blob_
2340: 7a 65 72 6f 28 70 5a 69 70 29 3b 0a 20 20 20 20  zero(pZip);.    
2350: 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 62 6c  return;.  }.  bl
2360: 6f 62 5f 7a 65 72 6f 28 26 66 69 6c 65 29 3b 0a  ob_zero(&file);.
2370: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 68 61 73    blob_zero(&has
2380: 68 29 3b 0a 20 20 62 6c 6f 62 5f 63 6f 70 79 28  h);.  blob_copy(
2390: 26 66 69 6c 65 2c 20 26 6d 66 69 6c 65 29 3b 0a  &file, &mfile);.
23a0: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 66 69 6c    blob_zero(&fil
23b0: 65 6e 61 6d 65 29 3b 0a 20 20 7a 69 70 5f 6f 70  ename);.  zip_op
23c0: 65 6e 28 29 3b 0a 0a 20 20 69 66 28 20 7a 44 69  en();..  if( zDi
23d0: 72 20 26 26 20 7a 44 69 72 5b 30 5d 20 29 7b 0a  r && zDir[0] ){.
23e0: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66      blob_appendf
23f0: 28 26 66 69 6c 65 6e 61 6d 65 2c 20 22 25 73 2f  (&filename, "%s/
2400: 22 2c 20 7a 44 69 72 29 3b 0a 20 20 7d 0a 20 20  ", zDir);.  }.  
2410: 6e 50 72 65 66 69 78 20 3d 20 62 6c 6f 62 5f 73  nPrefix = blob_s
2420: 69 7a 65 28 26 66 69 6c 65 6e 61 6d 65 29 3b 0a  ize(&filename);.
2430: 0a 20 20 69 66 28 20 6d 61 6e 69 66 65 73 74 5f  .  if( manifest_
2440: 70 61 72 73 65 28 26 6d 2c 20 26 6d 66 69 6c 65  parse(&m, &mfile
2450: 29 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  ) ){.    char *z
2460: 4e 61 6d 65 3b 0a 20 20 20 20 7a 69 70 5f 73 65  Name;.    zip_se
2470: 74 5f 74 69 6d 65 64 61 74 65 28 6d 2e 72 44 61  t_timedate(m.rDa
2480: 74 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 61 70  te);.    blob_ap
2490: 70 65 6e 64 28 26 66 69 6c 65 6e 61 6d 65 2c 20  pend(&filename, 
24a0: 22 6d 61 6e 69 66 65 73 74 22 2c 20 2d 31 29 3b  "manifest", -1);
24b0: 0a 20 20 20 20 7a 4e 61 6d 65 20 3d 20 62 6c 6f  .    zName = blo
24c0: 62 5f 73 74 72 28 26 66 69 6c 65 6e 61 6d 65 29  b_str(&filename)
24d0: 3b 0a 20 20 20 20 7a 69 70 5f 61 64 64 5f 66 6f  ;.    zip_add_fo
24e0: 6c 64 65 72 73 28 7a 4e 61 6d 65 29 3b 0a 20 20  lders(zName);.  
24f0: 20 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65 28 7a    zip_add_file(z
2500: 4e 61 6d 65 2c 20 26 66 69 6c 65 29 3b 0a 20 20  Name, &file);.  
2510: 20 20 73 68 61 31 73 75 6d 5f 62 6c 6f 62 28 26    sha1sum_blob(&
2520: 66 69 6c 65 2c 20 26 68 61 73 68 29 3b 0a 20 20  file, &hash);.  
2530: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 66 69    blob_reset(&fi
2540: 6c 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 61 70  le);.    blob_ap
2550: 70 65 6e 64 28 26 68 61 73 68 2c 20 22 5c 6e 22  pend(&hash, "\n"
2560: 2c 20 31 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72  , 1);.    blob_r
2570: 65 73 69 7a 65 28 26 66 69 6c 65 6e 61 6d 65 2c  esize(&filename,
2580: 20 6e 50 72 65 66 69 78 29 3b 0a 20 20 20 20 62   nPrefix);.    b
2590: 6c 6f 62 5f 61 70 70 65 6e 64 28 26 66 69 6c 65  lob_append(&file
25a0: 6e 61 6d 65 2c 20 22 6d 61 6e 69 66 65 73 74 2e  name, "manifest.
25b0: 75 75 69 64 22 2c 20 2d 31 29 3b 0a 20 20 20 20  uuid", -1);.    
25c0: 7a 4e 61 6d 65 20 3d 20 62 6c 6f 62 5f 73 74 72  zName = blob_str
25d0: 28 26 66 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 20  (&filename);.   
25e0: 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65 28 7a 4e   zip_add_file(zN
25f0: 61 6d 65 2c 20 26 68 61 73 68 29 3b 0a 20 20 20  ame, &hash);.   
2600: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 68 61 73   blob_reset(&has
2610: 68 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b  h);.    for(i=0;
2620: 20 69 3c 6d 2e 6e 46 69 6c 65 3b 20 69 2b 2b 29   i<m.nFile; i++)
2630: 7b 0a 20 20 20 20 20 20 69 6e 74 20 66 69 64 20  {.      int fid 
2640: 3d 20 75 75 69 64 5f 74 6f 5f 72 69 64 28 6d 2e  = uuid_to_rid(m.
2650: 61 46 69 6c 65 5b 69 5d 2e 7a 55 75 69 64 2c 20  aFile[i].zUuid, 
2660: 30 29 3b 0a 20 20 20 20 20 20 69 66 28 20 66 69  0);.      if( fi
2670: 64 20 29 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e  d ){.        con
2680: 74 65 6e 74 5f 67 65 74 28 66 69 64 2c 20 26 66  tent_get(fid, &f
2690: 69 6c 65 29 3b 0a 20 20 20 20 20 20 20 20 62 6c  ile);.        bl
26a0: 6f 62 5f 72 65 73 69 7a 65 28 26 66 69 6c 65 6e  ob_resize(&filen
26b0: 61 6d 65 2c 20 6e 50 72 65 66 69 78 29 3b 0a 20  ame, nPrefix);. 
26c0: 20 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65         blob_appe
26d0: 6e 64 28 26 66 69 6c 65 6e 61 6d 65 2c 20 6d 2e  nd(&filename, m.
26e0: 61 46 69 6c 65 5b 69 5d 2e 7a 4e 61 6d 65 2c 20  aFile[i].zName, 
26f0: 2d 31 29 3b 0a 20 20 20 20 20 20 20 20 7a 4e 61  -1);.        zNa
2700: 6d 65 20 3d 20 62 6c 6f 62 5f 73 74 72 28 26 66  me = blob_str(&f
2710: 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 20 20 20 20  ilename);.      
2720: 20 20 7a 69 70 5f 61 64 64 5f 66 6f 6c 64 65 72    zip_add_folder
2730: 73 28 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20  s(zName);.      
2740: 20 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65 28 7a    zip_add_file(z
2750: 4e 61 6d 65 2c 20 26 66 69 6c 65 29 3b 0a 20 20  Name, &file);.  
2760: 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74        blob_reset
2770: 28 26 66 69 6c 65 29 3b 0a 20 20 20 20 20 20 7d  (&file);.      }
2780: 0a 20 20 20 20 7d 0a 20 20 20 20 6d 61 6e 69 66  .    }.    manif
2790: 65 73 74 5f 63 6c 65 61 72 28 26 6d 29 3b 0a 20  est_clear(&m);. 
27a0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 62 6c 6f 62   }else{.    blob
27b0: 5f 72 65 73 65 74 28 26 6d 66 69 6c 65 29 3b 0a  _reset(&mfile);.
27c0: 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26      blob_reset(&
27d0: 66 69 6c 65 29 3b 0a 20 20 7d 0a 20 20 62 6c 6f  file);.  }.  blo
27e0: 62 5f 72 65 73 65 74 28 26 66 69 6c 65 6e 61 6d  b_reset(&filenam
27f0: 65 29 3b 0a 20 20 7a 69 70 5f 63 6c 6f 73 65 28  e);.  zip_close(
2800: 70 5a 69 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  pZip);.}../*.** 
2810: 43 4f 4d 4d 41 4e 44 3a 20 74 65 73 74 2d 62 61  COMMAND: test-ba
2820: 73 65 6c 69 6e 65 2d 7a 69 70 0a 2a 2a 0a 2a 2a  seline-zip.**.**
2830: 20 47 65 6e 65 72 61 74 65 20 61 20 5a 49 50 20   Generate a ZIP 
2840: 61 72 63 68 69 76 65 20 66 6f 72 20 61 20 73 70  archive for a sp
2850: 65 63 69 66 69 65 64 20 62 61 73 65 6c 69 6e 65  ecified baseline
2860: 2e 0a 2a 2f 0a 76 6f 69 64 20 62 61 73 65 6c 69  ..*/.void baseli
2870: 6e 65 5f 7a 69 70 5f 63 6d 64 28 76 6f 69 64 29  ne_zip_cmd(void)
2880: 7b 0a 20 20 69 6e 74 20 72 69 64 3b 0a 20 20 42  {.  int rid;.  B
2890: 6c 6f 62 20 7a 69 70 3b 0a 20 20 69 66 28 20 67  lob zip;.  if( g
28a0: 2e 61 72 67 63 21 3d 34 20 29 7b 0a 20 20 20 20  .argc!=4 ){.    
28b0: 75 73 61 67 65 28 22 55 55 49 44 20 5a 49 50 46  usage("UUID ZIPF
28c0: 49 4c 45 22 29 3b 0a 20 20 7d 0a 20 20 64 62 5f  ILE");.  }.  db_
28d0: 6d 75 73 74 5f 62 65 5f 77 69 74 68 69 6e 5f 74  must_be_within_t
28e0: 72 65 65 28 29 3b 0a 20 20 72 69 64 20 3d 20 6e  ree();.  rid = n
28f0: 61 6d 65 5f 74 6f 5f 72 69 64 28 67 2e 61 72 67  ame_to_rid(g.arg
2900: 76 5b 32 5d 29 3b 0a 20 20 7a 69 70 5f 6f 66 5f  v[2]);.  zip_of_
2910: 62 61 73 65 6c 69 6e 65 28 72 69 64 2c 20 26 7a  baseline(rid, &z
2920: 69 70 2c 20 67 2e 61 72 67 76 5b 32 5d 29 3b 0a  ip, g.argv[2]);.
2930: 20 20 62 6c 6f 62 5f 77 72 69 74 65 5f 74 6f 5f    blob_write_to_
2940: 66 69 6c 65 28 26 7a 69 70 2c 20 67 2e 61 72 67  file(&zip, g.arg
2950: 76 5b 33 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  v[3]);.}../*.** 
2960: 57 45 42 50 41 47 45 3a 20 7a 69 70 0a 2a 2a 20  WEBPAGE: zip.** 
2970: 55 52 4c 3a 20 2f 7a 69 70 2f 52 49 44 2e 7a 69  URL: /zip/RID.zi
2980: 70 0a 2a 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65  p.**.** Generate
2990: 20 61 20 5a 49 50 20 61 72 63 68 69 76 65 20 66   a ZIP archive f
29a0: 6f 72 20 74 68 65 20 62 61 73 65 6c 69 6e 65 2e  or the baseline.
29b0: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 61 74 20  .** Return that 
29c0: 5a 49 50 20 61 72 63 68 69 76 65 20 61 73 20 74  ZIP archive as t
29d0: 68 65 20 48 54 54 50 20 72 65 70 6c 79 20 63 6f  he HTTP reply co
29e0: 6e 74 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 64 20 62  ntent..*/.void b
29f0: 61 73 65 6c 69 6e 65 5f 7a 69 70 5f 70 61 67 65  aseline_zip_page
2a00: 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 72 69  (void){.  int ri
2a10: 64 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65  d;.  char *zName
2a20: 2c 20 2a 7a 52 69 64 3b 0a 20 20 69 6e 74 20 6e  , *zRid;.  int n
2a30: 4e 61 6d 65 2c 20 6e 52 69 64 3b 0a 20 20 42 6c  Name, nRid;.  Bl
2a40: 6f 62 20 7a 69 70 3b 0a 0a 20 20 6c 6f 67 69 6e  ob zip;..  login
2a50: 5f 63 68 65 63 6b 5f 63 72 65 64 65 6e 74 69 61  _check_credentia
2a60: 6c 73 28 29 3b 0a 20 20 69 66 28 20 21 67 2e 6f  ls();.  if( !g.o
2a70: 6b 5a 69 70 20 26 26 20 28 21 67 2e 6f 6b 52 65  kZip && (!g.okRe
2a80: 61 64 20 7c 7c 20 21 67 2e 6f 6b 48 69 73 74 6f  ad || !g.okHisto
2a90: 72 79 29 20 29 7b 20 6c 6f 67 69 6e 5f 6e 65 65  ry) ){ login_nee
2aa0: 64 65 64 28 29 3b 20 72 65 74 75 72 6e 3b 20 7d  ded(); return; }
2ab0: 0a 20 20 7a 4e 61 6d 65 20 3d 20 6d 70 72 69 6e  .  zName = mprin
2ac0: 74 66 28 22 25 73 22 2c 20 50 44 28 22 6e 61 6d  tf("%s", PD("nam
2ad0: 65 22 2c 22 22 29 29 3b 0a 20 20 6e 4e 61 6d 65  e",""));.  nName
2ae0: 20 3d 20 73 74 72 6c 65 6e 28 7a 4e 61 6d 65 29   = strlen(zName)
2af0: 3b 0a 20 20 7a 52 69 64 20 3d 20 6d 70 72 69 6e  ;.  zRid = mprin
2b00: 74 66 28 22 25 73 22 2c 20 50 44 28 22 75 75 69  tf("%s", PD("uui
2b10: 64 22 2c 22 22 29 29 3b 0a 20 20 6e 52 69 64 20  d",""));.  nRid 
2b20: 3d 20 73 74 72 6c 65 6e 28 7a 52 69 64 29 3b 0a  = strlen(zRid);.
2b30: 20 20 66 6f 72 28 6e 4e 61 6d 65 3d 73 74 72 6c    for(nName=strl
2b40: 65 6e 28 7a 4e 61 6d 65 29 2d 31 3b 20 6e 4e 61  en(zName)-1; nNa
2b50: 6d 65 3e 35 3b 20 6e 4e 61 6d 65 2d 2d 29 7b 0a  me>5; nName--){.
2b60: 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b 6e 4e      if( zName[nN
2b70: 61 6d 65 5d 3d 3d 27 2e 27 20 29 7b 0a 20 20 20  ame]=='.' ){.   
2b80: 20 20 20 7a 4e 61 6d 65 5b 6e 4e 61 6d 65 5d 20     zName[nName] 
2b90: 3d 20 30 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  = 0;.      break
2ba0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 69  ;.    }.  }.  ri
2bb0: 64 20 3d 20 6e 61 6d 65 5f 74 6f 5f 72 69 64 28  d = name_to_rid(
2bc0: 6e 52 69 64 3f 7a 52 69 64 3a 7a 4e 61 6d 65 29  nRid?zRid:zName)
2bd0: 3b 0a 20 20 69 66 28 20 72 69 64 3d 3d 30 20 29  ;.  if( rid==0 )
2be0: 7b 0a 20 20 20 20 40 20 4e 6f 74 20 66 6f 75 6e  {.    @ Not foun
2bf0: 64 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20  d.    return;.  
2c00: 7d 0a 20 20 69 66 28 20 6e 52 69 64 3d 3d 30 20  }.  if( nRid==0 
2c10: 26 26 20 6e 4e 61 6d 65 3e 31 30 20 29 20 7a 4e  && nName>10 ) zN
2c20: 61 6d 65 5b 31 30 5d 20 3d 20 30 3b 0a 20 20 7a  ame[10] = 0;.  z
2c30: 69 70 5f 6f 66 5f 62 61 73 65 6c 69 6e 65 28 72  ip_of_baseline(r
2c40: 69 64 2c 20 26 7a 69 70 2c 20 7a 4e 61 6d 65 29  id, &zip, zName)
2c50: 3b 0a 20 20 66 72 65 65 28 20 7a 4e 61 6d 65 20  ;.  free( zName 
2c60: 29 3b 0a 20 20 66 72 65 65 28 20 7a 52 69 64 20  );.  free( zRid 
2c70: 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f 63 6f 6e  );.  cgi_set_con
2c80: 74 65 6e 74 28 26 7a 69 70 29 3b 0a 20 20 63 67  tent(&zip);.  cg
2c90: 69 5f 73 65 74 5f 63 6f 6e 74 65 6e 74 5f 74 79  i_set_content_ty
2ca0: 70 65 28 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f  pe("application/
2cb0: 7a 69 70 22 29 3b 0a 7d 0a                       zip");.}.