Home | History | Annotate | Line # | Download | only in vndcompress
vndcompress.c revision 1.1
      1  1.1  hubertf /* $Id: vndcompress.c,v 1.1 2005/07/25 12:17:59 hubertf Exp $ */
      2  1.1  hubertf 
      3  1.1  hubertf /*
      4  1.1  hubertf  * Copyright (c) 2005 by Florian Stoehr <netbsd (at) wolfnode.de>
      5  1.1  hubertf  * All rights reserved.
      6  1.1  hubertf  *
      7  1.1  hubertf  * Redistribution and use in source and binary forms, with or without
      8  1.1  hubertf  * modification, are permitted provided that the following conditions
      9  1.1  hubertf  * are met:
     10  1.1  hubertf  * 1. Redistributions of source code must retain the above copyright
     11  1.1  hubertf  *    notice, this list of conditions and the following disclaimer.
     12  1.1  hubertf  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  hubertf  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  hubertf  *    documentation and/or other materials provided with the distribution.
     15  1.1  hubertf  * 3. All advertising materials mentioning features or use of this software
     16  1.1  hubertf  *    must display the following acknowledgement:
     17  1.1  hubertf  *        This product includes software developed by Florian Stoehr
     18  1.1  hubertf  * 4. The name of Florian Stoehr may not be used to endorse or promote
     19  1.1  hubertf  *    products derived from this software without specific prior written
     20  1.1  hubertf  *    permission.
     21  1.1  hubertf  *
     22  1.1  hubertf  * THIS SOFTWARE IS PROVIDED BY FLORIAN STOEHR ``AS IS'' AND
     23  1.1  hubertf  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     24  1.1  hubertf  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     25  1.1  hubertf  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     26  1.1  hubertf  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     27  1.1  hubertf  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     28  1.1  hubertf  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     29  1.1  hubertf  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     30  1.1  hubertf  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     31  1.1  hubertf  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     32  1.1  hubertf  * POSSIBILITY OF SUCH DAMAGE.
     33  1.1  hubertf  */
     34  1.1  hubertf 
     35  1.1  hubertf /*
     36  1.1  hubertf  * cloop2 - Compressed filesystem images
     37  1.1  hubertf  * vndcompress program - Compress/decompress filesystem images to
     38  1.1  hubertf  * the cloop2 format
     39  1.1  hubertf  */
     40  1.1  hubertf #include <arpa/inet.h>
     41  1.1  hubertf 
     42  1.1  hubertf #include <err.h>
     43  1.1  hubertf #include <fcntl.h>
     44  1.1  hubertf #include <stdarg.h>
     45  1.1  hubertf #include <stdio.h>
     46  1.1  hubertf #include <stdlib.h>
     47  1.1  hubertf #include <string.h>
     48  1.1  hubertf #include <unistd.h>
     49  1.1  hubertf #include <zlib.h>
     50  1.1  hubertf 
     51  1.1  hubertf #include "vndcompress.h"
     52  1.1  hubertf 
     53  1.1  hubertf enum opermodes {
     54  1.1  hubertf 	OM_COMPRESS,	/* Compress a fs       */
     55  1.1  hubertf 	OM_UNCOMPRESS,  /* Uncompress an image */
     56  1.1  hubertf };
     57  1.1  hubertf 
     58  1.1  hubertf /*
     59  1.1  hubertf  * This is the original header of the Linux files. It is useless
     60  1.1  hubertf  * on NetBSD and integrated for compatibility issues only.
     61  1.1  hubertf  */
     62  1.1  hubertf static const char *cloop_sh = "#!/bin/sh\n" "#V2.0 Format\n" "insmod cloop.o file=$0 && mount -r -t iso9660 /dev/cloop $1\n" "exit $?\n";
     63  1.1  hubertf 
     64  1.1  hubertf int opmode;
     65  1.1  hubertf 
     66  1.1  hubertf /*
     67  1.1  hubertf  * Print usage information, then exit program
     68  1.1  hubertf  */
     69  1.1  hubertf void
     70  1.1  hubertf usage(void)
     71  1.1  hubertf {
     72  1.1  hubertf 	if (opmode == OM_COMPRESS) {
     73  1.1  hubertf 		printf("usage: vndcompress disk/fs-image compressed-image [blocksize]\n");
     74  1.1  hubertf 	} else {
     75  1.1  hubertf 		printf("usage: vnduncompress compressed-image disk/fs-image\n");
     76  1.1  hubertf 	}
     77  1.1  hubertf 
     78  1.1  hubertf 	exit(EXIT_FAILURE);
     79  1.1  hubertf }
     80  1.1  hubertf 
     81  1.1  hubertf /*
     82  1.1  hubertf  * Compress a given file system
     83  1.1  hubertf  */
     84  1.1  hubertf void
     85  1.1  hubertf vndcompress(const char *fs, const char *comp, uint32_t blocksize)
     86  1.1  hubertf {
     87  1.1  hubertf 	int fd_in, fd_out;
     88  1.1  hubertf 	int total_blocks, offtable_size;
     89  1.1  hubertf 	int i;
     90  1.1  hubertf 	int read_blocksize;
     91  1.1  hubertf 	off_t fsize, diffatom, cursize;
     92  1.1  hubertf 	struct cloop_header clh;
     93  1.1  hubertf 	uint64_t *offtable;
     94  1.1  hubertf 	uint64_t curoff;
     95  1.1  hubertf 	unsigned long complen;
     96  1.1  hubertf 	unsigned char *cb, *ucb;
     97  1.1  hubertf 
     98  1.1  hubertf 	fd_in = open(fs, O_RDONLY);
     99  1.1  hubertf 
    100  1.1  hubertf 	if (fd_in < 0)
    101  1.1  hubertf 		err(EXIT_FAILURE, "Cannot open input file \"%s\"", fs);
    102  1.1  hubertf 		/* NOTREACHED */
    103  1.1  hubertf 
    104  1.1  hubertf 	fd_out = open(comp, O_CREAT | O_TRUNC | O_WRONLY,
    105  1.1  hubertf 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    106  1.1  hubertf 
    107  1.1  hubertf 	if (fd_out < 0)
    108  1.1  hubertf 		err(EXIT_FAILURE, "Cannot create output file \"%s\"", comp);
    109  1.1  hubertf 		/* NOTREACHED */
    110  1.1  hubertf 
    111  1.1  hubertf 	if ((blocksize % ATOMBLOCK) || (blocksize < ATOMBLOCK))
    112  1.1  hubertf 		errx(EXIT_FAILURE, "Invalid block size: %d (Block size must be "\
    113  1.1  hubertf 			"a multiple of %d Bytes)", blocksize, ATOMBLOCK);
    114  1.1  hubertf 		/* NOTREACHED */
    115  1.1  hubertf 
    116  1.1  hubertf 	/*
    117  1.1  hubertf 	 * Init the compression
    118  1.1  hubertf 	 */
    119  1.1  hubertf 
    120  1.1  hubertf 	/* Determine number of total input blocks, round up to complete blocks */
    121  1.1  hubertf 	fsize = lseek(fd_in, 0, SEEK_END);
    122  1.1  hubertf 	lseek(fd_in, 0, SEEK_SET);
    123  1.1  hubertf 	total_blocks = fsize / blocksize;
    124  1.1  hubertf 
    125  1.1  hubertf 	printf("Using blocksize: %d ", blocksize);
    126  1.1  hubertf 
    127  1.1  hubertf 	if (fsize % blocksize) {
    128  1.1  hubertf 		printf("(%d complete and 1 zero-padded blocks)\n", total_blocks);
    129  1.1  hubertf 		total_blocks++;
    130  1.1  hubertf 	} else {
    131  1.1  hubertf 		printf("(%d complete blocks)\n", total_blocks);
    132  1.1  hubertf 	}
    133  1.1  hubertf 
    134  1.1  hubertf 	/* Struct fillup */
    135  1.1  hubertf 	memset(&clh, 0, sizeof(struct cloop_header));
    136  1.1  hubertf 	memcpy(clh.sh, cloop_sh, strlen(cloop_sh));
    137  1.1  hubertf 
    138  1.1  hubertf 	/* Remember the header is also in network format! */
    139  1.1  hubertf 	clh.block_size = htonl(blocksize);
    140  1.1  hubertf 	clh.num_blocks = htonl(total_blocks);
    141  1.1  hubertf 
    142  1.1  hubertf 	/* Prepare the offset table (unsigned 64-bit big endian offsets) */
    143  1.1  hubertf 	offtable_size = (total_blocks + 1) * sizeof(uint64_t);
    144  1.1  hubertf 	offtable = (uint64_t *)malloc(offtable_size);
    145  1.1  hubertf 
    146  1.1  hubertf 	/*
    147  1.1  hubertf 	 * Setup block buffers.
    148  1.1  hubertf 	 * Since compression may actually stretch a block in bad cases,
    149  1.1  hubertf 	 * make the "compressed" space large enough here.
    150  1.1  hubertf 	 */
    151  1.1  hubertf 	ucb = (unsigned char *)malloc(blocksize);
    152  1.1  hubertf 	cb = (unsigned char *)malloc(blocksize * 2);
    153  1.1  hubertf 
    154  1.1  hubertf 	/*
    155  1.1  hubertf 	 * Compression
    156  1.1  hubertf 	 *
    157  1.1  hubertf 	 * We'll leave file caching to the operating system and write
    158  1.1  hubertf 	 * first the (fixed-size) header with dummy-data, then the compressed
    159  1.1  hubertf 	 * blocks block-by-block to disk. After that, we overwrite the offset
    160  1.1  hubertf 	 * table in the image file with the real offset table.
    161  1.1  hubertf 	 */
    162  1.1  hubertf 	if (write(fd_out, &clh, sizeof(struct cloop_header))
    163  1.1  hubertf 		< sizeof(struct cloop_header))
    164  1.1  hubertf 		err(EXIT_FAILURE, "Cannot write to output file \"%s\"", comp);
    165  1.1  hubertf 		/* NOTREACHED */
    166  1.1  hubertf 
    167  1.1  hubertf 	if (write(fd_out, offtable, offtable_size) < offtable_size)
    168  1.1  hubertf 		err(EXIT_FAILURE, "Cannot write to output file \"%s\"", comp);
    169  1.1  hubertf 		/* NOTREACHED */
    170  1.1  hubertf 
    171  1.1  hubertf 	/*
    172  1.1  hubertf 	 * Offsets are relative to the beginning of the file, not
    173  1.1  hubertf 	 * relative to offset table start
    174  1.1  hubertf 	 */
    175  1.1  hubertf 	curoff = sizeof(struct cloop_header) + offtable_size;
    176  1.1  hubertf 
    177  1.1  hubertf 	/* Compression loop */
    178  1.1  hubertf 	for (i = 0; i < total_blocks; i++) {
    179  1.1  hubertf 
    180  1.1  hubertf 		/* By default, assume to read blocksize bytes */
    181  1.1  hubertf 		read_blocksize = blocksize;
    182  1.1  hubertf 
    183  1.1  hubertf 		/*
    184  1.1  hubertf 		 * However, the last block may be smaller than block size.
    185  1.1  hubertf 		 * If this is the case, pad uncompressed buffer with zeros
    186  1.1  hubertf 		 * (by zero-filling before the read() call)
    187  1.1  hubertf 		 */
    188  1.1  hubertf 		if (i == total_blocks - 1) {
    189  1.1  hubertf 			if (fsize % blocksize) {
    190  1.1  hubertf 				read_blocksize = fsize % blocksize;
    191  1.1  hubertf 				memset(ucb, 0x00, blocksize);
    192  1.1  hubertf 			}
    193  1.1  hubertf 		}
    194  1.1  hubertf 
    195  1.1  hubertf 		if (read(fd_in, ucb, read_blocksize) < read_blocksize)
    196  1.1  hubertf 			err(EXIT_FAILURE, "Cannot read input file \"%s\"", fs);
    197  1.1  hubertf 			/* NOTREACHED */
    198  1.1  hubertf 
    199  1.1  hubertf 		complen = blocksize * 2;
    200  1.1  hubertf 
    201  1.1  hubertf 		if (compress2(cb, &complen, ucb, blocksize, Z_BEST_COMPRESSION) != Z_OK)
    202  1.1  hubertf 			errx(EXIT_FAILURE, "Compression failed in block %d", i);
    203  1.1  hubertf 			/* NOTREACHED */
    204  1.1  hubertf 
    205  1.1  hubertf 		if (write(fd_out, cb, complen) < complen)
    206  1.1  hubertf 			err(EXIT_FAILURE, "Cannot write to output file \"%s\"", comp);
    207  1.1  hubertf 			/* NOTREACHED */
    208  1.1  hubertf 
    209  1.1  hubertf 		*(offtable + i) = SWAPPER(curoff);
    210  1.1  hubertf 		curoff += complen;
    211  1.1  hubertf 	}
    212  1.1  hubertf 
    213  1.1  hubertf 	/* Always write +1 block to determine (compressed) block size */
    214  1.1  hubertf 	*(offtable + total_blocks) = SWAPPER(curoff);
    215  1.1  hubertf 
    216  1.1  hubertf 	/* Fixup compression table */
    217  1.1  hubertf 	lseek(fd_out, sizeof(struct cloop_header), SEEK_SET);
    218  1.1  hubertf 
    219  1.1  hubertf 	if (write(fd_out, offtable, offtable_size) < offtable_size)
    220  1.1  hubertf 		err(EXIT_FAILURE, "Cannot write to output file \"%s\"", comp);
    221  1.1  hubertf 		/* NOTREACHED */
    222  1.1  hubertf 
    223  1.1  hubertf 	/* Finally, align the image size to be a multiple of ATOMBLOCK bytes */
    224  1.1  hubertf 	cursize = lseek(fd_out, 0, SEEK_END);
    225  1.1  hubertf 
    226  1.1  hubertf 	if (cursize % ATOMBLOCK) {
    227  1.1  hubertf 		/*
    228  1.1  hubertf 		 * Reusing the cb buffer here. It *IS* large enough since
    229  1.1  hubertf 		 * blocksize may not be smaller than ATOMBLOCK
    230  1.1  hubertf 		 */
    231  1.1  hubertf 		diffatom = (((cursize / ATOMBLOCK) + 1) * ATOMBLOCK) - cursize;
    232  1.1  hubertf 		memset(cb, 0, blocksize * 2);
    233  1.1  hubertf 		write(fd_out, cb, diffatom);
    234  1.1  hubertf 	}
    235  1.1  hubertf 
    236  1.1  hubertf 	free(cb);
    237  1.1  hubertf 	free(ucb);
    238  1.1  hubertf 	free(offtable);
    239  1.1  hubertf 
    240  1.1  hubertf 	close(fd_in);
    241  1.1  hubertf 	close(fd_out);
    242  1.1  hubertf }
    243  1.1  hubertf 
    244  1.1  hubertf /*
    245  1.1  hubertf  * Read in header and offset table from compressed image
    246  1.1  hubertf  */
    247  1.1  hubertf uint64_t *
    248  1.1  hubertf readheader(int fd, struct cloop_header *clh, off_t *dstart)
    249  1.1  hubertf {
    250  1.1  hubertf 	uint32_t offtable_size;
    251  1.1  hubertf 	uint64_t *offt;
    252  1.1  hubertf 
    253  1.1  hubertf 	if (read(fd, clh, sizeof(struct cloop_header))
    254  1.1  hubertf 		< sizeof(struct cloop_header))
    255  1.1  hubertf 		return NULL;
    256  1.1  hubertf 
    257  1.1  hubertf 	/* Convert endianness */
    258  1.1  hubertf 	clh->block_size = ntohl(clh->block_size);
    259  1.1  hubertf 	clh->num_blocks = ntohl(clh->num_blocks);
    260  1.1  hubertf 
    261  1.1  hubertf 	offtable_size = (clh->num_blocks + 1) * sizeof(uint64_t);
    262  1.1  hubertf 	offt = (uint64_t *)malloc(offtable_size);
    263  1.1  hubertf 
    264  1.1  hubertf 	if (read(fd, offt, offtable_size) < offtable_size) {
    265  1.1  hubertf 		free(offt);
    266  1.1  hubertf 		return NULL;
    267  1.1  hubertf 	}
    268  1.1  hubertf 
    269  1.1  hubertf 	*dstart = offtable_size + sizeof(struct cloop_header);
    270  1.1  hubertf 
    271  1.1  hubertf 	return offt;
    272  1.1  hubertf }
    273  1.1  hubertf 
    274  1.1  hubertf /*
    275  1.1  hubertf  * Decompress a given file system image
    276  1.1  hubertf  */
    277  1.1  hubertf void
    278  1.1  hubertf vnduncompress(const char *comp, const char *fs)
    279  1.1  hubertf {
    280  1.1  hubertf 	int fd_in, fd_out;
    281  1.1  hubertf 	int i;
    282  1.1  hubertf 	struct cloop_header clh;
    283  1.1  hubertf 	uint64_t *offtable;
    284  1.1  hubertf 	off_t imgofs, datastart;
    285  1.1  hubertf 	unsigned long complen, uncomplen;
    286  1.1  hubertf 	unsigned char *cb, *ucb;
    287  1.1  hubertf 
    288  1.1  hubertf 	/*
    289  1.1  hubertf 	 * Setup decompression, read in header tables
    290  1.1  hubertf 	 */
    291  1.1  hubertf 	fd_in = open(comp, O_RDONLY);
    292  1.1  hubertf 
    293  1.1  hubertf 	if (fd_in < 0)
    294  1.1  hubertf 		err(EXIT_FAILURE, "Cannot open input file \"%s\"", comp);
    295  1.1  hubertf 		/* NOTREACHED */
    296  1.1  hubertf 
    297  1.1  hubertf 	fd_out = open(fs, O_CREAT | O_TRUNC | O_WRONLY,
    298  1.1  hubertf 		S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
    299  1.1  hubertf 
    300  1.1  hubertf 	if (fd_out < 0)
    301  1.1  hubertf 		err(EXIT_FAILURE, "Cannot create output file \"%s\"", fs);
    302  1.1  hubertf 		/* NOTREACHED */
    303  1.1  hubertf 
    304  1.1  hubertf 	offtable = readheader(fd_in, &clh, &datastart);
    305  1.1  hubertf 
    306  1.1  hubertf 	if (offtable == NULL)
    307  1.1  hubertf 		errx(EXIT_FAILURE, "Input file \"%s\": Size mismatch, too small to be a valid image", comp);
    308  1.1  hubertf 		/* NOTREACHED */
    309  1.1  hubertf 
    310  1.1  hubertf 	/* As for the compression, alloc the compressed block bigger */
    311  1.1  hubertf 	ucb = (unsigned char *)malloc(clh.block_size);
    312  1.1  hubertf 	cb = (unsigned char *)malloc(clh.block_size * 2);
    313  1.1  hubertf 
    314  1.1  hubertf 	/*
    315  1.1  hubertf 	 * Perform the actual decompression
    316  1.1  hubertf 	 */
    317  1.1  hubertf 	for (i = 0; i < clh.num_blocks; i++) {
    318  1.1  hubertf 		int rc;
    319  1.1  hubertf 
    320  1.1  hubertf 		imgofs = SWAPPER(*(offtable + i));
    321  1.1  hubertf 		lseek(fd_in, imgofs, SEEK_SET);
    322  1.1  hubertf 
    323  1.1  hubertf 		complen = SWAPPER(*(offtable + i + 1))
    324  1.1  hubertf 		           - SWAPPER(*(offtable + i));
    325  1.1  hubertf 
    326  1.1  hubertf 		if (read(fd_in, cb, complen) < complen)
    327  1.1  hubertf 			err(EXIT_FAILURE, "Cannot read compressed block %d from \"%s\"", i, comp);
    328  1.1  hubertf 			/* NOTREACHED */
    329  1.1  hubertf 
    330  1.1  hubertf 		uncomplen = clh.block_size;
    331  1.1  hubertf 		rc = uncompress(ucb, &uncomplen, cb, complen);
    332  1.1  hubertf 		if (rc != Z_OK)
    333  1.1  hubertf 			errx(EXIT_FAILURE, "Cannot decompress block %d from \"%s\" (rc=%d)",
    334  1.1  hubertf 			    i, comp, rc);
    335  1.1  hubertf 			/* NOTREACHED */
    336  1.1  hubertf 
    337  1.1  hubertf 		write(fd_out, ucb, clh.block_size);
    338  1.1  hubertf 	}
    339  1.1  hubertf 
    340  1.1  hubertf 	free(cb);
    341  1.1  hubertf 	free(ucb);
    342  1.1  hubertf 	free(offtable);
    343  1.1  hubertf 
    344  1.1  hubertf 	close(fd_in);
    345  1.1  hubertf 	close(fd_out);
    346  1.1  hubertf }
    347  1.1  hubertf 
    348  1.1  hubertf /*
    349  1.1  hubertf  * vndcompress: Handle cloop2-compatible compressed file systems; This is the
    350  1.1  hubertf  *              user-level configuration program, to be used in conjunction
    351  1.1  hubertf  *              with the vnd(4) driver.
    352  1.1  hubertf  */
    353  1.1  hubertf int
    354  1.1  hubertf main(int argc, char **argv)
    355  1.1  hubertf {
    356  1.1  hubertf 	char *ep, *p;
    357  1.1  hubertf 	char ch;
    358  1.1  hubertf 
    359  1.1  hubertf 	setprogname(argv[0]);
    360  1.1  hubertf 
    361  1.1  hubertf 	if ((p = strrchr(argv[0], '/')) == NULL)
    362  1.1  hubertf 		p = argv[0];
    363  1.1  hubertf 	else
    364  1.1  hubertf 		++p;
    365  1.1  hubertf 	if (strcmp(p, "vnduncompress") == 0)
    366  1.1  hubertf 		opmode = OM_UNCOMPRESS;
    367  1.1  hubertf         else if (strcmp(p, "vndcompress") == 0)
    368  1.1  hubertf                 opmode = OM_COMPRESS;
    369  1.1  hubertf         else
    370  1.1  hubertf 		warnx("unknown program name '%s'", p);
    371  1.1  hubertf 
    372  1.1  hubertf 	/* Process command-line options */
    373  1.1  hubertf 	while ((ch = getopt(argc, argv, "cd")) != -1) {
    374  1.1  hubertf 		switch (ch) {
    375  1.1  hubertf 		case 'c':
    376  1.1  hubertf 			opmode = OM_COMPRESS;
    377  1.1  hubertf 			break;
    378  1.1  hubertf 
    379  1.1  hubertf 		case 'd':
    380  1.1  hubertf 			opmode = OM_UNCOMPRESS;
    381  1.1  hubertf 			break;
    382  1.1  hubertf 
    383  1.1  hubertf 		default:
    384  1.1  hubertf 			usage();
    385  1.1  hubertf 			/* NOTREACHED */
    386  1.1  hubertf 		}
    387  1.1  hubertf 	}
    388  1.1  hubertf 
    389  1.1  hubertf 	argc -= optind;
    390  1.1  hubertf 	argv += optind;
    391  1.1  hubertf 
    392  1.1  hubertf 	if (argc < 2) {
    393  1.1  hubertf 		usage();
    394  1.1  hubertf 		/* NOTREACHED */
    395  1.1  hubertf 	}
    396  1.1  hubertf 
    397  1.1  hubertf 	switch (opmode) {
    398  1.1  hubertf 	case OM_COMPRESS:
    399  1.1  hubertf 		if (argc > 2) {
    400  1.1  hubertf 			vndcompress(argv[0], argv[1], strtoul(argv[2], &ep, 10));
    401  1.1  hubertf 		} else {
    402  1.1  hubertf 			vndcompress(argv[0], argv[1], DEF_BLOCKSIZE);
    403  1.1  hubertf 		}
    404  1.1  hubertf 		break;
    405  1.1  hubertf 
    406  1.1  hubertf 	case OM_UNCOMPRESS:
    407  1.1  hubertf 		vnduncompress(argv[0], argv[1]);
    408  1.1  hubertf 		break;
    409  1.1  hubertf 	}
    410  1.1  hubertf 
    411  1.1  hubertf 	exit(EXIT_SUCCESS);
    412  1.1  hubertf }
    413