Hex Artifact Content
Not logged in

Artifact 967d1ecc3665a08c065e293b9e3e94faf97ab542:

File src/zip.c part of check-in [9b780d220b] - Add a ZIP archive generator. by drh on 2007-07-31 19:18:53.

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 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61  */../*.** Initia
05f0: 6c 69 7a 65 20 61 20 6e 65 77 20 5a 49 50 20 61  lize a new ZIP a
0600: 72 63 68 69 76 65 2e 0a 2a 2f 0a 76 6f 69 64 20  rchive..*/.void 
0610: 7a 69 70 5f 6f 70 65 6e 28 76 6f 69 64 29 7b 0a  zip_open(void){.
0620: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 62 6f 64    blob_zero(&bod
0630: 79 29 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28  y);.  blob_zero(
0640: 26 74 6f 63 29 3b 0a 20 20 6e 45 6e 74 72 79 20  &toc);.  nEntry 
0650: 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70  = 0;.}../*.** Ap
0660: 70 65 6e 64 20 61 20 73 69 6e 67 6c 65 20 66 69  pend a single fi
0670: 6c 65 20 74 6f 20 61 20 67 72 6f 77 69 6e 67 20  le to a growing 
0680: 5a 49 50 20 61 72 63 68 69 76 65 2e 0a 2a 2a 0a  ZIP archive..**.
0690: 2a 2a 20 70 46 69 6c 65 20 69 73 20 74 68 65 20  ** pFile is the 
06a0: 66 69 6c 65 20 74 6f 20 62 65 20 61 70 70 65 6e  file to be appen
06b0: 64 65 64 2e 20 20 7a 4e 61 6d 65 20 69 73 20 74  ded.  zName is t
06c0: 68 65 20 6e 61 6d 65 0a 2a 2a 20 74 68 61 74 20  he name.** that 
06d0: 74 68 65 20 66 69 6c 65 20 73 68 6f 75 6c 64 20  the file should 
06e0: 62 65 20 73 61 76 65 64 20 61 73 2e 0a 2a 2f 0a  be saved as..*/.
06f0: 69 6e 74 20 7a 69 70 5f 61 64 64 5f 66 69 6c 65  int zip_add_file
0700: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61  (const char *zNa
0710: 6d 65 2c 20 63 6f 6e 73 74 20 42 6c 6f 62 20 2a  me, const Blob *
0720: 70 46 69 6c 65 29 7b 0a 20 20 7a 5f 73 74 72 65  pFile){.  z_stre
0730: 61 6d 20 73 74 72 65 61 6d 3b 0a 20 20 69 6e 74  am stream;.  int
0740: 20 6e 61 6d 65 4c 65 6e 3b 0a 20 20 69 6e 74 20   nameLen;.  int 
0750: 73 6b 69 70 3b 0a 20 20 69 6e 74 20 74 6f 4f 75  skip;.  int toOu
0760: 74 3b 0a 20 20 69 6e 74 20 69 53 74 61 72 74 3b  t;.  int iStart;
0770: 0a 20 20 69 6e 74 20 69 43 52 43 3b 0a 20 20 69  .  int iCRC;.  i
0780: 6e 74 20 6e 42 79 74 65 3b 0a 20 20 69 6e 74 20  nt nByte;.  int 
0790: 6e 42 79 74 65 43 6f 6d 70 72 3b 0a 20 20 63 68  nByteCompr;.  ch
07a0: 61 72 20 2a 7a 3b 0a 20 20 63 68 61 72 20 7a 48  ar *z;.  char zH
07b0: 64 72 5b 33 30 5d 3b 0a 20 20 63 68 61 72 20 7a  dr[30];.  char z
07c0: 42 75 66 5b 31 30 30 5d 3b 0a 20 20 63 68 61 72  Buf[100];.  char
07d0: 20 7a 4f 75 74 42 75 66 5b 31 30 30 30 30 30 5d   zOutBuf[100000]
07e0: 3b 0a 0a 20 20 2f 2a 20 46 69 6c 6c 20 69 6e 20  ;..  /* Fill in 
07f0: 61 73 20 6d 75 63 68 20 6f 66 20 74 68 65 20 68  as much of the h
0800: 65 61 64 65 72 20 61 73 20 77 65 20 6b 6e 6f 77  eader as we know
0810: 2e 0a 20 20 2a 2f 0a 20 20 6e 61 6d 65 4c 65 6e  ..  */.  nameLen
0820: 20 3d 20 73 74 72 6c 65 6e 28 7a 4e 61 6d 65 29   = strlen(zName)
0830: 3b 0a 20 20 70 75 74 33 32 28 26 7a 48 64 72 5b  ;.  put32(&zHdr[
0840: 30 5d 2c 20 30 78 30 34 30 33 34 62 35 30 29 3b  0], 0x04034b50);
0850: 0a 20 20 70 75 74 31 36 28 26 7a 48 64 72 5b 34  .  put16(&zHdr[4
0860: 5d 2c 20 30 78 30 30 31 34 29 3b 0a 20 20 70 75  ], 0x0014);.  pu
0870: 74 31 36 28 26 7a 48 64 72 5b 36 5d 2c 20 30 29  t16(&zHdr[6], 0)
0880: 3b 0a 20 20 70 75 74 31 36 28 26 7a 48 64 72 5b  ;.  put16(&zHdr[
0890: 38 5d 2c 20 38 29 3b 0a 20 20 70 75 74 31 36 28  8], 8);.  put16(
08a0: 26 7a 48 64 72 5b 31 30 5d 2c 20 30 29 3b 0a 20  &zHdr[10], 0);. 
08b0: 20 70 75 74 31 36 28 26 7a 48 64 72 5b 31 32 5d   put16(&zHdr[12]
08c0: 2c 20 30 29 3b 0a 20 20 70 75 74 31 36 28 26 7a  , 0);.  put16(&z
08d0: 48 64 72 5b 32 36 5d 2c 20 6e 61 6d 65 4c 65 6e  Hdr[26], nameLen
08e0: 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 48 64 72  );.  put16(&zHdr
08f0: 5b 32 38 5d 2c 20 30 29 3b 0a 0a 20 20 2f 2a 20  [28], 0);..  /* 
0900: 57 72 69 74 65 20 74 68 65 20 68 65 61 64 65 72  Write the header
0910: 20 61 6e 64 20 66 69 6c 65 6e 61 6d 65 2e 0a 20   and filename.. 
0920: 20 2a 2f 0a 20 20 69 53 74 61 72 74 20 3d 20 62   */.  iStart = b
0930: 6c 6f 62 5f 73 69 7a 65 28 26 62 6f 64 79 29 3b  lob_size(&body);
0940: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26  .  blob_append(&
0950: 62 6f 64 79 2c 20 7a 48 64 72 2c 20 33 30 29 3b  body, zHdr, 30);
0960: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26  .  blob_append(&
0970: 62 6f 64 79 2c 20 7a 4e 61 6d 65 2c 20 6e 61 6d  body, zName, nam
0980: 65 4c 65 6e 29 3b 0a 0a 20 20 2f 2a 20 54 68 65  eLen);..  /* The
0990: 20 66 69 72 73 74 20 74 77 6f 20 62 79 74 65 73   first two bytes
09a0: 20 74 68 61 74 20 63 6f 6d 65 20 6f 75 74 20 6f   that come out o
09b0: 66 20 74 68 65 20 64 65 66 6c 61 74 65 20 63 6f  f the deflate co
09c0: 6d 70 72 65 73 73 6f 72 20 61 72 65 0a 20 20 2a  mpressor are.  *
09d0: 2a 20 73 6f 6d 65 20 6b 69 6e 64 20 6f 66 20 68  * some kind of h
09e0: 65 61 64 65 72 20 74 68 61 74 20 5a 49 50 20 64  eader that ZIP d
09f0: 6f 65 73 20 6e 6f 74 20 75 73 65 2e 20 20 53 6f  oes not use.  So
0a00: 20 73 6b 69 70 20 74 68 65 20 66 69 72 73 74 20   skip the first 
0a10: 74 77 6f 0a 20 20 2a 2a 20 6f 75 74 70 75 74 20  two.  ** output 
0a20: 62 79 74 65 73 2e 0a 20 20 2a 2f 0a 20 20 73 6b  bytes..  */.  sk
0a30: 69 70 20 3d 20 32 3b 0a 0a 20 20 2f 2a 20 57 72  ip = 2;..  /* Wr
0a40: 69 74 65 20 74 68 65 20 63 6f 6d 70 72 65 73 73  ite the compress
0a50: 65 64 20 66 69 6c 65 2e 20 20 43 6f 6d 70 75 74  ed file.  Comput
0a60: 65 20 74 68 65 20 43 52 43 20 61 73 20 77 65 20  e the CRC as we 
0a70: 70 72 6f 67 72 65 73 73 2e 0a 20 20 2a 2f 0a 20  progress..  */. 
0a80: 20 73 74 72 65 61 6d 2e 7a 61 6c 6c 6f 63 20 3d   stream.zalloc =
0a90: 20 28 61 6c 6c 6f 63 5f 66 75 6e 63 29 30 3b 0a   (alloc_func)0;.
0aa0: 20 20 73 74 72 65 61 6d 2e 7a 66 72 65 65 20 3d    stream.zfree =
0ab0: 20 28 66 72 65 65 5f 66 75 6e 63 29 30 3b 0a 20   (free_func)0;. 
0ac0: 20 73 74 72 65 61 6d 2e 6f 70 61 71 75 65 20 3d   stream.opaque =
0ad0: 20 30 3b 0a 20 20 73 74 72 65 61 6d 2e 61 76 61   0;.  stream.ava
0ae0: 69 6c 5f 69 6e 20 3d 20 62 6c 6f 62 5f 73 69 7a  il_in = blob_siz
0af0: 65 28 70 46 69 6c 65 29 3b 0a 20 20 73 74 72 65  e(pFile);.  stre
0b00: 61 6d 2e 6e 65 78 74 5f 69 6e 20 3d 20 28 75 6e  am.next_in = (un
0b10: 73 69 67 6e 65 64 20 63 68 61 72 2a 29 62 6c 6f  signed char*)blo
0b20: 62 5f 62 75 66 66 65 72 28 70 46 69 6c 65 29 3b  b_buffer(pFile);
0b30: 0a 20 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f  .  stream.avail_
0b40: 6f 75 74 20 3d 20 73 69 7a 65 6f 66 28 7a 4f 75  out = sizeof(zOu
0b50: 74 42 75 66 29 3b 0a 20 20 73 74 72 65 61 6d 2e  tBuf);.  stream.
0b60: 6e 65 78 74 5f 6f 75 74 20 3d 20 28 75 6e 73 69  next_out = (unsi
0b70: 67 6e 65 64 20 63 68 61 72 2a 29 7a 4f 75 74 42  gned char*)zOutB
0b80: 75 66 3b 0a 20 20 64 65 66 6c 61 74 65 49 6e 69  uf;.  deflateIni
0b90: 74 28 26 73 74 72 65 61 6d 2c 20 39 29 3b 0a 20  t(&stream, 9);. 
0ba0: 20 69 43 52 43 20 3d 20 63 72 63 33 32 28 30 2c   iCRC = crc32(0,
0bb0: 20 73 74 72 65 61 6d 2e 6e 65 78 74 5f 69 6e 2c   stream.next_in,
0bc0: 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 69 6e   stream.avail_in
0bd0: 29 3b 0a 20 20 77 68 69 6c 65 28 20 73 74 72 65  );.  while( stre
0be0: 61 6d 2e 61 76 61 69 6c 5f 69 6e 3e 30 20 29 7b  am.avail_in>0 ){
0bf0: 0a 20 20 20 20 64 65 66 6c 61 74 65 28 26 73 74  .    deflate(&st
0c00: 72 65 61 6d 2c 20 30 29 3b 0a 20 20 20 20 74 6f  ream, 0);.    to
0c10: 4f 75 74 20 3d 20 73 69 7a 65 6f 66 28 7a 4f 75  Out = sizeof(zOu
0c20: 74 42 75 66 29 20 2d 20 73 74 72 65 61 6d 2e 61  tBuf) - stream.a
0c30: 76 61 69 6c 5f 6f 75 74 3b 0a 20 20 20 20 69 66  vail_out;.    if
0c40: 28 20 74 6f 4f 75 74 3e 73 6b 69 70 20 29 7b 0a  ( toOut>skip ){.
0c50: 20 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e        blob_appen
0c60: 64 28 26 62 6f 64 79 2c 20 26 7a 4f 75 74 42 75  d(&body, &zOutBu
0c70: 66 5b 73 6b 69 70 5d 2c 20 74 6f 4f 75 74 20 2d  f[skip], toOut -
0c80: 20 73 6b 69 70 29 3b 0a 20 20 20 20 20 20 73 6b   skip);.      sk
0c90: 69 70 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73  ip = 0;.    }els
0ca0: 65 7b 0a 20 20 20 20 20 20 73 6b 69 70 20 2d 3d  e{.      skip -=
0cb0: 20 74 6f 4f 75 74 3b 0a 20 20 20 20 7d 0a 20 20   toOut;.    }.  
0cc0: 20 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 6f    stream.avail_o
0cd0: 75 74 20 3d 20 73 69 7a 65 6f 66 28 7a 4f 75 74  ut = sizeof(zOut
0ce0: 42 75 66 29 3b 0a 20 20 20 20 73 74 72 65 61 6d  Buf);.    stream
0cf0: 2e 6e 65 78 74 5f 6f 75 74 20 3d 20 28 75 6e 73  .next_out = (uns
0d00: 69 67 6e 65 64 20 63 68 61 72 2a 29 7a 4f 75 74  igned char*)zOut
0d10: 42 75 66 3b 0a 20 20 7d 0a 20 20 64 6f 7b 0a 20  Buf;.  }.  do{. 
0d20: 20 20 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f     stream.avail_
0d30: 6f 75 74 20 3d 20 73 69 7a 65 6f 66 28 7a 4f 75  out = sizeof(zOu
0d40: 74 42 75 66 29 3b 0a 20 20 20 20 73 74 72 65 61  tBuf);.    strea
0d50: 6d 2e 6e 65 78 74 5f 6f 75 74 20 3d 20 28 75 6e  m.next_out = (un
0d60: 73 69 67 6e 65 64 20 63 68 61 72 2a 29 7a 4f 75  signed char*)zOu
0d70: 74 42 75 66 3b 0a 20 20 20 20 64 65 66 6c 61 74  tBuf;.    deflat
0d80: 65 28 26 73 74 72 65 61 6d 2c 20 5a 5f 46 49 4e  e(&stream, Z_FIN
0d90: 49 53 48 29 3b 0a 20 20 20 20 74 6f 4f 75 74 20  ISH);.    toOut 
0da0: 3d 20 73 69 7a 65 6f 66 28 7a 4f 75 74 42 75 66  = sizeof(zOutBuf
0db0: 29 20 2d 20 73 74 72 65 61 6d 2e 61 76 61 69 6c  ) - stream.avail
0dc0: 5f 6f 75 74 3b 0a 20 20 20 20 69 66 28 20 74 6f  _out;.    if( to
0dd0: 4f 75 74 3e 73 6b 69 70 20 29 7b 0a 20 20 20 20  Out>skip ){.    
0de0: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 62    blob_append(&b
0df0: 6f 64 79 2c 20 26 7a 4f 75 74 42 75 66 5b 73 6b  ody, &zOutBuf[sk
0e00: 69 70 5d 2c 20 74 6f 4f 75 74 20 2d 20 73 6b 69  ip], toOut - ski
0e10: 70 29 3b 0a 20 20 20 20 20 20 73 6b 69 70 20 3d  p);.      skip =
0e20: 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   0;.    }else{. 
0e30: 20 20 20 20 20 73 6b 69 70 20 2d 3d 20 74 6f 4f       skip -= toO
0e40: 75 74 3b 0a 20 20 20 20 7d 0a 20 20 7d 77 68 69  ut;.    }.  }whi
0e50: 6c 65 28 20 73 74 72 65 61 6d 2e 61 76 61 69 6c  le( stream.avail
0e60: 5f 6f 75 74 3d 3d 30 20 29 3b 0a 20 20 6e 42 79  _out==0 );.  nBy
0e70: 74 65 20 3d 20 73 74 72 65 61 6d 2e 74 6f 74 61  te = stream.tota
0e80: 6c 5f 69 6e 3b 0a 20 20 6e 42 79 74 65 43 6f 6d  l_in;.  nByteCom
0e90: 70 72 20 3d 20 73 74 72 65 61 6d 2e 74 6f 74 61  pr = stream.tota
0ea0: 6c 5f 6f 75 74 20 2d 20 32 3b 0a 20 20 64 65 66  l_out - 2;.  def
0eb0: 6c 61 74 65 45 6e 64 28 26 73 74 72 65 61 6d 29  lateEnd(&stream)
0ec0: 3b 0a 0a 20 20 2f 2a 20 47 6f 20 62 61 63 6b 20  ;..  /* Go back 
0ed0: 61 6e 64 20 77 72 69 74 65 20 74 68 65 20 68 65  and write the he
0ee0: 61 64 65 72 2c 20 6e 6f 77 20 74 68 61 74 20 77  ader, now that w
0ef0: 65 20 6b 6e 6f 77 20 74 68 65 20 63 6f 6d 70 72  e know the compr
0f00: 65 73 73 65 64 20 66 69 6c 65 20 73 69 7a 65 2e  essed file size.
0f10: 0a 20 20 2a 2f 0a 20 20 7a 20 3d 20 26 62 6c 6f  .  */.  z = &blo
0f20: 62 5f 62 75 66 66 65 72 28 26 62 6f 64 79 29 5b  b_buffer(&body)[
0f30: 69 53 74 61 72 74 5d 3b 0a 20 20 70 75 74 33 32  iStart];.  put32
0f40: 28 26 7a 5b 31 34 5d 2c 20 69 43 52 43 29 3b 0a  (&z[14], iCRC);.
0f50: 20 20 70 75 74 33 32 28 26 7a 5b 31 38 5d 2c 20    put32(&z[18], 
0f60: 6e 42 79 74 65 43 6f 6d 70 72 29 3b 0a 20 20 70  nByteCompr);.  p
0f70: 75 74 33 32 28 26 7a 5b 32 32 5d 2c 20 6e 42 79  ut32(&z[22], nBy
0f80: 74 65 29 3b 0a 0a 20 20 2f 2a 20 4d 61 6b 65 20  te);..  /* Make 
0f90: 61 6e 20 65 6e 74 72 79 20 69 6e 20 74 68 65 20  an entry in the 
0fa0: 74 61 62 6c 65 73 20 6f 66 20 63 6f 6e 74 65 6e  tables of conten
0fb0: 74 73 0a 20 20 2a 2f 0a 20 20 6d 65 6d 73 65 74  ts.  */.  memset
0fc0: 28 7a 42 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66  (zBuf, 0, sizeof
0fd0: 28 7a 42 75 66 29 29 3b 0a 20 20 70 75 74 33 32  (zBuf));.  put32
0fe0: 28 26 7a 42 75 66 5b 30 5d 2c 20 30 78 30 32 30  (&zBuf[0], 0x020
0ff0: 31 34 62 35 30 29 3b 0a 20 20 70 75 74 31 36 28  14b50);.  put16(
1000: 26 7a 42 75 66 5b 34 5d 2c 20 30 78 30 33 31 37  &zBuf[4], 0x0317
1010: 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66  );.  put16(&zBuf
1020: 5b 36 5d 2c 20 30 78 30 30 31 34 29 3b 0a 20 20  [6], 0x0014);.  
1030: 70 75 74 31 36 28 26 7a 42 75 66 5b 38 5d 2c 20  put16(&zBuf[8], 
1040: 30 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75  0);.  put16(&zBu
1050: 66 5b 31 30 5d 2c 20 30 78 30 30 30 38 29 3b 0a  f[10], 0x0008);.
1060: 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 31 32    put16(&zBuf[12
1070: 5d 2c 20 30 29 3b 20 20 0a 20 20 70 75 74 31 36  ], 0);  .  put16
1080: 28 26 7a 42 75 66 5b 31 34 5d 2c 20 30 29 3b 0a  (&zBuf[14], 0);.
1090: 20 20 70 75 74 33 32 28 26 7a 42 75 66 5b 31 36    put32(&zBuf[16
10a0: 5d 2c 20 69 43 52 43 29 3b 0a 20 20 70 75 74 33  ], iCRC);.  put3
10b0: 32 28 26 7a 42 75 66 5b 32 30 5d 2c 20 6e 42 79  2(&zBuf[20], nBy
10c0: 74 65 43 6f 6d 70 72 29 3b 0a 20 20 70 75 74 33  teCompr);.  put3
10d0: 32 28 26 7a 42 75 66 5b 32 34 5d 2c 20 6e 42 79  2(&zBuf[24], nBy
10e0: 74 65 29 3b 0a 20 20 70 75 74 31 36 28 26 7a 42  te);.  put16(&zB
10f0: 75 66 5b 32 38 5d 2c 20 6e 61 6d 65 4c 65 6e 29  uf[28], nameLen)
1100: 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b  ;.  put16(&zBuf[
1110: 33 30 5d 2c 20 30 29 3b 0a 20 20 70 75 74 31 36  30], 0);.  put16
1120: 28 26 7a 42 75 66 5b 33 32 5d 2c 20 30 29 3b 0a  (&zBuf[32], 0);.
1130: 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b 33 34    put16(&zBuf[34
1140: 5d 2c 20 31 29 3b 0a 20 20 70 75 74 31 36 28 26  ], 1);.  put16(&
1150: 7a 42 75 66 5b 33 36 5d 2c 20 30 29 3b 0a 20 20  zBuf[36], 0);.  
1160: 70 75 74 33 32 28 26 7a 42 75 66 5b 33 38 5d 2c  put32(&zBuf[38],
1170: 20 28 30 31 30 30 30 30 30 20 7c 20 30 36 34 34   (0100000 | 0644
1180: 29 3c 3c 31 36 29 3b 0a 20 20 70 75 74 33 32 28  )<<16);.  put32(
1190: 26 7a 42 75 66 5b 34 32 5d 2c 20 69 53 74 61 72  &zBuf[42], iStar
11a0: 74 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e  t);.  blob_appen
11b0: 64 28 26 74 6f 63 2c 20 7a 42 75 66 2c 20 34 36  d(&toc, zBuf, 46
11c0: 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64  );.  blob_append
11d0: 28 26 74 6f 63 2c 20 7a 4e 61 6d 65 2c 20 6e 61  (&toc, zName, na
11e0: 6d 65 4c 65 6e 29 3b 0a 20 20 6e 45 6e 74 72 79  meLen);.  nEntry
11f0: 2b 2b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 57 72  ++;.}.../*.** Wr
1200: 69 74 65 20 74 68 65 20 5a 49 50 20 61 72 63 68  ite the ZIP arch
1210: 69 76 65 20 69 6e 74 6f 20 74 68 65 20 67 69 76  ive into the giv
1220: 65 6e 20 42 4c 4f 42 2e 0a 2a 2f 0a 69 6e 74 20  en BLOB..*/.int 
1230: 7a 69 70 5f 63 6c 6f 73 65 28 42 6c 6f 62 20 2a  zip_close(Blob *
1240: 70 5a 69 70 29 7b 0a 20 20 69 6e 74 20 69 54 6f  pZip){.  int iTo
1250: 63 53 74 61 72 74 3b 0a 20 20 69 6e 74 20 69 54  cStart;.  int iT
1260: 6f 63 45 6e 64 3b 0a 20 20 63 68 61 72 20 7a 42  ocEnd;.  char zB
1270: 75 66 5b 33 30 5d 3b 0a 0a 20 20 69 54 6f 63 53  uf[30];..  iTocS
1280: 74 61 72 74 20 3d 20 62 6c 6f 62 5f 73 69 7a 65  tart = blob_size
1290: 28 26 62 6f 64 79 29 3b 0a 20 20 62 6c 6f 62 5f  (&body);.  blob_
12a0: 61 70 70 65 6e 64 28 26 62 6f 64 79 2c 20 62 6c  append(&body, bl
12b0: 6f 62 5f 62 75 66 66 65 72 28 26 74 6f 63 29 2c  ob_buffer(&toc),
12c0: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 74 6f 63 29   blob_size(&toc)
12d0: 29 3b 0a 20 20 69 54 6f 63 45 6e 64 20 3d 20 62  );.  iTocEnd = b
12e0: 6c 6f 62 5f 73 69 7a 65 28 26 62 6f 64 79 29 3b  lob_size(&body);
12f0: 0a 0a 20 20 6d 65 6d 73 65 74 28 7a 42 75 66 2c  ..  memset(zBuf,
1300: 20 30 2c 20 73 69 7a 65 6f 66 28 7a 42 75 66 29   0, sizeof(zBuf)
1310: 29 3b 0a 20 20 70 75 74 33 32 28 26 7a 42 75 66  );.  put32(&zBuf
1320: 5b 30 5d 2c 20 30 78 30 36 30 35 34 62 35 30 29  [0], 0x06054b50)
1330: 3b 0a 20 20 70 75 74 31 36 28 26 7a 42 75 66 5b  ;.  put16(&zBuf[
1340: 34 5d 2c 20 30 29 3b 0a 20 20 70 75 74 31 36 28  4], 0);.  put16(
1350: 26 7a 42 75 66 5b 36 5d 2c 20 30 29 3b 0a 20 20  &zBuf[6], 0);.  
1360: 70 75 74 31 36 28 26 7a 42 75 66 5b 38 5d 2c 20  put16(&zBuf[8], 
1370: 6e 45 6e 74 72 79 29 3b 0a 20 20 70 75 74 31 36  nEntry);.  put16
1380: 28 26 7a 42 75 66 5b 31 30 5d 2c 20 6e 45 6e 74  (&zBuf[10], nEnt
1390: 72 79 29 3b 0a 20 20 70 75 74 33 32 28 26 7a 42  ry);.  put32(&zB
13a0: 75 66 5b 31 32 5d 2c 20 69 54 6f 63 45 6e 64 20  uf[12], iTocEnd 
13b0: 2d 20 69 54 6f 63 53 74 61 72 74 29 3b 0a 20 20  - iTocStart);.  
13c0: 70 75 74 33 32 28 26 7a 42 75 66 5b 31 36 5d 2c  put32(&zBuf[16],
13d0: 20 69 54 6f 63 53 74 61 72 74 29 3b 0a 20 20 70   iTocStart);.  p
13e0: 75 74 31 36 28 26 7a 42 75 66 5b 32 30 5d 2c 20  ut16(&zBuf[20], 
13f0: 30 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e  0);.  blob_appen
1400: 64 28 26 62 6f 64 79 2c 20 7a 42 75 66 2c 20 32  d(&body, zBuf, 2
1410: 32 29 3b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74  2);.  blob_reset
1420: 28 26 74 6f 63 29 3b 0a 20 20 2a 70 5a 69 70 20  (&toc);.  *pZip 
1430: 3d 20 62 6f 64 79 3b 0a 20 20 62 6c 6f 62 5f 7a  = body;.  blob_z
1440: 65 72 6f 28 26 62 6f 64 79 29 3b 0a 20 20 6e 45  ero(&body);.  nE
1450: 6e 74 72 79 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a  ntry = 0;.}../*.
1460: 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 74 65 73 74  ** COMMAND: test
1470: 2d 66 69 6c 65 7a 69 70 0a 2a 2a 0a 2a 2a 20 47  -filezip.**.** G
1480: 65 6e 65 72 61 74 65 20 61 20 5a 49 50 20 61 72  enerate a ZIP ar
1490: 63 68 69 76 65 20 73 70 65 63 69 66 69 65 64 20  chive specified 
14a0: 62 79 20 74 68 65 20 66 69 72 73 74 20 61 72 67  by the first arg
14b0: 75 6d 65 6e 74 20 74 68 61 74 0a 2a 2a 20 63 6f  ument that.** co
14c0: 6e 74 61 69 6e 73 20 66 69 6c 65 73 20 67 69 76  ntains files giv
14d0: 65 6e 20 69 6e 20 74 68 65 20 73 65 63 6f 6e 64  en in the second
14e0: 20 61 6e 64 20 73 75 62 73 65 71 75 65 6e 74 20   and subsequent 
14f0: 61 72 67 75 6d 65 6e 74 73 2e 0a 2a 2f 0a 76 6f  arguments..*/.vo
1500: 69 64 20 66 69 6c 65 7a 69 70 5f 63 6d 64 28 76  id filezip_cmd(v
1510: 6f 69 64 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  oid){.  int i;. 
1520: 20 42 6c 6f 62 20 7a 69 70 3b 0a 20 20 42 6c 6f   Blob zip;.  Blo
1530: 62 20 66 69 6c 65 3b 0a 20 20 69 66 28 20 67 2e  b file;.  if( g.
1540: 61 72 67 63 3c 33 20 29 7b 0a 20 20 20 20 75 73  argc<3 ){.    us
1550: 61 67 65 28 22 41 52 43 48 49 56 45 20 46 49 4c  age("ARCHIVE FIL
1560: 45 2e 2e 2e 2e 22 29 3b 0a 20 20 7d 0a 20 20 7a  E....");.  }.  z
1570: 69 70 5f 6f 70 65 6e 28 29 3b 0a 20 20 66 6f 72  ip_open();.  for
1580: 28 69 3d 33 3b 20 69 3c 67 2e 61 72 67 63 3b 20  (i=3; i<g.argc; 
1590: 69 2b 2b 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 7a  i++){.    blob_z
15a0: 65 72 6f 28 26 66 69 6c 65 29 3b 0a 20 20 20 20  ero(&file);.    
15b0: 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 66  blob_read_from_f
15c0: 69 6c 65 28 26 66 69 6c 65 2c 20 67 2e 61 72 67  ile(&file, g.arg
15d0: 76 5b 69 5d 29 3b 0a 20 20 20 20 7a 69 70 5f 61  v[i]);.    zip_a
15e0: 64 64 5f 66 69 6c 65 28 67 2e 61 72 67 76 5b 69  dd_file(g.argv[i
15f0: 5d 2c 20 26 66 69 6c 65 29 3b 0a 20 20 20 20 62  ], &file);.    b
1600: 6c 6f 62 5f 72 65 73 65 74 28 26 66 69 6c 65 29  lob_reset(&file)
1610: 3b 0a 20 20 7d 0a 20 20 7a 69 70 5f 63 6c 6f 73  ;.  }.  zip_clos
1620: 65 28 26 7a 69 70 29 3b 0a 20 20 62 6c 6f 62 5f  e(&zip);.  blob_
1630: 77 72 69 74 65 5f 74 6f 5f 66 69 6c 65 28 26 7a  write_to_file(&z
1640: 69 70 2c 20 67 2e 61 72 67 76 5b 32 5d 29 3b 0a  ip, g.argv[2]);.
1650: 7d 0a                                            }.