Hex Artifact Content
Not logged in

Artifact df3f3d2e3919faa5e5fcf62e99de9534d19f1d07:

File src/zip.c part of check-in [7ae01ee47b] - fixed an 'integer overflow' warning from the Sun compiler. Thank to Kevin for the tip. by stephan on 2008-09-19 11:11:01.

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 28 75 6e 73 69 67 6e  uf[38], ((unsign
1440: 65 64 29 28 30 31 30 30 30 30 30 20 7c 20 30 36  ed)(0100000 | 06
1450: 34 34 29 29 3c 3c 31 36 29 3b 0a 20 20 70 75 74  44))<<16);.  put
1460: 33 32 28 26 7a 42 75 66 5b 34 32 5d 2c 20 69 53  32(&zBuf[42], iS
1470: 74 61 72 74 29 3b 0a 20 20 62 6c 6f 62 5f 61 70  tart);.  blob_ap
1480: 70 65 6e 64 28 26 74 6f 63 2c 20 7a 42 75 66 2c  pend(&toc, zBuf,
1490: 20 34 36 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70   46);.  blob_app
14a0: 65 6e 64 28 26 74 6f 63 2c 20 7a 4e 61 6d 65 2c  end(&toc, zName,
14b0: 20 6e 61 6d 65 4c 65 6e 29 3b 0a 20 20 6e 45 6e   nameLen);.  nEn
14c0: 74 72 79 2b 2b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a  try++;.}.../*.**
14d0: 20 57 72 69 74 65 20 74 68 65 20 5a 49 50 20 61   Write the ZIP a
14e0: 72 63 68 69 76 65 20 69 6e 74 6f 20 74 68 65 20  rchive into the 
14f0: 67 69 76 65 6e 20 42 4c 4f 42 2e 0a 2a 2f 0a 76  given BLOB..*/.v
1500: 6f 69 64 20 7a 69 70 5f 63 6c 6f 73 65 28 42 6c  oid zip_close(Bl
1510: 6f 62 20 2a 70 5a 69 70 29 7b 0a 20 20 69 6e 74  ob *pZip){.  int
1520: 20 69 54 6f 63 53 74 61 72 74 3b 0a 20 20 69 6e   iTocStart;.  in
1530: 74 20 69 54 6f 63 45 6e 64 3b 0a 20 20 63 68 61  t iTocEnd;.  cha
1540: 72 20 7a 42 75 66 5b 33 30 5d 3b 0a 0a 20 20 69  r zBuf[30];..  i
1550: 54 6f 63 53 74 61 72 74 20 3d 20 62 6c 6f 62 5f  TocStart = blob_
1560: 73 69 7a 65 28 26 62 6f 64 79 29 3b 0a 20 20 62  size(&body);.  b
1570: 6c 6f 62 5f 61 70 70 65 6e 64 28 26 62 6f 64 79  lob_append(&body
1580: 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 74  , blob_buffer(&t
1590: 6f 63 29 2c 20 62 6c 6f 62 5f 73 69 7a 65 28 26  oc), blob_size(&
15a0: 74 6f 63 29 29 3b 0a 20 20 69 54 6f 63 45 6e 64  toc));.  iTocEnd
15b0: 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 26 62 6f   = blob_size(&bo
15c0: 64 79 29 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 7a  dy);..  memset(z
15d0: 42 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28 7a  Buf, 0, sizeof(z
15e0: 42 75 66 29 29 3b 0a 20 20 70 75 74 33 32 28 26  Buf));.  put32(&
15f0: 7a 42 75 66 5b 30 5d 2c 20 30 78 30 36 30 35 34  zBuf[0], 0x06054
1600: 62 35 30 29 3b 0a 20 20 70 75 74 31 36 28 26 7a  b50);.  put16(&z
1610: 42 75 66 5b 34 5d 2c 20 30 29 3b 0a 20 20 70 75  Buf[4], 0);.  pu
1620: 74 31 36 28 26 7a 42 75 66 5b 36 5d 2c 20 30 29  t16(&zBuf[6], 0)
1630: 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b  ;.  put16(&zBuf[
1640: 38 5d 2c 20 6e 45 6e 74 72 79 29 3b 0a 20 20 70  8], nEntry);.  p
1650: 75 74 31 36 28 26 7a 42 75 66 5b 31 30 5d 2c 20  ut16(&zBuf[10], 
1660: 6e 45 6e 74 72 79 29 3b 0a 20 20 70 75 74 33 32  nEntry);.  put32
1670: 28 26 7a 42 75 66 5b 31 32 5d 2c 20 69 54 6f 63  (&zBuf[12], iToc
1680: 45 6e 64 20 2d 20 69 54 6f 63 53 74 61 72 74 29  End - iTocStart)
1690: 3b 0a 20 20 70 75 74 33 32 28 26 7a 42 75 66 5b  ;.  put32(&zBuf[
16a0: 31 36 5d 2c 20 69 54 6f 63 53 74 61 72 74 29 3b  16], iTocStart);
16b0: 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 32  .  put16(&zBuf[2
16c0: 30 5d 2c 20 30 29 3b 0a 20 20 62 6c 6f 62 5f 61  0], 0);.  blob_a
16d0: 70 70 65 6e 64 28 26 62 6f 64 79 2c 20 7a 42 75  ppend(&body, zBu
16e0: 66 2c 20 32 32 29 3b 0a 20 20 62 6c 6f 62 5f 72  f, 22);.  blob_r
16f0: 65 73 65 74 28 26 74 6f 63 29 3b 0a 20 20 2a 70  eset(&toc);.  *p
1700: 5a 69 70 20 3d 20 62 6f 64 79 3b 0a 20 20 62 6c  Zip = body;.  bl
1710: 6f 62 5f 7a 65 72 6f 28 26 62 6f 64 79 29 3b 0a  ob_zero(&body);.
1720: 20 20 6e 45 6e 74 72 79 20 3d 20 30 3b 0a 7d 0a    nEntry = 0;.}.
1730: 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20  ./*.** COMMAND: 
1740: 74 65 73 74 2d 66 69 6c 65 7a 69 70 0a 2a 2a 0a  test-filezip.**.
1750: 2a 2a 20 47 65 6e 65 72 61 74 65 20 61 20 5a 49  ** Generate a ZI
1760: 50 20 61 72 63 68 69 76 65 20 73 70 65 63 69 66  P archive specif
1770: 69 65 64 20 62 79 20 74 68 65 20 66 69 72 73 74  ied by the first
1780: 20 61 72 67 75 6d 65 6e 74 20 74 68 61 74 0a 2a   argument that.*
1790: 2a 20 63 6f 6e 74 61 69 6e 73 20 66 69 6c 65 73  * contains files
17a0: 20 67 69 76 65 6e 20 69 6e 20 74 68 65 20 73 65   given in the se
17b0: 63 6f 6e 64 20 61 6e 64 20 73 75 62 73 65 71 75  cond and subsequ
17c0: 65 6e 74 20 61 72 67 75 6d 65 6e 74 73 2e 0a 2a  ent arguments..*
17d0: 2f 0a 76 6f 69 64 20 66 69 6c 65 7a 69 70 5f 63  /.void filezip_c
17e0: 6d 64 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20  md(void){.  int 
17f0: 69 3b 0a 20 20 42 6c 6f 62 20 7a 69 70 3b 0a 20  i;.  Blob zip;. 
1800: 20 42 6c 6f 62 20 66 69 6c 65 3b 0a 20 20 69 66   Blob file;.  if
1810: 28 20 67 2e 61 72 67 63 3c 33 20 29 7b 0a 20 20  ( g.argc<3 ){.  
1820: 20 20 75 73 61 67 65 28 22 41 52 43 48 49 56 45    usage("ARCHIVE
1830: 20 46 49 4c 45 2e 2e 2e 2e 22 29 3b 0a 20 20 7d   FILE....");.  }
1840: 0a 20 20 7a 69 70 5f 6f 70 65 6e 28 29 3b 0a 20  .  zip_open();. 
1850: 20 66 6f 72 28 69 3d 33 3b 20 69 3c 67 2e 61 72   for(i=3; i<g.ar
1860: 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 62 6c  gc; i++){.    bl
1870: 6f 62 5f 7a 65 72 6f 28 26 66 69 6c 65 29 3b 0a  ob_zero(&file);.
1880: 20 20 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72      blob_read_fr
1890: 6f 6d 5f 66 69 6c 65 28 26 66 69 6c 65 2c 20 67  om_file(&file, g
18a0: 2e 61 72 67 76 5b 69 5d 29 3b 0a 20 20 20 20 7a  .argv[i]);.    z
18b0: 69 70 5f 61 64 64 5f 66 69 6c 65 28 67 2e 61 72  ip_add_file(g.ar
18c0: 67 76 5b 69 5d 2c 20 26 66 69 6c 65 29 3b 0a 20  gv[i], &file);. 
18d0: 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 66     blob_reset(&f
18e0: 69 6c 65 29 3b 0a 20 20 7d 0a 20 20 7a 69 70 5f  ile);.  }.  zip_
18f0: 63 6c 6f 73 65 28 26 7a 69 70 29 3b 0a 20 20 62  close(&zip);.  b
1900: 6c 6f 62 5f 77 72 69 74 65 5f 74 6f 5f 66 69 6c  lob_write_to_fil
1910: 65 28 26 7a 69 70 2c 20 67 2e 61 72 67 76 5b 32  e(&zip, g.argv[2
1920: 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 47 69 76  ]);.}../*.** Giv
1930: 65 6e 20 74 68 65 20 52 49 44 20 66 6f 72 20 61  en the RID for a
1940: 20 6d 61 6e 69 66 65 73 74 2c 20 63 6f 6e 73 74   manifest, const
1950: 72 75 63 74 20 61 20 5a 49 50 20 61 72 63 68 69  ruct a ZIP archi
1960: 76 65 20 63 6f 6e 74 61 69 6e 69 6e 67 0a 2a 2a  ve containing.**
1970: 20 61 6c 6c 20 66 69 6c 65 73 20 69 6e 20 74 68   all files in th
1980: 65 20 63 6f 72 72 65 73 70 6f 6e 64 69 6e 67 20  e corresponding 
1990: 62 61 73 65 6c 69 6e 65 2e 0a 2a 2a 0a 2a 2a 20  baseline..**.** 
19a0: 49 66 20 52 49 44 20 69 73 20 66 6f 72 20 61 6e  If RID is for an
19b0: 20 6f 62 6a 65 63 74 20 74 68 61 74 20 69 73 20   object that is 
19c0: 6e 6f 74 20 61 20 72 65 61 6c 20 6d 61 6e 69 66  not a real manif
19d0: 65 73 74 2c 20 74 68 65 6e 20 74 68 65 0a 2a 2a  est, then the.**
19e0: 20 72 65 73 75 6c 74 69 6e 67 20 5a 49 50 20 61   resulting ZIP a
19f0: 72 63 68 69 76 65 20 63 6f 6e 74 61 69 6e 73 20  rchive contains 
1a00: 61 20 73 69 6e 67 6c 65 20 66 69 6c 65 20 77 68  a single file wh
1a10: 69 63 68 20 69 73 20 74 68 65 20 52 49 44 0a 2a  ich is the RID.*
1a20: 2a 20 6f 62 6a 65 63 74 2e 0a 2a 2a 0a 2a 2a 20  * object..**.** 
1a30: 49 66 20 74 68 65 20 52 49 44 20 6f 62 6a 65 63  If the RID objec
1a40: 74 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74  t does not exist
1a50: 20 69 6e 20 74 68 65 20 72 65 70 6f 73 69 74 6f   in the reposito
1a60: 72 79 2c 20 74 68 65 6e 0a 2a 2a 20 70 5a 69 70  ry, then.** pZip
1a70: 20 69 73 20 7a 65 72 6f 65 64 2e 0a 2a 2a 0a 2a   is zeroed..**.*
1a80: 2a 20 7a 44 69 72 20 69 73 20 61 20 22 73 79 6e  * zDir is a "syn
1a90: 74 68 65 74 69 63 22 20 73 75 62 64 69 72 65 63  thetic" subdirec
1aa0: 74 6f 72 79 20 77 68 69 63 68 20 61 6c 6c 20 7a  tory which all z
1ab0: 69 70 70 65 64 20 66 69 6c 65 73 20 67 65 74 0a  ipped files get.
1ac0: 2a 2a 20 61 64 64 65 64 20 74 6f 20 61 73 20 70  ** added to as p
1ad0: 61 72 74 20 6f 66 20 74 68 65 20 7a 69 70 20 66  art of the zip f
1ae0: 69 6c 65 2e 20 49 74 20 6d 61 79 20 62 65 20 30  ile. It may be 0
1af0: 20 6f 72 20 61 6e 20 65 6d 70 74 79 20 73 74 72   or an empty str
1b00: 69 6e 67 2c 0a 2a 2a 20 69 6e 20 77 68 69 63 68  ing,.** in which
1b10: 20 63 61 73 65 20 69 74 20 69 73 20 69 67 6e 6f   case it is igno
1b20: 72 65 64 2e 20 54 68 65 20 69 6e 74 65 6e 74 69  red. The intenti
1b30: 6f 6e 20 69 73 20 74 6f 20 63 72 65 61 74 65 20  on is to create 
1b40: 61 20 7a 69 70 20 77 68 69 63 68 0a 2a 2a 20 70  a zip which.** p
1b50: 6f 6c 69 74 65 6c 79 20 65 78 70 61 6e 64 73 20  olitely expands 
1b60: 69 6e 74 6f 20 61 20 73 75 62 64 69 72 20 69 6e  into a subdir in
1b70: 73 74 65 61 64 20 6f 66 20 66 69 6c 6c 69 6e 67  stead of filling
1b80: 20 79 6f 75 72 20 63 75 72 72 65 6e 74 20 64 69   your current di
1b90: 72 0a 2a 2a 20 77 69 74 68 20 73 6f 75 72 63 65  r.** with source
1ba0: 20 66 69 6c 65 73 2e 20 46 6f 72 20 65 78 61 6d   files. For exam
1bb0: 70 6c 65 2c 20 70 61 73 73 20 61 20 55 55 49 44  ple, pass a UUID
1bc0: 20 6f 72 20 22 50 72 6f 6a 65 63 74 4e 61 6d 65   or "ProjectName
1bd0: 22 2e 0a 2a 2a 0a 2a 2f 0a 76 6f 69 64 20 7a 69  "..**.*/.void zi
1be0: 70 5f 6f 66 5f 62 61 73 65 6c 69 6e 65 28 69 6e  p_of_baseline(in
1bf0: 74 20 72 69 64 2c 20 42 6c 6f 62 20 2a 70 5a 69  t rid, Blob *pZi
1c00: 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  p, const char *z
1c10: 44 69 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  Dir){.  int i;. 
1c20: 20 42 6c 6f 62 20 6d 66 69 6c 65 2c 20 66 69 6c   Blob mfile, fil
1c30: 65 2c 20 68 61 73 68 3b 0a 20 20 4d 61 6e 69 66  e, hash;.  Manif
1c40: 65 73 74 20 6d 3b 0a 20 20 42 6c 6f 62 20 66 69  est m;.  Blob fi
1c50: 6c 65 6e 61 6d 65 3b 0a 20 20 69 6e 74 20 6e 50  lename;.  int nP
1c60: 72 65 66 69 78 3b 0a 20 20 0a 20 20 63 6f 6e 74  refix;.  .  cont
1c70: 65 6e 74 5f 67 65 74 28 72 69 64 2c 20 26 6d 66  ent_get(rid, &mf
1c80: 69 6c 65 29 3b 0a 20 20 69 66 28 20 62 6c 6f 62  ile);.  if( blob
1c90: 5f 73 69 7a 65 28 26 6d 66 69 6c 65 29 3d 3d 30  _size(&mfile)==0
1ca0: 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 7a 65 72   ){.    blob_zer
1cb0: 6f 28 70 5a 69 70 29 3b 0a 20 20 20 20 72 65 74  o(pZip);.    ret
1cc0: 75 72 6e 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62 5f  urn;.  }.  blob_
1cd0: 7a 65 72 6f 28 26 66 69 6c 65 29 3b 0a 20 20 62  zero(&file);.  b
1ce0: 6c 6f 62 5f 7a 65 72 6f 28 26 68 61 73 68 29 3b  lob_zero(&hash);
1cf0: 0a 20 20 62 6c 6f 62 5f 63 6f 70 79 28 26 66 69  .  blob_copy(&fi
1d00: 6c 65 2c 20 26 6d 66 69 6c 65 29 3b 0a 20 20 62  le, &mfile);.  b
1d10: 6c 6f 62 5f 7a 65 72 6f 28 26 66 69 6c 65 6e 61  lob_zero(&filena
1d20: 6d 65 29 3b 0a 20 20 7a 69 70 5f 6f 70 65 6e 28  me);.  zip_open(
1d30: 29 3b 0a 0a 20 20 69 66 28 20 7a 44 69 72 20 26  );..  if( zDir &
1d40: 26 20 7a 44 69 72 5b 30 5d 20 29 7b 0a 20 20 20  & zDir[0] ){.   
1d50: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 66   blob_appendf(&f
1d60: 69 6c 65 6e 61 6d 65 2c 20 22 25 73 2f 22 2c 20  ilename, "%s/", 
1d70: 7a 44 69 72 29 3b 0a 20 20 7d 0a 20 20 6e 50 72  zDir);.  }.  nPr
1d80: 65 66 69 78 20 3d 20 62 6c 6f 62 5f 73 69 7a 65  efix = blob_size
1d90: 28 26 66 69 6c 65 6e 61 6d 65 29 3b 0a 0a 20 20  (&filename);..  
1da0: 69 66 28 20 6d 61 6e 69 66 65 73 74 5f 70 61 72  if( manifest_par
1db0: 73 65 28 26 6d 2c 20 26 6d 66 69 6c 65 29 20 29  se(&m, &mfile) )
1dc0: 7b 0a 20 20 20 20 7a 69 70 5f 73 65 74 5f 74 69  {.    zip_set_ti
1dd0: 6d 65 64 61 74 65 28 6d 2e 72 44 61 74 65 29 3b  medate(m.rDate);
1de0: 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64  .    blob_append
1df0: 28 26 66 69 6c 65 6e 61 6d 65 2c 20 22 6d 61 6e  (&filename, "man
1e00: 69 66 65 73 74 22 2c 20 2d 31 29 3b 0a 20 20 20  ifest", -1);.   
1e10: 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65 28 62 6c   zip_add_file(bl
1e20: 6f 62 5f 73 74 72 28 26 66 69 6c 65 6e 61 6d 65  ob_str(&filename
1e30: 29 2c 20 26 66 69 6c 65 29 3b 0a 20 20 20 20 73  ), &file);.    s
1e40: 68 61 31 73 75 6d 5f 62 6c 6f 62 28 26 66 69 6c  ha1sum_blob(&fil
1e50: 65 2c 20 26 68 61 73 68 29 3b 0a 20 20 20 20 62  e, &hash);.    b
1e60: 6c 6f 62 5f 72 65 73 65 74 28 26 66 69 6c 65 29  lob_reset(&file)
1e70: 3b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e  ;.    blob_appen
1e80: 64 28 26 68 61 73 68 2c 20 22 5c 6e 22 2c 20 31  d(&hash, "\n", 1
1e90: 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 69  );.    blob_resi
1ea0: 7a 65 28 26 66 69 6c 65 6e 61 6d 65 2c 20 6e 50  ze(&filename, nP
1eb0: 72 65 66 69 78 29 3b 0a 20 20 20 20 62 6c 6f 62  refix);.    blob
1ec0: 5f 61 70 70 65 6e 64 28 26 66 69 6c 65 6e 61 6d  _append(&filenam
1ed0: 65 2c 20 22 6d 61 6e 69 66 65 73 74 2e 75 75 69  e, "manifest.uui
1ee0: 64 22 2c 20 2d 31 29 3b 0a 20 20 20 20 7a 69 70  d", -1);.    zip
1ef0: 5f 61 64 64 5f 66 69 6c 65 28 62 6c 6f 62 5f 73  _add_file(blob_s
1f00: 74 72 28 26 66 69 6c 65 6e 61 6d 65 29 2c 20 26  tr(&filename), &
1f10: 68 61 73 68 29 3b 0a 20 20 20 20 62 6c 6f 62 5f  hash);.    blob_
1f20: 72 65 73 65 74 28 26 68 61 73 68 29 3b 0a 20 20  reset(&hash);.  
1f30: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6d 2e 6e    for(i=0; i<m.n
1f40: 46 69 6c 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  File; i++){.    
1f50: 20 20 69 6e 74 20 66 69 64 20 3d 20 75 75 69 64    int fid = uuid
1f60: 5f 74 6f 5f 72 69 64 28 6d 2e 61 46 69 6c 65 5b  _to_rid(m.aFile[
1f70: 69 5d 2e 7a 55 75 69 64 2c 20 30 29 3b 0a 20 20  i].zUuid, 0);.  
1f80: 20 20 20 20 69 66 28 20 66 69 64 20 29 7b 0a 20      if( fid ){. 
1f90: 20 20 20 20 20 20 20 63 6f 6e 74 65 6e 74 5f 67         content_g
1fa0: 65 74 28 66 69 64 2c 20 26 66 69 6c 65 29 3b 0a  et(fid, &file);.
1fb0: 20 20 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 73          blob_res
1fc0: 69 7a 65 28 26 66 69 6c 65 6e 61 6d 65 2c 20 6e  ize(&filename, n
1fd0: 50 72 65 66 69 78 29 3b 0a 20 20 20 20 20 20 20  Prefix);.       
1fe0: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 66 69   blob_append(&fi
1ff0: 6c 65 6e 61 6d 65 2c 20 6d 2e 61 46 69 6c 65 5b  lename, m.aFile[
2000: 69 5d 2e 7a 4e 61 6d 65 2c 20 2d 31 29 3b 0a 20  i].zName, -1);. 
2010: 20 20 20 20 20 20 20 7a 69 70 5f 61 64 64 5f 66         zip_add_f
2020: 69 6c 65 28 62 6c 6f 62 5f 73 74 72 28 26 66 69  ile(blob_str(&fi
2030: 6c 65 6e 61 6d 65 29 2c 20 26 66 69 6c 65 29 3b  lename), &file);
2040: 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f 72 65  .        blob_re
2050: 73 65 74 28 26 66 69 6c 65 29 3b 0a 20 20 20 20  set(&file);.    
2060: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 6d 61    }.    }.    ma
2070: 6e 69 66 65 73 74 5f 63 6c 65 61 72 28 26 6d 29  nifest_clear(&m)
2080: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 62  ;.  }else{.    b
2090: 6c 6f 62 5f 72 65 73 65 74 28 26 6d 66 69 6c 65  lob_reset(&mfile
20a0: 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65  );.    blob_rese
20b0: 74 28 26 66 69 6c 65 29 3b 0a 20 20 7d 0a 20 20  t(&file);.  }.  
20c0: 62 6c 6f 62 5f 72 65 73 65 74 28 26 66 69 6c 65  blob_reset(&file
20d0: 6e 61 6d 65 29 3b 0a 20 20 7a 69 70 5f 63 6c 6f  name);.  zip_clo
20e0: 73 65 28 70 5a 69 70 29 3b 0a 7d 0a 0a 2f 2a 0a  se(pZip);.}../*.
20f0: 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 74 65 73 74  ** COMMAND: test
2100: 2d 62 61 73 65 6c 69 6e 65 2d 7a 69 70 0a 2a 2a  -baseline-zip.**
2110: 0a 2a 2a 20 47 65 6e 65 72 61 74 65 20 61 20 5a  .** Generate a Z
2120: 49 50 20 61 72 63 68 69 76 65 20 66 6f 72 20 61  IP archive for a
2130: 20 73 70 65 63 69 66 69 65 64 20 62 61 73 65 6c   specified basel
2140: 69 6e 65 2e 0a 2a 2f 0a 76 6f 69 64 20 62 61 73  ine..*/.void bas
2150: 65 6c 69 6e 65 5f 7a 69 70 5f 63 6d 64 28 76 6f  eline_zip_cmd(vo
2160: 69 64 29 7b 0a 20 20 69 6e 74 20 72 69 64 3b 0a  id){.  int rid;.
2170: 20 20 42 6c 6f 62 20 7a 69 70 3b 0a 20 20 69 66    Blob zip;.  if
2180: 28 20 67 2e 61 72 67 63 21 3d 34 20 29 7b 0a 20  ( g.argc!=4 ){. 
2190: 20 20 20 75 73 61 67 65 28 22 55 55 49 44 20 5a     usage("UUID Z
21a0: 49 50 46 49 4c 45 22 29 3b 0a 20 20 7d 0a 20 20  IPFILE");.  }.  
21b0: 64 62 5f 6d 75 73 74 5f 62 65 5f 77 69 74 68 69  db_must_be_withi
21c0: 6e 5f 74 72 65 65 28 29 3b 0a 20 20 72 69 64 20  n_tree();.  rid 
21d0: 3d 20 6e 61 6d 65 5f 74 6f 5f 72 69 64 28 67 2e  = name_to_rid(g.
21e0: 61 72 67 76 5b 32 5d 29 3b 0a 20 20 7a 69 70 5f  argv[2]);.  zip_
21f0: 6f 66 5f 62 61 73 65 6c 69 6e 65 28 72 69 64 2c  of_baseline(rid,
2200: 20 26 7a 69 70 2c 20 67 2e 61 72 67 76 5b 32 5d   &zip, g.argv[2]
2210: 29 3b 0a 20 20 62 6c 6f 62 5f 77 72 69 74 65 5f  );.  blob_write_
2220: 74 6f 5f 66 69 6c 65 28 26 7a 69 70 2c 20 67 2e  to_file(&zip, g.
2230: 61 72 67 76 5b 33 5d 29 3b 0a 7d 0a 0a 2f 2a 0a  argv[3]);.}../*.
2240: 2a 2a 20 57 45 42 50 41 47 45 3a 20 7a 69 70 0a  ** WEBPAGE: zip.
2250: 2a 2a 20 55 52 4c 3a 20 2f 7a 69 70 2f 52 49 44  ** URL: /zip/RID
2260: 2e 7a 69 70 0a 2a 2a 0a 2a 2a 20 47 65 6e 65 72  .zip.**.** Gener
2270: 61 74 65 20 61 20 5a 49 50 20 61 72 63 68 69 76  ate a ZIP archiv
2280: 65 20 66 6f 72 20 74 68 65 20 62 61 73 65 6c 69  e for the baseli
2290: 6e 65 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  ne..** Return th
22a0: 61 74 20 5a 49 50 20 61 72 63 68 69 76 65 20 61  at ZIP archive a
22b0: 73 20 74 68 65 20 48 54 54 50 20 72 65 70 6c 79  s the HTTP reply
22c0: 20 63 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 76 6f 69   content..*/.voi
22d0: 64 20 62 61 73 65 6c 69 6e 65 5f 7a 69 70 5f 70  d baseline_zip_p
22e0: 61 67 65 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74  age(void){.  int
22f0: 20 72 69 64 3b 0a 20 20 63 68 61 72 20 2a 7a 4e   rid;.  char *zN
2300: 61 6d 65 2c 20 2a 7a 52 69 64 3b 0a 20 20 69 6e  ame, *zRid;.  in
2310: 74 20 6e 4e 61 6d 65 2c 20 6e 52 69 64 3b 0a 20  t nName, nRid;. 
2320: 20 42 6c 6f 62 20 7a 69 70 3b 0a 0a 20 20 6c 6f   Blob zip;..  lo
2330: 67 69 6e 5f 63 68 65 63 6b 5f 63 72 65 64 65 6e  gin_check_creden
2340: 74 69 61 6c 73 28 29 3b 0a 20 20 69 66 28 20 21  tials();.  if( !
2350: 67 2e 6f 6b 5a 69 70 20 26 26 20 28 21 67 2e 6f  g.okZip && (!g.o
2360: 6b 52 65 61 64 20 7c 7c 20 21 67 2e 6f 6b 48 69  kRead || !g.okHi
2370: 73 74 6f 72 79 29 20 29 7b 20 6c 6f 67 69 6e 5f  story) ){ login_
2380: 6e 65 65 64 65 64 28 29 3b 20 72 65 74 75 72 6e  needed(); return
2390: 3b 20 7d 0a 20 20 7a 4e 61 6d 65 20 3d 20 6d 70  ; }.  zName = mp
23a0: 72 69 6e 74 66 28 22 25 73 22 2c 20 50 44 28 22  rintf("%s", PD("
23b0: 6e 61 6d 65 22 2c 22 22 29 29 3b 0a 20 20 6e 4e  name",""));.  nN
23c0: 61 6d 65 20 3d 20 73 74 72 6c 65 6e 28 7a 4e 61  ame = strlen(zNa
23d0: 6d 65 29 3b 0a 20 20 7a 52 69 64 20 3d 20 6d 70  me);.  zRid = mp
23e0: 72 69 6e 74 66 28 22 25 73 22 2c 20 50 44 28 22  rintf("%s", PD("
23f0: 75 75 69 64 22 2c 22 22 29 29 3b 0a 20 20 6e 52  uuid",""));.  nR
2400: 69 64 20 3d 20 73 74 72 6c 65 6e 28 7a 52 69 64  id = strlen(zRid
2410: 29 3b 0a 20 20 66 6f 72 28 6e 4e 61 6d 65 3d 73  );.  for(nName=s
2420: 74 72 6c 65 6e 28 7a 4e 61 6d 65 29 2d 31 3b 20  trlen(zName)-1; 
2430: 6e 4e 61 6d 65 3e 35 3b 20 6e 4e 61 6d 65 2d 2d  nName>5; nName--
2440: 29 7b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65  ){.    if( zName
2450: 5b 6e 4e 61 6d 65 5d 3d 3d 27 2e 27 20 29 7b 0a  [nName]=='.' ){.
2460: 20 20 20 20 20 20 7a 4e 61 6d 65 5b 6e 4e 61 6d        zName[nNam
2470: 65 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 62 72  e] = 0;.      br
2480: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  eak;.    }.  }. 
2490: 20 72 69 64 20 3d 20 6e 61 6d 65 5f 74 6f 5f 72   rid = name_to_r
24a0: 69 64 28 6e 52 69 64 3f 7a 52 69 64 3a 7a 4e 61  id(nRid?zRid:zNa
24b0: 6d 65 29 3b 0a 20 20 69 66 28 20 72 69 64 3d 3d  me);.  if( rid==
24c0: 30 20 29 7b 0a 20 20 20 20 40 20 4e 6f 74 20 66  0 ){.    @ Not f
24d0: 6f 75 6e 64 0a 20 20 20 20 72 65 74 75 72 6e 3b  ound.    return;
24e0: 0a 20 20 7d 0a 20 20 69 66 28 20 6e 52 69 64 3d  .  }.  if( nRid=
24f0: 3d 30 20 26 26 20 6e 4e 61 6d 65 3e 31 30 20 29  =0 && nName>10 )
2500: 20 7a 4e 61 6d 65 5b 31 30 5d 20 3d 20 30 3b 0a   zName[10] = 0;.
2510: 20 20 7a 69 70 5f 6f 66 5f 62 61 73 65 6c 69 6e    zip_of_baselin
2520: 65 28 72 69 64 2c 20 26 7a 69 70 2c 20 7a 4e 61  e(rid, &zip, zNa
2530: 6d 65 29 3b 0a 20 20 66 72 65 65 28 20 7a 4e 61  me);.  free( zNa
2540: 6d 65 20 29 3b 0a 20 20 66 72 65 65 28 20 7a 52  me );.  free( zR
2550: 69 64 20 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f  id );.  cgi_set_
2560: 63 6f 6e 74 65 6e 74 28 26 7a 69 70 29 3b 0a 20  content(&zip);. 
2570: 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74 65 6e 74   cgi_set_content
2580: 5f 74 79 70 65 28 22 61 70 70 6c 69 63 61 74 69  _type("applicati
2590: 6f 6e 2f 7a 69 70 22 29 3b 0a 20 20 63 67 69 5f  on/zip");.  cgi_
25a0: 72 65 70 6c 79 28 29 3b 0a 7d 0a                 reply();.}.