rev |
line source |
pascal@10932
|
1 --- compressed_loop.h
|
pascal@10932
|
2 +++ compressed_loop.h
|
pascal@10933
|
3 @@ -41,6 +41,85 @@
|
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@10933
|
20 +static inline char *build_index(struct block_info *offsets, unsigned long n,
|
pascal@10933
|
21 + unsigned long block_size)
|
pascal@10932
|
22 +{
|
pascal@10933
|
23 + u_int16_t *ofs16 = (u_int16_t *) offsets;
|
pascal@10932
|
24 + u_int32_t *ofs32 = (u_int32_t *) offsets;
|
pascal@10932
|
25 + loff_t *ofs64 = (loff_t *) offsets;
|
pascal@10933
|
26 +
|
pascal@10932
|
27 + if (ofs32[0] == 0) {
|
pascal@10932
|
28 + if (ofs32[2]) { /* ACCELERATED KNOPPIX V1.0 */
|
pascal@10933
|
29 + while (n--) {
|
pascal@10932
|
30 + offsets[n].offset = __be64_to_cpu(offsets[n].offset);
|
pascal@10932
|
31 + offsets[n].size = ntohl(offsets[n].size);
|
pascal@10933
|
32 + }
|
pascal@10932
|
33 + return "128BE accelerated knoppix 1.0";
|
pascal@10932
|
34 + }
|
pascal@10932
|
35 + else { /* V2.0 */
|
pascal@10933
|
36 + loff_t last = __be64_to_cpu(ofs64[n]);
|
pascal@10933
|
37 + while (n--) {
|
pascal@10932
|
38 + offsets[n].size = last -
|
pascal@10932
|
39 + (offsets[n].offset = __be64_to_cpu(ofs64[n]));
|
pascal@10932
|
40 + last = offsets[n].offset;
|
pascal@10933
|
41 + }
|
pascal@10932
|
42 + return "64BE v2.0";
|
pascal@10932
|
43 + }
|
pascal@10932
|
44 + }
|
pascal@10932
|
45 + else if (ofs32[1] == 0) { /* V1.0 */
|
pascal@10933
|
46 + loff_t last = __be64_to_cpu(ofs64[n]);
|
pascal@10933
|
47 + while (n--) {
|
pascal@10932
|
48 + offsets[n].size = last -
|
pascal@10932
|
49 + (offsets[n].offset = __le64_to_cpu(ofs64[n]));
|
pascal@10932
|
50 + last = offsets[n].offset;
|
pascal@10933
|
51 + }
|
pascal@10932
|
52 + return "64LE v1.0";
|
pascal@10932
|
53 + }
|
pascal@10933
|
54 + else if (ntohl(ofs32[0]) == (4*n) + 0x8C) { /* V0.68 */
|
pascal@10933
|
55 + loff_t last = ntohl(ofs32[n]);
|
pascal@10933
|
56 + while (n--) {
|
pascal@10932
|
57 + offsets[n].size = last -
|
pascal@10932
|
58 + (offsets[n].offset = ntohl(ofs32[n]));
|
pascal@10932
|
59 + last = offsets[n].offset;
|
pascal@10933
|
60 + }
|
pascal@10932
|
61 + return "32BE v0.68";
|
pascal@10932
|
62 + }
|
pascal@10933
|
63 + else { /* V3.0 */
|
pascal@10933
|
64 + char *type;
|
pascal@10933
|
65 + int i, j, smallest;
|
pascal@10933
|
66 +
|
pascal@10933
|
67 + smallest = (block_size < 32768) ? 0 : block_size>>10;
|
pascal@10933
|
68 + if (block_size > 0x10000) {
|
pascal@10933
|
69 + for (i = 0; i < n; i++)
|
pascal@10933
|
70 + offsets[n].size = smallest + ntohl(ofs32[n]);
|
pascal@10933
|
71 + type = "32BE size v3.0";
|
pascal@10933
|
72 + }
|
pascal@10933
|
73 + else {
|
pascal@10933
|
74 + for (i = 0; i < n; i++)
|
pascal@10933
|
75 + offsets[n].size = smallest + ntohs(ofs16[n]);
|
pascal@10933
|
76 + type = "16BE size v3.0";
|
pascal@10933
|
77 + }
|
pascal@10933
|
78 + for (i = j = 0; i < n; i++) {
|
pascal@10933
|
79 + offsets[i].offset = j;
|
pascal@10933
|
80 + j += offsets[i].size;
|
pascal@10933
|
81 + }
|
pascal@10933
|
82 + return type;
|
pascal@10933
|
83 + }
|
pascal@10932
|
84 +}
|
pascal@10932
|
85 +
|
pascal@10932
|
86 /* Cloop suspend IOCTL */
|
pascal@10932
|
87 #define CLOOP_SUSPEND 0x4C07
|
pascal@10932
|
88
|
pascal@10932
|
89
|
pascal@10932
|
90 --- cloopreader.h
|
pascal@10932
|
91 +++ cloopreader.h
|
pascal@10932
|
92 @@ -33,7 +33,7 @@
|
pascal@10932
|
93 int numblocks;
|
pascal@10932
|
94 ulong blocksize;
|
pascal@10932
|
95
|
pascal@10932
|
96 - loff_t* toc; /* Data index */
|
pascal@10932
|
97 + struct block_info *toc; /* Data index */
|
pascal@10932
|
98 size_t tocsize;
|
pascal@10932
|
99
|
pascal@10932
|
100 unsigned char* cblock; /* Compressed block */
|
pascal@10932
|
101
|
pascal@10932
|
102 --- cloopreader.c
|
pascal@10932
|
103 +++ cloopreader.c
|
pascal@10933
|
104 @@ -59,10 +59,20 @@
|
pascal@10932
|
105
|
pascal@10932
|
106 ALLOC(c->pblock,c->blocksize);
|
pascal@10932
|
107
|
pascal@10932
|
108 - c->tocsize=sizeof *c->toc * (c->numblocks+1); /* One extra address is position of EOF */
|
pascal@10932
|
109 + c->tocsize=sizeof(*c->toc) * c->numblocks;
|
pascal@10933
|
110 + if (c->numblocks == -1) {
|
pascal@10933
|
111 + struct cloop_tail tail;
|
pascal@10933
|
112 +
|
pascal@10933
|
113 + OP(lseek(c->fh, - sizeof(tail), SEEK_END));
|
pascal@10933
|
114 + OP(read_all(c->fh, &tail, sizeof(tail)));
|
pascal@10933
|
115 + c->numblocks = ntohl(tail.num_blocks);
|
pascal@10933
|
116 + c->tocsize = ntohl(tail.index_size) * c->numblocks;
|
pascal@10933
|
117 + OP(lseek(c->fh, - sizeof(tail) - c->tocsize, SEEK_END));
|
pascal@10933
|
118 + }
|
pascal@10932
|
119 ALLOC(c->toc,c->tocsize);
|
pascal@10932
|
120
|
pascal@10932
|
121 OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */
|
pascal@10933
|
122 + build_index(c->toc, c->numblocks, c->blocksize);
|
pascal@10932
|
123 c->cblocksizecur=0;
|
pascal@10932
|
124 c->curblock=-1;
|
pascal@10932
|
125 return 0;
|
pascal@10933
|
126 @@ -79,10 +89,10 @@
|
pascal@10932
|
127 if(page>=c->numblocks){errno=EFAULT;return -1;}
|
pascal@10932
|
128 c->curblock=page;
|
pascal@10932
|
129
|
pascal@10932
|
130 - bprintf("Seeking to 0x%Lx\n",btc(c->toc[page]));
|
pascal@10932
|
131 - OP(lseek(c->fh,btc(c->toc[page]), SEEK_SET));
|
pascal@10932
|
132 + bprintf("Seeking to 0x%Lx\n",c->toc[page].offset);
|
pascal@10932
|
133 + OP(lseek(c->fh,c->toc[page].offset, SEEK_SET));
|
pascal@10932
|
134
|
pascal@10932
|
135 - c->cblocksize=btc(c->toc[page+1]) - btc(c->toc[page]);
|
pascal@10932
|
136 + c->cblocksize=c->toc[page].size;
|
pascal@10932
|
137 bprintf("Compressed size=%lu\n",c->cblocksize);
|
pascal@10932
|
138 if(c->cblocksize > c->cblocksizecur){
|
pascal@10932
|
139 if(c->cblocksizecur)free(c->cblock);
|
pascal@10933
|
140
|
pascal@10932
|
141 --- extract_compressed_fs.c
|
pascal@10932
|
142 +++ extract_compressed_fs.c
|
pascal@10932
|
143 @@ -7,6 +7,7 @@
|
pascal@10932
|
144 struct cloop_head head;
|
pascal@10932
|
145 unsigned int i;
|
pascal@10932
|
146 unsigned char *buffer, *clear_buffer;
|
pascal@10932
|
147 + struct block_info *offsets;
|
pascal@10932
|
148
|
pascal@10932
|
149 if (argc != 2) {
|
pascal@10932
|
150 fprintf(stderr, "Need filename\n");
|
pascal@10933
|
151 @@ -30,35 +31,48 @@
|
pascal@10932
|
152 fprintf(stderr, "%u blocks of size %u. Preamble:\n%s\n",
|
pascal@10932
|
153 ntohl(head.num_blocks), ntohl(head.block_size), head.preamble);
|
pascal@10932
|
154
|
pascal@10933
|
155 + i = ntohl(head.num_blocks);
|
pascal@10933
|
156 + if (i == -1) {
|
pascal@10933
|
157 + struct cloop_tail tail;
|
pascal@10933
|
158 + if (lseek(handle, - sizeof(tail), SEEK_END) < 0 ||
|
pascal@10933
|
159 + read(handle, &tail, sizeof(tail)) != sizeof(tail) ||
|
pascal@10933
|
160 + lseek(handle, - sizeof(tail) -
|
pascal@10933
|
161 + (ntohl(tail.num_blocks) * ntohl(tail.index_size)),
|
pascal@10933
|
162 + SEEK_END) < 0) {
|
pascal@10933
|
163 + perror("Reading tail\n");
|
pascal@10933
|
164 + exit(1);
|
pascal@10933
|
165 + }
|
pascal@10933
|
166 + head.num_blocks = tail.num_blocks;
|
pascal@10933
|
167 + i = ntohl(tail.num_blocks) * ntohl(tail.index_size);
|
pascal@10933
|
168 + }
|
pascal@10933
|
169 + else i *= sizeof(*offsets);
|
pascal@10932
|
170 + offsets = malloc(i);
|
pascal@10932
|
171 + if (!offsets || read(handle, offsets, i) != i) {
|
pascal@10932
|
172 + perror("Reading index\n");
|
pascal@10932
|
173 + exit(1);
|
pascal@10932
|
174 + }
|
pascal@10932
|
175 +
|
pascal@10933
|
176 + fprintf(stderr, "Index %s.\n", build_index(offsets,
|
pascal@10933
|
177 + ntohl(head.num_blocks), ntohl(head.block_size)));
|
pascal@10932
|
178 +
|
pascal@10932
|
179 for (i = 0; i < ntohl(head.num_blocks); i++) {
|
pascal@10932
|
180 - int currpos;
|
pascal@10932
|
181 unsigned long destlen = ntohl(head.block_size);
|
pascal@10932
|
182 - loff_t offset[2];
|
pascal@10932
|
183 - unsigned int size;
|
pascal@10932
|
184 + unsigned int size = offsets[i].size;
|
pascal@10932
|
185
|
pascal@10932
|
186 - read(handle, &offset, 2*sizeof(loff_t));
|
pascal@10932
|
187 - lseek(handle, -sizeof(loff_t), SEEK_CUR);
|
pascal@10932
|
188 -
|
pascal@10932
|
189 - currpos = lseek(handle, 0, SEEK_CUR);
|
pascal@10932
|
190 - if (lseek(handle, __be64_to_cpu(offset[0]), SEEK_SET) < 0) {
|
pascal@10932
|
191 + if (lseek(handle, offsets[i].offset, SEEK_SET) < 0) {
|
pascal@10932
|
192 fprintf(stderr, "lseek to %Lu: %s\n",
|
pascal@10932
|
193 - __be64_to_cpu(offset[0]), strerror(errno));
|
pascal@10932
|
194 + offsets[i].offset, strerror(errno));
|
pascal@10932
|
195 exit(1);
|
pascal@10932
|
196 }
|
pascal@10932
|
197
|
pascal@10932
|
198 - size=__be64_to_cpu(offset[1])-__be64_to_cpu(offset[0]);
|
pascal@10932
|
199 if (size > ntohl(head.block_size) + ntohl(head.block_size)/1000
|
pascal@10932
|
200 + 12 + 4) {
|
pascal@10932
|
201 fprintf(stderr,
|
pascal@10932
|
202 "Size %u for block %u (offset %Lu) too big\n",
|
pascal@10932
|
203 - size, i, __be64_to_cpu(offset[0]));
|
pascal@10932
|
204 + size, i, offsets[i].offset);
|
pascal@10932
|
205 exit(1);
|
pascal@10932
|
206 }
|
pascal@10932
|
207 read(handle, buffer, size);
|
pascal@10932
|
208 - if (lseek(handle, currpos, SEEK_SET) < 0) {
|
pascal@10932
|
209 - perror("seeking");
|
pascal@10932
|
210 - exit(1);
|
pascal@10932
|
211 - }
|
pascal@10932
|
212
|
pascal@10932
|
213 fprintf(stderr, "Block %u length %u => %lu\n",
|
pascal@10932
|
214 i, size, destlen);
|