Hex Artifact Content
Not logged in

Artifact a6ead783d298ac49f3edfeb9e0d41d64cdcf40ed:

File src/zip.c part of check-in [95e17f4e3f] - Generate the "manifest.uuid" file containing the SHA1 hash of the "manifest" file whenever the manifest is generated. Makefiles can used the "manifest.uuid" to insert the version number into the executable. by drh on 2007-08-25 19:31:31.

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 0a 2f 2a 0a 2a 2a 20   date */../*.** 
0640: 49 6e 69 74 69 61 6c 69 7a 65 20 61 20 6e 65 77  Initialize a new
0650: 20 5a 49 50 20 61 72 63 68 69 76 65 2e 0a 2a 2f   ZIP archive..*/
0660: 0a 76 6f 69 64 20 7a 69 70 5f 6f 70 65 6e 28 76  .void zip_open(v
0670: 6f 69 64 29 7b 0a 20 20 62 6c 6f 62 5f 7a 65 72  oid){.  blob_zer
0680: 6f 28 26 62 6f 64 79 29 3b 0a 20 20 62 6c 6f 62  o(&body);.  blob
0690: 5f 7a 65 72 6f 28 26 74 6f 63 29 3b 0a 20 20 6e  _zero(&toc);.  n
06a0: 45 6e 74 72 79 20 3d 20 30 3b 0a 20 20 64 6f 73  Entry = 0;.  dos
06b0: 54 69 6d 65 20 3d 20 30 3b 0a 20 20 64 6f 73 44  Time = 0;.  dosD
06c0: 61 74 65 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a  ate = 0;.}../*.*
06d0: 2a 20 53 65 74 20 74 68 65 20 64 61 74 65 20 61  * Set the date a
06e0: 6e 64 20 74 69 6d 65 20 76 61 6c 75 65 73 20 66  nd time values f
06f0: 72 6f 6d 20 61 6e 20 49 53 4f 38 36 30 31 20 64  rom an ISO8601 d
0700: 61 74 65 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 76  ate string..*/.v
0710: 6f 69 64 20 7a 69 70 5f 73 65 74 5f 74 69 6d 65  oid zip_set_time
0720: 64 61 74 65 5f 66 72 6f 6d 5f 73 74 72 28 63 6f  date_from_str(co
0730: 6e 73 74 20 63 68 61 72 20 2a 7a 44 61 74 65 29  nst char *zDate)
0740: 7b 0a 20 20 69 6e 74 20 79 2c 20 6d 2c 20 64 3b  {.  int y, m, d;
0750: 0a 20 20 69 6e 74 20 48 2c 20 4d 2c 20 53 3b 0a  .  int H, M, S;.
0760: 0a 20 20 79 20 3d 20 61 74 6f 69 28 7a 44 61 74  .  y = atoi(zDat
0770: 65 29 3b 0a 20 20 6d 20 3d 20 61 74 6f 69 28 26  e);.  m = atoi(&
0780: 7a 44 61 74 65 5b 35 5d 29 3b 0a 20 20 64 20 3d  zDate[5]);.  d =
0790: 20 61 74 6f 69 28 26 7a 44 61 74 65 5b 38 5d 29   atoi(&zDate[8])
07a0: 3b 0a 20 20 48 20 3d 20 61 74 6f 69 28 26 7a 44  ;.  H = atoi(&zD
07b0: 61 74 65 5b 31 31 5d 29 3b 0a 20 20 4d 20 3d 20  ate[11]);.  M = 
07c0: 61 74 6f 69 28 26 7a 44 61 74 65 5b 31 34 5d 29  atoi(&zDate[14])
07d0: 3b 0a 20 20 53 20 3d 20 61 74 6f 69 28 26 7a 44  ;.  S = atoi(&zD
07e0: 61 74 65 5b 31 37 5d 29 3b 0a 20 20 64 6f 73 54  ate[17]);.  dosT
07f0: 69 6d 65 20 3d 20 28 48 3c 3c 31 31 29 20 2b 20  ime = (H<<11) + 
0800: 28 4d 3c 3c 35 29 20 2b 20 53 3b 0a 20 20 64 6f  (M<<5) + S;.  do
0810: 73 44 61 74 65 20 3d 20 28 28 79 2d 31 39 38 30  sDate = ((y-1980
0820: 29 3c 3c 39 29 20 2b 20 28 6d 3c 3c 35 29 20 2b  )<<9) + (m<<5) +
0830: 20 64 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74   d;.}../*.** Set
0840: 20 74 68 65 20 64 61 74 65 20 61 6e 64 20 74 69   the date and ti
0850: 6d 65 20 66 72 6f 6d 20 61 20 6a 75 6c 69 61 6e  me from a julian
0860: 20 64 61 79 20 6e 75 6d 62 65 72 2e 0a 2a 2f 0a   day number..*/.
0870: 76 6f 69 64 20 7a 69 70 5f 73 65 74 5f 74 69 6d  void zip_set_tim
0880: 65 64 61 74 65 28 64 6f 75 62 6c 65 20 72 44 61  edate(double rDa
0890: 74 65 29 7b 0a 20 20 63 68 61 72 20 2a 7a 44 61  te){.  char *zDa
08a0: 74 65 20 3d 20 64 62 5f 74 65 78 74 28 30 2c 20  te = db_text(0, 
08b0: 22 53 45 4c 45 43 54 20 64 61 74 65 74 69 6d 65  "SELECT datetime
08c0: 28 25 2e 31 37 67 29 22 2c 20 72 44 61 74 65 29  (%.17g)", rDate)
08d0: 3b 0a 20 20 7a 69 70 5f 73 65 74 5f 74 69 6d 65  ;.  zip_set_time
08e0: 64 61 74 65 5f 66 72 6f 6d 5f 73 74 72 28 7a 44  date_from_str(zD
08f0: 61 74 65 29 3b 0a 20 20 66 72 65 65 28 7a 44 61  ate);.  free(zDa
0900: 74 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70  te);.}../*.** Ap
0910: 70 65 6e 64 20 61 20 73 69 6e 67 6c 65 20 66 69  pend a single fi
0920: 6c 65 20 74 6f 20 61 20 67 72 6f 77 69 6e 67 20  le to a growing 
0930: 5a 49 50 20 61 72 63 68 69 76 65 2e 0a 2a 2a 0a  ZIP archive..**.
0940: 2a 2a 20 70 46 69 6c 65 20 69 73 20 74 68 65 20  ** pFile is the 
0950: 66 69 6c 65 20 74 6f 20 62 65 20 61 70 70 65 6e  file to be appen
0960: 64 65 64 2e 20 20 7a 4e 61 6d 65 20 69 73 20 74  ded.  zName is t
0970: 68 65 20 6e 61 6d 65 0a 2a 2a 20 74 68 61 74 20  he name.** that 
0980: 74 68 65 20 66 69 6c 65 20 73 68 6f 75 6c 64 20  the file should 
0990: 62 65 20 73 61 76 65 64 20 61 73 2e 0a 2a 2f 0a  be saved as..*/.
09a0: 76 6f 69 64 20 7a 69 70 5f 61 64 64 5f 66 69 6c  void zip_add_fil
09b0: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e  e(const char *zN
09c0: 61 6d 65 2c 20 63 6f 6e 73 74 20 42 6c 6f 62 20  ame, const Blob 
09d0: 2a 70 46 69 6c 65 29 7b 0a 20 20 7a 5f 73 74 72  *pFile){.  z_str
09e0: 65 61 6d 20 73 74 72 65 61 6d 3b 0a 20 20 69 6e  eam stream;.  in
09f0: 74 20 6e 61 6d 65 4c 65 6e 3b 0a 20 20 69 6e 74  t nameLen;.  int
0a00: 20 73 6b 69 70 3b 0a 20 20 69 6e 74 20 74 6f 4f   skip;.  int toO
0a10: 75 74 3b 0a 20 20 69 6e 74 20 69 53 74 61 72 74  ut;.  int iStart
0a20: 3b 0a 20 20 69 6e 74 20 69 43 52 43 3b 0a 20 20  ;.  int iCRC;.  
0a30: 69 6e 74 20 6e 42 79 74 65 3b 0a 20 20 69 6e 74  int nByte;.  int
0a40: 20 6e 42 79 74 65 43 6f 6d 70 72 3b 0a 20 20 63   nByteCompr;.  c
0a50: 68 61 72 20 2a 7a 3b 0a 20 20 63 68 61 72 20 7a  har *z;.  char z
0a60: 48 64 72 5b 33 30 5d 3b 0a 20 20 63 68 61 72 20  Hdr[30];.  char 
0a70: 7a 42 75 66 5b 31 30 30 5d 3b 0a 20 20 63 68 61  zBuf[100];.  cha
0a80: 72 20 7a 4f 75 74 42 75 66 5b 31 30 30 30 30 30  r zOutBuf[100000
0a90: 5d 3b 0a 0a 20 20 2f 2a 20 46 69 6c 6c 20 69 6e  ];..  /* Fill in
0aa0: 20 61 73 20 6d 75 63 68 20 6f 66 20 74 68 65 20   as much of the 
0ab0: 68 65 61 64 65 72 20 61 73 20 77 65 20 6b 6e 6f  header as we kno
0ac0: 77 2e 0a 20 20 2a 2f 0a 20 20 6e 61 6d 65 4c 65  w..  */.  nameLe
0ad0: 6e 20 3d 20 73 74 72 6c 65 6e 28 7a 4e 61 6d 65  n = strlen(zName
0ae0: 29 3b 0a 20 20 70 75 74 33 32 28 26 7a 48 64 72  );.  put32(&zHdr
0af0: 5b 30 5d 2c 20 30 78 30 34 30 33 34 62 35 30 29  [0], 0x04034b50)
0b00: 3b 0a 20 20 70 75 74 31 36 28 26 7a 48 64 72 5b  ;.  put16(&zHdr[
0b10: 34 5d 2c 20 30 78 30 30 31 34 29 3b 0a 20 20 70  4], 0x0014);.  p
0b20: 75 74 31 36 28 26 7a 48 64 72 5b 36 5d 2c 20 30  ut16(&zHdr[6], 0
0b30: 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 48 64 72  );.  put16(&zHdr
0b40: 5b 38 5d 2c 20 38 29 3b 0a 20 20 70 75 74 31 36  [8], 8);.  put16
0b50: 28 26 7a 48 64 72 5b 31 30 5d 2c 20 64 6f 73 54  (&zHdr[10], dosT
0b60: 69 6d 65 29 3b 0a 20 20 70 75 74 31 36 28 26 7a  ime);.  put16(&z
0b70: 48 64 72 5b 31 32 5d 2c 20 64 6f 73 44 61 74 65  Hdr[12], dosDate
0b80: 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 48 64 72  );.  put16(&zHdr
0b90: 5b 32 36 5d 2c 20 6e 61 6d 65 4c 65 6e 29 3b 0a  [26], nameLen);.
0ba0: 20 20 70 75 74 31 36 28 26 7a 48 64 72 5b 32 38    put16(&zHdr[28
0bb0: 5d 2c 20 30 29 3b 0a 0a 20 20 2f 2a 20 57 72 69  ], 0);..  /* Wri
0bc0: 74 65 20 74 68 65 20 68 65 61 64 65 72 20 61 6e  te the header an
0bd0: 64 20 66 69 6c 65 6e 61 6d 65 2e 0a 20 20 2a 2f  d filename..  */
0be0: 0a 20 20 69 53 74 61 72 74 20 3d 20 62 6c 6f 62  .  iStart = blob
0bf0: 5f 73 69 7a 65 28 26 62 6f 64 79 29 3b 0a 20 20  _size(&body);.  
0c00: 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 62 6f 64  blob_append(&bod
0c10: 79 2c 20 7a 48 64 72 2c 20 33 30 29 3b 0a 20 20  y, zHdr, 30);.  
0c20: 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 62 6f 64  blob_append(&bod
0c30: 79 2c 20 7a 4e 61 6d 65 2c 20 6e 61 6d 65 4c 65  y, zName, nameLe
0c40: 6e 29 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 66 69  n);..  /* The fi
0c50: 72 73 74 20 74 77 6f 20 62 79 74 65 73 20 74 68  rst two bytes th
0c60: 61 74 20 63 6f 6d 65 20 6f 75 74 20 6f 66 20 74  at come out of t
0c70: 68 65 20 64 65 66 6c 61 74 65 20 63 6f 6d 70 72  he deflate compr
0c80: 65 73 73 6f 72 20 61 72 65 0a 20 20 2a 2a 20 73  essor are.  ** s
0c90: 6f 6d 65 20 6b 69 6e 64 20 6f 66 20 68 65 61 64  ome kind of head
0ca0: 65 72 20 74 68 61 74 20 5a 49 50 20 64 6f 65 73  er that ZIP does
0cb0: 20 6e 6f 74 20 75 73 65 2e 20 20 53 6f 20 73 6b   not use.  So sk
0cc0: 69 70 20 74 68 65 20 66 69 72 73 74 20 74 77 6f  ip the first two
0cd0: 0a 20 20 2a 2a 20 6f 75 74 70 75 74 20 62 79 74  .  ** output byt
0ce0: 65 73 2e 0a 20 20 2a 2f 0a 20 20 73 6b 69 70 20  es..  */.  skip 
0cf0: 3d 20 32 3b 0a 0a 20 20 2f 2a 20 57 72 69 74 65  = 2;..  /* Write
0d00: 20 74 68 65 20 63 6f 6d 70 72 65 73 73 65 64 20   the compressed 
0d10: 66 69 6c 65 2e 20 20 43 6f 6d 70 75 74 65 20 74  file.  Compute t
0d20: 68 65 20 43 52 43 20 61 73 20 77 65 20 70 72 6f  he CRC as we pro
0d30: 67 72 65 73 73 2e 0a 20 20 2a 2f 0a 20 20 73 74  gress..  */.  st
0d40: 72 65 61 6d 2e 7a 61 6c 6c 6f 63 20 3d 20 28 61  ream.zalloc = (a
0d50: 6c 6c 6f 63 5f 66 75 6e 63 29 30 3b 0a 20 20 73  lloc_func)0;.  s
0d60: 74 72 65 61 6d 2e 7a 66 72 65 65 20 3d 20 28 66  tream.zfree = (f
0d70: 72 65 65 5f 66 75 6e 63 29 30 3b 0a 20 20 73 74  ree_func)0;.  st
0d80: 72 65 61 6d 2e 6f 70 61 71 75 65 20 3d 20 30 3b  ream.opaque = 0;
0d90: 0a 20 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f  .  stream.avail_
0da0: 69 6e 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 70  in = blob_size(p
0db0: 46 69 6c 65 29 3b 0a 20 20 73 74 72 65 61 6d 2e  File);.  stream.
0dc0: 6e 65 78 74 5f 69 6e 20 3d 20 28 75 6e 73 69 67  next_in = (unsig
0dd0: 6e 65 64 20 63 68 61 72 2a 29 62 6c 6f 62 5f 62  ned char*)blob_b
0de0: 75 66 66 65 72 28 70 46 69 6c 65 29 3b 0a 20 20  uffer(pFile);.  
0df0: 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f 75 74  stream.avail_out
0e00: 20 3d 20 73 69 7a 65 6f 66 28 7a 4f 75 74 42 75   = sizeof(zOutBu
0e10: 66 29 3b 0a 20 20 73 74 72 65 61 6d 2e 6e 65 78  f);.  stream.nex
0e20: 74 5f 6f 75 74 20 3d 20 28 75 6e 73 69 67 6e 65  t_out = (unsigne
0e30: 64 20 63 68 61 72 2a 29 7a 4f 75 74 42 75 66 3b  d char*)zOutBuf;
0e40: 0a 20 20 64 65 66 6c 61 74 65 49 6e 69 74 28 26  .  deflateInit(&
0e50: 73 74 72 65 61 6d 2c 20 39 29 3b 0a 20 20 69 43  stream, 9);.  iC
0e60: 52 43 20 3d 20 63 72 63 33 32 28 30 2c 20 73 74  RC = crc32(0, st
0e70: 72 65 61 6d 2e 6e 65 78 74 5f 69 6e 2c 20 73 74  ream.next_in, st
0e80: 72 65 61 6d 2e 61 76 61 69 6c 5f 69 6e 29 3b 0a  ream.avail_in);.
0e90: 20 20 77 68 69 6c 65 28 20 73 74 72 65 61 6d 2e    while( stream.
0ea0: 61 76 61 69 6c 5f 69 6e 3e 30 20 29 7b 0a 20 20  avail_in>0 ){.  
0eb0: 20 20 64 65 66 6c 61 74 65 28 26 73 74 72 65 61    deflate(&strea
0ec0: 6d 2c 20 30 29 3b 0a 20 20 20 20 74 6f 4f 75 74  m, 0);.    toOut
0ed0: 20 3d 20 73 69 7a 65 6f 66 28 7a 4f 75 74 42 75   = sizeof(zOutBu
0ee0: 66 29 20 2d 20 73 74 72 65 61 6d 2e 61 76 61 69  f) - stream.avai
0ef0: 6c 5f 6f 75 74 3b 0a 20 20 20 20 69 66 28 20 74  l_out;.    if( t
0f00: 6f 4f 75 74 3e 73 6b 69 70 20 29 7b 0a 20 20 20  oOut>skip ){.   
0f10: 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26     blob_append(&
0f20: 62 6f 64 79 2c 20 26 7a 4f 75 74 42 75 66 5b 73  body, &zOutBuf[s
0f30: 6b 69 70 5d 2c 20 74 6f 4f 75 74 20 2d 20 73 6b  kip], toOut - sk
0f40: 69 70 29 3b 0a 20 20 20 20 20 20 73 6b 69 70 20  ip);.      skip 
0f50: 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  = 0;.    }else{.
0f60: 20 20 20 20 20 20 73 6b 69 70 20 2d 3d 20 74 6f        skip -= to
0f70: 4f 75 74 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73  Out;.    }.    s
0f80: 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f 75 74 20  tream.avail_out 
0f90: 3d 20 73 69 7a 65 6f 66 28 7a 4f 75 74 42 75 66  = sizeof(zOutBuf
0fa0: 29 3b 0a 20 20 20 20 73 74 72 65 61 6d 2e 6e 65  );.    stream.ne
0fb0: 78 74 5f 6f 75 74 20 3d 20 28 75 6e 73 69 67 6e  xt_out = (unsign
0fc0: 65 64 20 63 68 61 72 2a 29 7a 4f 75 74 42 75 66  ed char*)zOutBuf
0fd0: 3b 0a 20 20 7d 0a 20 20 64 6f 7b 0a 20 20 20 20  ;.  }.  do{.    
0fe0: 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f 75 74  stream.avail_out
0ff0: 20 3d 20 73 69 7a 65 6f 66 28 7a 4f 75 74 42 75   = sizeof(zOutBu
1000: 66 29 3b 0a 20 20 20 20 73 74 72 65 61 6d 2e 6e  f);.    stream.n
1010: 65 78 74 5f 6f 75 74 20 3d 20 28 75 6e 73 69 67  ext_out = (unsig
1020: 6e 65 64 20 63 68 61 72 2a 29 7a 4f 75 74 42 75  ned char*)zOutBu
1030: 66 3b 0a 20 20 20 20 64 65 66 6c 61 74 65 28 26  f;.    deflate(&
1040: 73 74 72 65 61 6d 2c 20 5a 5f 46 49 4e 49 53 48  stream, Z_FINISH
1050: 29 3b 0a 20 20 20 20 74 6f 4f 75 74 20 3d 20 73  );.    toOut = s
1060: 69 7a 65 6f 66 28 7a 4f 75 74 42 75 66 29 20 2d  izeof(zOutBuf) -
1070: 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f 75   stream.avail_ou
1080: 74 3b 0a 20 20 20 20 69 66 28 20 74 6f 4f 75 74  t;.    if( toOut
1090: 3e 73 6b 69 70 20 29 7b 0a 20 20 20 20 20 20 62  >skip ){.      b
10a0: 6c 6f 62 5f 61 70 70 65 6e 64 28 26 62 6f 64 79  lob_append(&body
10b0: 2c 20 26 7a 4f 75 74 42 75 66 5b 73 6b 69 70 5d  , &zOutBuf[skip]
10c0: 2c 20 74 6f 4f 75 74 20 2d 20 73 6b 69 70 29 3b  , toOut - skip);
10d0: 0a 20 20 20 20 20 20 73 6b 69 70 20 3d 20 30 3b  .      skip = 0;
10e0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
10f0: 20 20 73 6b 69 70 20 2d 3d 20 74 6f 4f 75 74 3b    skip -= toOut;
1100: 0a 20 20 20 20 7d 0a 20 20 7d 77 68 69 6c 65 28  .    }.  }while(
1110: 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f 75   stream.avail_ou
1120: 74 3d 3d 30 20 29 3b 0a 20 20 6e 42 79 74 65 20  t==0 );.  nByte 
1130: 3d 20 73 74 72 65 61 6d 2e 74 6f 74 61 6c 5f 69  = stream.total_i
1140: 6e 3b 0a 20 20 6e 42 79 74 65 43 6f 6d 70 72 20  n;.  nByteCompr 
1150: 3d 20 73 74 72 65 61 6d 2e 74 6f 74 61 6c 5f 6f  = stream.total_o
1160: 75 74 20 2d 20 32 3b 0a 20 20 64 65 66 6c 61 74  ut - 2;.  deflat
1170: 65 45 6e 64 28 26 73 74 72 65 61 6d 29 3b 0a 0a  eEnd(&stream);..
1180: 20 20 2f 2a 20 47 6f 20 62 61 63 6b 20 61 6e 64    /* Go back and
1190: 20 77 72 69 74 65 20 74 68 65 20 68 65 61 64 65   write the heade
11a0: 72 2c 20 6e 6f 77 20 74 68 61 74 20 77 65 20 6b  r, now that we k
11b0: 6e 6f 77 20 74 68 65 20 63 6f 6d 70 72 65 73 73  now the compress
11c0: 65 64 20 66 69 6c 65 20 73 69 7a 65 2e 0a 20 20  ed file size..  
11d0: 2a 2f 0a 20 20 7a 20 3d 20 26 62 6c 6f 62 5f 62  */.  z = &blob_b
11e0: 75 66 66 65 72 28 26 62 6f 64 79 29 5b 69 53 74  uffer(&body)[iSt
11f0: 61 72 74 5d 3b 0a 20 20 70 75 74 33 32 28 26 7a  art];.  put32(&z
1200: 5b 31 34 5d 2c 20 69 43 52 43 29 3b 0a 20 20 70  [14], iCRC);.  p
1210: 75 74 33 32 28 26 7a 5b 31 38 5d 2c 20 6e 42 79  ut32(&z[18], nBy
1220: 74 65 43 6f 6d 70 72 29 3b 0a 20 20 70 75 74 33  teCompr);.  put3
1230: 32 28 26 7a 5b 32 32 5d 2c 20 6e 42 79 74 65 29  2(&z[22], nByte)
1240: 3b 0a 0a 20 20 2f 2a 20 4d 61 6b 65 20 61 6e 20  ;..  /* Make an 
1250: 65 6e 74 72 79 20 69 6e 20 74 68 65 20 74 61 62  entry in the tab
1260: 6c 65 73 20 6f 66 20 63 6f 6e 74 65 6e 74 73 0a  les of contents.
1270: 20 20 2a 2f 0a 20 20 6d 65 6d 73 65 74 28 7a 42    */.  memset(zB
1280: 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28 7a 42  uf, 0, sizeof(zB
1290: 75 66 29 29 3b 0a 20 20 70 75 74 33 32 28 26 7a  uf));.  put32(&z
12a0: 42 75 66 5b 30 5d 2c 20 30 78 30 32 30 31 34 62  Buf[0], 0x02014b
12b0: 35 30 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 42  50);.  put16(&zB
12c0: 75 66 5b 34 5d 2c 20 30 78 30 33 31 37 29 3b 0a  uf[4], 0x0317);.
12d0: 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 36 5d    put16(&zBuf[6]
12e0: 2c 20 30 78 30 30 31 34 29 3b 0a 20 20 70 75 74  , 0x0014);.  put
12f0: 31 36 28 26 7a 42 75 66 5b 38 5d 2c 20 30 29 3b  16(&zBuf[8], 0);
1300: 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 31  .  put16(&zBuf[1
1310: 30 5d 2c 20 30 78 30 30 30 38 29 3b 0a 20 20 70  0], 0x0008);.  p
1320: 75 74 31 36 28 26 7a 42 75 66 5b 31 32 5d 2c 20  ut16(&zBuf[12], 
1330: 64 6f 73 54 69 6d 65 29 3b 0a 20 20 70 75 74 31  dosTime);.  put1
1340: 36 28 26 7a 42 75 66 5b 31 34 5d 2c 20 64 6f 73  6(&zBuf[14], dos
1350: 44 61 74 65 29 3b 0a 20 20 70 75 74 33 32 28 26  Date);.  put32(&
1360: 7a 42 75 66 5b 31 36 5d 2c 20 69 43 52 43 29 3b  zBuf[16], iCRC);
1370: 0a 20 20 70 75 74 33 32 28 26 7a 42 75 66 5b 32  .  put32(&zBuf[2
1380: 30 5d 2c 20 6e 42 79 74 65 43 6f 6d 70 72 29 3b  0], nByteCompr);
1390: 0a 20 20 70 75 74 33 32 28 26 7a 42 75 66 5b 32  .  put32(&zBuf[2
13a0: 34 5d 2c 20 6e 42 79 74 65 29 3b 0a 20 20 70 75  4], nByte);.  pu
13b0: 74 31 36 28 26 7a 42 75 66 5b 32 38 5d 2c 20 6e  t16(&zBuf[28], n
13c0: 61 6d 65 4c 65 6e 29 3b 0a 20 20 70 75 74 31 36  ameLen);.  put16
13d0: 28 26 7a 42 75 66 5b 33 30 5d 2c 20 30 29 3b 0a  (&zBuf[30], 0);.
13e0: 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 33 32    put16(&zBuf[32
13f0: 5d 2c 20 30 29 3b 0a 20 20 70 75 74 31 36 28 26  ], 0);.  put16(&
1400: 7a 42 75 66 5b 33 34 5d 2c 20 31 29 3b 0a 20 20  zBuf[34], 1);.  
1410: 70 75 74 31 36 28 26 7a 42 75 66 5b 33 36 5d 2c  put16(&zBuf[36],
1420: 20 30 29 3b 0a 20 20 70 75 74 33 32 28 26 7a 42   0);.  put32(&zB
1430: 75 66 5b 33 38 5d 2c 20 28 30 31 30 30 30 30 30  uf[38], (0100000
1440: 20 7c 20 30 36 34 34 29 3c 3c 31 36 29 3b 0a 20   | 0644)<<16);. 
1450: 20 70 75 74 33 32 28 26 7a 42 75 66 5b 34 32 5d   put32(&zBuf[42]
1460: 2c 20 69 53 74 61 72 74 29 3b 0a 20 20 62 6c 6f  , iStart);.  blo
1470: 62 5f 61 70 70 65 6e 64 28 26 74 6f 63 2c 20 7a  b_append(&toc, z
1480: 42 75 66 2c 20 34 36 29 3b 0a 20 20 62 6c 6f 62  Buf, 46);.  blob
1490: 5f 61 70 70 65 6e 64 28 26 74 6f 63 2c 20 7a 4e  _append(&toc, zN
14a0: 61 6d 65 2c 20 6e 61 6d 65 4c 65 6e 29 3b 0a 20  ame, nameLen);. 
14b0: 20 6e 45 6e 74 72 79 2b 2b 3b 0a 7d 0a 0a 0a 2f   nEntry++;.}.../
14c0: 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68 65 20 5a  *.** Write the Z
14d0: 49 50 20 61 72 63 68 69 76 65 20 69 6e 74 6f 20  IP archive into 
14e0: 74 68 65 20 67 69 76 65 6e 20 42 4c 4f 42 2e 0a  the given BLOB..
14f0: 2a 2f 0a 76 6f 69 64 20 7a 69 70 5f 63 6c 6f 73  */.void zip_clos
1500: 65 28 42 6c 6f 62 20 2a 70 5a 69 70 29 7b 0a 20  e(Blob *pZip){. 
1510: 20 69 6e 74 20 69 54 6f 63 53 74 61 72 74 3b 0a   int iTocStart;.
1520: 20 20 69 6e 74 20 69 54 6f 63 45 6e 64 3b 0a 20    int iTocEnd;. 
1530: 20 63 68 61 72 20 7a 42 75 66 5b 33 30 5d 3b 0a   char zBuf[30];.
1540: 0a 20 20 69 54 6f 63 53 74 61 72 74 20 3d 20 62  .  iTocStart = b
1550: 6c 6f 62 5f 73 69 7a 65 28 26 62 6f 64 79 29 3b  lob_size(&body);
1560: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26  .  blob_append(&
1570: 62 6f 64 79 2c 20 62 6c 6f 62 5f 62 75 66 66 65  body, blob_buffe
1580: 72 28 26 74 6f 63 29 2c 20 62 6c 6f 62 5f 73 69  r(&toc), blob_si
1590: 7a 65 28 26 74 6f 63 29 29 3b 0a 20 20 69 54 6f  ze(&toc));.  iTo
15a0: 63 45 6e 64 20 3d 20 62 6c 6f 62 5f 73 69 7a 65  cEnd = blob_size
15b0: 28 26 62 6f 64 79 29 3b 0a 0a 20 20 6d 65 6d 73  (&body);..  mems
15c0: 65 74 28 7a 42 75 66 2c 20 30 2c 20 73 69 7a 65  et(zBuf, 0, size
15d0: 6f 66 28 7a 42 75 66 29 29 3b 0a 20 20 70 75 74  of(zBuf));.  put
15e0: 33 32 28 26 7a 42 75 66 5b 30 5d 2c 20 30 78 30  32(&zBuf[0], 0x0
15f0: 36 30 35 34 62 35 30 29 3b 0a 20 20 70 75 74 31  6054b50);.  put1
1600: 36 28 26 7a 42 75 66 5b 34 5d 2c 20 30 29 3b 0a  6(&zBuf[4], 0);.
1610: 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 36 5d    put16(&zBuf[6]
1620: 2c 20 30 29 3b 0a 20 20 70 75 74 31 36 28 26 7a  , 0);.  put16(&z
1630: 42 75 66 5b 38 5d 2c 20 6e 45 6e 74 72 79 29 3b  Buf[8], nEntry);
1640: 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 31  .  put16(&zBuf[1
1650: 30 5d 2c 20 6e 45 6e 74 72 79 29 3b 0a 20 20 70  0], nEntry);.  p
1660: 75 74 33 32 28 26 7a 42 75 66 5b 31 32 5d 2c 20  ut32(&zBuf[12], 
1670: 69 54 6f 63 45 6e 64 20 2d 20 69 54 6f 63 53 74  iTocEnd - iTocSt
1680: 61 72 74 29 3b 0a 20 20 70 75 74 33 32 28 26 7a  art);.  put32(&z
1690: 42 75 66 5b 31 36 5d 2c 20 69 54 6f 63 53 74 61  Buf[16], iTocSta
16a0: 72 74 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 42  rt);.  put16(&zB
16b0: 75 66 5b 32 30 5d 2c 20 30 29 3b 0a 20 20 62 6c  uf[20], 0);.  bl
16c0: 6f 62 5f 61 70 70 65 6e 64 28 26 62 6f 64 79 2c  ob_append(&body,
16d0: 20 7a 42 75 66 2c 20 32 32 29 3b 0a 20 20 62 6c   zBuf, 22);.  bl
16e0: 6f 62 5f 72 65 73 65 74 28 26 74 6f 63 29 3b 0a  ob_reset(&toc);.
16f0: 20 20 2a 70 5a 69 70 20 3d 20 62 6f 64 79 3b 0a    *pZip = body;.
1700: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 62 6f 64    blob_zero(&bod
1710: 79 29 3b 0a 20 20 6e 45 6e 74 72 79 20 3d 20 30  y);.  nEntry = 0
1720: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41  ;.}../*.** COMMA
1730: 4e 44 3a 20 74 65 73 74 2d 66 69 6c 65 7a 69 70  ND: test-filezip
1740: 0a 2a 2a 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20  .**.** Generate 
1750: 61 20 5a 49 50 20 61 72 63 68 69 76 65 20 73 70  a ZIP archive sp
1760: 65 63 69 66 69 65 64 20 62 79 20 74 68 65 20 66  ecified by the f
1770: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74 68  irst argument th
1780: 61 74 0a 2a 2a 20 63 6f 6e 74 61 69 6e 73 20 66  at.** contains f
1790: 69 6c 65 73 20 67 69 76 65 6e 20 69 6e 20 74 68  iles given in th
17a0: 65 20 73 65 63 6f 6e 64 20 61 6e 64 20 73 75 62  e second and sub
17b0: 73 65 71 75 65 6e 74 20 61 72 67 75 6d 65 6e 74  sequent argument
17c0: 73 2e 0a 2a 2f 0a 76 6f 69 64 20 66 69 6c 65 7a  s..*/.void filez
17d0: 69 70 5f 63 6d 64 28 76 6f 69 64 29 7b 0a 20 20  ip_cmd(void){.  
17e0: 69 6e 74 20 69 3b 0a 20 20 42 6c 6f 62 20 7a 69  int i;.  Blob zi
17f0: 70 3b 0a 20 20 42 6c 6f 62 20 66 69 6c 65 3b 0a  p;.  Blob file;.
1800: 20 20 69 66 28 20 67 2e 61 72 67 63 3c 33 20 29    if( g.argc<3 )
1810: 7b 0a 20 20 20 20 75 73 61 67 65 28 22 41 52 43  {.    usage("ARC
1820: 48 49 56 45 20 46 49 4c 45 2e 2e 2e 2e 22 29 3b  HIVE FILE....");
1830: 0a 20 20 7d 0a 20 20 7a 69 70 5f 6f 70 65 6e 28  .  }.  zip_open(
1840: 29 3b 0a 20 20 66 6f 72 28 69 3d 33 3b 20 69 3c  );.  for(i=3; i<
1850: 67 2e 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20  g.argc; i++){.  
1860: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 66 69 6c    blob_zero(&fil
1870: 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 61  e);.    blob_rea
1880: 64 5f 66 72 6f 6d 5f 66 69 6c 65 28 26 66 69 6c  d_from_file(&fil
1890: 65 2c 20 67 2e 61 72 67 76 5b 69 5d 29 3b 0a 20  e, g.argv[i]);. 
18a0: 20 20 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65 28     zip_add_file(
18b0: 67 2e 61 72 67 76 5b 69 5d 2c 20 26 66 69 6c 65  g.argv[i], &file
18c0: 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65  );.    blob_rese
18d0: 74 28 26 66 69 6c 65 29 3b 0a 20 20 7d 0a 20 20  t(&file);.  }.  
18e0: 7a 69 70 5f 63 6c 6f 73 65 28 26 7a 69 70 29 3b  zip_close(&zip);
18f0: 0a 20 20 62 6c 6f 62 5f 77 72 69 74 65 5f 74 6f  .  blob_write_to
1900: 5f 66 69 6c 65 28 26 7a 69 70 2c 20 67 2e 61 72  _file(&zip, g.ar
1910: 67 76 5b 32 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  gv[2]);.}../*.**
1920: 20 47 69 76 65 6e 20 74 68 65 20 52 49 44 20 66   Given the RID f
1930: 6f 72 20 61 20 6d 61 6e 69 66 65 73 74 2c 20 63  or a manifest, c
1940: 6f 6e 73 74 72 75 63 74 20 61 20 5a 49 50 20 61  onstruct a ZIP a
1950: 72 63 68 69 76 65 20 63 6f 6e 74 61 69 6e 69 6e  rchive containin
1960: 67 0a 2a 2a 20 61 6c 6c 20 66 69 6c 65 73 20 69  g.** all files i
1970: 6e 20 74 68 65 20 63 6f 72 72 65 73 70 6f 6e 64  n the correspond
1980: 69 6e 67 20 62 61 73 65 6c 69 6e 65 2e 0a 2a 2a  ing baseline..**
1990: 0a 2a 2a 20 49 66 20 52 49 44 20 69 73 20 66 6f  .** If RID is fo
19a0: 72 20 61 6e 20 6f 62 6a 65 63 74 20 74 68 61 74  r an object that
19b0: 20 69 73 20 6e 6f 74 20 61 20 72 65 61 6c 20 6d   is not a real m
19c0: 61 6e 69 66 65 73 74 2c 20 74 68 65 6e 20 74 68  anifest, then th
19d0: 65 0a 2a 2a 20 72 65 73 75 6c 74 69 6e 67 20 5a  e.** resulting Z
19e0: 49 50 20 61 72 63 68 69 76 65 20 63 6f 6e 74 61  IP archive conta
19f0: 69 6e 73 20 61 20 73 69 6e 67 6c 65 20 66 69 6c  ins a single fil
1a00: 65 20 77 68 69 63 68 20 69 73 20 74 68 65 20 52  e which is the R
1a10: 49 44 0a 2a 2a 20 6f 62 6a 65 63 74 2e 0a 2a 2a  ID.** object..**
1a20: 0a 2a 2a 20 49 66 20 74 68 65 20 52 49 44 20 6f  .** If the RID o
1a30: 62 6a 65 63 74 20 64 6f 65 73 20 6e 6f 74 20 65  bject does not e
1a40: 78 69 73 74 20 69 6e 20 74 68 65 20 72 65 70 6f  xist in the repo
1a50: 73 69 74 6f 72 79 2c 20 74 68 65 6e 0a 2a 2a 20  sitory, then.** 
1a60: 70 5a 69 70 20 69 73 20 7a 65 72 6f 65 64 2e 0a  pZip is zeroed..
1a70: 2a 2f 0a 76 6f 69 64 20 7a 69 70 5f 6f 66 5f 62  */.void zip_of_b
1a80: 61 73 65 6c 69 6e 65 28 69 6e 74 20 72 69 64 2c  aseline(int rid,
1a90: 20 42 6c 6f 62 20 2a 70 5a 69 70 29 7b 0a 20 20   Blob *pZip){.  
1aa0: 69 6e 74 20 69 3b 0a 20 20 42 6c 6f 62 20 6d 66  int i;.  Blob mf
1ab0: 69 6c 65 2c 20 66 69 6c 65 2c 20 68 61 73 68 3b  ile, file, hash;
1ac0: 0a 20 20 4d 61 6e 69 66 65 73 74 20 6d 3b 0a 0a  .  Manifest m;..
1ad0: 20 20 63 6f 6e 74 65 6e 74 5f 67 65 74 28 72 69    content_get(ri
1ae0: 64 2c 20 26 6d 66 69 6c 65 29 3b 0a 20 20 69 66  d, &mfile);.  if
1af0: 28 20 62 6c 6f 62 5f 73 69 7a 65 28 26 6d 66 69  ( blob_size(&mfi
1b00: 6c 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 62 6c  le)==0 ){.    bl
1b10: 6f 62 5f 7a 65 72 6f 28 70 5a 69 70 29 3b 0a 20  ob_zero(pZip);. 
1b20: 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20     return;.  }. 
1b30: 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 66 69 6c 65   blob_zero(&file
1b40: 29 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26  );.  blob_zero(&
1b50: 68 61 73 68 29 3b 0a 20 20 62 6c 6f 62 5f 63 6f  hash);.  blob_co
1b60: 70 79 28 26 66 69 6c 65 2c 20 26 6d 66 69 6c 65  py(&file, &mfile
1b70: 29 3b 0a 20 20 7a 69 70 5f 6f 70 65 6e 28 29 3b  );.  zip_open();
1b80: 0a 20 20 69 66 28 20 6d 61 6e 69 66 65 73 74 5f  .  if( manifest_
1b90: 70 61 72 73 65 28 26 6d 2c 20 26 6d 66 69 6c 65  parse(&m, &mfile
1ba0: 29 20 29 7b 0a 20 20 20 20 7a 69 70 5f 73 65 74  ) ){.    zip_set
1bb0: 5f 74 69 6d 65 64 61 74 65 28 6d 2e 72 44 61 74  _timedate(m.rDat
1bc0: 65 29 3b 0a 20 20 20 20 7a 69 70 5f 61 64 64 5f  e);.    zip_add_
1bd0: 66 69 6c 65 28 22 6d 61 6e 69 66 65 73 74 22 2c  file("manifest",
1be0: 20 26 66 69 6c 65 29 3b 0a 20 20 20 20 73 68 61   &file);.    sha
1bf0: 31 73 75 6d 5f 62 6c 6f 62 28 26 66 69 6c 65 2c  1sum_blob(&file,
1c00: 20 26 68 61 73 68 29 3b 0a 20 20 20 20 62 6c 6f   &hash);.    blo
1c10: 62 5f 72 65 73 65 74 28 26 66 69 6c 65 29 3b 0a  b_reset(&file);.
1c20: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28      blob_append(
1c30: 26 68 61 73 68 2c 20 22 5c 6e 22 2c 20 31 29 3b  &hash, "\n", 1);
1c40: 0a 20 20 20 20 7a 69 70 5f 61 64 64 5f 66 69 6c  .    zip_add_fil
1c50: 65 28 22 6d 61 6e 69 66 65 73 74 2e 75 75 69 64  e("manifest.uuid
1c60: 22 2c 20 26 68 61 73 68 29 3b 0a 20 20 20 20 62  ", &hash);.    b
1c70: 6c 6f 62 5f 72 65 73 65 74 28 26 68 61 73 68 29  lob_reset(&hash)
1c80: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69  ;.    for(i=0; i
1c90: 3c 6d 2e 6e 46 69 6c 65 3b 20 69 2b 2b 29 7b 0a  <m.nFile; i++){.
1ca0: 20 20 20 20 20 20 69 6e 74 20 66 69 64 20 3d 20        int fid = 
1cb0: 75 75 69 64 5f 74 6f 5f 72 69 64 28 6d 2e 61 46  uuid_to_rid(m.aF
1cc0: 69 6c 65 5b 69 5d 2e 7a 55 75 69 64 2c 20 30 29  ile[i].zUuid, 0)
1cd0: 3b 0a 20 20 20 20 20 20 69 66 28 20 66 69 64 20  ;.      if( fid 
1ce0: 29 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e 74 65  ){.        conte
1cf0: 6e 74 5f 67 65 74 28 66 69 64 2c 20 26 66 69 6c  nt_get(fid, &fil
1d00: 65 29 3b 0a 20 20 20 20 20 20 20 20 7a 69 70 5f  e);.        zip_
1d10: 61 64 64 5f 66 69 6c 65 28 6d 2e 61 46 69 6c 65  add_file(m.aFile
1d20: 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 26 66 69 6c 65  [i].zName, &file
1d30: 29 3b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f  );.        blob_
1d40: 72 65 73 65 74 28 26 66 69 6c 65 29 3b 0a 20 20  reset(&file);.  
1d50: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
1d60: 6d 61 6e 69 66 65 73 74 5f 63 6c 65 61 72 28 26  manifest_clear(&
1d70: 6d 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  m);.  }else{.   
1d80: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 6d 66 69   blob_reset(&mfi
1d90: 6c 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65  le);.    blob_re
1da0: 73 65 74 28 26 66 69 6c 65 29 3b 0a 20 20 7d 0a  set(&file);.  }.
1db0: 20 20 7a 69 70 5f 63 6c 6f 73 65 28 70 5a 69 70    zip_close(pZip
1dc0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d  );.}../*.** COMM
1dd0: 41 4e 44 3a 20 74 65 73 74 2d 62 61 73 65 6c 69  AND: test-baseli
1de0: 6e 65 2d 7a 69 70 0a 2a 2a 0a 2a 2a 20 47 65 6e  ne-zip.**.** Gen
1df0: 65 72 61 74 65 20 61 20 5a 49 50 20 61 72 63 68  erate a ZIP arch
1e00: 69 76 65 20 66 6f 72 20 61 20 73 70 65 63 69 66  ive for a specif
1e10: 69 65 64 20 62 61 73 65 6c 69 6e 65 2e 0a 2a 2f  ied baseline..*/
1e20: 0a 76 6f 69 64 20 62 61 73 65 6c 69 6e 65 5f 7a  .void baseline_z
1e30: 69 70 5f 63 6d 64 28 76 6f 69 64 29 7b 0a 20 20  ip_cmd(void){.  
1e40: 69 6e 74 20 72 69 64 3b 0a 20 20 42 6c 6f 62 20  int rid;.  Blob 
1e50: 7a 69 70 3b 0a 20 20 69 66 28 20 67 2e 61 72 67  zip;.  if( g.arg
1e60: 63 21 3d 34 20 29 7b 0a 20 20 20 20 75 73 61 67  c!=4 ){.    usag
1e70: 65 28 22 55 55 49 44 20 5a 49 50 46 49 4c 45 22  e("UUID ZIPFILE"
1e80: 29 3b 0a 20 20 7d 0a 20 20 64 62 5f 6d 75 73 74  );.  }.  db_must
1e90: 5f 62 65 5f 77 69 74 68 69 6e 5f 74 72 65 65 28  _be_within_tree(
1ea0: 29 3b 0a 20 20 72 69 64 20 3d 20 6e 61 6d 65 5f  );.  rid = name_
1eb0: 74 6f 5f 72 69 64 28 67 2e 61 72 67 76 5b 32 5d  to_rid(g.argv[2]
1ec0: 29 3b 0a 20 20 7a 69 70 5f 6f 66 5f 62 61 73 65  );.  zip_of_base
1ed0: 6c 69 6e 65 28 72 69 64 2c 20 26 7a 69 70 29 3b  line(rid, &zip);
1ee0: 0a 20 20 62 6c 6f 62 5f 77 72 69 74 65 5f 74 6f  .  blob_write_to
1ef0: 5f 66 69 6c 65 28 26 7a 69 70 2c 20 67 2e 61 72  _file(&zip, g.ar
1f00: 67 76 5b 33 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  gv[3]);.}../*.**
1f10: 20 57 45 42 50 41 47 45 3a 20 7a 69 70 0a 2a 2a   WEBPAGE: zip.**
1f20: 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20 61 20 5a  .** Generate a Z
1f30: 49 50 20 61 72 63 68 69 76 65 20 66 6f 72 20 74  IP archive for t
1f40: 68 65 20 62 61 73 65 6c 69 6e 65 20 73 70 65 63  he baseline spec
1f50: 69 66 69 65 64 20 62 79 20 67 2e 7a 45 78 74 72  ified by g.zExtr
1f60: 61 0a 2a 2a 20 61 6e 64 20 72 65 74 75 72 6e 20  a.** and return 
1f70: 74 68 61 74 20 5a 49 50 20 61 72 63 68 69 76 65  that ZIP archive
1f80: 20 61 73 20 74 68 65 20 48 54 54 50 20 72 65 70   as the HTTP rep
1f90: 6c 79 20 63 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 76  ly content..*/.v
1fa0: 6f 69 64 20 62 61 73 65 6c 69 6e 65 5f 7a 69 70  oid baseline_zip
1fb0: 5f 70 61 67 65 28 76 6f 69 64 29 7b 0a 20 20 69  _page(void){.  i
1fc0: 6e 74 20 72 69 64 3b 0a 20 20 63 68 61 72 20 2a  nt rid;.  char *
1fd0: 7a 4e 61 6d 65 3b 0a 20 20 69 6e 74 20 69 3b 0a  zName;.  int i;.
1fe0: 20 20 42 6c 6f 62 20 7a 69 70 3b 0a 0a 20 20 6c    Blob zip;..  l
1ff0: 6f 67 69 6e 5f 63 68 65 63 6b 5f 63 72 65 64 65  ogin_check_crede
2000: 6e 74 69 61 6c 73 28 29 3b 0a 20 20 69 66 28 20  ntials();.  if( 
2010: 21 67 2e 6f 6b 52 65 61 64 20 7c 7c 20 21 67 2e  !g.okRead || !g.
2020: 6f 6b 48 69 73 74 6f 72 79 20 29 7b 20 6c 6f 67  okHistory ){ log
2030: 69 6e 5f 6e 65 65 64 65 64 28 29 3b 20 72 65 74  in_needed(); ret
2040: 75 72 6e 3b 20 7d 0a 20 20 7a 4e 61 6d 65 20 3d  urn; }.  zName =
2050: 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 67   mprintf("%s", g
2060: 2e 7a 45 78 74 72 61 29 3b 0a 20 20 69 20 3d 20  .zExtra);.  i = 
2070: 73 74 72 6c 65 6e 28 7a 4e 61 6d 65 29 3b 0a 20  strlen(zName);. 
2080: 20 66 6f 72 28 69 3d 73 74 72 6c 65 6e 28 7a 4e   for(i=strlen(zN
2090: 61 6d 65 29 2d 31 3b 20 69 3e 35 3b 20 69 2d 2d  ame)-1; i>5; i--
20a0: 29 7b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65  ){.    if( zName
20b0: 5b 69 5d 3d 3d 27 2e 27 20 29 7b 0a 20 20 20 20  [i]=='.' ){.    
20c0: 20 20 7a 4e 61 6d 65 5b 69 5d 20 3d 20 30 3b 0a    zName[i] = 0;.
20d0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
20e0: 20 7d 0a 20 20 7d 0a 20 20 72 69 64 20 3d 20 6e   }.  }.  rid = n
20f0: 61 6d 65 5f 74 6f 5f 72 69 64 28 7a 4e 61 6d 65  ame_to_rid(zName
2100: 29 3b 0a 20 20 69 66 28 20 72 69 64 3d 3d 30 20  );.  if( rid==0 
2110: 29 7b 0a 20 20 20 20 40 20 4e 6f 74 20 66 6f 75  ){.    @ Not fou
2120: 6e 64 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a 20  nd.    return;. 
2130: 20 7d 0a 20 20 7a 69 70 5f 6f 66 5f 62 61 73 65   }.  zip_of_base
2140: 6c 69 6e 65 28 72 69 64 2c 20 26 7a 69 70 29 3b  line(rid, &zip);
2150: 0a 20 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74 65  .  cgi_set_conte
2160: 6e 74 28 26 7a 69 70 29 3b 0a 20 20 63 67 69 5f  nt(&zip);.  cgi_
2170: 73 65 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70 65  set_content_type
2180: 28 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 7a 69  ("application/zi
2190: 70 22 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79  p");.  cgi_reply
21a0: 28 29 3b 0a 7d 0a                                ();.}.