wok rev 10935
fusecloop: add create_compressed_fs
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sat Aug 27 13:32:15 2011 +0200 (2011-08-27) |
parents | 27a1c1c0fdf3 |
children | e5f7f1b3d407 |
files | fusecloop/stuff/fusecloop.u |
line diff
1.1 --- a/fusecloop/stuff/fusecloop.u Fri Aug 26 20:47:01 2011 +0200 1.2 +++ b/fusecloop/stuff/fusecloop.u Sat Aug 27 13:32:15 2011 +0200 1.3 @@ -1,6 +1,6 @@ 1.4 --- compressed_loop.h 1.5 +++ compressed_loop.h 1.6 -@@ -41,6 +41,85 @@ 1.7 +@@ -41,6 +41,73 @@ 1.8 /* data_index (num_blocks 64bit pointers, network order)... */ 1.9 /* compressed data (gzip block compressed format)... */ 1.10 1.11 @@ -17,10 +17,8 @@ 1.12 + u_int32_t optidx; /* 32-bit index number */ 1.13 +}; 1.14 + 1.15 -+static inline char *build_index(struct block_info *offsets, unsigned long n, 1.16 -+ unsigned long block_size) 1.17 ++static inline char *build_index(struct block_info *offsets, unsigned long n) 1.18 +{ 1.19 -+ u_int16_t *ofs16 = (u_int16_t *) offsets; 1.20 + u_int32_t *ofs32 = (u_int32_t *) offsets; 1.21 + loff_t *ofs64 = (loff_t *) offsets; 1.22 + 1.23 @@ -61,25 +59,15 @@ 1.24 + return "32BE v0.68"; 1.25 + } 1.26 + else { /* V3.0 */ 1.27 -+ char *type; 1.28 -+ int i, j, smallest; 1.29 ++ int i, j; 1.30 + 1.31 -+ smallest = (block_size < 32768) ? 0 : block_size>>10; 1.32 -+ if (block_size > 0x10000) { 1.33 -+ for (i = 0; i < n; i++) 1.34 -+ offsets[n].size = smallest + ntohl(ofs32[n]); 1.35 -+ type = "32BE size v3.0"; 1.36 -+ } 1.37 -+ else { 1.38 -+ for (i = 0; i < n; i++) 1.39 -+ offsets[n].size = smallest + ntohs(ofs16[n]); 1.40 -+ type = "16BE size v3.0"; 1.41 -+ } 1.42 -+ for (i = j = 0; i < n; i++) { 1.43 ++ for (i = n; i-- > 0; ) 1.44 ++ offsets[i].size = ntohl(ofs32[i]); 1.45 ++ for (i = 0, j = sizeof(struct cloop_head); i < n; i++) { 1.46 + offsets[i].offset = j; 1.47 + j += offsets[i].size; 1.48 + } 1.49 -+ return type; 1.50 ++ return "32BE v3.0"; 1.51 + } 1.52 +} 1.53 + 1.54 @@ -101,7 +89,7 @@ 1.55 1.56 --- cloopreader.c 1.57 +++ cloopreader.c 1.58 -@@ -59,10 +59,20 @@ 1.59 +@@ -59,10 +59,21 @@ 1.60 1.61 ALLOC(c->pblock,c->blocksize); 1.62 1.63 @@ -109,21 +97,22 @@ 1.64 + c->tocsize=sizeof(*c->toc) * c->numblocks; 1.65 + if (c->numblocks == -1) { 1.66 + struct cloop_tail tail; 1.67 ++ loff_t end = lseek(c->fh,0,SEEK_END); /* lseek(,-n,SEEK_END) buggy ? */ 1.68 + 1.69 -+ OP(lseek(c->fh, - sizeof(tail), SEEK_END)); 1.70 ++ OP(lseek(c->fh, end - sizeof(tail), SEEK_SET)); 1.71 + OP(read_all(c->fh, &tail, sizeof(tail))); 1.72 + c->numblocks = ntohl(tail.num_blocks); 1.73 + c->tocsize = ntohl(tail.index_size) * c->numblocks; 1.74 -+ OP(lseek(c->fh, - sizeof(tail) - c->tocsize, SEEK_END)); 1.75 ++ OP(lseek(c->fh, end - sizeof(tail) - c->tocsize, SEEK_SET)); 1.76 + } 1.77 ALLOC(c->toc,c->tocsize); 1.78 1.79 OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */ 1.80 -+ build_index(c->toc, c->numblocks, c->blocksize); 1.81 ++ build_index(c->toc, c->numblocks); 1.82 c->cblocksizecur=0; 1.83 c->curblock=-1; 1.84 return 0; 1.85 -@@ -79,10 +89,10 @@ 1.86 +@@ -79,10 +90,10 @@ 1.87 if(page>=c->numblocks){errno=EFAULT;return -1;} 1.88 c->curblock=page; 1.89 1.90 @@ -140,20 +129,51 @@ 1.91 1.92 --- extract_compressed_fs.c 1.93 +++ extract_compressed_fs.c 1.94 -@@ -7,6 +7,7 @@ 1.95 +@@ -1,15 +1,18 @@ 1.96 + /* Extracts a filesystem back from a compressed fs file */ 1.97 + #include "common_header.h" 1.98 ++#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" 1.99 + 1.100 + int main(int argc, char *argv[]) 1.101 + { 1.102 + int handle; 1.103 struct cloop_head head; 1.104 unsigned int i; 1.105 ++ unsigned long num_blocks, block_size, zblock_maxsize; 1.106 unsigned char *buffer, *clear_buffer; 1.107 + struct block_info *offsets; 1.108 1.109 - if (argc != 2) { 1.110 - fprintf(stderr, "Need filename\n"); 1.111 -@@ -30,35 +31,48 @@ 1.112 - fprintf(stderr, "%u blocks of size %u. Preamble:\n%s\n", 1.113 - ntohl(head.num_blocks), ntohl(head.block_size), head.preamble); 1.114 +- if (argc != 2) { 1.115 +- fprintf(stderr, "Need filename\n"); 1.116 ++ if (argc < 2 || argv[1][0] == '-') { 1.117 ++ fprintf(stderr, "Usage: extract_compressed_fs file [--convert-to-v2] > output\n"); 1.118 + exit(1); 1.119 + } 1.120 1.121 -+ i = ntohl(head.num_blocks); 1.122 -+ if (i == -1) { 1.123 +@@ -24,44 +27,77 @@ 1.124 + exit(1); 1.125 + } 1.126 + 1.127 +- buffer = malloc(ntohl(head.block_size) + ntohl(head.block_size)/1000 1.128 +- + 12 + 4); 1.129 +- clear_buffer = malloc(ntohl(head.block_size)); 1.130 +- fprintf(stderr, "%u blocks of size %u. Preamble:\n%s\n", 1.131 +- ntohl(head.num_blocks), ntohl(head.block_size), head.preamble); 1.132 +- 1.133 +- for (i = 0; i < ntohl(head.num_blocks); i++) { 1.134 +- int currpos; 1.135 +- unsigned long destlen = ntohl(head.block_size); 1.136 +- loff_t offset[2]; 1.137 +- unsigned int size; 1.138 ++ num_blocks = ntohl(head.num_blocks); 1.139 ++ block_size = ntohl(head.block_size); 1.140 ++ zblock_maxsize = block_size + block_size/1000 + 12 + 4; 1.141 ++ buffer = malloc(zblock_maxsize); 1.142 ++ clear_buffer = malloc(block_size); 1.143 ++ fprintf(stderr, "%lu blocks of size %lu. Preamble:\n%s\n", 1.144 ++ num_blocks, block_size, head.preamble); 1.145 ++ 1.146 ++ if (num_blocks == -1) { 1.147 + struct cloop_tail tail; 1.148 + if (lseek(handle, - sizeof(tail), SEEK_END) < 0 || 1.149 + read(handle, &tail, sizeof(tail)) != sizeof(tail) || 1.150 @@ -164,23 +184,40 @@ 1.151 + exit(1); 1.152 + } 1.153 + head.num_blocks = tail.num_blocks; 1.154 -+ i = ntohl(tail.num_blocks) * ntohl(tail.index_size); 1.155 ++ num_blocks = ntohl(head.num_blocks); 1.156 ++ i = num_blocks * ntohl(tail.index_size); 1.157 + } 1.158 -+ else i *= sizeof(*offsets); 1.159 ++ else i = num_blocks * sizeof(*offsets); 1.160 + offsets = malloc(i); 1.161 + if (!offsets || read(handle, offsets, i) != i) { 1.162 + perror("Reading index\n"); 1.163 + exit(1); 1.164 + } 1.165 + 1.166 -+ fprintf(stderr, "Index %s.\n", build_index(offsets, 1.167 -+ ntohl(head.num_blocks), ntohl(head.block_size))); 1.168 ++ fprintf(stderr, "Index %s.\n", build_index(offsets, num_blocks)); 1.169 + 1.170 - for (i = 0; i < ntohl(head.num_blocks); i++) { 1.171 -- int currpos; 1.172 - unsigned long destlen = ntohl(head.block_size); 1.173 -- loff_t offset[2]; 1.174 -- unsigned int size; 1.175 ++ if (argc > 2) { 1.176 ++ loff_t offset; 1.177 ++ int delta = ((num_blocks + 1) * sizeof(offset)) + 1.178 ++ sizeof(head) - offsets[0].offset; 1.179 ++ 1.180 ++ strcpy(head.preamble, CLOOP_PREAMBLE); 1.181 ++ write(STDOUT_FILENO, &head, sizeof(head)); 1.182 ++ for (i = 0; i < num_blocks; i++) { 1.183 ++ offset = __be64_to_cpu(delta + offsets[i].offset); 1.184 ++ write(STDOUT_FILENO, &offset, sizeof(offset)); 1.185 ++ } 1.186 ++ offset = __be64_to_cpu(delta + offsets[num_blocks-1].offset + offsets[num_blocks-1].size); 1.187 ++ write(STDOUT_FILENO, &offset, sizeof(offset)); 1.188 ++ for (i = 0; i < num_blocks && lseek(handle, offsets[i].offset, SEEK_SET) >= 0; i++) { 1.189 ++ read(handle, buffer, offsets[i].size); 1.190 ++ write(STDOUT_FILENO, buffer, offsets[i].size); 1.191 ++ } 1.192 ++ return 0; 1.193 ++ } 1.194 ++ 1.195 ++ for (i = 0; i < num_blocks; i++) { 1.196 ++ unsigned long destlen = block_size; 1.197 + unsigned int size = offsets[i].size; 1.198 1.199 - read(handle, &offset, 2*sizeof(loff_t)); 1.200 @@ -196,8 +233,9 @@ 1.201 } 1.202 1.203 - size=__be64_to_cpu(offset[1])-__be64_to_cpu(offset[0]); 1.204 - if (size > ntohl(head.block_size) + ntohl(head.block_size)/1000 1.205 - + 12 + 4) { 1.206 +- if (size > ntohl(head.block_size) + ntohl(head.block_size)/1000 1.207 +- + 12 + 4) { 1.208 ++ if (size > zblock_maxsize) { 1.209 fprintf(stderr, 1.210 "Size %u for block %u (offset %Lu) too big\n", 1.211 - size, i, __be64_to_cpu(offset[0])); 1.212 @@ -210,5 +248,136 @@ 1.213 - exit(1); 1.214 - } 1.215 1.216 - fprintf(stderr, "Block %u length %u => %lu\n", 1.217 - i, size, destlen); 1.218 +- fprintf(stderr, "Block %u length %u => %lu\n", 1.219 +- i, size, destlen); 1.220 ++ fprintf(stderr, "Block %u at %llu length %u => %lu\n", 1.221 ++ i, offsets[i].offset, size, destlen); 1.222 + if (i == 3) { 1.223 + fprintf(stderr, 1.224 + "Block head:%02X%02X%02X%02X%02X%02X%02X%02X\n", 1.225 +@@ -105,12 +141,12 @@ 1.226 + fprintf(stderr, "Uncomp: unknown error %u\n", i); 1.227 + exit(1); 1.228 + } 1.229 +- if (destlen != ntohl(head.block_size)) { 1.230 +- fprintf(stderr, "Uncomp: bad len %u (%lu not %u)\n", i, 1.231 +- destlen, ntohl(head.block_size)); 1.232 ++ if (destlen != block_size) { 1.233 ++ fprintf(stderr, "Uncomp: bad len %u (%lu not %lu)\n", i, 1.234 ++ destlen, block_size); 1.235 + exit(1); 1.236 + } 1.237 +- write(STDOUT_FILENO, clear_buffer, ntohl(head.block_size)); 1.238 ++ write(STDOUT_FILENO, clear_buffer, block_size); 1.239 + } 1.240 + return 0; 1.241 + } 1.242 + 1.243 +--- Makefile 1.244 ++++ Makefile 1.245 +@@ -1,16 +1,19 @@ 1.246 + PROGNAME=fusecloop 1.247 + ARCFILES=*.c *.h *.pl Makefile configure README VERSION HELP INSTALL typescript *.cloop COPYING 1.248 +-PROGS=fusecloop cloopreaderdemo extract_compressed_fs 1.249 ++PROGS=fusecloop cloopreaderdemo extract_compressed_fs create_compressed_fs 1.250 + FUSECFLAGS=`pkg-config fuse --cflags` 1.251 + FUSELDFLAGS=`pkg-config fuse --libs` 1.252 + 1.253 + CFLAGS= -Wall 1.254 + 1.255 +-all: fusecloop extract_compressed_fs 1.256 ++all: fusecloop extract_compressed_fs create_compressed_fs 1.257 + 1.258 + extract_compressed_fs: extract_compressed_fs.c 1.259 + ${CC} ${CFLAGS} ${LDFLAGS} -lz extract_compressed_fs.c -o extract_compressed_fs 1.260 + 1.261 ++create_compressed_fs: create_compressed_fs.c 1.262 ++ ${CC} ${CFLAGS} ${LDFLAGS} -lz create_compressed_fs.c -o create_compressed_fs 1.263 ++ 1.264 + fusecloop: fusecloop.c cloopreader.o strver debug.o 1.265 + ${CC} ${CFLAGS} ${LDFLAGS} -lz cloopreader.o ${FUSECFLAGS} ${FUSELDFLAGS} fusecloop.c debug.o -o fusecloop 1.266 + 1.267 + 1.268 +--- create_compressed_fs.c 1.269 ++++ create_compressed_fs.c 1.270 +@@ -0,0 +1,80 @@ 1.271 ++/* Creates a compressed file */ 1.272 ++#include "common_header.h" 1.273 ++ 1.274 ++#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" 1.275 ++#define CHUNK 65536 1.276 ++#define DEFAULT_BLOCKSIZE 65536 1.277 ++ 1.278 ++static void quit(char *s) 1.279 ++{ 1.280 ++ fprintf(stderr, "%s\n", s); 1.281 ++ exit(1); 1.282 ++} 1.283 ++ 1.284 ++static int readblock(unsigned char *buffer, int n) 1.285 ++{ 1.286 ++ int i; 1.287 ++ 1.288 ++ memset(buffer, 0, n); 1.289 ++ for (i = 0 ; i < n;) { 1.290 ++ int j = read(STDIN_FILENO, buffer + i, n - i); 1.291 ++ if (j < 0 && errno == EINTR) continue; 1.292 ++ if (j <= 0) break; 1.293 ++ i += j; 1.294 ++ } 1.295 ++ return i; 1.296 ++} 1.297 ++ 1.298 ++int main(int argc, char *argv[]) 1.299 ++{ 1.300 ++ struct cloop_head head; 1.301 ++ struct cloop_tail tail; 1.302 ++ unsigned long block_size = 0; 1.303 ++ unsigned char *compressed, *uncompressed; 1.304 ++ unsigned long *index; 1.305 ++ int n, indexmax, zlenmax; 1.306 ++ 1.307 ++ if (argc > 1) { 1.308 ++ if (argv[1][0] < '0' || argv[1][0] > '9') 1.309 ++ quit("Usage : create_compressed_fs [block size] < input > output"); 1.310 ++ block_size = atoi(argv[1]); 1.311 ++ } 1.312 ++ if (block_size < 4096) 1.313 ++ block_size = DEFAULT_BLOCKSIZE; 1.314 ++ fprintf(stderr, "Block size is %lu\n", block_size); 1.315 ++ zlenmax = block_size + block_size/1000 + 12; 1.316 ++ 1.317 ++ memset(&head, 0, sizeof(head)); 1.318 ++ strcpy(head.preamble, CLOOP_PREAMBLE); 1.319 ++ head.num_blocks = -1; 1.320 ++ head.block_size = htonl(block_size); 1.321 ++ write(STDOUT_FILENO, &head, sizeof(head)); 1.322 ++ 1.323 ++ compressed = malloc(zlenmax); 1.324 ++ uncompressed = malloc(block_size); 1.325 ++ index = malloc(indexmax = CHUNK); 1.326 ++ if (!compressed || !uncompressed || !index) 1.327 ++ quit("Malloc failed"); 1.328 ++ 1.329 ++ for (n = 0; readblock(uncompressed, block_size); n++) { 1.330 ++ unsigned long len = zlenmax; 1.331 ++ 1.332 ++ if (compress2(compressed, &len, uncompressed, block_size, 1.333 ++ Z_BEST_COMPRESSION) != Z_OK) 1.334 ++ quit("Compression failed"); 1.335 ++ fprintf(stderr, "Block %u length %lu => %lu\n", 1.336 ++ n, block_size, len); 1.337 ++ write(STDOUT_FILENO, compressed, len); 1.338 ++ if (n * sizeof(*index) >= indexmax) { 1.339 ++ index = realloc(index, indexmax += CHUNK); 1.340 ++ if (!index) 1.341 ++ quit("Realloc"); 1.342 ++ } 1.343 ++ index[n] = ntohl(len); 1.344 ++ } 1.345 ++ write(STDOUT_FILENO, index, n * sizeof(*index)); 1.346 ++ tail.index_size = ntohl(sizeof(*index)); 1.347 ++ tail.num_blocks = ntohl(n); 1.348 ++ write(STDOUT_FILENO, &tail, sizeof(tail)); 1.349 ++ return 0; 1.350 ++}