rev |
line source |
pascal@10932
|
1 --- compressed_loop.h
|
pascal@10932
|
2 +++ compressed_loop.h
|
pascal@17168
|
3 @@ -41,6 +41,75 @@
|
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@12214
|
9 + u_int32_t table_size;
|
pascal@10933
|
10 + u_int32_t index_size;
|
pascal@10933
|
11 + u_int32_t num_blocks;
|
pascal@10933
|
12 +};
|
pascal@10933
|
13 +
|
pascal@10932
|
14 +struct block_info
|
pascal@10932
|
15 +{
|
pascal@10932
|
16 + loff_t offset; /* 64-bit offsets of compressed block */
|
pascal@10932
|
17 + u_int32_t size; /* 32-bit compressed block size */
|
pascal@10932
|
18 + u_int32_t optidx; /* 32-bit index number */
|
pascal@10932
|
19 +};
|
pascal@10932
|
20 +
|
pascal@10935
|
21 +static inline char *build_index(struct block_info *offsets, unsigned long n)
|
pascal@10932
|
22 +{
|
pascal@10932
|
23 + u_int32_t *ofs32 = (u_int32_t *) offsets;
|
pascal@10932
|
24 + loff_t *ofs64 = (loff_t *) offsets;
|
pascal@10933
|
25 +
|
pascal@10932
|
26 + if (ofs32[0] == 0) {
|
pascal@10932
|
27 + if (ofs32[2]) { /* ACCELERATED KNOPPIX V1.0 */
|
pascal@10933
|
28 + while (n--) {
|
pascal@10932
|
29 + offsets[n].offset = __be64_to_cpu(offsets[n].offset);
|
pascal@10932
|
30 + offsets[n].size = ntohl(offsets[n].size);
|
pascal@10933
|
31 + }
|
pascal@12214
|
32 + return (char *) "128BE accelerated knoppix 1.0";
|
pascal@10932
|
33 + }
|
pascal@10932
|
34 + else { /* V2.0 */
|
pascal@10933
|
35 + loff_t last = __be64_to_cpu(ofs64[n]);
|
pascal@10933
|
36 + while (n--) {
|
pascal@10932
|
37 + offsets[n].size = last -
|
pascal@10932
|
38 + (offsets[n].offset = __be64_to_cpu(ofs64[n]));
|
pascal@10932
|
39 + last = offsets[n].offset;
|
pascal@10933
|
40 + }
|
pascal@12214
|
41 + return (char *) "64BE v2.0";
|
pascal@10932
|
42 + }
|
pascal@10932
|
43 + }
|
pascal@10932
|
44 + else if (ofs32[1] == 0) { /* V1.0 */
|
pascal@11113
|
45 + loff_t last = __le64_to_cpu(ofs64[n]);
|
pascal@10933
|
46 + while (n--) {
|
pascal@10932
|
47 + offsets[n].size = last -
|
pascal@10932
|
48 + (offsets[n].offset = __le64_to_cpu(ofs64[n]));
|
pascal@10932
|
49 + last = offsets[n].offset;
|
pascal@10933
|
50 + }
|
pascal@12214
|
51 + return (char *) "64LE v1.0";
|
pascal@10932
|
52 + }
|
pascal@10933
|
53 + else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */
|
pascal@10933
|
54 + loff_t last = ntohl(ofs32[n]);
|
pascal@10933
|
55 + while (n--) {
|
pascal@10932
|
56 + offsets[n].size = last -
|
pascal@10932
|
57 + (offsets[n].offset = ntohl(ofs32[n]));
|
pascal@10932
|
58 + last = offsets[n].offset;
|
pascal@10933
|
59 + }
|
pascal@12214
|
60 + return (char *) "32BE v0.68";
|
pascal@10932
|
61 + }
|
pascal@10933
|
62 + else { /* V3.0 */
|
pascal@17169
|
63 + unsigned long i;
|
pascal@17168
|
64 + loff_t j;
|
pascal@10933
|
65 +
|
pascal@17169
|
66 + for (i = n; i-- != 0; )
|
pascal@10935
|
67 + offsets[i].size = ntohl(ofs32[i]);
|
pascal@10935
|
68 + for (i = 0, j = sizeof(struct cloop_head); i < n; i++) {
|
pascal@10933
|
69 + offsets[i].offset = j;
|
pascal@10933
|
70 + j += offsets[i].size;
|
pascal@10933
|
71 + }
|
pascal@12214
|
72 + return (char *) "32BE v3.0";
|
pascal@10933
|
73 + }
|
pascal@10932
|
74 +}
|
pascal@10932
|
75 +
|
pascal@10932
|
76 /* Cloop suspend IOCTL */
|
pascal@10932
|
77 #define CLOOP_SUSPEND 0x4C07
|
pascal@10932
|
78
|
pascal@10932
|
79
|
pascal@10932
|
80 --- cloopreader.h
|
pascal@10932
|
81 +++ cloopreader.h
|
pascal@10932
|
82 @@ -33,7 +33,7 @@
|
pascal@10932
|
83 int numblocks;
|
pascal@10932
|
84 ulong blocksize;
|
pascal@10932
|
85
|
pascal@10932
|
86 - loff_t* toc; /* Data index */
|
pascal@10932
|
87 + struct block_info *toc; /* Data index */
|
pascal@10932
|
88 size_t tocsize;
|
pascal@10932
|
89
|
pascal@10932
|
90 unsigned char* cblock; /* Compressed block */
|
pascal@10932
|
91
|
pascal@10932
|
92 --- cloopreader.c
|
pascal@10932
|
93 +++ cloopreader.c
|
pascal@12214
|
94 @@ -59,10 +59,32 @@
|
pascal@10932
|
95
|
pascal@10932
|
96 ALLOC(c->pblock,c->blocksize);
|
pascal@10932
|
97
|
pascal@10932
|
98 - c->tocsize=sizeof *c->toc * (c->numblocks+1); /* One extra address is position of EOF */
|
pascal@12214
|
99 - ALLOC(c->toc,c->tocsize);
|
pascal@12214
|
100 + if (c->numblocks + 1 == 0) {
|
pascal@10933
|
101 + struct cloop_tail tail;
|
pascal@10935
|
102 + loff_t end = lseek(c->fh,0,SEEK_END); /* lseek(,-n,SEEK_END) buggy ? */
|
pascal@12214
|
103 + void *p;
|
pascal@12214
|
104 + ulong toclen, len;
|
pascal@12214
|
105
|
pascal@12214
|
106 - OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */
|
pascal@10935
|
107 + OP(lseek(c->fh, end - sizeof(tail), SEEK_SET));
|
pascal@10933
|
108 + OP(read_all(c->fh, &tail, sizeof(tail)));
|
pascal@10933
|
109 + c->numblocks = ntohl(tail.num_blocks);
|
pascal@12214
|
110 + c->tocsize = sizeof(*c->toc) * c->numblocks;
|
pascal@12214
|
111 + len = ntohl(tail.table_size);
|
pascal@12214
|
112 + toclen = (ntohl(tail.index_size) & 255) * c->numblocks;
|
pascal@12214
|
113 + OP(lseek(c->fh, end - sizeof(tail) - len, SEEK_SET));
|
pascal@17168
|
114 + ALLOC(c->toc, sizeof(*c->toc) * c->numblocks);
|
pascal@12214
|
115 + ALLOC(p,len);
|
pascal@12214
|
116 + OP(read_all(c->fh,p,len)); /* read Data Index */
|
pascal@12214
|
117 + if (uncompress((void *)c->toc,&toclen,p,len) != Z_OK)
|
pascal@12214
|
118 + exit(1);
|
pascal@12214
|
119 + free(p);
|
pascal@10933
|
120 + }
|
pascal@12214
|
121 + else {
|
pascal@12214
|
122 + c->tocsize = sizeof(*c->toc) * c->numblocks;
|
pascal@12214
|
123 + ALLOC(c->toc,c->tocsize);
|
pascal@12214
|
124 + OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */
|
pascal@12214
|
125 + }
|
pascal@10935
|
126 + build_index(c->toc, c->numblocks);
|
pascal@10932
|
127 c->cblocksizecur=0;
|
pascal@10932
|
128 c->curblock=-1;
|
pascal@10932
|
129 return 0;
|
pascal@12214
|
130 @@ -79,10 +101,10 @@
|
pascal@10932
|
131 if(page>=c->numblocks){errno=EFAULT;return -1;}
|
pascal@10932
|
132 c->curblock=page;
|
pascal@10932
|
133
|
pascal@10932
|
134 - bprintf("Seeking to 0x%Lx\n",btc(c->toc[page]));
|
pascal@10932
|
135 - OP(lseek(c->fh,btc(c->toc[page]), SEEK_SET));
|
pascal@10932
|
136 + bprintf("Seeking to 0x%Lx\n",c->toc[page].offset);
|
pascal@10932
|
137 + OP(lseek(c->fh,c->toc[page].offset, SEEK_SET));
|
pascal@10932
|
138
|
pascal@10932
|
139 - c->cblocksize=btc(c->toc[page+1]) - btc(c->toc[page]);
|
pascal@10932
|
140 + c->cblocksize=c->toc[page].size;
|
pascal@10932
|
141 bprintf("Compressed size=%lu\n",c->cblocksize);
|
pascal@10932
|
142 if(c->cblocksize > c->cblocksizecur){
|
pascal@10932
|
143 if(c->cblocksizecur)free(c->cblock);
|
pascal@10933
|
144
|
pascal@10932
|
145 --- extract_compressed_fs.c
|
pascal@10932
|
146 +++ extract_compressed_fs.c
|
pascal@17885
|
147 @@ -1,19 +1,23 @@
|
pascal@10935
|
148 /* Extracts a filesystem back from a compressed fs file */
|
pascal@10937
|
149 +#define _LARGEFILE64_SOURCE
|
pascal@10935
|
150 #include "common_header.h"
|
pascal@12214
|
151 +#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V2.0 Format\n" "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n"
|
pascal@10935
|
152
|
pascal@10935
|
153 int main(int argc, char *argv[])
|
pascal@10935
|
154 {
|
pascal@10935
|
155 int handle;
|
pascal@10932
|
156 struct cloop_head head;
|
pascal@10932
|
157 unsigned int i;
|
pascal@17996
|
158 + unsigned long num_blocks, block_size, zblock_maxsize, lastlen = 0;
|
pascal@10932
|
159 unsigned char *buffer, *clear_buffer;
|
pascal@10932
|
160 + struct block_info *offsets;
|
pascal@10932
|
161
|
pascal@10935
|
162 - if (argc != 2) {
|
pascal@10935
|
163 - fprintf(stderr, "Need filename\n");
|
pascal@10935
|
164 + if (argc < 2 || argv[1][0] == '-') {
|
pascal@10935
|
165 + fprintf(stderr, "Usage: extract_compressed_fs file [--convert-to-v2] > output\n");
|
pascal@10935
|
166 exit(1);
|
pascal@10935
|
167 }
|
pascal@10932
|
168
|
pascal@17885
|
169 - handle = open(argv[1], O_RDONLY);
|
pascal@17885
|
170 + handle = open(argv[1], O_RDONLY|O_LARGEFILE);
|
pascal@17885
|
171 if (handle < 0) {
|
pascal@17885
|
172 perror("Opening compressed file\n");
|
pascal@17885
|
173 exit(1);
|
pascal@17996
|
174 @@ -24,44 +28,100 @@
|
pascal@10935
|
175 exit(1);
|
pascal@10935
|
176 }
|
pascal@10935
|
177
|
pascal@10935
|
178 - buffer = malloc(ntohl(head.block_size) + ntohl(head.block_size)/1000
|
pascal@10935
|
179 - + 12 + 4);
|
pascal@10935
|
180 - clear_buffer = malloc(ntohl(head.block_size));
|
pascal@10935
|
181 - fprintf(stderr, "%u blocks of size %u. Preamble:\n%s\n",
|
pascal@10935
|
182 - ntohl(head.num_blocks), ntohl(head.block_size), head.preamble);
|
pascal@12214
|
183 + num_blocks = ntohl(head.num_blocks);
|
pascal@12214
|
184 + block_size = ntohl(head.block_size);
|
pascal@12214
|
185 + zblock_maxsize = block_size + block_size/1000 + 12 + 4;
|
pascal@12214
|
186 + buffer = malloc(zblock_maxsize);
|
pascal@12214
|
187 + clear_buffer = malloc(block_size);
|
pascal@12214
|
188
|
pascal@10935
|
189 - for (i = 0; i < ntohl(head.num_blocks); i++) {
|
pascal@10935
|
190 - int currpos;
|
pascal@10935
|
191 - unsigned long destlen = ntohl(head.block_size);
|
pascal@10935
|
192 - loff_t offset[2];
|
pascal@10935
|
193 - unsigned int size;
|
pascal@12214
|
194 + if (num_blocks == (unsigned long) -1) {
|
pascal@12214
|
195 + void *table;
|
pascal@10933
|
196 + struct cloop_tail tail;
|
pascal@12214
|
197 + unsigned long len, table_size;
|
pascal@10937
|
198 + loff_t end = lseek64(handle, 0, SEEK_END);
|
pascal@12214
|
199 +
|
pascal@10937
|
200 + if (lseek64(handle, end - sizeof(tail), SEEK_SET) < 0 ||
|
pascal@10933
|
201 + read(handle, &tail, sizeof(tail)) != sizeof(tail) ||
|
pascal@10937
|
202 + lseek64(handle, end - sizeof(tail) -
|
pascal@12214
|
203 + ntohl(tail.table_size), SEEK_SET) < 0) {
|
pascal@10933
|
204 + perror("Reading tail\n");
|
pascal@10933
|
205 + exit(1);
|
pascal@10933
|
206 + }
|
pascal@10933
|
207 + head.num_blocks = tail.num_blocks;
|
pascal@10935
|
208 + num_blocks = ntohl(head.num_blocks);
|
pascal@12214
|
209 + table_size = ntohl(tail.table_size);
|
pascal@12214
|
210 + table = malloc(table_size);
|
pascal@12214
|
211 + len = i = num_blocks * (ntohl(tail.index_size) & 255);
|
pascal@17996
|
212 + lastlen = ntohl(tail.index_size) / 256;
|
pascal@12214
|
213 + offsets = malloc(num_blocks * sizeof(*offsets));
|
pascal@12214
|
214 + if (!table || !offsets ||
|
pascal@12214
|
215 + read(handle, table, table_size) != table_size ||
|
pascal@12214
|
216 + uncompress((void *)offsets, &len, table, table_size) != Z_OK ||
|
pascal@12214
|
217 + len != i) {
|
pascal@12214
|
218 + perror("Reading index\n");
|
pascal@12214
|
219 + exit(1);
|
pascal@12214
|
220 + }
|
pascal@12214
|
221 + free(table);
|
pascal@10933
|
222 + }
|
pascal@12214
|
223 + else {
|
pascal@12214
|
224 + offsets = malloc(i = num_blocks * sizeof(*offsets));
|
pascal@12214
|
225 + if (!offsets || read(handle, offsets, i) != i) {
|
pascal@12214
|
226 + perror("Reading index\n");
|
pascal@12214
|
227 + exit(1);
|
pascal@12214
|
228 + }
|
pascal@10932
|
229 + }
|
pascal@10932
|
230 +
|
pascal@12214
|
231 + fprintf(stderr, "%lu blocks of size %lu. Preamble:\n%s\n",
|
pascal@12214
|
232 + num_blocks, block_size, head.preamble);
|
pascal@10935
|
233 + fprintf(stderr, "Index %s.\n", build_index(offsets, num_blocks));
|
pascal@10932
|
234 +
|
pascal@10935
|
235 + if (argc > 2) {
|
pascal@14712
|
236 + unsigned n;
|
pascal@10936
|
237 + loff_t data, offset = ((num_blocks + 1) * sizeof(offset)) + sizeof(head);
|
pascal@10935
|
238 +
|
pascal@10935
|
239 + strcpy(head.preamble, CLOOP_PREAMBLE);
|
pascal@14712
|
240 + write(STDOUT_FILENO, &head, n = sizeof(head));
|
pascal@10935
|
241 + for (i = 0; i < num_blocks; i++) {
|
pascal@10936
|
242 + data = __be64_to_cpu(offset);
|
pascal@10936
|
243 + write(STDOUT_FILENO, &data, sizeof(data));
|
pascal@14712
|
244 + n += sizeof(data);
|
pascal@10936
|
245 + offset += offsets[i].size;
|
pascal@10935
|
246 + }
|
pascal@10936
|
247 + data = __be64_to_cpu(offset);
|
pascal@10936
|
248 + write(STDOUT_FILENO, &data, sizeof(data));
|
pascal@10937
|
249 + for (i = 0; i < num_blocks && lseek64(handle, offsets[i].offset, SEEK_SET) >= 0; i++) {
|
pascal@10935
|
250 + read(handle, buffer, offsets[i].size);
|
pascal@10935
|
251 + write(STDOUT_FILENO, buffer, offsets[i].size);
|
pascal@14712
|
252 + n += offsets[i].size;
|
pascal@14712
|
253 + }
|
pascal@14712
|
254 + n &= 0x1FF;
|
pascal@14712
|
255 + if (n) {
|
pascal@14712
|
256 + memset(buffer, 0, 512);
|
pascal@14712
|
257 + write(STDOUT_FILENO, buffer, 512 - n);
|
pascal@10935
|
258 + }
|
pascal@10935
|
259 + return 0;
|
pascal@10935
|
260 + }
|
pascal@10935
|
261 +
|
pascal@10935
|
262 + for (i = 0; i < num_blocks; i++) {
|
pascal@10935
|
263 + unsigned long destlen = block_size;
|
pascal@10932
|
264 + unsigned int size = offsets[i].size;
|
pascal@10932
|
265
|
pascal@10932
|
266 - read(handle, &offset, 2*sizeof(loff_t));
|
pascal@10932
|
267 - lseek(handle, -sizeof(loff_t), SEEK_CUR);
|
pascal@10932
|
268 -
|
pascal@10932
|
269 - currpos = lseek(handle, 0, SEEK_CUR);
|
pascal@10932
|
270 - if (lseek(handle, __be64_to_cpu(offset[0]), SEEK_SET) < 0) {
|
pascal@10937
|
271 + if (lseek64(handle, offsets[i].offset, SEEK_SET) < 0) {
|
pascal@10932
|
272 fprintf(stderr, "lseek to %Lu: %s\n",
|
pascal@10932
|
273 - __be64_to_cpu(offset[0]), strerror(errno));
|
pascal@10932
|
274 + offsets[i].offset, strerror(errno));
|
pascal@10932
|
275 exit(1);
|
pascal@10932
|
276 }
|
pascal@10932
|
277
|
pascal@10932
|
278 - size=__be64_to_cpu(offset[1])-__be64_to_cpu(offset[0]);
|
pascal@10935
|
279 - if (size > ntohl(head.block_size) + ntohl(head.block_size)/1000
|
pascal@10935
|
280 - + 12 + 4) {
|
pascal@10935
|
281 + if (size > zblock_maxsize) {
|
pascal@10932
|
282 fprintf(stderr,
|
pascal@10932
|
283 "Size %u for block %u (offset %Lu) too big\n",
|
pascal@10932
|
284 - size, i, __be64_to_cpu(offset[0]));
|
pascal@10932
|
285 + size, i, offsets[i].offset);
|
pascal@10932
|
286 exit(1);
|
pascal@10932
|
287 }
|
pascal@10932
|
288 read(handle, buffer, size);
|
pascal@10932
|
289 - if (lseek(handle, currpos, SEEK_SET) < 0) {
|
pascal@10932
|
290 - perror("seeking");
|
pascal@10932
|
291 - exit(1);
|
pascal@10932
|
292 - }
|
pascal@10932
|
293
|
pascal@10935
|
294 - fprintf(stderr, "Block %u length %u => %lu\n",
|
pascal@10935
|
295 - i, size, destlen);
|
pascal@10935
|
296 + fprintf(stderr, "Block %u at %llu length %u => %lu\n",
|
pascal@10935
|
297 + i, offsets[i].offset, size, destlen);
|
pascal@10935
|
298 if (i == 3) {
|
pascal@10935
|
299 fprintf(stderr,
|
pascal@10935
|
300 "Block head:%02X%02X%02X%02X%02X%02X%02X%02X\n",
|
pascal@17996
|
301 @@ -105,12 +165,12 @@
|
pascal@10937
|
302 fprintf(stderr, "Uncomp: unknown error %u\n", i);
|
pascal@10937
|
303 exit(1);
|
pascal@10937
|
304 }
|
pascal@10937
|
305 - if (destlen != ntohl(head.block_size)) {
|
pascal@10937
|
306 - fprintf(stderr, "Uncomp: bad len %u (%lu not %u)\n", i,
|
pascal@10937
|
307 - destlen, ntohl(head.block_size));
|
pascal@10937
|
308 + if (destlen != block_size) {
|
pascal@10937
|
309 + fprintf(stderr, "Uncomp: bad len %u (%lu not %lu)\n", i,
|
pascal@10937
|
310 + destlen, block_size);
|
pascal@10937
|
311 exit(1);
|
pascal@10937
|
312 }
|
pascal@10937
|
313 - write(STDOUT_FILENO, clear_buffer, ntohl(head.block_size));
|
pascal@17996
|
314 + write(STDOUT_FILENO, clear_buffer, (lastlen != 0 && (i+1) == num_blocks) ? lastlen : block_size);
|
pascal@10937
|
315 }
|
pascal@10937
|
316 return 0;
|
pascal@10937
|
317 }
|
pascal@10935
|
318
|
pascal@10935
|
319 --- Makefile
|
pascal@10935
|
320 +++ Makefile
|
pascal@10935
|
321 @@ -1,16 +1,19 @@
|
pascal@10935
|
322 PROGNAME=fusecloop
|
pascal@10935
|
323 ARCFILES=*.c *.h *.pl Makefile configure README VERSION HELP INSTALL typescript *.cloop COPYING
|
pascal@10935
|
324 -PROGS=fusecloop cloopreaderdemo extract_compressed_fs
|
pascal@10935
|
325 +PROGS=fusecloop cloopreaderdemo extract_compressed_fs create_compressed_fs
|
pascal@10935
|
326 FUSECFLAGS=`pkg-config fuse --cflags`
|
pascal@10935
|
327 FUSELDFLAGS=`pkg-config fuse --libs`
|
pascal@10935
|
328
|
pascal@10935
|
329 CFLAGS= -Wall
|
pascal@10935
|
330
|
pascal@10935
|
331 -all: fusecloop extract_compressed_fs
|
pascal@10935
|
332 +all: fusecloop extract_compressed_fs create_compressed_fs
|
pascal@10935
|
333
|
pascal@10935
|
334 extract_compressed_fs: extract_compressed_fs.c
|
pascal@10935
|
335 ${CC} ${CFLAGS} ${LDFLAGS} -lz extract_compressed_fs.c -o extract_compressed_fs
|
pascal@10935
|
336
|
pascal@10935
|
337 +create_compressed_fs: create_compressed_fs.c
|
pascal@10935
|
338 + ${CC} ${CFLAGS} ${LDFLAGS} -lz create_compressed_fs.c -o create_compressed_fs
|
pascal@10935
|
339 +
|
pascal@10935
|
340 fusecloop: fusecloop.c cloopreader.o strver debug.o
|
pascal@10935
|
341 ${CC} ${CFLAGS} ${LDFLAGS} -lz cloopreader.o ${FUSECFLAGS} ${FUSELDFLAGS} fusecloop.c debug.o -o fusecloop
|
pascal@10935
|
342
|
pascal@10935
|
343
|
pascal@12214
|
344
|
pascal@10935
|
345 --- create_compressed_fs.c
|
pascal@10935
|
346 +++ create_compressed_fs.c
|
pascal@17996
|
347 @@ -0,0 +1,149 @@
|
pascal@12214
|
348 +#ifdef FIND_BEST_COMPRESSION
|
pascal@12214
|
349 +#include <compress.h>
|
pascal@12214
|
350 +extern "C" {
|
pascal@12214
|
351 +#include <stdlib.h>
|
pascal@12214
|
352 +#include <string.h>
|
pascal@12214
|
353 +
|
pascal@12214
|
354 +static int best_compress(unsigned char *compressed,
|
pascal@12214
|
355 + unsigned long *compressed_len,
|
pascal@12214
|
356 + unsigned char *uncompressed,
|
pascal@12214
|
357 + unsigned long uncompressed_len)
|
pascal@12214
|
358 +{
|
pascal@12214
|
359 + int i, j, err;
|
pascal@12214
|
360 + unsigned char *buf[2];
|
pascal@12214
|
361 + unsigned len;
|
pascal@12214
|
362 + unsigned long llen, best = *compressed_len * 2;
|
pascal@12214
|
363 + static unsigned char *buffer;
|
pascal@12214
|
364 + static unsigned long buffersz;
|
pascal@12214
|
365 +
|
pascal@12214
|
366 + if (buffersz < *compressed_len) {
|
pascal@12214
|
367 + if (buffer) free(buffer);
|
pascal@12214
|
368 + buffer = (unsigned char *) malloc(buffersz = *compressed_len);
|
pascal@12214
|
369 + if (!buffer) return Z_MEM_ERROR;
|
pascal@12214
|
370 + }
|
pascal@12214
|
371 + buf[0] = compressed;
|
pascal@12214
|
372 + buf[1] = buffer;
|
pascal@12214
|
373 + for (i = j = 0; i <= 10; i++) {
|
pascal@12214
|
374 + llen = len = *compressed_len;
|
pascal@12214
|
375 + if (i == 10)
|
pascal@12214
|
376 + err = (compress_zlib(shrink_extreme, buf[j],
|
pascal@12214
|
377 + len, uncompressed,
|
pascal@12214
|
378 + uncompressed_len)) ? Z_OK : Z_DATA_ERROR;
|
pascal@12214
|
379 + else {
|
pascal@12214
|
380 + err = compress2(buf[j], &llen, uncompressed,
|
pascal@12214
|
381 + uncompressed_len, i);
|
pascal@12214
|
382 + len = llen;
|
pascal@12214
|
383 + }
|
pascal@12214
|
384 + if (err != Z_OK) return err;
|
pascal@12214
|
385 + if (len < best) {
|
pascal@12214
|
386 + best = len;
|
pascal@12214
|
387 + j = 1 - j;
|
pascal@12214
|
388 + }
|
pascal@12214
|
389 + }
|
pascal@12214
|
390 + *compressed_len = best;
|
pascal@12214
|
391 + if (j == 0)
|
pascal@12214
|
392 + memcpy(compressed, buffer, best);
|
pascal@12214
|
393 + return err;
|
pascal@12214
|
394 +}
|
pascal@12214
|
395 +#define compress2(a,b,c,d,e) best_compress(a,b,c,d)
|
pascal@12214
|
396 +#endif
|
pascal@12214
|
397 +
|
pascal@10935
|
398 +/* Creates a compressed file */
|
pascal@10935
|
399 +#include "common_header.h"
|
pascal@10935
|
400 +
|
pascal@12214
|
401 +#define CLOOP_PREAMBLE "#!/bin/sh\n" "#V3.0 Format\n" "modprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n"
|
pascal@10935
|
402 +#define CHUNK 65536
|
pascal@10935
|
403 +#define DEFAULT_BLOCKSIZE 65536
|
pascal@10935
|
404 +
|
pascal@12214
|
405 +static void quit(const char *s)
|
pascal@10935
|
406 +{
|
pascal@10935
|
407 + fprintf(stderr, "%s\n", s);
|
pascal@10935
|
408 + exit(1);
|
pascal@10935
|
409 +}
|
pascal@10935
|
410 +
|
pascal@10935
|
411 +static int readblock(unsigned char *buffer, int n)
|
pascal@10935
|
412 +{
|
pascal@10935
|
413 + int i;
|
pascal@10935
|
414 +
|
pascal@10935
|
415 + memset(buffer, 0, n);
|
pascal@10935
|
416 + for (i = 0 ; i < n;) {
|
pascal@10935
|
417 + int j = read(STDIN_FILENO, buffer + i, n - i);
|
pascal@10935
|
418 + if (j < 0 && errno == EINTR) continue;
|
pascal@10935
|
419 + if (j <= 0) break;
|
pascal@10935
|
420 + i += j;
|
pascal@10935
|
421 + }
|
pascal@10935
|
422 + return i;
|
pascal@10935
|
423 +}
|
pascal@10935
|
424 +
|
pascal@10935
|
425 +int main(int argc, char *argv[])
|
pascal@10935
|
426 +{
|
pascal@10935
|
427 + struct cloop_head head;
|
pascal@10935
|
428 + struct cloop_tail tail;
|
pascal@10935
|
429 + unsigned long block_size = 0;
|
pascal@10935
|
430 + unsigned char *compressed, *uncompressed;
|
pascal@10935
|
431 + unsigned long *index;
|
pascal@10935
|
432 + int n, indexmax, zlenmax;
|
pascal@17996
|
433 + unsigned long lastlen, len, pos;
|
pascal@12214
|
434 + static char padding[512];
|
pascal@10935
|
435 +
|
pascal@10935
|
436 + if (argc > 1) {
|
pascal@10935
|
437 + if (argv[1][0] < '0' || argv[1][0] > '9')
|
pascal@10935
|
438 + quit("Usage : create_compressed_fs [block size] < input > output");
|
pascal@10935
|
439 + block_size = atoi(argv[1]);
|
pascal@10935
|
440 + }
|
pascal@10935
|
441 + if (block_size < 4096)
|
pascal@10935
|
442 + block_size = DEFAULT_BLOCKSIZE;
|
pascal@10935
|
443 + fprintf(stderr, "Block size is %lu\n", block_size);
|
pascal@10935
|
444 + zlenmax = block_size + block_size/1000 + 12;
|
pascal@10935
|
445 +
|
pascal@10935
|
446 + memset(&head, 0, sizeof(head));
|
pascal@10935
|
447 + strcpy(head.preamble, CLOOP_PREAMBLE);
|
pascal@10935
|
448 + head.num_blocks = -1;
|
pascal@10935
|
449 + head.block_size = htonl(block_size);
|
pascal@10935
|
450 + write(STDOUT_FILENO, &head, sizeof(head));
|
pascal@12214
|
451 + pos = sizeof(head);
|
pascal@10935
|
452 +
|
pascal@12214
|
453 + compressed = (unsigned char *) malloc(zlenmax);
|
pascal@12214
|
454 + uncompressed = (unsigned char *) malloc(block_size);
|
pascal@12214
|
455 + index = (unsigned long *) malloc(indexmax = CHUNK);
|
pascal@10935
|
456 + if (!compressed || !uncompressed || !index)
|
pascal@10935
|
457 + quit("Malloc failed");
|
pascal@10935
|
458 +
|
pascal@17996
|
459 + for (n = 0; (len = readblock(uncompressed, block_size)) != 0; n++) {
|
pascal@17996
|
460 + if (len) lastlen = len;
|
pascal@12214
|
461 + len = zlenmax;
|
pascal@10935
|
462 + if (compress2(compressed, &len, uncompressed, block_size,
|
pascal@10935
|
463 + Z_BEST_COMPRESSION) != Z_OK)
|
pascal@10935
|
464 + quit("Compression failed");
|
pascal@10935
|
465 + fprintf(stderr, "Block %u length %lu => %lu\n",
|
pascal@10935
|
466 + n, block_size, len);
|
pascal@10935
|
467 + write(STDOUT_FILENO, compressed, len);
|
pascal@12214
|
468 + pos += len;
|
pascal@10935
|
469 + if (n * sizeof(*index) >= indexmax) {
|
pascal@12214
|
470 + index = (unsigned long *) realloc(index,
|
pascal@12214
|
471 + indexmax += CHUNK);
|
pascal@10935
|
472 + if (!index)
|
pascal@10935
|
473 + quit("Realloc");
|
pascal@10935
|
474 + }
|
pascal@10935
|
475 + index[n] = ntohl(len);
|
pascal@10935
|
476 + }
|
pascal@17996
|
477 + if (block_size >= 0x1000000) lastlen = 0;
|
pascal@17996
|
478 + tail.index_size = ntohl(sizeof(*index) + 256*(lastlen % 0xFFffFF));
|
pascal@10935
|
479 + tail.num_blocks = ntohl(n);
|
pascal@12214
|
480 + n *= sizeof(*index);
|
pascal@12214
|
481 + len = n + n/1000 + 12;
|
pascal@17991
|
482 + compressed = (unsigned char *) realloc(compressed, len);
|
pascal@12214
|
483 + if (!compressed || compress2(compressed, &len, (unsigned char *) index,
|
pascal@12214
|
484 + n, Z_BEST_COMPRESSION) != Z_OK)
|
pascal@12214
|
485 + quit("Index compression failed");
|
pascal@12214
|
486 + tail.table_size = ntohl(len);
|
pascal@12214
|
487 + pos += len + sizeof(tail);
|
pascal@12214
|
488 + n = pos & 511;
|
pascal@12214
|
489 + if (n) write(STDOUT_FILENO, padding, 512 - n);
|
pascal@12214
|
490 + write(STDOUT_FILENO, compressed, len);
|
pascal@10935
|
491 + write(STDOUT_FILENO, &tail, sizeof(tail));
|
pascal@10935
|
492 + return 0;
|
pascal@10935
|
493 +}
|
pascal@12214
|
494 +#ifdef FIND_BEST_COMPRESSION
|
pascal@12214
|
495 +}
|
pascal@12214
|
496 +#endif
|
pascal@12214
|
497
|
pascal@10938
|
498 --- fusecloop.c
|
pascal@10938
|
499 +++ fusecloop.c
|
pascal@10938
|
500 @@ -65,7 +65,7 @@
|
pascal@10938
|
501
|
pascal@10938
|
502 memcpy(stbuf,&stb,sizeof stb);
|
pascal@10938
|
503 stbuf->st_mode&=~0222;
|
pascal@10938
|
504 - stbuf->st_size = cd.blocksize * cd.numblocks;
|
pascal@10938
|
505 + stbuf->st_size = (loff_t) cd.blocksize * cd.numblocks;
|
pascal@10938
|
506 /*
|
pascal@10938
|
507 stbuf->st_mode = S_IFREG | 0444;
|
pascal@10938
|
508 stbuf->st_nlink = 1;
|