Fossil SCM

Add an "extended timestamp" field to generated ZIP archives. The extended timestamp is in UTC so it does not mangle the time when the server and client are in different timezones. Ticket [28044ab5a42b75]

drh 2009-08-15 02:17 trunk
Commit 90048e0b30f12377b33110b279f19299643fe830
1 file changed +135 -66
+135 -66
--- src/zip.c
+++ src/zip.c
@@ -48,10 +48,13 @@
4848
static Blob body; /* The body of the ZIP archive */
4949
static Blob toc; /* The table of contents */
5050
static int nEntry; /* Number of files */
5151
static int dosTime; /* DOS-format time */
5252
static int dosDate; /* DOS-format date */
53
+static int unixTime; /* Seconds since 1970 */
54
+static int nDir; /* Number of entries in azDir[] */
55
+static char **azDir; /* Directory names already added to the archive */
5356
5457
/*
5558
** Initialize a new ZIP archive.
5659
*/
5760
void zip_open(void){
@@ -58,10 +61,11 @@
5861
blob_zero(&body);
5962
blob_zero(&toc);
6063
nEntry = 0;
6164
dosTime = 0;
6265
dosDate = 0;
66
+ unixTime = 0;
6367
}
6468
6569
/*
6670
** Set the date and time values from an ISO8601 date string.
6771
*/
@@ -84,10 +88,37 @@
8488
*/
8589
void zip_set_timedate(double rDate){
8690
char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
8791
zip_set_timedate_from_str(zDate);
8892
free(zDate);
93
+ unixTime = (rDate - 2440587.5)*86400.0;
94
+}
95
+
96
+/*
97
+** If the given filename includes one or more directory entries, make
98
+** sure the directories are already in the archive. If they are not
99
+** in the archive, add them.
100
+*/
101
+void zip_add_folders(char *zName){
102
+ int i, c;
103
+ int j;
104
+ for(i=0; zName[i]; i++){
105
+ if( zName[i]=='/' ){
106
+ c = zName[i+1];
107
+ zName[i+1] = 0;
108
+ for(j=0; j<nDir; j++){
109
+ if( strcmp(zName, azDir[j])==0 ) break;
110
+ }
111
+ if( j>=nDir ){
112
+ nDir++;
113
+ azDir = realloc(azDir, nDir);
114
+ azDir[j] = sqlite3_mprintf("%s", zName);
115
+ zip_add_file(zName, 0);
116
+ }
117
+ zName[i+1] = c;
118
+ }
119
+ }
89120
}
90121
91122
/*
92123
** Append a single file to a growing ZIP archive.
93124
**
@@ -98,110 +129,135 @@
98129
z_stream stream;
99130
int nameLen;
100131
int skip;
101132
int toOut;
102133
int iStart;
103
- int iCRC;
104
- int nByte;
105
- int nByteCompr;
134
+ int iCRC = 0;
135
+ int nByte = 0;
136
+ int nByteCompr = 0;
137
+ int nBlob; /* Size of the blob */
138
+ int iMethod; /* Compression method. */
139
+ int iMode = 0644; /* Access permissions */
106140
char *z;
107141
char zHdr[30];
142
+ char zExTime[13];
108143
char zBuf[100];
109144
char zOutBuf[100000];
110145
111146
/* Fill in as much of the header as we know.
112147
*/
148
+ nBlob = pFile ? blob_size(pFile) : 0;
149
+ if( nBlob>0 ){
150
+ iMethod = 8;
151
+ iMode = 0100644;
152
+ }else{
153
+ iMethod = 0;
154
+ iMode = 040755;
155
+ }
113156
nameLen = strlen(zName);
157
+ memset(zHdr, 0, sizeof(zHdr));
114158
put32(&zHdr[0], 0x04034b50);
115
- put16(&zHdr[4], 0x0014);
159
+ put16(&zHdr[4], 0x000a);
116160
put16(&zHdr[6], 0);
117
- put16(&zHdr[8], 8);
161
+ put16(&zHdr[8], iMethod);
118162
put16(&zHdr[10], dosTime);
119163
put16(&zHdr[12], dosDate);
120164
put16(&zHdr[26], nameLen);
121
- put16(&zHdr[28], 0);
165
+ put16(&zHdr[28], 13);
166
+
167
+ put16(&zExTime[0], 0x5455);
168
+ put16(&zExTime[2], 9);
169
+ zExTime[4] = 3;
170
+ put32(&zExTime[5], unixTime);
171
+ put32(&zExTime[9], unixTime);
172
+
122173
123174
/* Write the header and filename.
124175
*/
125176
iStart = blob_size(&body);
126177
blob_append(&body, zHdr, 30);
127178
blob_append(&body, zName, nameLen);
128
-
129
- /* The first two bytes that come out of the deflate compressor are
130
- ** some kind of header that ZIP does not use. So skip the first two
131
- ** output bytes.
132
- */
133
- skip = 2;
134
-
135
- /* Write the compressed file. Compute the CRC as we progress.
136
- */
137
- stream.zalloc = (alloc_func)0;
138
- stream.zfree = (free_func)0;
139
- stream.opaque = 0;
140
- stream.avail_in = blob_size(pFile);
141
- stream.next_in = (unsigned char*)blob_buffer(pFile);
142
- stream.avail_out = sizeof(zOutBuf);
143
- stream.next_out = (unsigned char*)zOutBuf;
144
- deflateInit(&stream, 9);
145
- iCRC = crc32(0, stream.next_in, stream.avail_in);
146
- while( stream.avail_in>0 ){
147
- deflate(&stream, 0);
148
- toOut = sizeof(zOutBuf) - stream.avail_out;
149
- if( toOut>skip ){
150
- blob_append(&body, &zOutBuf[skip], toOut - skip);
151
- skip = 0;
152
- }else{
153
- skip -= toOut;
154
- }
155
- stream.avail_out = sizeof(zOutBuf);
156
- stream.next_out = (unsigned char*)zOutBuf;
157
- }
158
- do{
159
- stream.avail_out = sizeof(zOutBuf);
160
- stream.next_out = (unsigned char*)zOutBuf;
161
- deflate(&stream, Z_FINISH);
162
- toOut = sizeof(zOutBuf) - stream.avail_out;
163
- if( toOut>skip ){
164
- blob_append(&body, &zOutBuf[skip], toOut - skip);
165
- skip = 0;
166
- }else{
167
- skip -= toOut;
168
- }
169
- }while( stream.avail_out==0 );
170
- nByte = stream.total_in;
171
- nByteCompr = stream.total_out - 2;
172
- deflateEnd(&stream);
173
-
174
- /* Go back and write the header, now that we know the compressed file size.
175
- */
176
- z = &blob_buffer(&body)[iStart];
177
- put32(&z[14], iCRC);
178
- put32(&z[18], nByteCompr);
179
- put32(&z[22], nByte);
180
-
179
+ blob_append(&body, zExTime, 13);
180
+
181
+ if( nBlob>0 ){
182
+ /* The first two bytes that come out of the deflate compressor are
183
+ ** some kind of header that ZIP does not use. So skip the first two
184
+ ** output bytes.
185
+ */
186
+ skip = 2;
187
+
188
+ /* Write the compressed file. Compute the CRC as we progress.
189
+ */
190
+ stream.zalloc = (alloc_func)0;
191
+ stream.zfree = (free_func)0;
192
+ stream.opaque = 0;
193
+ stream.avail_in = blob_size(pFile);
194
+ stream.next_in = (unsigned char*)blob_buffer(pFile);
195
+ stream.avail_out = sizeof(zOutBuf);
196
+ stream.next_out = (unsigned char*)zOutBuf;
197
+ deflateInit(&stream, 9);
198
+ iCRC = crc32(0, stream.next_in, stream.avail_in);
199
+ while( stream.avail_in>0 ){
200
+ deflate(&stream, 0);
201
+ toOut = sizeof(zOutBuf) - stream.avail_out;
202
+ if( toOut>skip ){
203
+ blob_append(&body, &zOutBuf[skip], toOut - skip);
204
+ skip = 0;
205
+ }else{
206
+ skip -= toOut;
207
+ }
208
+ stream.avail_out = sizeof(zOutBuf);
209
+ stream.next_out = (unsigned char*)zOutBuf;
210
+ }
211
+ do{
212
+ stream.avail_out = sizeof(zOutBuf);
213
+ stream.next_out = (unsigned char*)zOutBuf;
214
+ deflate(&stream, Z_FINISH);
215
+ toOut = sizeof(zOutBuf) - stream.avail_out;
216
+ if( toOut>skip ){
217
+ blob_append(&body, &zOutBuf[skip], toOut - skip);
218
+ skip = 0;
219
+ }else{
220
+ skip -= toOut;
221
+ }
222
+ }while( stream.avail_out==0 );
223
+ nByte = stream.total_in;
224
+ nByteCompr = stream.total_out - 2;
225
+ deflateEnd(&stream);
226
+
227
+ /* Go back and write the header, now that we know the compressed file size.
228
+ */
229
+ z = &blob_buffer(&body)[iStart];
230
+ put32(&z[14], iCRC);
231
+ put32(&z[18], nByteCompr);
232
+ put32(&z[22], nByte);
233
+ }
234
+
181235
/* Make an entry in the tables of contents
182236
*/
183237
memset(zBuf, 0, sizeof(zBuf));
184238
put32(&zBuf[0], 0x02014b50);
185239
put16(&zBuf[4], 0x0317);
186
- put16(&zBuf[6], 0x0014);
240
+ put16(&zBuf[6], 0x000a);
187241
put16(&zBuf[8], 0);
188
- put16(&zBuf[10], 0x0008);
242
+ put16(&zBuf[10], iMethod);
189243
put16(&zBuf[12], dosTime);
190244
put16(&zBuf[14], dosDate);
191245
put32(&zBuf[16], iCRC);
192246
put32(&zBuf[20], nByteCompr);
193247
put32(&zBuf[24], nByte);
194248
put16(&zBuf[28], nameLen);
195
- put16(&zBuf[30], 0);
249
+ put16(&zBuf[30], 9);
196250
put16(&zBuf[32], 0);
197251
put16(&zBuf[34], 0);
198252
put16(&zBuf[36], 0);
199
- put32(&zBuf[38], ((unsigned)(0100000 | 0644))<<16);
253
+ put32(&zBuf[38], ((unsigned)iMode)<<16);
200254
put32(&zBuf[42], iStart);
201255
blob_append(&toc, zBuf, 46);
202256
blob_append(&toc, zName, nameLen);
257
+ put16(&zExTime[2], 5);
258
+ blob_append(&toc, zExTime, 9);
203259
nEntry++;
204260
}
205261
206262
207263
/*
@@ -208,10 +264,11 @@
208264
** Write the ZIP archive into the given BLOB.
209265
*/
210266
void zip_close(Blob *pZip){
211267
int iTocStart;
212268
int iTocEnd;
269
+ int i;
213270
char zBuf[30];
214271
215272
iTocStart = blob_size(&body);
216273
blob_append(&body, blob_buffer(&toc), blob_size(&toc));
217274
iTocEnd = blob_size(&body);
@@ -228,10 +285,16 @@
228285
blob_append(&body, zBuf, 22);
229286
blob_reset(&toc);
230287
*pZip = body;
231288
blob_zero(&body);
232289
nEntry = 0;
290
+ for(i=0; i<nDir; i++){
291
+ sqlite3_free(azDir[i]);
292
+ }
293
+ free(azDir);
294
+ nDir = 0;
295
+ azDir = 0;
233296
}
234297
235298
/*
236299
** COMMAND: test-filezip
237300
**
@@ -296,27 +359,33 @@
296359
blob_appendf(&filename, "%s/", zDir);
297360
}
298361
nPrefix = blob_size(&filename);
299362
300363
if( manifest_parse(&m, &mfile) ){
364
+ char *zName;
301365
zip_set_timedate(m.rDate);
302366
blob_append(&filename, "manifest", -1);
303
- zip_add_file(blob_str(&filename), &file);
367
+ zName = blob_str(&filename);
368
+ zip_add_folders(zName);
369
+ zip_add_file(zName, &file);
304370
sha1sum_blob(&file, &hash);
305371
blob_reset(&file);
306372
blob_append(&hash, "\n", 1);
307373
blob_resize(&filename, nPrefix);
308374
blob_append(&filename, "manifest.uuid", -1);
309
- zip_add_file(blob_str(&filename), &hash);
375
+ zName = blob_str(&filename);
376
+ zip_add_file(zName, &hash);
310377
blob_reset(&hash);
311378
for(i=0; i<m.nFile; i++){
312379
int fid = uuid_to_rid(m.aFile[i].zUuid, 0);
313380
if( fid ){
314381
content_get(fid, &file);
315382
blob_resize(&filename, nPrefix);
316383
blob_append(&filename, m.aFile[i].zName, -1);
317
- zip_add_file(blob_str(&filename), &file);
384
+ zName = blob_str(&filename);
385
+ zip_add_folders(zName);
386
+ zip_add_file(zName, &file);
318387
blob_reset(&file);
319388
}
320389
}
321390
manifest_clear(&m);
322391
}else{
323392
--- src/zip.c
+++ src/zip.c
@@ -48,10 +48,13 @@
48 static Blob body; /* The body of the ZIP archive */
49 static Blob toc; /* The table of contents */
50 static int nEntry; /* Number of files */
51 static int dosTime; /* DOS-format time */
52 static int dosDate; /* DOS-format date */
 
 
 
53
54 /*
55 ** Initialize a new ZIP archive.
56 */
57 void zip_open(void){
@@ -58,10 +61,11 @@
58 blob_zero(&body);
59 blob_zero(&toc);
60 nEntry = 0;
61 dosTime = 0;
62 dosDate = 0;
 
63 }
64
65 /*
66 ** Set the date and time values from an ISO8601 date string.
67 */
@@ -84,10 +88,37 @@
84 */
85 void zip_set_timedate(double rDate){
86 char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
87 zip_set_timedate_from_str(zDate);
88 free(zDate);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89 }
90
91 /*
92 ** Append a single file to a growing ZIP archive.
93 **
@@ -98,110 +129,135 @@
98 z_stream stream;
99 int nameLen;
100 int skip;
101 int toOut;
102 int iStart;
103 int iCRC;
104 int nByte;
105 int nByteCompr;
 
 
 
106 char *z;
107 char zHdr[30];
 
108 char zBuf[100];
109 char zOutBuf[100000];
110
111 /* Fill in as much of the header as we know.
112 */
 
 
 
 
 
 
 
 
113 nameLen = strlen(zName);
 
114 put32(&zHdr[0], 0x04034b50);
115 put16(&zHdr[4], 0x0014);
116 put16(&zHdr[6], 0);
117 put16(&zHdr[8], 8);
118 put16(&zHdr[10], dosTime);
119 put16(&zHdr[12], dosDate);
120 put16(&zHdr[26], nameLen);
121 put16(&zHdr[28], 0);
 
 
 
 
 
 
 
122
123 /* Write the header and filename.
124 */
125 iStart = blob_size(&body);
126 blob_append(&body, zHdr, 30);
127 blob_append(&body, zName, nameLen);
128
129 /* The first two bytes that come out of the deflate compressor are
130 ** some kind of header that ZIP does not use. So skip the first two
131 ** output bytes.
132 */
133 skip = 2;
134
135 /* Write the compressed file. Compute the CRC as we progress.
136 */
137 stream.zalloc = (alloc_func)0;
138 stream.zfree = (free_func)0;
139 stream.opaque = 0;
140 stream.avail_in = blob_size(pFile);
141 stream.next_in = (unsigned char*)blob_buffer(pFile);
142 stream.avail_out = sizeof(zOutBuf);
143 stream.next_out = (unsigned char*)zOutBuf;
144 deflateInit(&stream, 9);
145 iCRC = crc32(0, stream.next_in, stream.avail_in);
146 while( stream.avail_in>0 ){
147 deflate(&stream, 0);
148 toOut = sizeof(zOutBuf) - stream.avail_out;
149 if( toOut>skip ){
150 blob_append(&body, &zOutBuf[skip], toOut - skip);
151 skip = 0;
152 }else{
153 skip -= toOut;
154 }
155 stream.avail_out = sizeof(zOutBuf);
156 stream.next_out = (unsigned char*)zOutBuf;
157 }
158 do{
159 stream.avail_out = sizeof(zOutBuf);
160 stream.next_out = (unsigned char*)zOutBuf;
161 deflate(&stream, Z_FINISH);
162 toOut = sizeof(zOutBuf) - stream.avail_out;
163 if( toOut>skip ){
164 blob_append(&body, &zOutBuf[skip], toOut - skip);
165 skip = 0;
166 }else{
167 skip -= toOut;
168 }
169 }while( stream.avail_out==0 );
170 nByte = stream.total_in;
171 nByteCompr = stream.total_out - 2;
172 deflateEnd(&stream);
173
174 /* Go back and write the header, now that we know the compressed file size.
175 */
176 z = &blob_buffer(&body)[iStart];
177 put32(&z[14], iCRC);
178 put32(&z[18], nByteCompr);
179 put32(&z[22], nByte);
180
 
 
 
181 /* Make an entry in the tables of contents
182 */
183 memset(zBuf, 0, sizeof(zBuf));
184 put32(&zBuf[0], 0x02014b50);
185 put16(&zBuf[4], 0x0317);
186 put16(&zBuf[6], 0x0014);
187 put16(&zBuf[8], 0);
188 put16(&zBuf[10], 0x0008);
189 put16(&zBuf[12], dosTime);
190 put16(&zBuf[14], dosDate);
191 put32(&zBuf[16], iCRC);
192 put32(&zBuf[20], nByteCompr);
193 put32(&zBuf[24], nByte);
194 put16(&zBuf[28], nameLen);
195 put16(&zBuf[30], 0);
196 put16(&zBuf[32], 0);
197 put16(&zBuf[34], 0);
198 put16(&zBuf[36], 0);
199 put32(&zBuf[38], ((unsigned)(0100000 | 0644))<<16);
200 put32(&zBuf[42], iStart);
201 blob_append(&toc, zBuf, 46);
202 blob_append(&toc, zName, nameLen);
 
 
203 nEntry++;
204 }
205
206
207 /*
@@ -208,10 +264,11 @@
208 ** Write the ZIP archive into the given BLOB.
209 */
210 void zip_close(Blob *pZip){
211 int iTocStart;
212 int iTocEnd;
 
213 char zBuf[30];
214
215 iTocStart = blob_size(&body);
216 blob_append(&body, blob_buffer(&toc), blob_size(&toc));
217 iTocEnd = blob_size(&body);
@@ -228,10 +285,16 @@
228 blob_append(&body, zBuf, 22);
229 blob_reset(&toc);
230 *pZip = body;
231 blob_zero(&body);
232 nEntry = 0;
 
 
 
 
 
 
233 }
234
235 /*
236 ** COMMAND: test-filezip
237 **
@@ -296,27 +359,33 @@
296 blob_appendf(&filename, "%s/", zDir);
297 }
298 nPrefix = blob_size(&filename);
299
300 if( manifest_parse(&m, &mfile) ){
 
301 zip_set_timedate(m.rDate);
302 blob_append(&filename, "manifest", -1);
303 zip_add_file(blob_str(&filename), &file);
 
 
304 sha1sum_blob(&file, &hash);
305 blob_reset(&file);
306 blob_append(&hash, "\n", 1);
307 blob_resize(&filename, nPrefix);
308 blob_append(&filename, "manifest.uuid", -1);
309 zip_add_file(blob_str(&filename), &hash);
 
310 blob_reset(&hash);
311 for(i=0; i<m.nFile; i++){
312 int fid = uuid_to_rid(m.aFile[i].zUuid, 0);
313 if( fid ){
314 content_get(fid, &file);
315 blob_resize(&filename, nPrefix);
316 blob_append(&filename, m.aFile[i].zName, -1);
317 zip_add_file(blob_str(&filename), &file);
 
 
318 blob_reset(&file);
319 }
320 }
321 manifest_clear(&m);
322 }else{
323
--- src/zip.c
+++ src/zip.c
@@ -48,10 +48,13 @@
48 static Blob body; /* The body of the ZIP archive */
49 static Blob toc; /* The table of contents */
50 static int nEntry; /* Number of files */
51 static int dosTime; /* DOS-format time */
52 static int dosDate; /* DOS-format date */
53 static int unixTime; /* Seconds since 1970 */
54 static int nDir; /* Number of entries in azDir[] */
55 static char **azDir; /* Directory names already added to the archive */
56
57 /*
58 ** Initialize a new ZIP archive.
59 */
60 void zip_open(void){
@@ -58,10 +61,11 @@
61 blob_zero(&body);
62 blob_zero(&toc);
63 nEntry = 0;
64 dosTime = 0;
65 dosDate = 0;
66 unixTime = 0;
67 }
68
69 /*
70 ** Set the date and time values from an ISO8601 date string.
71 */
@@ -84,10 +88,37 @@
88 */
89 void zip_set_timedate(double rDate){
90 char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate);
91 zip_set_timedate_from_str(zDate);
92 free(zDate);
93 unixTime = (rDate - 2440587.5)*86400.0;
94 }
95
96 /*
97 ** If the given filename includes one or more directory entries, make
98 ** sure the directories are already in the archive. If they are not
99 ** in the archive, add them.
100 */
101 void zip_add_folders(char *zName){
102 int i, c;
103 int j;
104 for(i=0; zName[i]; i++){
105 if( zName[i]=='/' ){
106 c = zName[i+1];
107 zName[i+1] = 0;
108 for(j=0; j<nDir; j++){
109 if( strcmp(zName, azDir[j])==0 ) break;
110 }
111 if( j>=nDir ){
112 nDir++;
113 azDir = realloc(azDir, nDir);
114 azDir[j] = sqlite3_mprintf("%s", zName);
115 zip_add_file(zName, 0);
116 }
117 zName[i+1] = c;
118 }
119 }
120 }
121
122 /*
123 ** Append a single file to a growing ZIP archive.
124 **
@@ -98,110 +129,135 @@
129 z_stream stream;
130 int nameLen;
131 int skip;
132 int toOut;
133 int iStart;
134 int iCRC = 0;
135 int nByte = 0;
136 int nByteCompr = 0;
137 int nBlob; /* Size of the blob */
138 int iMethod; /* Compression method. */
139 int iMode = 0644; /* Access permissions */
140 char *z;
141 char zHdr[30];
142 char zExTime[13];
143 char zBuf[100];
144 char zOutBuf[100000];
145
146 /* Fill in as much of the header as we know.
147 */
148 nBlob = pFile ? blob_size(pFile) : 0;
149 if( nBlob>0 ){
150 iMethod = 8;
151 iMode = 0100644;
152 }else{
153 iMethod = 0;
154 iMode = 040755;
155 }
156 nameLen = strlen(zName);
157 memset(zHdr, 0, sizeof(zHdr));
158 put32(&zHdr[0], 0x04034b50);
159 put16(&zHdr[4], 0x000a);
160 put16(&zHdr[6], 0);
161 put16(&zHdr[8], iMethod);
162 put16(&zHdr[10], dosTime);
163 put16(&zHdr[12], dosDate);
164 put16(&zHdr[26], nameLen);
165 put16(&zHdr[28], 13);
166
167 put16(&zExTime[0], 0x5455);
168 put16(&zExTime[2], 9);
169 zExTime[4] = 3;
170 put32(&zExTime[5], unixTime);
171 put32(&zExTime[9], unixTime);
172
173
174 /* Write the header and filename.
175 */
176 iStart = blob_size(&body);
177 blob_append(&body, zHdr, 30);
178 blob_append(&body, zName, nameLen);
179 blob_append(&body, zExTime, 13);
180
181 if( nBlob>0 ){
182 /* The first two bytes that come out of the deflate compressor are
183 ** some kind of header that ZIP does not use. So skip the first two
184 ** output bytes.
185 */
186 skip = 2;
187
188 /* Write the compressed file. Compute the CRC as we progress.
189 */
190 stream.zalloc = (alloc_func)0;
191 stream.zfree = (free_func)0;
192 stream.opaque = 0;
193 stream.avail_in = blob_size(pFile);
194 stream.next_in = (unsigned char*)blob_buffer(pFile);
195 stream.avail_out = sizeof(zOutBuf);
196 stream.next_out = (unsigned char*)zOutBuf;
197 deflateInit(&stream, 9);
198 iCRC = crc32(0, stream.next_in, stream.avail_in);
199 while( stream.avail_in>0 ){
200 deflate(&stream, 0);
201 toOut = sizeof(zOutBuf) - stream.avail_out;
202 if( toOut>skip ){
203 blob_append(&body, &zOutBuf[skip], toOut - skip);
204 skip = 0;
205 }else{
206 skip -= toOut;
207 }
208 stream.avail_out = sizeof(zOutBuf);
209 stream.next_out = (unsigned char*)zOutBuf;
210 }
211 do{
212 stream.avail_out = sizeof(zOutBuf);
213 stream.next_out = (unsigned char*)zOutBuf;
214 deflate(&stream, Z_FINISH);
215 toOut = sizeof(zOutBuf) - stream.avail_out;
216 if( toOut>skip ){
217 blob_append(&body, &zOutBuf[skip], toOut - skip);
218 skip = 0;
219 }else{
220 skip -= toOut;
221 }
222 }while( stream.avail_out==0 );
223 nByte = stream.total_in;
224 nByteCompr = stream.total_out - 2;
225 deflateEnd(&stream);
226
227 /* Go back and write the header, now that we know the compressed file size.
228 */
229 z = &blob_buffer(&body)[iStart];
230 put32(&z[14], iCRC);
231 put32(&z[18], nByteCompr);
232 put32(&z[22], nByte);
233 }
234
235 /* Make an entry in the tables of contents
236 */
237 memset(zBuf, 0, sizeof(zBuf));
238 put32(&zBuf[0], 0x02014b50);
239 put16(&zBuf[4], 0x0317);
240 put16(&zBuf[6], 0x000a);
241 put16(&zBuf[8], 0);
242 put16(&zBuf[10], iMethod);
243 put16(&zBuf[12], dosTime);
244 put16(&zBuf[14], dosDate);
245 put32(&zBuf[16], iCRC);
246 put32(&zBuf[20], nByteCompr);
247 put32(&zBuf[24], nByte);
248 put16(&zBuf[28], nameLen);
249 put16(&zBuf[30], 9);
250 put16(&zBuf[32], 0);
251 put16(&zBuf[34], 0);
252 put16(&zBuf[36], 0);
253 put32(&zBuf[38], ((unsigned)iMode)<<16);
254 put32(&zBuf[42], iStart);
255 blob_append(&toc, zBuf, 46);
256 blob_append(&toc, zName, nameLen);
257 put16(&zExTime[2], 5);
258 blob_append(&toc, zExTime, 9);
259 nEntry++;
260 }
261
262
263 /*
@@ -208,10 +264,11 @@
264 ** Write the ZIP archive into the given BLOB.
265 */
266 void zip_close(Blob *pZip){
267 int iTocStart;
268 int iTocEnd;
269 int i;
270 char zBuf[30];
271
272 iTocStart = blob_size(&body);
273 blob_append(&body, blob_buffer(&toc), blob_size(&toc));
274 iTocEnd = blob_size(&body);
@@ -228,10 +285,16 @@
285 blob_append(&body, zBuf, 22);
286 blob_reset(&toc);
287 *pZip = body;
288 blob_zero(&body);
289 nEntry = 0;
290 for(i=0; i<nDir; i++){
291 sqlite3_free(azDir[i]);
292 }
293 free(azDir);
294 nDir = 0;
295 azDir = 0;
296 }
297
298 /*
299 ** COMMAND: test-filezip
300 **
@@ -296,27 +359,33 @@
359 blob_appendf(&filename, "%s/", zDir);
360 }
361 nPrefix = blob_size(&filename);
362
363 if( manifest_parse(&m, &mfile) ){
364 char *zName;
365 zip_set_timedate(m.rDate);
366 blob_append(&filename, "manifest", -1);
367 zName = blob_str(&filename);
368 zip_add_folders(zName);
369 zip_add_file(zName, &file);
370 sha1sum_blob(&file, &hash);
371 blob_reset(&file);
372 blob_append(&hash, "\n", 1);
373 blob_resize(&filename, nPrefix);
374 blob_append(&filename, "manifest.uuid", -1);
375 zName = blob_str(&filename);
376 zip_add_file(zName, &hash);
377 blob_reset(&hash);
378 for(i=0; i<m.nFile; i++){
379 int fid = uuid_to_rid(m.aFile[i].zUuid, 0);
380 if( fid ){
381 content_get(fid, &file);
382 blob_resize(&filename, nPrefix);
383 blob_append(&filename, m.aFile[i].zName, -1);
384 zName = blob_str(&filename);
385 zip_add_folders(zName);
386 zip_add_file(zName, &file);
387 blob_reset(&file);
388 }
389 }
390 manifest_clear(&m);
391 }else{
392

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button