rev |
line source |
pascal@10932
|
1 --- compressed_loop.h
|
pascal@10932
|
2 +++ compressed_loop.h
|
pascal@10935
|
3 @@ -41,6 +41,73 @@
|
pascal@10932
|
4 /* data_index (num_blocks 64bit pointers, network order)... */
|
pascal@10932
|
5 /* compressed data (gzip block compressed format)... */
|
pascal@10932
|
6
|
pascal@10933
|
7 +struct cloop_tail
|
pascal@10933
|
8 +{
|
pascal@10933
|
9 + u_int32_t index_size;
|
pascal@10933
|
10 + u_int32_t num_blocks;
|
pascal@10933
|
11 +};
|
pascal@10933
|
12 +
|
pascal@10932
|
13 +struct block_info
|
pascal@10932
|
14 +{
|
pascal@10932
|
15 + loff_t offset; /* 64-bit offsets of compressed block */
|
pascal@10932
|
16 + u_int32_t size; /* 32-bit compressed block size */
|
pascal@10932
|
17 + u_int32_t optidx; /* 32-bit index number */
|
pascal@10932
|
18 +};
|
pascal@10932
|
19 +
|
pascal@10935
|
20 +static inline char *build_index(struct block_info *offsets, unsigned long n)
|
pascal@10932
|
21 +{
|
pascal@10932
|
22 + u_int32_t *ofs32 = (u_int32_t *) offsets;
|
pascal@10932
|
23 + loff_t *ofs64 = (loff_t *) offsets;
|
pascal@10933
|
24 +
|
pascal@10932
|
25 + if (ofs32[0] == 0) {
|
pascal@10932
|
26 + if (ofs32[2]) { /* ACCELERATED KNOPPIX V1.0 */
|
pascal@10933
|
27 + while (n--) {
|
pascal@10932
|
28 + offsets[n].offset = __be64_to_cpu(offsets[n].offset);
|
pascal@10932
|
29 + offsets[n].size = ntohl(offsets[n].size);
|
pascal@10933
|
30 + }
|
pascal@10932
|
31 + return "128BE accelerated knoppix 1.0";
|
pascal@10932
|
32 + }
|
pascal@10932
|
33 + else { /* V2.0 */
|
pascal@10933
|
34 + loff_t last = __be64_to_cpu(ofs64[n]);
|
pascal@10933
|
35 + while (n--) {
|
pascal@10932
|
36 + offsets[n].size = last -
|
pascal@10932
|
37 + (offsets[n].offset = __be64_to_cpu(ofs64[n]));
|
pascal@10932
|
38 + last = offsets[n].offset;
|
pascal@10933
|
39 + }
|
pascal@10932
|
40 + return "64BE v2.0";
|
pascal@10932
|
41 + }
|
pascal@10932
|
42 + }
|
pascal@10932
|
43 + else if (ofs32[1] == 0) { /* V1.0 */
|
pascal@10933
|
44 + loff_t last = __be64_to_cpu(ofs64[n]);
|
pascal@10933
|
45 + while (n--) {
|
pascal@10932
|
46 + offsets[n].size = last -
|
pascal@10932
|
47 + (offsets[n].offset = __le64_to_cpu(ofs64[n]));
|
pascal@10932
|
48 + last = offsets[n].offset;
|
pascal@10933
|
49 + }
|
pascal@10932
|
50 + return "64LE v1.0";
|
pascal@10932
|
51 + }
|
pascal@10933
|
52 + else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */
|
pascal@10933
|
53 + loff_t last = ntohl(ofs32[n]);
|
pascal@10933
|
54 + while (n--) {
|
pascal@10932
|
55 + offsets[n].size = last -
|
pascal@10932
|
56 + (offsets[n].offset = ntohl(ofs32[n]));
|
pascal@10932
|
57 + last = offsets[n].offset;
|
pascal@10933
|
58 + }
|
pascal@10932
|
59 + return "32BE v0.68";
|
pascal@10932
|
60 + }
|
pascal@10933
|
61 + else { /* V3.0 */
|
pascal@10935
|
62 + int i, j;
|
pascal@10933
|
63 +
|
pascal@10935
|
64 + for (i = n; i-- > 0; )
|
pascal@10935
|
65 + offsets[i].size = ntohl(ofs32[i]);
|
pascal@10935
|
66 + for (i = 0, j = sizeof(struct cloop_head); i < n; i++) {
|
pascal@10933
|
67 + offsets[i].offset = j;
|
pascal@10933
|
68 + j += offsets[i].size;
|
pascal@10933
|
69 + }
|
pascal@10935
|
70 + return "32BE v3.0";
|
pascal@10933
|
71 + }
|
pascal@10932
|
72 +}
|
pascal@10932
|
73 +
|
pascal@10932
|
74 /* Cloop suspend IOCTL */
|
pascal@10932
|
75 #define CLOOP_SUSPEND 0x4C07
|
pascal@10932
|
76
|
pascal@10932
|
77
|
pascal@10932
|
78 --- cloopreader.h
|
pascal@10932
|
79 +++ cloopreader.h
|
pascal@10932
|
80 @@ -33,7 +33,7 @@
|
pascal@10932
|
81 int numblocks;
|
pascal@10932
|
82 ulong blocksize;
|
pascal@10932
|
83
|
pascal@10932
|
84 - loff_t* toc; /* Data index */
|
pascal@10932
|
85 + struct block_info *toc; /* Data index */
|
pascal@10932
|
86 size_t tocsize;
|
pascal@10932
|
87
|
pascal@10932
|
88 unsigned char* cblock; /* Compressed block */
|
pascal@10932
|
89
|
pascal@10932
|
90 --- cloopreader.c
|
pascal@10932
|
91 +++ cloopreader.c
|
pascal@10935
|
92 @@ -59,10 +59,21 @@
|
pascal@10932
|
93
|
pascal@10932
|
94 ALLOC(c->pblock,c->blocksize);
|
pascal@10932
|
95
|
pascal@10932
|
96 - c->tocsize=sizeof *c->toc * (c->numblocks+1); /* One extra address is position of EOF */
|
pascal@10932
|
97 + c->tocsize=sizeof(*c->toc) * c->numblocks;
|
pascal@10933
|
98 + if (c->numblocks == -1) {
|
pascal@10933
|
99 + struct cloop_tail tail;
|
pascal@10935
|
100 + loff_t end = lseek(c->fh,0,SEEK_END); /* lseek(,-n,SEEK_END) buggy ? */
|
pascal@10933
|
101 +
|
pascal@10935
|
102 + OP(lseek(c->fh, end - sizeof(tail), SEEK_SET));
|
pascal@10933
|
103 + OP(read_all(c->fh, &tail, sizeof(tail)));
|
pascal@10933
|
104 + c->numblocks = ntohl(tail.num_blocks);
|
pascal@10933
|
105 + c->tocsize = ntohl(tail.index_size) * c->numblocks;
|
pascal@10935
|
106 + OP(lseek(c->fh, end - sizeof(tail) - c->tocsize, SEEK_SET));
|
pascal@10933
|
107 + }
|
pascal@10932
|
108 ALLOC(c->toc,c->tocsize);
|
pascal@10932
|
109
|
pascal@10932
|
110 OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */
|
pascal@10935
|
111 + build_index(c->toc, c->numblocks);
|
pascal@10932
|
112 c->cblocksizecur=0;
|
pascal@10932
|
113 c->curblock=-1;
|
pascal@10932
|
114 return 0;
|
pascal@10935
|
115 @@ -79,10 +90,10 @@
|
pascal@10932
|
116 if(page>=c->numblocks){errno=EFAULT;return -1;}
|
pascal@10932
|
117 c->curblock=page;
|
pascal@10932
|
118
|
pascal@10932
|
119 - bprintf("Seeking to 0x%Lx\n",btc(c->toc[page]));
|
pascal@10932
|
120 - OP(lseek(c->fh,btc(c->toc[page]), SEEK_SET));
|
pascal@10932
|
121 + bprintf("Seeking to 0x%Lx\n",c->toc[page].offset);
|
pascal@10932
|
122 + OP(lseek(c->fh,c->toc[page].offset, SEEK_SET));
|
pascal@10932
|
123
|
pascal@10932
|
124 - c->cblocksize=btc(c->toc[page+1]) - btc(c->toc[page]);
|
pascal@10932
|
125 + c->cblocksize=c->toc[page].size;
|
pascal@10932
|
126 bprintf("Compressed size=%lu\n",c->cblocksize);
|
pascal@10932
|
127 if(c->cblocksize > c->cblocksizecur){
|
pascal@10932
|
128 if(c->cblocksizecur)free(c->cblock);
|
pascal@10933
|
129
|
pascal@10932
|
130 --- extract_compressed_fs.c
|
pascal@10932
|
131 +++ extract_compressed_fs.c
|
pascal@10935
|
132 @@ -1,15 +1,18 @@
|
pascal@10935
|
133 /* Extracts a filesystem back from a compressed fs file */
|
pascal@10935
|
134 #include "common_header.h"
|
pascal@10935
|
135 +#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V2.0 Format\n" "insmod cloop.o file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n"
|
pascal@10935
|
136
|
pascal@10935
|
137 int main(int argc, char *argv[])
|
pascal@10935
|
138 {
|
pascal@10935
|
139 int handle;
|
pascal@10932
|
140 struct cloop_head head;
|
pascal@10932
|
141 unsigned int i;
|
pascal@10935
|
142 + unsigned long num_blocks, block_size, zblock_maxsize;
|
pascal@10932
|
143 unsigned char *buffer, *clear_buffer;
|
pascal@10932
|
144 + struct block_info *offsets;
|
pascal@10932
|
145
|
pascal@10935
|
146 - if (argc != 2) {
|
pascal@10935
|
147 - fprintf(stderr, "Need filename\n");
|
pascal@10935
|
148 + if (argc < 2 || argv[1][0] == '-') {
|
pascal@10935
|
149 + fprintf(stderr, "Usage: extract_compressed_fs file [--convert-to-v2] > output\n");
|
pascal@10935
|
150 exit(1);
|
pascal@10935
|
151 }
|
pascal@10932
|
152
|
pascal@10935
|
153 @@ -24,44 +27,77 @@
|
pascal@10935
|
154 exit(1);
|
pascal@10935
|
155 }
|
pascal@10935
|
156
|
pascal@10935
|
157 - buffer = malloc(ntohl(head.block_size) + ntohl(head.block_size)/1000
|
pascal@10935
|
158 - + 12 + 4);
|
pascal@10935
|
159 - clear_buffer = malloc(ntohl(head.block_size));
|
pascal@10935
|
160 - fprintf(stderr, "%u blocks of size %u. Preamble:\n%s\n",
|
pascal@10935
|
161 - ntohl(head.num_blocks), ntohl(head.block_size), head.preamble);
|
pascal@10935
|
162 -
|
pascal@10935
|
163 - for (i = 0; i < ntohl(head.num_blocks); i++) {
|
pascal@10935
|
164 - int currpos;
|
pascal@10935
|
165 - unsigned long destlen = ntohl(head.block_size);
|
pascal@10935
|
166 - loff_t offset[2];
|
pascal@10935
|
167 - unsigned int size;
|
pascal@10935
|
168 + num_blocks = ntohl(head.num_blocks);
|
pascal@10935
|
169 + block_size = ntohl(head.block_size);
|
pascal@10935
|
170 + zblock_maxsize = block_size + block_size/1000 + 12 + 4;
|
pascal@10935
|
171 + buffer = malloc(zblock_maxsize);
|
pascal@10935
|
172 + clear_buffer = malloc(block_size);
|
pascal@10935
|
173 + fprintf(stderr, "%lu blocks of size %lu. Preamble:\n%s\n",
|
pascal@10935
|
174 + num_blocks, block_size, head.preamble);
|
pascal@10935
|
175 +
|
pascal@10935
|
176 + if (num_blocks == -1) {
|
pascal@10933
|
177 + struct cloop_tail tail;
|
pascal@10933
|
178 + if (lseek(handle, - sizeof(tail), SEEK_END) < 0 ||
|
pascal@10933
|
179 + read(handle, &tail, sizeof(tail)) != sizeof(tail) ||
|
pascal@10933
|
180 + lseek(handle, - sizeof(tail) -
|
pascal@10933
|
181 + (ntohl(tail.num_blocks) * ntohl(tail.index_size)),
|
pascal@10933
|
182 + SEEK_END) < 0) {
|
pascal@10933
|
183 + perror("Reading tail\n");
|
pascal@10933
|
184 + exit(1);
|
pascal@10933
|
185 + }
|
pascal@10933
|
186 + head.num_blocks = tail.num_blocks;
|
pascal@10935
|
187 + num_blocks = ntohl(head.num_blocks);
|
pascal@10935
|
188 + i = num_blocks * ntohl(tail.index_size);
|
pascal@10933
|
189 + }
|
pascal@10935
|
190 + else i = num_blocks * sizeof(*offsets);
|
pascal@10932
|
191 + offsets = malloc(i);
|
pascal@10932
|
192 + if (!offsets || read(handle, offsets, i) != i) {
|
pascal@10932
|
193 + perror("Reading index\n");
|
pascal@10932
|
194 + exit(1);
|
pascal@10932
|
195 + }
|
pascal@10932
|
196 +
|
pascal@10935
|
197 + fprintf(stderr, "Index %s.\n", build_index(offsets, num_blocks));
|
pascal@10932
|
198 +
|
pascal@10935
|
199 + if (argc > 2) {
|
pascal@10935
|
200 + loff_t offset;
|
pascal@10935
|
201 + int delta = ((num_blocks + 1) * sizeof(offset)) +
|
pascal@10935
|
202 + sizeof(head) - offsets[0].offset;
|
pascal@10935
|
203 +
|
pascal@10935
|
204 + strcpy(head.preamble, CLOOP_PREAMBLE);
|
pascal@10935
|
205 + write(STDOUT_FILENO, &head, sizeof(head));
|
pascal@10935
|
206 + for (i = 0; i < num_blocks; i++) {
|
pascal@10935
|
207 + offset = __be64_to_cpu(delta + offsets[i].offset);
|
pascal@10935
|
208 + write(STDOUT_FILENO, &offset, sizeof(offset));
|
pascal@10935
|
209 + }
|
pascal@10935
|
210 + offset = __be64_to_cpu(delta + offsets[num_blocks-1].offset + offsets[num_blocks-1].size);
|
pascal@10935
|
211 + write(STDOUT_FILENO, &offset, sizeof(offset));
|
pascal@10935
|
212 + for (i = 0; i < num_blocks && lseek(handle, offsets[i].offset, SEEK_SET) >= 0; i++) {
|
pascal@10935
|
213 + read(handle, buffer, offsets[i].size);
|
pascal@10935
|
214 + write(STDOUT_FILENO, buffer, offsets[i].size);
|
pascal@10935
|
215 + }
|
pascal@10935
|
216 + return 0;
|
pascal@10935
|
217 + }
|
pascal@10935
|
218 +
|
pascal@10935
|
219 + for (i = 0; i < num_blocks; i++) {
|
pascal@10935
|
220 + unsigned long destlen = block_size;
|
pascal@10932
|
221 + unsigned int size = offsets[i].size;
|
pascal@10932
|
222
|
pascal@10932
|
223 - read(handle, &offset, 2*sizeof(loff_t));
|
pascal@10932
|
224 - lseek(handle, -sizeof(loff_t), SEEK_CUR);
|
pascal@10932
|
225 -
|
pascal@10932
|
226 - currpos = lseek(handle, 0, SEEK_CUR);
|
pascal@10932
|
227 - if (lseek(handle, __be64_to_cpu(offset[0]), SEEK_SET) < 0) {
|
pascal@10932
|
228 + if (lseek(handle, offsets[i].offset, SEEK_SET) < 0) {
|
pascal@10932
|
229 fprintf(stderr, "lseek to %Lu: %s\n",
|
pascal@10932
|
230 - __be64_to_cpu(offset[0]), strerror(errno));
|
pascal@10932
|
231 + offsets[i].offset, strerror(errno));
|
pascal@10932
|
232 exit(1);
|
pascal@10932
|
233 }
|
pascal@10932
|
234
|
pascal@10932
|
235 - size=__be64_to_cpu(offset[1])-__be64_to_cpu(offset[0]);
|
pascal@10935
|
236 - if (size > ntohl(head.block_size) + ntohl(head.block_size)/1000
|
pascal@10935
|
237 - + 12 + 4) {
|
pascal@10935
|
238 + if (size > zblock_maxsize) {
|
pascal@10932
|
239 fprintf(stderr,
|
pascal@10932
|
240 "Size %u for block %u (offset %Lu) too big\n",
|
pascal@10932
|
241 - size, i, __be64_to_cpu(offset[0]));
|
pascal@10932
|
242 + size, i, offsets[i].offset);
|
pascal@10932
|
243 exit(1);
|
pascal@10932
|
244 }
|
pascal@10932
|
245 read(handle, buffer, size);
|
pascal@10932
|
246 - if (lseek(handle, currpos, SEEK_SET) < 0) {
|
pascal@10932
|
247 - perror("seeking");
|
pascal@10932
|
248 - exit(1);
|
pascal@10932
|
249 - }
|
pascal@10932
|
250
|
pascal@10935
|
251 - fprintf(stderr, "Block %u length %u => %lu\n",
|
pascal@10935
|
252 - i, size, destlen);
|
pascal@10935
|
253 + fprintf(stderr, "Block %u at %llu length %u => %lu\n",
|
pascal@10935
|
254 + i, offsets[i].offset, size, destlen);
|
pascal@10935
|
255 if (i == 3) {
|
pascal@10935
|
256 fprintf(stderr,
|
pascal@10935
|
257 "Block head:%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
pascal@10935
|
258 @@ -105,12 +141,12 @@
|
pascal@10935
|
259 fprintf(stderr, "Uncomp: unknown error %u\n", i);
|
pascal@10935
|
260 exit(1);
|
pascal@10935
|
261 }
|
pascal@10935
|
262 - if (destlen != ntohl(head.block_size)) {
|
pascal@10935
|
263 - fprintf(stderr, "Uncomp: bad len %u (%lu not %u)\n", i,
|
pascal@10935
|
264 - destlen, ntohl(head.block_size));
|
pascal@10935
|
265 + if (destlen != block_size) {
|
pascal@10935
|
266 + fprintf(stderr, "Uncomp: bad len %u (%lu not %lu)\n", i,
|
pascal@10935
|
267 + destlen, block_size);
|
pascal@10935
|
268 exit(1);
|
pascal@10935
|
269 }
|
pascal@10935
|
270 - write(STDOUT_FILENO, clear_buffer, ntohl(head.block_size));
|
pascal@10935
|
271 + write(STDOUT_FILENO, clear_buffer, block_size);
|
pascal@10935
|
272 }
|
pascal@10935
|
273 return 0;
|
pascal@10935
|
274 }
|
pascal@10935
|
275
|
pascal@10935
|
276 --- Makefile
|
pascal@10935
|
277 +++ Makefile
|
pascal@10935
|
278 @@ -1,16 +1,19 @@
|
pascal@10935
|
279 PROGNAME=fusecloop
|
pascal@10935
|
280 ARCFILES=*.c *.h *.pl Makefile configure README VERSION HELP INSTALL typescript *.cloop COPYING
|
pascal@10935
|
281 -PROGS=fusecloop cloopreaderdemo extract_compressed_fs
|
pascal@10935
|
282 +PROGS=fusecloop cloopreaderdemo extract_compressed_fs create_compressed_fs
|
pascal@10935
|
283 FUSECFLAGS=`pkg-config fuse --cflags`
|
pascal@10935
|
284 FUSELDFLAGS=`pkg-config fuse --libs`
|
pascal@10935
|
285
|
pascal@10935
|
286 CFLAGS= -Wall
|
pascal@10935
|
287
|
pascal@10935
|
288 -all: fusecloop extract_compressed_fs
|
pascal@10935
|
289 +all: fusecloop extract_compressed_fs create_compressed_fs
|
pascal@10935
|
290
|
pascal@10935
|
291 extract_compressed_fs: extract_compressed_fs.c
|
pascal@10935
|
292 ${CC} ${CFLAGS} ${LDFLAGS} -lz extract_compressed_fs.c -o extract_compressed_fs
|
pascal@10935
|
293
|
pascal@10935
|
294 +create_compressed_fs: create_compressed_fs.c
|
pascal@10935
|
295 + ${CC} ${CFLAGS} ${LDFLAGS} -lz create_compressed_fs.c -o create_compressed_fs
|
pascal@10935
|
296 +
|
pascal@10935
|
297 fusecloop: fusecloop.c cloopreader.o strver debug.o
|
pascal@10935
|
298 ${CC} ${CFLAGS} ${LDFLAGS} -lz cloopreader.o ${FUSECFLAGS} ${FUSELDFLAGS} fusecloop.c debug.o -o fusecloop
|
pascal@10935
|
299
|
pascal@10935
|
300
|
pascal@10935
|
301 --- create_compressed_fs.c
|
pascal@10935
|
302 +++ create_compressed_fs.c
|
pascal@10935
|
303 @@ -0,0 +1,80 @@
|
pascal@10935
|
304 +/* Creates a compressed file */
|
pascal@10935
|
305 +#include "common_header.h"
|
pascal@10935
|
306 +
|
pascal@10935
|
307 +#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V3.0 Format\n" "insmod cloop.o file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n"
|
pascal@10935
|
308 +#define CHUNK 65536
|
pascal@10935
|
309 +#define DEFAULT_BLOCKSIZE 65536
|
pascal@10935
|
310 +
|
pascal@10935
|
311 +static void quit(char *s)
|
pascal@10935
|
312 +{
|
pascal@10935
|
313 + fprintf(stderr, "%s\n", s);
|
pascal@10935
|
314 + exit(1);
|
pascal@10935
|
315 +}
|
pascal@10935
|
316 +
|
pascal@10935
|
317 +static int readblock(unsigned char *buffer, int n)
|
pascal@10935
|
318 +{
|
pascal@10935
|
319 + int i;
|
pascal@10935
|
320 +
|
pascal@10935
|
321 + memset(buffer, 0, n);
|
pascal@10935
|
322 + for (i = 0 ; i < n;) {
|
pascal@10935
|
323 + int j = read(STDIN_FILENO, buffer + i, n - i);
|
pascal@10935
|
324 + if (j < 0 && errno == EINTR) continue;
|
pascal@10935
|
325 + if (j <= 0) break;
|
pascal@10935
|
326 + i += j;
|
pascal@10935
|
327 + }
|
pascal@10935
|
328 + return i;
|
pascal@10935
|
329 +}
|
pascal@10935
|
330 +
|
pascal@10935
|
331 +int main(int argc, char *argv[])
|
pascal@10935
|
332 +{
|
pascal@10935
|
333 + struct cloop_head head;
|
pascal@10935
|
334 + struct cloop_tail tail;
|
pascal@10935
|
335 + unsigned long block_size = 0;
|
pascal@10935
|
336 + unsigned char *compressed, *uncompressed;
|
pascal@10935
|
337 + unsigned long *index;
|
pascal@10935
|
338 + int n, indexmax, zlenmax;
|
pascal@10935
|
339 +
|
pascal@10935
|
340 + if (argc > 1) {
|
pascal@10935
|
341 + if (argv[1][0] < '0' || argv[1][0] > '9')
|
pascal@10935
|
342 + quit("Usage : create_compressed_fs [block size] < input > output");
|
pascal@10935
|
343 + block_size = atoi(argv[1]);
|
pascal@10935
|
344 + }
|
pascal@10935
|
345 + if (block_size < 4096)
|
pascal@10935
|
346 + block_size = DEFAULT_BLOCKSIZE;
|
pascal@10935
|
347 + fprintf(stderr, "Block size is %lu\n", block_size);
|
pascal@10935
|
348 + zlenmax = block_size + block_size/1000 + 12;
|
pascal@10935
|
349 +
|
pascal@10935
|
350 + memset(&head, 0, sizeof(head));
|
pascal@10935
|
351 + strcpy(head.preamble, CLOOP_PREAMBLE);
|
pascal@10935
|
352 + head.num_blocks = -1;
|
pascal@10935
|
353 + head.block_size = htonl(block_size);
|
pascal@10935
|
354 + write(STDOUT_FILENO, &head, sizeof(head));
|
pascal@10935
|
355 +
|
pascal@10935
|
356 + compressed = malloc(zlenmax);
|
pascal@10935
|
357 + uncompressed = malloc(block_size);
|
pascal@10935
|
358 + index = malloc(indexmax = CHUNK);
|
pascal@10935
|
359 + if (!compressed || !uncompressed || !index)
|
pascal@10935
|
360 + quit("Malloc failed");
|
pascal@10935
|
361 +
|
pascal@10935
|
362 + for (n = 0; readblock(uncompressed, block_size); n++) {
|
pascal@10935
|
363 + unsigned long len = zlenmax;
|
pascal@10935
|
364 +
|
pascal@10935
|
365 + if (compress2(compressed, &len, uncompressed, block_size,
|
pascal@10935
|
366 + Z_BEST_COMPRESSION) != Z_OK)
|
pascal@10935
|
367 + quit("Compression failed");
|
pascal@10935
|
368 + fprintf(stderr, "Block %u length %lu => %lu\n",
|
pascal@10935
|
369 + n, block_size, len);
|
pascal@10935
|
370 + write(STDOUT_FILENO, compressed, len);
|
pascal@10935
|
371 + if (n * sizeof(*index) >= indexmax) {
|
pascal@10935
|
372 + index = realloc(index, indexmax += CHUNK);
|
pascal@10935
|
373 + if (!index)
|
pascal@10935
|
374 + quit("Realloc");
|
pascal@10935
|
375 + }
|
pascal@10935
|
376 + index[n] = ntohl(len);
|
pascal@10935
|
377 + }
|
pascal@10935
|
378 + write(STDOUT_FILENO, index, n * sizeof(*index));
|
pascal@10935
|
379 + tail.index_size = ntohl(sizeof(*index));
|
pascal@10935
|
380 + tail.num_blocks = ntohl(n);
|
pascal@10935
|
381 + write(STDOUT_FILENO, &tail, sizeof(tail));
|
pascal@10935
|
382 + return 0;
|
pascal@10935
|
383 +}
|