wok annotate fusecloop/stuff/fusecloop.u @ rev 20257

Add giflossy
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Mar 13 23:27:32 2018 +0100 (2018-03-13)
parents 792674d97726
children 63cdeb5a1e77
rev   line source
pascal@10932 1 --- compressed_loop.h
pascal@10932 2 +++ compressed_loop.h
pascal@18828 3 @@ -41,6 +41,80 @@
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@18828 70 + if (offsets[i].size & 0x80000000) {
pascal@18829 71 + unsigned long k = offsets[i].size & 0x7FFFFFFF;
pascal@18828 72 + offsets[i].offset = offsets[k].offset;
pascal@18828 73 + offsets[i].size = offsets[k].size;
pascal@18828 74 + }
pascal@18828 75 + else j += offsets[i].size;
pascal@10933 76 + }
pascal@12214 77 + return (char *) "32BE v3.0";
pascal@10933 78 + }
pascal@10932 79 +}
pascal@10932 80 +
pascal@10932 81 /* Cloop suspend IOCTL */
pascal@10932 82 #define CLOOP_SUSPEND 0x4C07
pascal@10932 83
pascal@10932 84
pascal@10932 85 --- cloopreader.h
pascal@10932 86 +++ cloopreader.h
pascal@10932 87 @@ -33,7 +33,7 @@
pascal@10932 88 int numblocks;
pascal@10932 89 ulong blocksize;
pascal@10932 90
pascal@10932 91 - loff_t* toc; /* Data index */
pascal@10932 92 + struct block_info *toc; /* Data index */
pascal@10932 93 size_t tocsize;
pascal@10932 94
pascal@10932 95 unsigned char* cblock; /* Compressed block */
pascal@10932 96
pascal@10932 97 --- cloopreader.c
pascal@10932 98 +++ cloopreader.c
pascal@12214 99 @@ -59,10 +59,32 @@
pascal@10932 100
pascal@10932 101 ALLOC(c->pblock,c->blocksize);
pascal@10932 102
pascal@10932 103 - c->tocsize=sizeof *c->toc * (c->numblocks+1); /* One extra address is position of EOF */
pascal@12214 104 - ALLOC(c->toc,c->tocsize);
pascal@12214 105 + if (c->numblocks + 1 == 0) {
pascal@10933 106 + struct cloop_tail tail;
pascal@10935 107 + loff_t end = lseek(c->fh,0,SEEK_END); /* lseek(,-n,SEEK_END) buggy ? */
pascal@12214 108 + void *p;
pascal@12214 109 + ulong toclen, len;
pascal@12214 110
pascal@12214 111 - OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */
pascal@10935 112 + OP(lseek(c->fh, end - sizeof(tail), SEEK_SET));
pascal@10933 113 + OP(read_all(c->fh, &tail, sizeof(tail)));
pascal@10933 114 + c->numblocks = ntohl(tail.num_blocks);
pascal@12214 115 + c->tocsize = sizeof(*c->toc) * c->numblocks;
pascal@12214 116 + len = ntohl(tail.table_size);
pascal@12214 117 + toclen = (ntohl(tail.index_size) & 255) * c->numblocks;
pascal@12214 118 + OP(lseek(c->fh, end - sizeof(tail) - len, SEEK_SET));
pascal@17168 119 + ALLOC(c->toc, sizeof(*c->toc) * c->numblocks);
pascal@12214 120 + ALLOC(p,len);
pascal@12214 121 + OP(read_all(c->fh,p,len)); /* read Data Index */
pascal@12214 122 + if (uncompress((void *)c->toc,&toclen,p,len) != Z_OK)
pascal@12214 123 + exit(1);
pascal@12214 124 + free(p);
pascal@10933 125 + }
pascal@12214 126 + else {
pascal@12214 127 + c->tocsize = sizeof(*c->toc) * c->numblocks;
pascal@12214 128 + ALLOC(c->toc,c->tocsize);
pascal@12214 129 + OP(read_all(c->fh,c->toc,c->tocsize)); /* read Data Index */
pascal@12214 130 + }
pascal@10935 131 + build_index(c->toc, c->numblocks);
pascal@10932 132 c->cblocksizecur=0;
pascal@10932 133 c->curblock=-1;
pascal@10932 134 return 0;
pascal@12214 135 @@ -79,10 +101,10 @@
pascal@10932 136 if(page>=c->numblocks){errno=EFAULT;return -1;}
pascal@10932 137 c->curblock=page;
pascal@10932 138
pascal@10932 139 - bprintf("Seeking to 0x%Lx\n",btc(c->toc[page]));
pascal@10932 140 - OP(lseek(c->fh,btc(c->toc[page]), SEEK_SET));
pascal@10932 141 + bprintf("Seeking to 0x%Lx\n",c->toc[page].offset);
pascal@10932 142 + OP(lseek(c->fh,c->toc[page].offset, SEEK_SET));
pascal@10932 143
pascal@10932 144 - c->cblocksize=btc(c->toc[page+1]) - btc(c->toc[page]);
pascal@10932 145 + c->cblocksize=c->toc[page].size;
pascal@10932 146 bprintf("Compressed size=%lu\n",c->cblocksize);
pascal@10932 147 if(c->cblocksize > c->cblocksizecur){
pascal@10932 148 if(c->cblocksizecur)free(c->cblock);
pascal@10933 149
pascal@10932 150 --- extract_compressed_fs.c
pascal@10932 151 +++ extract_compressed_fs.c
pascal@17885 152 @@ -1,19 +1,23 @@
pascal@10935 153 /* Extracts a filesystem back from a compressed fs file */
pascal@10937 154 +#define _LARGEFILE64_SOURCE
pascal@10935 155 #include "common_header.h"
pascal@12214 156 +#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 157
pascal@10935 158 int main(int argc, char *argv[])
pascal@10935 159 {
pascal@10935 160 int handle;
pascal@10932 161 struct cloop_head head;
pascal@10932 162 unsigned int i;
pascal@17996 163 + unsigned long num_blocks, block_size, zblock_maxsize, lastlen = 0;
pascal@10932 164 unsigned char *buffer, *clear_buffer;
pascal@10932 165 + struct block_info *offsets;
pascal@10932 166
pascal@10935 167 - if (argc != 2) {
pascal@10935 168 - fprintf(stderr, "Need filename\n");
pascal@10935 169 + if (argc < 2 || argv[1][0] == '-') {
pascal@10935 170 + fprintf(stderr, "Usage: extract_compressed_fs file [--convert-to-v2] > output\n");
pascal@10935 171 exit(1);
pascal@10935 172 }
pascal@10932 173
pascal@17885 174 - handle = open(argv[1], O_RDONLY);
pascal@17885 175 + handle = open(argv[1], O_RDONLY|O_LARGEFILE);
pascal@17885 176 if (handle < 0) {
pascal@17885 177 perror("Opening compressed file\n");
pascal@17885 178 exit(1);
pascal@18894 179 @@ -24,66 +28,100 @@
pascal@10935 180 exit(1);
pascal@10935 181 }
pascal@10935 182
pascal@10935 183 - buffer = malloc(ntohl(head.block_size) + ntohl(head.block_size)/1000
pascal@10935 184 - + 12 + 4);
pascal@10935 185 - clear_buffer = malloc(ntohl(head.block_size));
pascal@10935 186 - fprintf(stderr, "%u blocks of size %u. Preamble:\n%s\n",
pascal@10935 187 - ntohl(head.num_blocks), ntohl(head.block_size), head.preamble);
pascal@12214 188 + num_blocks = ntohl(head.num_blocks);
pascal@12214 189 + block_size = ntohl(head.block_size);
pascal@12214 190 + zblock_maxsize = block_size + block_size/1000 + 12 + 4;
pascal@12214 191 + buffer = malloc(zblock_maxsize);
pascal@12214 192 + clear_buffer = malloc(block_size);
pascal@12214 193
pascal@10935 194 - for (i = 0; i < ntohl(head.num_blocks); i++) {
pascal@10935 195 - int currpos;
pascal@10935 196 - unsigned long destlen = ntohl(head.block_size);
pascal@10935 197 - loff_t offset[2];
pascal@10935 198 - unsigned int size;
pascal@12214 199 + if (num_blocks == (unsigned long) -1) {
pascal@12214 200 + void *table;
pascal@10933 201 + struct cloop_tail tail;
pascal@12214 202 + unsigned long len, table_size;
pascal@10937 203 + loff_t end = lseek64(handle, 0, SEEK_END);
pascal@12214 204 +
pascal@10937 205 + if (lseek64(handle, end - sizeof(tail), SEEK_SET) < 0 ||
pascal@10933 206 + read(handle, &tail, sizeof(tail)) != sizeof(tail) ||
pascal@10937 207 + lseek64(handle, end - sizeof(tail) -
pascal@12214 208 + ntohl(tail.table_size), SEEK_SET) < 0) {
pascal@10933 209 + perror("Reading tail\n");
pascal@10933 210 + exit(1);
pascal@10933 211 + }
pascal@10933 212 + head.num_blocks = tail.num_blocks;
pascal@10935 213 + num_blocks = ntohl(head.num_blocks);
pascal@12214 214 + table_size = ntohl(tail.table_size);
pascal@12214 215 + table = malloc(table_size);
pascal@12214 216 + len = i = num_blocks * (ntohl(tail.index_size) & 255);
pascal@18894 217 + lastlen = ntohl(tail.index_size) / 256;
pascal@12214 218 + offsets = malloc(num_blocks * sizeof(*offsets));
pascal@12214 219 + if (!table || !offsets ||
pascal@12214 220 + read(handle, table, table_size) != table_size ||
pascal@12214 221 + uncompress((void *)offsets, &len, table, table_size) != Z_OK ||
pascal@12214 222 + len != i) {
pascal@12214 223 + perror("Reading index\n");
pascal@12214 224 + exit(1);
pascal@12214 225 + }
pascal@12214 226 + free(table);
pascal@10933 227 + }
pascal@12214 228 + else {
pascal@12214 229 + offsets = malloc(i = num_blocks * sizeof(*offsets));
pascal@12214 230 + if (!offsets || read(handle, offsets, i) != i) {
pascal@12214 231 + perror("Reading index\n");
pascal@12214 232 + exit(1);
pascal@12214 233 + }
pascal@10932 234 + }
pascal@10932 235 +
pascal@12214 236 + fprintf(stderr, "%lu blocks of size %lu. Preamble:\n%s\n",
pascal@12214 237 + num_blocks, block_size, head.preamble);
pascal@10935 238 + fprintf(stderr, "Index %s.\n", build_index(offsets, num_blocks));
pascal@10932 239 +
pascal@10935 240 + if (argc > 2) {
pascal@14712 241 + unsigned n;
pascal@10936 242 + loff_t data, offset = ((num_blocks + 1) * sizeof(offset)) + sizeof(head);
pascal@10935 243 +
pascal@10935 244 + strcpy(head.preamble, CLOOP_PREAMBLE);
pascal@14712 245 + write(STDOUT_FILENO, &head, n = sizeof(head));
pascal@10935 246 + for (i = 0; i < num_blocks; i++) {
pascal@10936 247 + data = __be64_to_cpu(offset);
pascal@10936 248 + write(STDOUT_FILENO, &data, sizeof(data));
pascal@14712 249 + n += sizeof(data);
pascal@10936 250 + offset += offsets[i].size;
pascal@10935 251 + }
pascal@10936 252 + data = __be64_to_cpu(offset);
pascal@10936 253 + write(STDOUT_FILENO, &data, sizeof(data));
pascal@10937 254 + for (i = 0; i < num_blocks && lseek64(handle, offsets[i].offset, SEEK_SET) >= 0; i++) {
pascal@10935 255 + read(handle, buffer, offsets[i].size);
pascal@10935 256 + write(STDOUT_FILENO, buffer, offsets[i].size);
pascal@14712 257 + n += offsets[i].size;
pascal@14712 258 + }
pascal@14712 259 + n &= 0x1FF;
pascal@14712 260 + if (n) {
pascal@14712 261 + memset(buffer, 0, 512);
pascal@14712 262 + write(STDOUT_FILENO, buffer, 512 - n);
pascal@10935 263 + }
pascal@10935 264 + return 0;
pascal@10935 265 + }
pascal@10935 266 +
pascal@10935 267 + for (i = 0; i < num_blocks; i++) {
pascal@10935 268 + unsigned long destlen = block_size;
pascal@10932 269 + unsigned int size = offsets[i].size;
pascal@10932 270
pascal@10932 271 - read(handle, &offset, 2*sizeof(loff_t));
pascal@10932 272 - lseek(handle, -sizeof(loff_t), SEEK_CUR);
pascal@10932 273 -
pascal@10932 274 - currpos = lseek(handle, 0, SEEK_CUR);
pascal@10932 275 - if (lseek(handle, __be64_to_cpu(offset[0]), SEEK_SET) < 0) {
pascal@10937 276 + if (lseek64(handle, offsets[i].offset, SEEK_SET) < 0) {
pascal@10932 277 fprintf(stderr, "lseek to %Lu: %s\n",
pascal@10932 278 - __be64_to_cpu(offset[0]), strerror(errno));
pascal@10932 279 + offsets[i].offset, strerror(errno));
pascal@10932 280 exit(1);
pascal@10932 281 }
pascal@10932 282
pascal@10932 283 - size=__be64_to_cpu(offset[1])-__be64_to_cpu(offset[0]);
pascal@10935 284 - if (size > ntohl(head.block_size) + ntohl(head.block_size)/1000
pascal@10935 285 - + 12 + 4) {
pascal@10935 286 + if (size > zblock_maxsize) {
pascal@10932 287 fprintf(stderr,
pascal@10932 288 "Size %u for block %u (offset %Lu) too big\n",
pascal@10932 289 - size, i, __be64_to_cpu(offset[0]));
pascal@10932 290 + size, i, offsets[i].offset);
pascal@10932 291 exit(1);
pascal@10932 292 }
pascal@10932 293 read(handle, buffer, size);
pascal@10932 294 - if (lseek(handle, currpos, SEEK_SET) < 0) {
pascal@10932 295 - perror("seeking");
pascal@10932 296 - exit(1);
pascal@10932 297 - }
pascal@10932 298
pascal@10935 299 - fprintf(stderr, "Block %u length %u => %lu\n",
pascal@10935 300 - i, size, destlen);
pascal@18894 301 - if (i == 3) {
pascal@18894 302 - fprintf(stderr,
pascal@18894 303 - "Block head:%02X%02X%02X%02X%02X%02X%02X%02X\n",
pascal@18894 304 - buffer[0],
pascal@18894 305 - buffer[1],
pascal@18894 306 - buffer[2],
pascal@18894 307 - buffer[3],
pascal@18894 308 - buffer[4],
pascal@18894 309 - buffer[5],
pascal@18894 310 - buffer[6],
pascal@18894 311 - buffer[7]);
pascal@18894 312 - fprintf(stderr,
pascal@18894 313 - "Block tail:%02X%02X%02X%02X%02X%02X%02X%02X\n",
pascal@18894 314 - buffer[3063],
pascal@18894 315 - buffer[3064],
pascal@18894 316 - buffer[3065],
pascal@18894 317 - buffer[3066],
pascal@18894 318 - buffer[3067],
pascal@18894 319 - buffer[3068],
pascal@18894 320 - buffer[3069],
pascal@18894 321 - buffer[3070]);
pascal@18894 322 - }
pascal@18894 323 + fprintf(stderr, "Block %u at %llu length %u",
pascal@18894 324 + i, offsets[i].offset, size);
pascal@18894 325 switch (uncompress(clear_buffer, &destlen,
pascal@18894 326 buffer, size)) {
pascal@18894 327 case Z_OK:
pascal@18894 328 @@ -105,12 +143,13 @@
pascal@10937 329 fprintf(stderr, "Uncomp: unknown error %u\n", i);
pascal@10937 330 exit(1);
pascal@10937 331 }
pascal@10937 332 - if (destlen != ntohl(head.block_size)) {
pascal@10937 333 - fprintf(stderr, "Uncomp: bad len %u (%lu not %u)\n", i,
pascal@10937 334 - destlen, ntohl(head.block_size));
pascal@18894 335 + fprintf(stderr, " => %lu\n", destlen);
pascal@18894 336 + if (destlen != block_size && i != num_blocks - 1) {
pascal@10937 337 + fprintf(stderr, "Uncomp: bad len %u (%lu not %lu)\n", i,
pascal@10937 338 + destlen, block_size);
pascal@10937 339 exit(1);
pascal@10937 340 }
pascal@10937 341 - write(STDOUT_FILENO, clear_buffer, ntohl(head.block_size));
pascal@17996 342 + write(STDOUT_FILENO, clear_buffer, (lastlen != 0 && (i+1) == num_blocks) ? lastlen : block_size);
pascal@10937 343 }
pascal@10937 344 return 0;
pascal@10937 345 }
pascal@10935 346 --- Makefile
pascal@10935 347 +++ Makefile
pascal@10935 348 @@ -1,16 +1,19 @@
pascal@10935 349 PROGNAME=fusecloop
pascal@10935 350 ARCFILES=*.c *.h *.pl Makefile configure README VERSION HELP INSTALL typescript *.cloop COPYING
pascal@10935 351 -PROGS=fusecloop cloopreaderdemo extract_compressed_fs
pascal@10935 352 +PROGS=fusecloop cloopreaderdemo extract_compressed_fs create_compressed_fs
pascal@10935 353 FUSECFLAGS=`pkg-config fuse --cflags`
pascal@10935 354 FUSELDFLAGS=`pkg-config fuse --libs`
pascal@10935 355
pascal@10935 356 CFLAGS= -Wall
pascal@10935 357
pascal@10935 358 -all: fusecloop extract_compressed_fs
pascal@10935 359 +all: fusecloop extract_compressed_fs create_compressed_fs
pascal@10935 360
pascal@10935 361 extract_compressed_fs: extract_compressed_fs.c
pascal@10935 362 ${CC} ${CFLAGS} ${LDFLAGS} -lz extract_compressed_fs.c -o extract_compressed_fs
pascal@10935 363
pascal@18894 364 +create_compressed_fs: create_compressed_fs.c md5sum.c
pascal@10935 365 + ${CC} ${CFLAGS} ${LDFLAGS} -lz create_compressed_fs.c -o create_compressed_fs
pascal@10935 366 +
pascal@10935 367 fusecloop: fusecloop.c cloopreader.o strver debug.o
pascal@10935 368 ${CC} ${CFLAGS} ${LDFLAGS} -lz cloopreader.o ${FUSECFLAGS} ${FUSELDFLAGS} fusecloop.c debug.o -o fusecloop
pascal@10935 369
pascal@10935 370
pascal@12214 371
pascal@18894 372 --- md5sum.c
pascal@18894 373 +++ md5sum.c
pascal@18894 374 @@ -0,0 +1,246 @@
pascal@18894 375 +/*
pascal@18894 376 + * Based on busybox code.
pascal@18894 377 + *
pascal@18894 378 + * Compute MD5 checksum of strings according to the
pascal@18894 379 + * definition of MD5 in RFC 1321 from April 1992.
pascal@18894 380 + *
pascal@18894 381 + * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
pascal@18894 382 + *
pascal@18894 383 + * Copyright (C) 1995-1999 Free Software Foundation, Inc.
pascal@18894 384 + * Copyright (C) 2001 Manuel Novoa III
pascal@18894 385 + * Copyright (C) 2003 Glenn L. McGrath
pascal@18894 386 + * Copyright (C) 2003 Erik Andersen
pascal@18894 387 + * Copyright (C) 2010 Denys Vlasenko
pascal@18894 388 + * Copyright (C) 2012 Pascal Bellard
pascal@18894 389 + *
pascal@18894 390 + * Licensed under GPLv2 or later
pascal@18894 391 + */
pascal@18894 392 +
pascal@18894 393 +#define ALIGN1
pascal@18894 394 +
pascal@18894 395 +static uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */
pascal@18894 396 +static uint64_t total64; /* must be directly before hash[] */
pascal@18894 397 +static uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */
pascal@18894 398 +
pascal@18894 399 +/* Emit a string of hex representation of bytes */
pascal@18894 400 +static char* bin2hex(char *p)
pascal@18894 401 +{
pascal@18894 402 + static const char bb_hexdigits_upcase[] ALIGN1 = "0123456789abcdef";
pascal@18894 403 + int count = 16;
pascal@18894 404 + const char *cp = (const char *) hash;
pascal@18894 405 + while (count) {
pascal@18894 406 + unsigned char c = *cp++;
pascal@18894 407 + /* put lowercase hex digits */
pascal@18894 408 + *p++ = bb_hexdigits_upcase[c >> 4];
pascal@18894 409 + *p++ = bb_hexdigits_upcase[c & 0xf];
pascal@18894 410 + count--;
pascal@18894 411 + }
pascal@18894 412 + return p;
pascal@18894 413 +}
pascal@18894 414 +
pascal@18894 415 +//#define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n))))
pascal@18894 416 +static uint32_t rotl32(uint32_t x, unsigned n)
pascal@18894 417 +{
pascal@18894 418 + return (x << n) | (x >> (32 - n));
pascal@18894 419 +}
pascal@18894 420 +
pascal@18894 421 +static void md5_process_block64(void);
pascal@18894 422 +
pascal@18894 423 +/* Feed data through a temporary buffer.
pascal@18894 424 + * The internal buffer remembers previous data until it has 64
pascal@18894 425 + * bytes worth to pass on.
pascal@18894 426 + */
pascal@18894 427 +static void common64_hash(const void *buffer, size_t len)
pascal@18894 428 +{
pascal@18894 429 + unsigned bufpos = total64 & 63;
pascal@18894 430 +
pascal@18894 431 + total64 += len;
pascal@18894 432 +
pascal@18894 433 + while (1) {
pascal@18894 434 + unsigned remaining = 64 - bufpos;
pascal@18894 435 + if (remaining > len)
pascal@18894 436 + remaining = len;
pascal@18894 437 + /* Copy data into aligned buffer */
pascal@18894 438 + memcpy(wbuffer + bufpos, buffer, remaining);
pascal@18894 439 + len -= remaining;
pascal@18894 440 + buffer = (const char *)buffer + remaining;
pascal@18894 441 + bufpos += remaining;
pascal@18894 442 + /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */
pascal@18894 443 + bufpos -= 64;
pascal@18894 444 + if (bufpos != 0)
pascal@18894 445 + break;
pascal@18894 446 + /* Buffer is filled up, process it */
pascal@18894 447 + md5_process_block64();
pascal@18894 448 + /*bufpos = 0; - already is */
pascal@18894 449 + }
pascal@18894 450 +}
pascal@18894 451 +
pascal@18894 452 +/* Process the remaining bytes in the buffer */
pascal@18894 453 +static void common64_end(void)
pascal@18894 454 +{
pascal@18894 455 + unsigned bufpos = total64 & 63;
pascal@18894 456 + /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */
pascal@18894 457 + wbuffer[bufpos++] = 0x80;
pascal@18894 458 +
pascal@18894 459 + /* This loop iterates either once or twice, no more, no less */
pascal@18894 460 + while (1) {
pascal@18894 461 + unsigned remaining = 64 - bufpos;
pascal@18894 462 + memset(wbuffer + bufpos, 0, remaining);
pascal@18894 463 + /* Do we have enough space for the length count? */
pascal@18894 464 + if (remaining >= 8) {
pascal@18894 465 + /* Store the 64-bit counter of bits in the buffer */
pascal@18894 466 + uint64_t t = total64 << 3;
pascal@18894 467 + /* wbuffer is suitably aligned for this */
pascal@18894 468 + *(uint64_t *) (&wbuffer[64 - 8]) = t;
pascal@18894 469 + }
pascal@18894 470 + md5_process_block64();
pascal@18894 471 + if (remaining >= 8)
pascal@18894 472 + break;
pascal@18894 473 + bufpos = 0;
pascal@18894 474 + }
pascal@18894 475 +}
pascal@18894 476 +
pascal@18894 477 +/* These are the four functions used in the four steps of the MD5 algorithm
pascal@18894 478 + * and defined in the RFC 1321. The first function is a little bit optimized
pascal@18894 479 + * (as found in Colin Plumbs public domain implementation).
pascal@18894 480 + * #define FF(b, c, d) ((b & c) | (~b & d))
pascal@18894 481 + */
pascal@18894 482 +#undef FF
pascal@18894 483 +#undef FG
pascal@18894 484 +#undef FH
pascal@18894 485 +#undef FI
pascal@18894 486 +#define FF(b, c, d) (d ^ (b & (c ^ d)))
pascal@18894 487 +#define FG(b, c, d) FF(d, b, c)
pascal@18894 488 +#define FH(b, c, d) (b ^ c ^ d)
pascal@18894 489 +#define FI(b, c, d) (c ^ (b | ~d))
pascal@18894 490 +
pascal@18894 491 +/* Hash a single block, 64 bytes long and 4-byte aligned */
pascal@18894 492 +static void md5_process_block64(void)
pascal@18894 493 +{
pascal@18894 494 + /* Before we start, one word to the strange constants.
pascal@18894 495 + They are defined in RFC 1321 as
pascal@18894 496 + T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
pascal@18894 497 + */
pascal@18894 498 + static const uint32_t C_array[] = {
pascal@18894 499 + /* round 1 */
pascal@18894 500 + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
pascal@18894 501 + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
pascal@18894 502 + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
pascal@18894 503 + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
pascal@18894 504 + /* round 2 */
pascal@18894 505 + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
pascal@18894 506 + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
pascal@18894 507 + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
pascal@18894 508 + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
pascal@18894 509 + /* round 3 */
pascal@18894 510 + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
pascal@18894 511 + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
pascal@18894 512 + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
pascal@18894 513 + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
pascal@18894 514 + /* round 4 */
pascal@18894 515 + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
pascal@18894 516 + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
pascal@18894 517 + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
pascal@18894 518 + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
pascal@18894 519 + };
pascal@18894 520 + static const char P_array[] ALIGN1 = {
pascal@18894 521 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
pascal@18894 522 + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
pascal@18894 523 + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
pascal@18894 524 + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 /* 4 */
pascal@18894 525 + };
pascal@18895 526 + uint32_t *words = (uint32_t *) wbuffer;
pascal@18894 527 + uint32_t A = hash[0];
pascal@18894 528 + uint32_t B = hash[1];
pascal@18894 529 + uint32_t C = hash[2];
pascal@18894 530 + uint32_t D = hash[3];
pascal@18894 531 +
pascal@18894 532 + static const char S_array[] ALIGN1 = {
pascal@18894 533 + 7, 12, 17, 22,
pascal@18894 534 + 5, 9, 14, 20,
pascal@18894 535 + 4, 11, 16, 23,
pascal@18894 536 + 6, 10, 15, 21
pascal@18894 537 + };
pascal@18894 538 + const uint32_t *pc;
pascal@18894 539 + const char *pp;
pascal@18894 540 + const char *ps;
pascal@18894 541 + int i;
pascal@18894 542 + uint32_t temp;
pascal@18894 543 +
pascal@18894 544 +
pascal@18894 545 + pc = C_array;
pascal@18894 546 + pp = P_array;
pascal@18894 547 + ps = S_array - 4;
pascal@18894 548 +
pascal@18894 549 + for (i = 0; i < 64; i++) {
pascal@18894 550 + if ((i & 0x0f) == 0)
pascal@18894 551 + ps += 4;
pascal@18894 552 + temp = A;
pascal@18894 553 + switch (i >> 4) {
pascal@18894 554 + case 0:
pascal@18894 555 + temp += FF(B, C, D);
pascal@18894 556 + break;
pascal@18894 557 + case 1:
pascal@18894 558 + temp += FG(B, C, D);
pascal@18894 559 + break;
pascal@18894 560 + case 2:
pascal@18894 561 + temp += FH(B, C, D);
pascal@18894 562 + break;
pascal@18894 563 + case 3:
pascal@18894 564 + temp += FI(B, C, D);
pascal@18894 565 + }
pascal@18894 566 + temp += words[(int) (*pp++)] + *pc++;
pascal@18894 567 + temp = rotl32(temp, ps[i & 3]);
pascal@18894 568 + temp += B;
pascal@18894 569 + A = D;
pascal@18894 570 + D = C;
pascal@18894 571 + C = B;
pascal@18894 572 + B = temp;
pascal@18894 573 + }
pascal@18894 574 + /* Add checksum to the starting values */
pascal@18894 575 + hash[0] += A;
pascal@18894 576 + hash[1] += B;
pascal@18894 577 + hash[2] += C;
pascal@18894 578 + hash[3] += D;
pascal@18894 579 +
pascal@18894 580 +}
pascal@18894 581 +#undef FF
pascal@18894 582 +#undef FG
pascal@18894 583 +#undef FH
pascal@18894 584 +#undef FI
pascal@18894 585 +
pascal@18894 586 +/* Initialize structure containing state of computation.
pascal@18894 587 + * (RFC 1321, 3.3: Step 3)
pascal@18894 588 + */
pascal@18894 589 +static void md5_begin(void)
pascal@18894 590 +{
pascal@18894 591 + hash[0] = 0x67452301;
pascal@18894 592 + hash[1] = 0xefcdab89;
pascal@18894 593 + hash[2] = 0x98badcfe;
pascal@18894 594 + hash[3] = 0x10325476;
pascal@18894 595 + total64 = 0;
pascal@18894 596 +}
pascal@18894 597 +
pascal@18894 598 +/* Used also for sha1 and sha256 */
pascal@18894 599 +#define md5_hash common64_hash
pascal@18894 600 +
pascal@18894 601 +/* Process the remaining bytes in the buffer and put result from CTX
pascal@18894 602 + * in first 16 bytes following RESBUF. The result is always in little
pascal@18894 603 + * endian byte order, so that a byte-wise output yields to the wanted
pascal@18894 604 + * ASCII representation of the message digest.
pascal@18894 605 + */
pascal@18894 606 +#define md5_end common64_end
pascal@18894 607 +
pascal@18894 608 +typedef struct { char hash[16]; } md5hash;
pascal@18894 609 +
pascal@18894 610 +static md5hash md5sum(uint8_t *buffer, int len)
pascal@18894 611 +{
pascal@18894 612 + md5hash val;
pascal@18894 613 +
pascal@18894 614 + md5_begin();
pascal@18894 615 + md5_hash(buffer, len);
pascal@18894 616 + md5_end();
pascal@18894 617 + memcpy(&val, hash, 16);
pascal@18894 618 +
pascal@18894 619 + return val;
pascal@18894 620 +}
pascal@10935 621 --- create_compressed_fs.c
pascal@10935 622 +++ create_compressed_fs.c
pascal@19561 623 @@ -0,0 +1,225 @@
pascal@12214 624 +#ifdef FIND_BEST_COMPRESSION
pascal@12214 625 +#include <compress.h>
pascal@12214 626 +extern "C" {
pascal@12214 627 +#include <stdlib.h>
pascal@12214 628 +#include <string.h>
pascal@12214 629 +
pascal@19561 630 +#define ZMAX 9
pascal@19408 631 +static shrink_t level;
pascal@19408 632 +static int pass, iter;
pascal@12214 633 +static int best_compress(unsigned char *compressed,
pascal@12214 634 + unsigned long *compressed_len,
pascal@12214 635 + unsigned char *uncompressed,
pascal@12214 636 + unsigned long uncompressed_len)
pascal@12214 637 +{
pascal@12214 638 + int i, j, err;
pascal@12214 639 + unsigned char *buf[2];
pascal@12214 640 + unsigned len;
pascal@12214 641 + unsigned long llen, best = *compressed_len * 2;
pascal@12214 642 + static unsigned char *buffer;
pascal@12214 643 + static unsigned long buffersz;
pascal@12214 644 +
pascal@12214 645 + if (buffersz < *compressed_len) {
pascal@12214 646 + if (buffer) free(buffer);
pascal@12214 647 + buffer = (unsigned char *) malloc(buffersz = *compressed_len);
pascal@12214 648 + if (!buffer) return Z_MEM_ERROR;
pascal@12214 649 + }
pascal@12214 650 + buf[0] = compressed;
pascal@12214 651 + buf[1] = buffer;
pascal@19561 652 + for (i = j = 0; i <= ZMAX+3 && (pass == 0 || i < pass); i++) {
pascal@12214 653 + llen = len = *compressed_len;
pascal@19560 654 + if (i >= ZMAX+1) {
pascal@19561 655 + level.level = (i == ZMAX+1) ? shrink_normal :
pascal@19561 656 + (i == ZMAX+2) ? shrink_extra : shrink_insane;
pascal@19408 657 + err = (compress_zlib(level, buf[j],
pascal@12214 658 + len, uncompressed,
pascal@12214 659 + uncompressed_len)) ? Z_OK : Z_DATA_ERROR;
pascal@19408 660 + } else {
pascal@12214 661 + err = compress2(buf[j], &llen, uncompressed,
pascal@12214 662 + uncompressed_len, i);
pascal@12214 663 + len = llen;
pascal@12214 664 + }
pascal@12214 665 + if (err != Z_OK) return err;
pascal@12214 666 + if (len < best) {
pascal@12214 667 + best = len;
pascal@12214 668 + j = 1 - j;
pascal@12214 669 + }
pascal@12214 670 + }
pascal@12214 671 + *compressed_len = best;
pascal@12214 672 + if (j == 0)
pascal@12214 673 + memcpy(compressed, buffer, best);
pascal@12214 674 + return err;
pascal@12214 675 +}
pascal@12214 676 +#define compress2(a,b,c,d,e) best_compress(a,b,c,d)
pascal@12214 677 +#endif
pascal@12214 678 +
pascal@18894 679 +#include <signal.h>
pascal@18894 680 +
pascal@10935 681 +/* Creates a compressed file */
pascal@10935 682 +#include "common_header.h"
pascal@10935 683 +
pascal@12214 684 +#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 685 +#define CHUNK 65536
pascal@10935 686 +#define DEFAULT_BLOCKSIZE 65536
pascal@10935 687 +
pascal@12214 688 +static void quit(const char *s)
pascal@10935 689 +{
pascal@10935 690 + fprintf(stderr, "%s\n", s);
pascal@10935 691 + exit(1);
pascal@10935 692 +}
pascal@10935 693 +
pascal@10935 694 +static int readblock(unsigned char *buffer, int n)
pascal@10935 695 +{
pascal@10935 696 + int i;
pascal@10935 697 +
pascal@10935 698 + memset(buffer, 0, n);
pascal@10935 699 + for (i = 0 ; i < n;) {
pascal@10935 700 + int j = read(STDIN_FILENO, buffer + i, n - i);
pascal@10935 701 + if (j < 0 && errno == EINTR) continue;
pascal@10935 702 + if (j <= 0) break;
pascal@10935 703 + i += j;
pascal@10935 704 + }
pascal@10935 705 + return i;
pascal@10935 706 +}
pascal@10935 707 +
pascal@18894 708 +#ifdef FIND_BEST_COMPRESSION
pascal@18894 709 +#include "md5sum.c"
pascal@18894 710 +#endif
pascal@18894 711 +
pascal@18894 712 +static unsigned n;
pascal@18894 713 +static unsigned long lastlen, pos, *block_index;
pascal@18894 714 +static unsigned char *compressed;
pascal@18894 715 +static unsigned long block_size = 0;
pascal@18894 716 +static void flush_index(int sig)
pascal@18894 717 +{
pascal@18894 718 + static char padding[512];
pascal@18894 719 + struct cloop_tail tail;
pascal@18894 720 + unsigned long len;
pascal@18894 721 +
pascal@18894 722 + fprintf(stderr, "Write index for %lu blocks\n", n);
pascal@18894 723 + if (block_size >= 0x1000000) lastlen = 0;
pascal@18894 724 + tail.index_size = ntohl(sizeof(*block_index) + 256*(lastlen % 0xFFffFF));
pascal@18894 725 + tail.num_blocks = ntohl(n);
pascal@18894 726 + n *= sizeof(*block_index);
pascal@18894 727 + len = n + n/1000 + 12;
pascal@18894 728 + compressed = (unsigned char *) realloc(compressed, len);
pascal@18894 729 + if (!compressed || compress2(compressed, &len, (unsigned char *) block_index,
pascal@18894 730 + n, Z_BEST_SPEED) != Z_OK)
pascal@18894 731 + quit("Index compression failed");
pascal@18894 732 + tail.table_size = ntohl(len);
pascal@18894 733 + pos += len + sizeof(tail);
pascal@18894 734 + n = pos & 511;
pascal@18894 735 + if (n) write(STDOUT_FILENO, padding, 512 - n);
pascal@18894 736 + write(STDOUT_FILENO, compressed, len);
pascal@18894 737 + write(STDOUT_FILENO, &tail, sizeof(tail));
pascal@18894 738 + exit(sig != 0);
pascal@18894 739 +}
pascal@18894 740 +
pascal@10935 741 +int main(int argc, char *argv[])
pascal@10935 742 +{
pascal@10935 743 + struct cloop_head head;
pascal@18894 744 + unsigned char *uncompressed;
pascal@18894 745 + unsigned long len;
pascal@18894 746 + unsigned indexmax, zlenmax;
pascal@18894 747 +#ifdef FIND_BEST_COMPRESSION
pascal@18894 748 + unsigned i, j, hashmax;
pascal@18894 749 + md5hash *hash;
pascal@18894 750 +#endif
pascal@10935 751 +
pascal@19408 752 +#ifdef FIND_BEST_COMPRESSION
pascal@19408 753 + while (argc > 1) {
pascal@19408 754 + if (argv[1][0] == '-') {
pascal@19408 755 + int *p = &pass;
pascal@19408 756 + switch (argv[1][1]) {
pascal@19408 757 + case 'i' : p = &iter;
pascal@19408 758 + case 'n' : *p = atoi(argv[2]);
pascal@19408 759 + argc -= 2;
pascal@19408 760 + argv += 2;
pascal@19408 761 + continue;
pascal@19408 762 + }
pascal@19408 763 + }
pascal@19408 764 + argc--;
pascal@19408 765 + if (argv[1][0] < '0' || argv[1][0] > '9')
pascal@19408 766 + quit("Usage : create_compressed_fs [-n <pass>][ -i <iter>] [block size] < input > output");
pascal@19408 767 +#else
pascal@10935 768 + if (argc > 1) {
pascal@10935 769 + if (argv[1][0] < '0' || argv[1][0] > '9')
pascal@10935 770 + quit("Usage : create_compressed_fs [block size] < input > output");
pascal@19408 771 +#endif
pascal@10935 772 + block_size = atoi(argv[1]);
pascal@10935 773 + }
pascal@10935 774 + if (block_size < 4096)
pascal@10935 775 + block_size = DEFAULT_BLOCKSIZE;
pascal@10935 776 + fprintf(stderr, "Block size is %lu\n", block_size);
pascal@10935 777 + zlenmax = block_size + block_size/1000 + 12;
pascal@10935 778 +
pascal@10935 779 + memset(&head, 0, sizeof(head));
pascal@10935 780 + strcpy(head.preamble, CLOOP_PREAMBLE);
pascal@10935 781 + head.num_blocks = -1;
pascal@10935 782 + head.block_size = htonl(block_size);
pascal@10935 783 + write(STDOUT_FILENO, &head, sizeof(head));
pascal@12214 784 + pos = sizeof(head);
pascal@10935 785 +
pascal@12214 786 + compressed = (unsigned char *) malloc(zlenmax);
pascal@12214 787 + uncompressed = (unsigned char *) malloc(block_size);
pascal@18894 788 + block_index = (unsigned long *) malloc(indexmax = CHUNK);
pascal@18894 789 +#ifdef FIND_BEST_COMPRESSION
pascal@18894 790 + hash = (md5hash *) malloc(hashmax = CHUNK);
pascal@18894 791 + if (!compressed || !uncompressed || !block_index || !hash)
pascal@18894 792 +#else
pascal@18894 793 + if (!compressed || !uncompressed || !block_index)
pascal@18894 794 +#endif
pascal@10935 795 + quit("Malloc failed");
pascal@10935 796 +
pascal@18894 797 + signal(SIGINT,flush_index);
pascal@18894 798 + signal(SIGQUIT,flush_index);
pascal@18894 799 + signal(SIGTERM,flush_index);
pascal@18894 800 +
pascal@17996 801 + for (n = 0; (len = readblock(uncompressed, block_size)) != 0; n++) {
pascal@17997 802 + lastlen = len;
pascal@18894 803 + if (n * sizeof(*block_index) >= indexmax) {
pascal@18894 804 + block_index = (unsigned long *) realloc(block_index,
pascal@12214 805 + indexmax += CHUNK);
pascal@18894 806 + if (!block_index)
pascal@10935 807 + quit("Realloc");
pascal@10935 808 + }
pascal@18894 809 +#ifdef FIND_BEST_COMPRESSION
pascal@18894 810 + if (n * sizeof(*hash) >= hashmax) {
pascal@18894 811 + hash = (md5hash *) realloc(hash, hashmax += CHUNK);
pascal@18895 812 + if (!hash)
pascal@18894 813 + quit("Realloc hash");
pascal@18894 814 + }
pascal@18894 815 + hash[n] = md5sum(uncompressed, len);
pascal@18894 816 + j = 0x7FFFFFFF;
pascal@18894 817 + if (n < j)
pascal@18894 818 + j = n;
pascal@18894 819 + for (i = 0; i < j; i++) {
pascal@18894 820 + if (* (uint32_t *) &hash[i] == * (uint32_t *) &hash[n]
pascal@18894 821 + && !memcmp(&hash[i],&hash[n],sizeof(*hash)))
pascal@18894 822 + break;
pascal@18894 823 + }
pascal@18894 824 + if (i != j) {
pascal@18894 825 + block_index[n] = ntohl(0x80000000 | i);
pascal@18894 826 + fprintf(stderr, "Block %u length %lu => duplicate %lu\n",
pascal@18894 827 + n, block_size, i);
pascal@18894 828 + }
pascal@18894 829 + else
pascal@18894 830 +#endif
pascal@18894 831 + {
pascal@18894 832 + len = zlenmax;
pascal@18894 833 + if (compress2(compressed, &len, uncompressed, lastlen,
pascal@18894 834 + Z_BEST_SPEED) != Z_OK)
pascal@18894 835 + quit("Compression failed");
pascal@18894 836 + fprintf(stderr, "Block %u length %lu => %lu\n",
pascal@18894 837 + n, block_size, len);
pascal@18894 838 + write(STDOUT_FILENO, compressed, len);
pascal@18894 839 + pos += len;
pascal@18894 840 + block_index[n] = ntohl(len);
pascal@18894 841 + }
pascal@10935 842 + }
pascal@18894 843 + flush_index(0);
pascal@10935 844 + return 0;
pascal@10935 845 +}
pascal@12214 846 +#ifdef FIND_BEST_COMPRESSION
pascal@12214 847 +}
pascal@12214 848 +#endif
pascal@10938 849 --- fusecloop.c
pascal@10938 850 +++ fusecloop.c
pascal@10938 851 @@ -65,7 +65,7 @@
pascal@10938 852
pascal@10938 853 memcpy(stbuf,&stb,sizeof stb);
pascal@10938 854 stbuf->st_mode&=~0222;
pascal@10938 855 - stbuf->st_size = cd.blocksize * cd.numblocks;
pascal@10938 856 + stbuf->st_size = (loff_t) cd.blocksize * cd.numblocks;
pascal@10938 857 /*
pascal@10938 858 stbuf->st_mode = S_IFREG | 0444;
pascal@10938 859 stbuf->st_nlink = 1;