1 /* Copyright (c) 2008, XenSource Inc.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above copyright
9  *       notice, this list of conditions and the following disclaimer in the
10  *       documentation and/or other materials provided with the distribution.
11  *     * Neither the name of XenSource Inc. nor the names of its contributors
12  *       may be used to endorse or promote products derived from this software
13  *       without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <langinfo.h>
32 #include <locale.h>
33 
34 #include "libvhd.h"
35 #include "vhd-util.h"
36 
37 #if 1
38 #define DFPRINTF(_f, _a...) fprintf(stdout, _f , ##_a)
39 #else
40 #define DFPRINTF(_f, _a...) ((void)0)
41 #endif
42 
43 typedef int (*vhd_util_func_t) (int, char **);
44 
45 struct command {
46 	char               *name;
47 	vhd_util_func_t     func;
48 };
49 
50 struct command commands[] = {
51 	{ .name = "create",      .func = vhd_util_create        },
52 	{ .name = "snapshot",    .func = vhd_util_snapshot      },
53 	{ .name = "query",       .func = vhd_util_query         },
54 	{ .name = "read",        .func = vhd_util_read          },
55 	{ .name = "set",         .func = vhd_util_set_field     },
56 	{ .name = "repair",      .func = vhd_util_repair        },
57 	{ .name = "resize",      .func = vhd_util_resize        },
58 	{ .name = "fill",        .func = vhd_util_fill          },
59 	{ .name = "coalesce",    .func = vhd_util_coalesce      },
60 	{ .name = "modify",      .func = vhd_util_modify        },
61 	{ .name = "scan",        .func = vhd_util_scan          },
62 	{ .name = "check",       .func = vhd_util_check         },
63 	{ .name = "revert",      .func = vhd_util_revert        },
64 };
65 
66 #define print_commands()					\
67 	do {							\
68 		int i, n;					\
69 		n = sizeof(commands) / sizeof(struct command);	\
70 		printf("COMMAND := { ");			\
71 		printf("%s", commands[0].name);			\
72 		for (i = 1; i < n; i++)				\
73 			printf(" | %s", commands[i].name);	\
74 		printf(" }\n");					\
75 	} while (0)
76 
77 TEST_FAIL_EXTERN_VARS;
78 
79 void
help(void)80 help(void)
81 {
82 	printf("usage: vhd-util COMMAND [OPTIONS]\n");
83 	print_commands();
84 	exit(0);
85 }
86 
87 struct command *
get_command(char * command)88 get_command(char *command)
89 {
90 	int i, n;
91 
92 	if (strnlen(command, 25) >= 25)
93 		return NULL;
94 
95 	n = sizeof(commands) / sizeof (struct command);
96 
97 	for (i = 0; i < n; i++)
98 		if (!strcmp(command, commands[i].name))
99 			return &commands[i];
100 
101 	return NULL;
102 }
103 
104 int
main(int argc,char * argv[])105 main(int argc, char *argv[])
106 {
107 	char **cargv;
108 	struct command *cmd;
109 	int cargc, i, cnt, ret;
110 
111 #ifdef CORE_DUMP
112 	#include <sys/resource.h>
113 	struct rlimit rlim;
114 	rlim.rlim_cur = RLIM_INFINITY;
115 	rlim.rlim_max = RLIM_INFINITY;
116 	if (setrlimit(RLIMIT_CORE, &rlim) < 0)
117 		fprintf(stderr, "setrlimit failed: %d\n", errno);
118 #endif
119 	setlocale(LC_CTYPE, "");
120 
121 	ret = 0;
122 
123 	if (argc < 2)
124 		help();
125 
126 	cargc = argc - 1;
127 	cmd   = get_command(argv[1]);
128 	if (!cmd) {
129 		fprintf(stderr, "invalid COMMAND %s\n", argv[1]);
130 		help();
131 	}
132 
133 	cargv = malloc(sizeof(char *) * cargc);
134 	if (!cargv)
135 		exit(ENOMEM);
136 
137 	cnt      = 1;
138 	cargv[0] = cmd->name;
139 	for (i = 1; i < cargc; i++) {
140 		char *arg = argv[i + (argc - cargc)];
141 
142 		if (!strcmp(arg, "--debug")) {
143 			libvhd_set_log_level(1);
144 			continue;
145 		}
146 
147 		cargv[cnt++] = arg;
148 	}
149 
150 #ifdef ENABLE_FAILURE_TESTING
151 	for (i = 0; i < NUM_FAIL_TESTS; i++) {
152 		TEST_FAIL[i] = 0;
153 		if (getenv(ENV_VAR_FAIL[i]))
154 			TEST_FAIL[i] = 1;
155 	}
156 #endif // ENABLE_FAILURE_TESTING
157 
158 	ret = cmd->func(cnt, cargv);
159 
160 	free(cargv);
161 
162 	return (ret >= 0 ? ret : -ret);
163 }
164