xref: /netbsd-src/usr.bin/vndcompress/main.c (revision 9aa3cfafcdb01ccf97f9883d6eaba6e5d73d78de)
1*9aa3cfafSriastradh /*	$NetBSD: main.c,v 1.3 2014/01/22 06:17:25 riastradh Exp $	*/
285bbc49aSriastradh 
385bbc49aSriastradh /*-
485bbc49aSriastradh  * Copyright (c) 2013 The NetBSD Foundation, Inc.
585bbc49aSriastradh  * All rights reserved.
685bbc49aSriastradh  *
785bbc49aSriastradh  * This code is derived from software contributed to The NetBSD Foundation
885bbc49aSriastradh  * by Taylor R. Campbell.
985bbc49aSriastradh  *
1085bbc49aSriastradh  * Redistribution and use in source and binary forms, with or without
1185bbc49aSriastradh  * modification, are permitted provided that the following conditions
1285bbc49aSriastradh  * are met:
1385bbc49aSriastradh  * 1. Redistributions of source code must retain the above copyright
1485bbc49aSriastradh  *    notice, this list of conditions and the following disclaimer.
1585bbc49aSriastradh  * 2. Redistributions in binary form must reproduce the above copyright
1685bbc49aSriastradh  *    notice, this list of conditions and the following disclaimer in the
1785bbc49aSriastradh  *    documentation and/or other materials provided with the distribution.
1885bbc49aSriastradh  *
1985bbc49aSriastradh  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2085bbc49aSriastradh  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2185bbc49aSriastradh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2285bbc49aSriastradh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2385bbc49aSriastradh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2485bbc49aSriastradh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2585bbc49aSriastradh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2685bbc49aSriastradh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2785bbc49aSriastradh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2885bbc49aSriastradh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2985bbc49aSriastradh  * POSSIBILITY OF SUCH DAMAGE.
3085bbc49aSriastradh  */
3185bbc49aSriastradh 
3285bbc49aSriastradh #include <sys/cdefs.h>
33*9aa3cfafSriastradh __RCSID("$NetBSD: main.c,v 1.3 2014/01/22 06:17:25 riastradh Exp $");
3485bbc49aSriastradh 
3585bbc49aSriastradh #include <assert.h>
3685bbc49aSriastradh #include <err.h>
3785bbc49aSriastradh #include <getopt.h>
3885bbc49aSriastradh #include <stdio.h>
3985bbc49aSriastradh #include <stdlib.h>
4085bbc49aSriastradh #include <string.h>
4185bbc49aSriastradh 
4285bbc49aSriastradh #include "common.h"
4385bbc49aSriastradh 
4485bbc49aSriastradh static int (*operation)(int, char **, const struct options *) = &vndcompress;
4585bbc49aSriastradh 
4685bbc49aSriastradh int
main(int argc,char ** argv)4785bbc49aSriastradh main(int argc, char **argv)
4885bbc49aSriastradh {
4985bbc49aSriastradh 	static const struct options zero_options;
5085bbc49aSriastradh 	struct options options = zero_options, *O = &options;
5185bbc49aSriastradh 	int ch;
5285bbc49aSriastradh 
5385bbc49aSriastradh 	setprogname(argv[0]);
5485bbc49aSriastradh 
5585bbc49aSriastradh 	if (strcmp(getprogname(), "vndcompress") == 0)
5685bbc49aSriastradh 		operation = &vndcompress;
5785bbc49aSriastradh 	else if (strcmp(getprogname(), "vnduncompress") == 0)
5885bbc49aSriastradh 		operation = &vnduncompress;
5985bbc49aSriastradh 	else
6085bbc49aSriastradh 		warnx("unknown program name, defaulting to vndcompress: %s",
6185bbc49aSriastradh 		    getprogname());
6285bbc49aSriastradh 
63*9aa3cfafSriastradh 	while ((ch = getopt(argc, argv, "b:cdk:l:p:rRw:")) != -1) {
6485bbc49aSriastradh 		switch (ch) {
65*9aa3cfafSriastradh 		case 'b':
66*9aa3cfafSriastradh 			if (ISSET(O->flags, FLAG_b)) {
67*9aa3cfafSriastradh 				warnx("-b may be supplied only once");
68*9aa3cfafSriastradh 				usage();
69*9aa3cfafSriastradh 			}
70*9aa3cfafSriastradh 			O->flags |= FLAG_b;
71*9aa3cfafSriastradh 			__CTASSERT(MIN_BLOCKSIZE <= MAX_BLOCKSIZE);
72*9aa3cfafSriastradh 			__CTASSERT(MAX_BLOCKSIZE <= LLONG_MAX);
73*9aa3cfafSriastradh 			O->blocksize = strsuftoll("block size", optarg,
74*9aa3cfafSriastradh 			    MIN_BLOCKSIZE, MAX_BLOCKSIZE);
75*9aa3cfafSriastradh 			break;
76*9aa3cfafSriastradh 
7785bbc49aSriastradh 		case 'c':
7885bbc49aSriastradh 			if (ISSET(O->flags, FLAG_d)) {
7985bbc49aSriastradh 				warnx("-c and -d are mutually exclusive");
8085bbc49aSriastradh 				usage();
8185bbc49aSriastradh 			}
8285bbc49aSriastradh 			O->flags |= FLAG_c;
8385bbc49aSriastradh 			operation = &vndcompress;
8485bbc49aSriastradh 			break;
8585bbc49aSriastradh 
8685bbc49aSriastradh 		case 'd':
8785bbc49aSriastradh 			if (ISSET(O->flags, FLAG_c)) {
8885bbc49aSriastradh 				warnx("-c and -d are mutually exclusive");
8985bbc49aSriastradh 				usage();
9085bbc49aSriastradh 			}
9185bbc49aSriastradh 			O->flags |= FLAG_d;
9285bbc49aSriastradh 			operation = &vnduncompress;
9385bbc49aSriastradh 			break;
9485bbc49aSriastradh 
9585bbc49aSriastradh 		case 'k':
9685bbc49aSriastradh 			if (ISSET(O->flags, FLAG_k)) {
9785bbc49aSriastradh 				warnx("-k may be supplied only once");
9885bbc49aSriastradh 				usage();
9985bbc49aSriastradh 			}
10085bbc49aSriastradh 			O->flags |= FLAG_k;
10185bbc49aSriastradh 			O->checkpoint_blocks = strsuftoll("checkpoint blocks",
10285bbc49aSriastradh 			    optarg,
10385bbc49aSriastradh 			    0, MIN(UINT32_MAX, (OFF_MAX / MIN_BLOCKSIZE)));
10485bbc49aSriastradh 			break;
10585bbc49aSriastradh 
10685bbc49aSriastradh 		case 'l':
10785bbc49aSriastradh 			if (ISSET(O->flags, FLAG_l)) {
10885bbc49aSriastradh 				warnx("-l may be supplied only once");
10985bbc49aSriastradh 				usage();
11085bbc49aSriastradh 			}
11185bbc49aSriastradh 			O->flags |= FLAG_l;
11285bbc49aSriastradh 			O->length = strsuftoll("length", optarg,
11385bbc49aSriastradh 			    0, MIN(OFF_MAX, UINT64_MAX));
11485bbc49aSriastradh 			break;
11585bbc49aSriastradh 
11685bbc49aSriastradh 		case 'p':
11785bbc49aSriastradh 			O->flags |= FLAG_p;
11885bbc49aSriastradh 			__CTASSERT(OFF_MAX <= LLONG_MAX);
11985bbc49aSriastradh 			O->end_block = strsuftoll("end block", optarg,
12085bbc49aSriastradh 			    0, MIN(UINT32_MAX, (OFF_MAX / MIN_BLOCKSIZE)));
12185bbc49aSriastradh 			break;
12285bbc49aSriastradh 
12385bbc49aSriastradh 		case 'r':
12485bbc49aSriastradh 			O->flags |= FLAG_r;
12585bbc49aSriastradh 			break;
12685bbc49aSriastradh 
12785bbc49aSriastradh 		case 'R':
12885bbc49aSriastradh 			O->flags |= FLAG_R;
12985bbc49aSriastradh 			break;
13085bbc49aSriastradh 
1317c5bfcbeSriastradh 		case 'w':
1327c5bfcbeSriastradh 			if (ISSET(O->flags, FLAG_w)) {
1337c5bfcbeSriastradh 				warnx("-w may be supplied only once");
1347c5bfcbeSriastradh 				usage();
1357c5bfcbeSriastradh 			}
1367c5bfcbeSriastradh 			O->flags |= FLAG_w;
1377c5bfcbeSriastradh 			O->window_size = strsuftoll("window size", optarg,
1387c5bfcbeSriastradh 			    0, MAX_WINDOW_SIZE);
1397c5bfcbeSriastradh 			break;
1407c5bfcbeSriastradh 
14185bbc49aSriastradh 		case '?':
14285bbc49aSriastradh 		default:
14385bbc49aSriastradh 			usage();
14485bbc49aSriastradh 		}
14585bbc49aSriastradh 	}
14685bbc49aSriastradh 
14785bbc49aSriastradh 	argc -= optind;
14885bbc49aSriastradh 	argv += optind;
14985bbc49aSriastradh 
15085bbc49aSriastradh 	if (operation == &vnduncompress) {
1517c5bfcbeSriastradh 		if (ISSET(O->flags, ~(FLAG_d | FLAG_w)))
15285bbc49aSriastradh 			usage();
15385bbc49aSriastradh 	} else {
15485bbc49aSriastradh 		assert(operation == &vndcompress);
155*9aa3cfafSriastradh 		if (ISSET(O->flags, ~(FLAG_b | FLAG_c | FLAG_k | FLAG_l |
156*9aa3cfafSriastradh 			    FLAG_p | FLAG_r | FLAG_R | FLAG_w)))
15785bbc49aSriastradh 			usage();
15885bbc49aSriastradh 		if (ISSET(O->flags, FLAG_R) && !ISSET(O->flags, FLAG_r)) {
15985bbc49aSriastradh 			warnx("-R makes no sense without -r");
16085bbc49aSriastradh 			usage();
16185bbc49aSriastradh 		}
16285bbc49aSriastradh 	}
16385bbc49aSriastradh 
16485bbc49aSriastradh 	return (*operation)(argc, argv, O);
16585bbc49aSriastradh }
16685bbc49aSriastradh 
16785bbc49aSriastradh void __dead
usage(void)16885bbc49aSriastradh usage(void)
16985bbc49aSriastradh {
17085bbc49aSriastradh 
17185bbc49aSriastradh 	(void)fprintf(stderr,
172*9aa3cfafSriastradh 	    "Usage: %s -c [-rR] [-b <blocksize>] [-k <checkpoint-blocks>]\n"
173*9aa3cfafSriastradh 	    "          [-l <length>] [-p <partial-offset>] [-w <winsize>]\n"
17485bbc49aSriastradh 	    "          <image> <compressed-image> [<blocksize>]\n"
17585bbc49aSriastradh 	    "       %s -d <compressed-image> <image>\n",
17685bbc49aSriastradh 	    getprogname(), getprogname());
17785bbc49aSriastradh 	exit(1);
17885bbc49aSriastradh }
179