File Annotation
Not logged in
9b780d220b 2007-07-31       drh: /*
9b780d220b 2007-07-31       drh: ** Copyright (c) 2007 D. Richard Hipp
9b780d220b 2007-07-31       drh: **
9b780d220b 2007-07-31       drh: ** This program is free software; you can redistribute it and/or
9b780d220b 2007-07-31       drh: ** modify it under the terms of the GNU General Public
9b780d220b 2007-07-31       drh: ** License version 2 as published by the Free Software Foundation.
9b780d220b 2007-07-31       drh: **
9b780d220b 2007-07-31       drh: ** This program is distributed in the hope that it will be useful,
9b780d220b 2007-07-31       drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9b780d220b 2007-07-31       drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9b780d220b 2007-07-31       drh: ** General Public License for more details.
9b780d220b 2007-07-31       drh: **
9b780d220b 2007-07-31       drh: ** You should have received a copy of the GNU General Public
9b780d220b 2007-07-31       drh: ** License along with this library; if not, write to the
9b780d220b 2007-07-31       drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
9b780d220b 2007-07-31       drh: ** Boston, MA  02111-1307, USA.
9b780d220b 2007-07-31       drh: **
9b780d220b 2007-07-31       drh: ** Author contact information:
9b780d220b 2007-07-31       drh: **   drh@hwaci.com
9b780d220b 2007-07-31       drh: **   http://www.hwaci.com/drh/
9b780d220b 2007-07-31       drh: **
9b780d220b 2007-07-31       drh: *******************************************************************************
9b780d220b 2007-07-31       drh: **
9b780d220b 2007-07-31       drh: ** This file contains code used to generate ZIP archives.
9b780d220b 2007-07-31       drh: */
9b780d220b 2007-07-31       drh: #include <assert.h>
9b780d220b 2007-07-31       drh: #include <zlib.h>
9b780d220b 2007-07-31       drh: #include "config.h"
9b780d220b 2007-07-31       drh: #include "zip.h"
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh: /*
9b780d220b 2007-07-31       drh: ** Write a 16- or 32-bit integer as little-endian into the given buffer.
9b780d220b 2007-07-31       drh: */
9b780d220b 2007-07-31       drh: static void put16(char *z, int v){
9b780d220b 2007-07-31       drh:   z[0] = v & 0xff;
9b780d220b 2007-07-31       drh:   z[1] = (v>>8) & 0xff;
9b780d220b 2007-07-31       drh: }
9b780d220b 2007-07-31       drh: static void put32(char *z, int v){
9b780d220b 2007-07-31       drh:   z[0] = v & 0xff;
9b780d220b 2007-07-31       drh:   z[1] = (v>>8) & 0xff;
9b780d220b 2007-07-31       drh:   z[2] = (v>>16) & 0xff;
9b780d220b 2007-07-31       drh:   z[3] = (v>>24) & 0xff;
9b780d220b 2007-07-31       drh: }
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh: /*
9b780d220b 2007-07-31       drh: ** Variables in which to accumulate a growing ZIP archive.
9b780d220b 2007-07-31       drh: */
9b780d220b 2007-07-31       drh: static Blob body;    /* The body of the ZIP archive */
9b780d220b 2007-07-31       drh: static Blob toc;     /* The table of contents */
9b780d220b 2007-07-31       drh: static int nEntry;   /* Number of files */
dead090c0b 2007-07-31       drh: static int dosTime;  /* DOS-format time */
dead090c0b 2007-07-31       drh: static int dosDate;  /* DOS-format date */
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh: /*
9b780d220b 2007-07-31       drh: ** Initialize a new ZIP archive.
9b780d220b 2007-07-31       drh: */
9b780d220b 2007-07-31       drh: void zip_open(void){
9b780d220b 2007-07-31       drh:   blob_zero(&body);
9b780d220b 2007-07-31       drh:   blob_zero(&toc);
9b780d220b 2007-07-31       drh:   nEntry = 0;
dead090c0b 2007-07-31       drh:   dosTime = 0;
dead090c0b 2007-07-31       drh:   dosDate = 0;
dead090c0b 2007-07-31       drh: }
dead090c0b 2007-07-31       drh: 
dead090c0b 2007-07-31       drh: /*
dead090c0b 2007-07-31       drh: ** Set the date and time values from an ISO8601 date string.
dead090c0b 2007-07-31       drh: */
dead090c0b 2007-07-31       drh: void zip_set_timedate_from_str(const char *zDate){
dead090c0b 2007-07-31       drh:   int y, m, d;
dead090c0b 2007-07-31       drh:   int H, M, S;
dead090c0b 2007-07-31       drh: 
dead090c0b 2007-07-31       drh:   y = atoi(zDate);
dead090c0b 2007-07-31       drh:   m = atoi(&zDate[5]);
dead090c0b 2007-07-31       drh:   d = atoi(&zDate[8]);
dead090c0b 2007-07-31       drh:   H = atoi(&zDate[11]);
dead090c0b 2007-07-31       drh:   M = atoi(&zDate[14]);
dead090c0b 2007-07-31       drh:   S = atoi(&zDate[17]);
39bbc6010e 2008-11-27       drh:   dosTime = (H<<11) + (M<<5) + (S>>1);
dead090c0b 2007-07-31       drh:   dosDate = ((y-1980)<<9) + (m<<5) + d;
dead090c0b 2007-07-31       drh: }
dead090c0b 2007-07-31       drh: 
dead090c0b 2007-07-31       drh: /*
dead090c0b 2007-07-31       drh: ** Set the date and time from a julian day number.
dead090c0b 2007-07-31       drh: */
dead090c0b 2007-07-31       drh: void zip_set_timedate(double rDate){
dead090c0b 2007-07-31       drh:   char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
dead090c0b 2007-07-31       drh:   zip_set_timedate_from_str(zDate);
dead090c0b 2007-07-31       drh:   free(zDate);
9b780d220b 2007-07-31       drh: }
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh: /*
9b780d220b 2007-07-31       drh: ** Append a single file to a growing ZIP archive.
9b780d220b 2007-07-31       drh: **
9b780d220b 2007-07-31       drh: ** pFile is the file to be appended.  zName is the name
9b780d220b 2007-07-31       drh: ** that the file should be saved as.
9b780d220b 2007-07-31       drh: */
dead090c0b 2007-07-31       drh: void zip_add_file(const char *zName, const Blob *pFile){
9b780d220b 2007-07-31       drh:   z_stream stream;
9b780d220b 2007-07-31       drh:   int nameLen;
9b780d220b 2007-07-31       drh:   int skip;
9b780d220b 2007-07-31       drh:   int toOut;
9b780d220b 2007-07-31       drh:   int iStart;
9b780d220b 2007-07-31       drh:   int iCRC;
9b780d220b 2007-07-31       drh:   int nByte;
9b780d220b 2007-07-31       drh:   int nByteCompr;
9b780d220b 2007-07-31       drh:   char *z;
9b780d220b 2007-07-31       drh:   char zHdr[30];
9b780d220b 2007-07-31       drh:   char zBuf[100];
9b780d220b 2007-07-31       drh:   char zOutBuf[100000];
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh:   /* Fill in as much of the header as we know.
9b780d220b 2007-07-31       drh:   */
9b780d220b 2007-07-31       drh:   nameLen = strlen(zName);
9b780d220b 2007-07-31       drh:   put32(&zHdr[0], 0x04034b50);
9b780d220b 2007-07-31       drh:   put16(&zHdr[4], 0x0014);
9b780d220b 2007-07-31       drh:   put16(&zHdr[6], 0);
9b780d220b 2007-07-31       drh:   put16(&zHdr[8], 8);
dead090c0b 2007-07-31       drh:   put16(&zHdr[10], dosTime);
dead090c0b 2007-07-31       drh:   put16(&zHdr[12], dosDate);
9b780d220b 2007-07-31       drh:   put16(&zHdr[26], nameLen);
9b780d220b 2007-07-31       drh:   put16(&zHdr[28], 0);
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh:   /* Write the header and filename.
9b780d220b 2007-07-31       drh:   */
9b780d220b 2007-07-31       drh:   iStart = blob_size(&body);
9b780d220b 2007-07-31       drh:   blob_append(&body, zHdr, 30);
9b780d220b 2007-07-31       drh:   blob_append(&body, zName, nameLen);
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh:   /* The first two bytes that come out of the deflate compressor are
9b780d220b 2007-07-31       drh:   ** some kind of header that ZIP does not use.  So skip the first two
9b780d220b 2007-07-31       drh:   ** output bytes.
9b780d220b 2007-07-31       drh:   */
9b780d220b 2007-07-31       drh:   skip = 2;
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh:   /* Write the compressed file.  Compute the CRC as we progress.
9b780d220b 2007-07-31       drh:   */
9b780d220b 2007-07-31       drh:   stream.zalloc = (alloc_func)0;
9b780d220b 2007-07-31       drh:   stream.zfree = (free_func)0;
9b780d220b 2007-07-31       drh:   stream.opaque = 0;
9b780d220b 2007-07-31       drh:   stream.avail_in = blob_size(pFile);
9b780d220b 2007-07-31       drh:   stream.next_in = (unsigned char*)blob_buffer(pFile);
9b780d220b 2007-07-31       drh:   stream.avail_out = sizeof(zOutBuf);
9b780d220b 2007-07-31       drh:   stream.next_out = (unsigned char*)zOutBuf;
9b780d220b 2007-07-31       drh:   deflateInit(&stream, 9);
9b780d220b 2007-07-31       drh:   iCRC = crc32(0, stream.next_in, stream.avail_in);
9b780d220b 2007-07-31       drh:   while( stream.avail_in>0 ){
9b780d220b 2007-07-31       drh:     deflate(&stream, 0);
9b780d220b 2007-07-31       drh:     toOut = sizeof(zOutBuf) - stream.avail_out;
9b780d220b 2007-07-31       drh:     if( toOut>skip ){
9b780d220b 2007-07-31       drh:       blob_append(&body, &zOutBuf[skip], toOut - skip);
9b780d220b 2007-07-31       drh:       skip = 0;
9b780d220b 2007-07-31       drh:     }else{
9b780d220b 2007-07-31       drh:       skip -= toOut;
9b780d220b 2007-07-31       drh:     }
9b780d220b 2007-07-31       drh:     stream.avail_out = sizeof(zOutBuf);
9b780d220b 2007-07-31       drh:     stream.next_out = (unsigned char*)zOutBuf;
9b780d220b 2007-07-31       drh:   }
9b780d220b 2007-07-31       drh:   do{
9b780d220b 2007-07-31       drh:     stream.avail_out = sizeof(zOutBuf);
9b780d220b 2007-07-31       drh:     stream.next_out = (unsigned char*)zOutBuf;
9b780d220b 2007-07-31       drh:     deflate(&stream, Z_FINISH);
9b780d220b 2007-07-31       drh:     toOut = sizeof(zOutBuf) - stream.avail_out;
9b780d220b 2007-07-31       drh:     if( toOut>skip ){
9b780d220b 2007-07-31       drh:       blob_append(&body, &zOutBuf[skip], toOut - skip);
9b780d220b 2007-07-31       drh:       skip = 0;
9b780d220b 2007-07-31       drh:     }else{
9b780d220b 2007-07-31       drh:       skip -= toOut;
9b780d220b 2007-07-31       drh:     }
9b780d220b 2007-07-31       drh:   }while( stream.avail_out==0 );
9b780d220b 2007-07-31       drh:   nByte = stream.total_in;
9b780d220b 2007-07-31       drh:   nByteCompr = stream.total_out - 2;
9b780d220b 2007-07-31       drh:   deflateEnd(&stream);
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh:   /* Go back and write the header, now that we know the compressed file size.
9b780d220b 2007-07-31       drh:   */
9b780d220b 2007-07-31       drh:   z = &blob_buffer(&body)[iStart];
9b780d220b 2007-07-31       drh:   put32(&z[14], iCRC);
9b780d220b 2007-07-31       drh:   put32(&z[18], nByteCompr);
9b780d220b 2007-07-31       drh:   put32(&z[22], nByte);
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh:   /* Make an entry in the tables of contents
9b780d220b 2007-07-31       drh:   */
9b780d220b 2007-07-31       drh:   memset(zBuf, 0, sizeof(zBuf));
9b780d220b 2007-07-31       drh:   put32(&zBuf[0], 0x02014b50);
9b780d220b 2007-07-31       drh:   put16(&zBuf[4], 0x0317);
9b780d220b 2007-07-31       drh:   put16(&zBuf[6], 0x0014);
9b780d220b 2007-07-31       drh:   put16(&zBuf[8], 0);
9b780d220b 2007-07-31       drh:   put16(&zBuf[10], 0x0008);
dead090c0b 2007-07-31       drh:   put16(&zBuf[12], dosTime);
dead090c0b 2007-07-31       drh:   put16(&zBuf[14], dosDate);
9b780d220b 2007-07-31       drh:   put32(&zBuf[16], iCRC);
9b780d220b 2007-07-31       drh:   put32(&zBuf[20], nByteCompr);
9b780d220b 2007-07-31       drh:   put32(&zBuf[24], nByte);
9b780d220b 2007-07-31       drh:   put16(&zBuf[28], nameLen);
9b780d220b 2007-07-31       drh:   put16(&zBuf[30], 0);
9b780d220b 2007-07-31       drh:   put16(&zBuf[32], 0);
deb6f2af4f 2009-06-20       drh:   put16(&zBuf[34], 0);
9b780d220b 2007-07-31       drh:   put16(&zBuf[36], 0);
7ae01ee47b 2008-09-19   stephan:   put32(&zBuf[38], ((unsigned)(0100000 | 0644))<<16);
9b780d220b 2007-07-31       drh:   put32(&zBuf[42], iStart);
9b780d220b 2007-07-31       drh:   blob_append(&toc, zBuf, 46);
9b780d220b 2007-07-31       drh:   blob_append(&toc, zName, nameLen);
9b780d220b 2007-07-31       drh:   nEntry++;
9b780d220b 2007-07-31       drh: }
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh: /*
9b780d220b 2007-07-31       drh: ** Write the ZIP archive into the given BLOB.
9b780d220b 2007-07-31       drh: */
dead090c0b 2007-07-31       drh: void zip_close(Blob *pZip){
9b780d220b 2007-07-31       drh:   int iTocStart;
9b780d220b 2007-07-31       drh:   int iTocEnd;
9b780d220b 2007-07-31       drh:   char zBuf[30];
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh:   iTocStart = blob_size(&body);
9b780d220b 2007-07-31       drh:   blob_append(&body, blob_buffer(&toc), blob_size(&toc));
9b780d220b 2007-07-31       drh:   iTocEnd = blob_size(&body);
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh:   memset(zBuf, 0, sizeof(zBuf));
9b780d220b 2007-07-31       drh:   put32(&zBuf[0], 0x06054b50);
9b780d220b 2007-07-31       drh:   put16(&zBuf[4], 0);
9b780d220b 2007-07-31       drh:   put16(&zBuf[6], 0);
9b780d220b 2007-07-31       drh:   put16(&zBuf[8], nEntry);
9b780d220b 2007-07-31       drh:   put16(&zBuf[10], nEntry);
9b780d220b 2007-07-31       drh:   put32(&zBuf[12], iTocEnd - iTocStart);
9b780d220b 2007-07-31       drh:   put32(&zBuf[16], iTocStart);
9b780d220b 2007-07-31       drh:   put16(&zBuf[20], 0);
9b780d220b 2007-07-31       drh:   blob_append(&body, zBuf, 22);
9b780d220b 2007-07-31       drh:   blob_reset(&toc);
9b780d220b 2007-07-31       drh:   *pZip = body;
9b780d220b 2007-07-31       drh:   blob_zero(&body);
9b780d220b 2007-07-31       drh:   nEntry = 0;
9b780d220b 2007-07-31       drh: }
9b780d220b 2007-07-31       drh: 
9b780d220b 2007-07-31       drh: /*
9b780d220b 2007-07-31       drh: ** COMMAND: test-filezip
9b780d220b 2007-07-31       drh: **
9b780d220b 2007-07-31       drh: ** Generate a ZIP archive specified by the first argument that
9b780d220b 2007-07-31       drh: ** contains files given in the second and subsequent arguments.
9b780d220b 2007-07-31       drh: */
9b780d220b 2007-07-31       drh: void filezip_cmd(void){
9b780d220b 2007-07-31       drh:   int i;
9b780d220b 2007-07-31       drh:   Blob zip;
9b780d220b 2007-07-31       drh:   Blob file;
9b780d220b 2007-07-31       drh:   if( g.argc<3 ){
9b780d220b 2007-07-31       drh:     usage("ARCHIVE FILE....");
9b780d220b 2007-07-31       drh:   }
9b780d220b 2007-07-31       drh:   zip_open();
9b780d220b 2007-07-31       drh:   for(i=3; i<g.argc; i++){
9b780d220b 2007-07-31       drh:     blob_zero(&file);
9b780d220b 2007-07-31       drh:     blob_read_from_file(&file, g.argv[i]);
9b780d220b 2007-07-31       drh:     zip_add_file(g.argv[i], &file);
9b780d220b 2007-07-31       drh:     blob_reset(&file);
9b780d220b 2007-07-31       drh:   }
9b780d220b 2007-07-31       drh:   zip_close(&zip);
9b780d220b 2007-07-31       drh:   blob_write_to_file(&zip, g.argv[2]);
dead090c0b 2007-07-31       drh: }
dead090c0b 2007-07-31       drh: 
dead090c0b 2007-07-31       drh: /*
dead090c0b 2007-07-31       drh: ** Given the RID for a manifest, construct a ZIP archive containing
dead090c0b 2007-07-31       drh: ** all files in the corresponding baseline.
dead090c0b 2007-07-31       drh: **
dead090c0b 2007-07-31       drh: ** If RID is for an object that is not a real manifest, then the
dead090c0b 2007-07-31       drh: ** resulting ZIP archive contains a single file which is the RID
dead090c0b 2007-07-31       drh: ** object.
dead090c0b 2007-07-31       drh: **
dead090c0b 2007-07-31       drh: ** If the RID object does not exist in the repository, then
dead090c0b 2007-07-31       drh: ** pZip is zeroed.
974fd92330 2008-02-08   stephan: **
4bbb00a8c8 2008-02-08       drh: ** zDir is a "synthetic" subdirectory which all zipped files get
974fd92330 2008-02-08   stephan: ** added to as part of the zip file. It may be 0 or an empty string,
974fd92330 2008-02-08   stephan: ** in which case it is ignored. The intention is to create a zip which
974fd92330 2008-02-08   stephan: ** politely expands into a subdir instead of filling your current dir
974fd92330 2008-02-08   stephan: ** with source files. For example, pass a UUID or "ProjectName".
974fd92330 2008-02-08   stephan: **
dead090c0b 2007-07-31       drh: */
4bbb00a8c8 2008-02-08       drh: void zip_of_baseline(int rid, Blob *pZip, const char *zDir){
dead090c0b 2007-07-31       drh:   int i;
95e17f4e3f 2007-08-25       drh:   Blob mfile, file, hash;
dead090c0b 2007-07-31       drh:   Manifest m;
4bbb00a8c8 2008-02-08       drh:   Blob filename;
4bbb00a8c8 2008-02-08       drh:   int nPrefix;
dead090c0b 2007-07-31       drh: 
dead090c0b 2007-07-31       drh:   content_get(rid, &mfile);
dead090c0b 2007-07-31       drh:   if( blob_size(&mfile)==0 ){
dead090c0b 2007-07-31       drh:     blob_zero(pZip);
dead090c0b 2007-07-31       drh:     return;
dead090c0b 2007-07-31       drh:   }
dead090c0b 2007-07-31       drh:   blob_zero(&file);
95e17f4e3f 2007-08-25       drh:   blob_zero(&hash);
dead090c0b 2007-07-31       drh:   blob_copy(&file, &mfile);
4bbb00a8c8 2008-02-08       drh:   blob_zero(&filename);
dead090c0b 2007-07-31       drh:   zip_open();
974fd92330 2008-02-08   stephan: 
4bbb00a8c8 2008-02-08       drh:   if( zDir && zDir[0] ){
4bbb00a8c8 2008-02-08       drh:     blob_appendf(&filename, "%s/", zDir);
974fd92330 2008-02-08   stephan:   }
4bbb00a8c8 2008-02-08       drh:   nPrefix = blob_size(&filename);
4bbb00a8c8 2008-02-08       drh: 
dead090c0b 2007-07-31       drh:   if( manifest_parse(&m, &mfile) ){
dead090c0b 2007-07-31       drh:     zip_set_timedate(m.rDate);
4bbb00a8c8 2008-02-08       drh:     blob_append(&filename, "manifest", -1);
4bbb00a8c8 2008-02-08       drh:     zip_add_file(blob_str(&filename), &file);
95e17f4e3f 2007-08-25       drh:     sha1sum_blob(&file, &hash);
dead090c0b 2007-07-31       drh:     blob_reset(&file);
95e17f4e3f 2007-08-25       drh:     blob_append(&hash, "\n", 1);
4bbb00a8c8 2008-02-08       drh:     blob_resize(&filename, nPrefix);
4bbb00a8c8 2008-02-08       drh:     blob_append(&filename, "manifest.uuid", -1);
4bbb00a8c8 2008-02-08       drh:     zip_add_file(blob_str(&filename), &hash);
95e17f4e3f 2007-08-25       drh:     blob_reset(&hash);
dead090c0b 2007-07-31       drh:     for(i=0; i<m.nFile; i++){
dead090c0b 2007-07-31       drh:       int fid = uuid_to_rid(m.aFile[i].zUuid, 0);
dead090c0b 2007-07-31       drh:       if( fid ){
dead090c0b 2007-07-31       drh:         content_get(fid, &file);
4bbb00a8c8 2008-02-08       drh:         blob_resize(&filename, nPrefix);
4bbb00a8c8 2008-02-08       drh:         blob_append(&filename, m.aFile[i].zName, -1);
4bbb00a8c8 2008-02-08       drh:         zip_add_file(blob_str(&filename), &file);
dead090c0b 2007-07-31       drh:         blob_reset(&file);
dead090c0b 2007-07-31       drh:       }
dead090c0b 2007-07-31       drh:     }
dead090c0b 2007-07-31       drh:     manifest_clear(&m);
dead090c0b 2007-07-31       drh:   }else{
dead090c0b 2007-07-31       drh:     blob_reset(&mfile);
dead090c0b 2007-07-31       drh:     blob_reset(&file);
dead090c0b 2007-07-31       drh:   }
4bbb00a8c8 2008-02-08       drh:   blob_reset(&filename);
dead090c0b 2007-07-31       drh:   zip_close(pZip);
dead090c0b 2007-07-31       drh: }
dead090c0b 2007-07-31       drh: 
dead090c0b 2007-07-31       drh: /*
dead090c0b 2007-07-31       drh: ** COMMAND: test-baseline-zip
dead090c0b 2007-07-31       drh: **
dead090c0b 2007-07-31       drh: ** Generate a ZIP archive for a specified baseline.
dead090c0b 2007-07-31       drh: */
dead090c0b 2007-07-31       drh: void baseline_zip_cmd(void){
dead090c0b 2007-07-31       drh:   int rid;
dead090c0b 2007-07-31       drh:   Blob zip;
dead090c0b 2007-07-31       drh:   if( g.argc!=4 ){
dead090c0b 2007-07-31       drh:     usage("UUID ZIPFILE");
dead090c0b 2007-07-31       drh:   }
dead090c0b 2007-07-31       drh:   db_must_be_within_tree();
dead090c0b 2007-07-31       drh:   rid = name_to_rid(g.argv[2]);
974fd92330 2008-02-08   stephan:   zip_of_baseline(rid, &zip, g.argv[2]);
dead090c0b 2007-07-31       drh:   blob_write_to_file(&zip, g.argv[3]);
6dab6149b1 2007-08-01       drh: }
6dab6149b1 2007-08-01       drh: 
6dab6149b1 2007-08-01       drh: /*
6dab6149b1 2007-08-01       drh: ** WEBPAGE: zip
677aa71bca 2007-10-12       drh: ** URL: /zip/RID.zip
6dab6149b1 2007-08-01       drh: **
677aa71bca 2007-10-12       drh: ** Generate a ZIP archive for the baseline.
677aa71bca 2007-10-12       drh: ** Return that ZIP archive as the HTTP reply content.
6dab6149b1 2007-08-01       drh: */
6dab6149b1 2007-08-01       drh: void baseline_zip_page(void){
6dab6149b1 2007-08-01       drh:   int rid;
417dd898ab 2008-08-13    hintze:   char *zName, *zRid;
417dd898ab 2008-08-13    hintze:   int nName, nRid;
6dab6149b1 2007-08-01       drh:   Blob zip;
6dab6149b1 2007-08-01       drh: 
6dab6149b1 2007-08-01       drh:   login_check_credentials();
fa6e993017 2008-08-12       cle:   if( !g.okZip && (!g.okRead || !g.okHistory) ){ login_needed(); return; }
677aa71bca 2007-10-12       drh:   zName = mprintf("%s", PD("name",""));
73a9b3d5d1 2008-02-08       drh:   nName = strlen(zName);
81a96aadf3 2008-08-17       cle:   zRid = mprintf("%s", PD("uuid",""));
417dd898ab 2008-08-13    hintze:   nRid = strlen(zRid);
73a9b3d5d1 2008-02-08       drh:   for(nName=strlen(zName)-1; nName>5; nName--){
73a9b3d5d1 2008-02-08       drh:     if( zName[nName]=='.' ){
73a9b3d5d1 2008-02-08       drh:       zName[nName] = 0;
6dab6149b1 2007-08-01       drh:       break;
6dab6149b1 2007-08-01       drh:     }
6dab6149b1 2007-08-01       drh:   }
417dd898ab 2008-08-13    hintze:   rid = name_to_rid(nRid?zRid:zName);
6dab6149b1 2007-08-01       drh:   if( rid==0 ){
6dab6149b1 2007-08-01       drh:     @ Not found
6dab6149b1 2007-08-01       drh:     return;
6dab6149b1 2007-08-01       drh:   }
417dd898ab 2008-08-13    hintze:   if( nRid==0 && nName>10 ) zName[10] = 0;
974fd92330 2008-02-08   stephan:   zip_of_baseline(rid, &zip, zName);
1ce0ac53ef 2008-02-12   stephan:   free( zName );
417dd898ab 2008-08-13    hintze:   free( zRid );
6dab6149b1 2007-08-01       drh:   cgi_set_content(&zip);
6dab6149b1 2007-08-01       drh:   cgi_set_content_type("application/zip");
9b780d220b 2007-07-31       drh: }