]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/tools/arguments.c
Include -devel suffix in version string
[mirror_lxc.git] / src / lxc / tools / arguments.c
CommitLineData
cda02a28
MN
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
9afe19d6 7 * Daniel Lezcano <daniel.lezcano at free.fr>
cda02a28
MN
8 * Michel Normand <normand at fr.ibm.com>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
250b1eec 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
cda02a28 23 */
ea0eb48b
CB
24
25#include <ctype.h>
26#include <errno.h>
27#include <limits.h>
cda02a28
MN
28#include <stdio.h>
29#include <stdlib.h>
cda02a28 30#include <string.h>
ea0eb48b 31#include <unistd.h>
cda02a28
MN
32#include <sys/stat.h>
33#include <sys/types.h>
cda02a28
MN
34
35#include "arguments.h"
67e571de 36#include "utils.h"
7f12cae9 37#include "version.h"
4be48327 38#include "namespace.h"
cda02a28 39
ea0eb48b
CB
40static int build_shortopts(const struct option *a_options, char *a_shortopts,
41 size_t a_size)
cda02a28 42{
84760c11 43 size_t i = 0;
ea0eb48b 44 const struct option *opt;
cda02a28
MN
45
46 if (!a_options || !a_shortopts || !a_size)
47 return -1;
48
49 for (opt = a_options; opt->name; opt++) {
50
51 if (!isascii(opt->val))
52 continue;
53
54 if (i < a_size)
55 a_shortopts[i++] = opt->val;
56 else
57 goto is2big;
58
59 if (opt->has_arg == no_argument)
60 continue;
61
62 if (i < a_size)
63 a_shortopts[i++] = ':';
64 else
65 goto is2big;
66
67 if (opt->has_arg == required_argument)
68 continue;
69
70 if (i < a_size)
71 a_shortopts[i++] = ':';
72 else
73 goto is2big;
74 }
75
76 if (i < a_size)
77 a_shortopts[i] = '\0';
78 else
79 goto is2big;
80
81 return 0;
82
ea0eb48b 83is2big:
cda02a28
MN
84 errno = E2BIG;
85 return -1;
86}
87
cda02a28
MN
88static void print_usage(const struct option longopts[],
89 const struct lxc_arguments *a_args)
90
91{
92 int i;
93 const struct option *opt;
94
95 fprintf(stderr, "Usage: %s ", a_args->progname);
96
97 for (opt = longopts, i = 1; opt->name; opt++, i++) {
98 int j;
ea0eb48b 99 char *uppername;
cda02a28 100
ea0eb48b 101 uppername = strdup(opt->name);
6d10f1fc
MS
102 if (!uppername)
103 exit(-ENOMEM);
104
cda02a28
MN
105 for (j = 0; uppername[j]; j++)
106 uppername[j] = toupper(uppername[j]);
107
108 fprintf(stderr, "[");
109
110 if (isprint(opt->val))
111 fprintf(stderr, "-%c|", opt->val);
112
113 fprintf(stderr, "--%s", opt->name);
114
115 if (opt->has_arg == required_argument)
116 fprintf(stderr, "=%s", uppername);
117
118 if (opt->has_arg == optional_argument)
119 fprintf(stderr, "[=%s]", uppername);
120
121 fprintf(stderr, "] ");
122
123 if (!(i % 4))
124 fprintf(stderr, "\n\t");
125
126 free(uppername);
127 }
128
129 fprintf(stderr, "\n");
130 exit(0);
131}
132
ea0eb48b
CB
133static void print_version()
134{
5f98011c 135 printf("%s\n", lxc_get_version());
7f12cae9
SG
136 exit(0);
137}
138
cda02a28
MN
139static void print_help(const struct lxc_arguments *args, int code)
140{
141 fprintf(stderr, "\
142Usage: %s %s\
143\n\
144Common options :\n\
145 -o, --logfile=FILE Output log to FILE instead of stderr\n\
146 -l, --logpriority=LEVEL Set log priority to LEVEL\n\
147 -q, --quiet Don't produce any output\n\
67e571de 148 -P, --lxcpath=PATH Use specified container path\n\
cda02a28
MN
149 -?, --help Give this help list\n\
150 --usage Give a short usage message\n\
7f12cae9 151 --version Print the version number\n\
cda02a28
MN
152\n\
153Mandatory or optional arguments to long options are also mandatory or optional\n\
154for any corresponding short options.\n\
155\n\
156See the %s man page for further information.\n\n",
157 args->progname, args->help, args->progname);
158
f002c8a7
SH
159 if (args->helpfn)
160 args->helpfn(args);
cda02a28
MN
161 exit(code);
162}
163
8d06bd13
DE
164static int lxc_arguments_lxcpath_add(struct lxc_arguments *args,
165 const char *lxcpath)
166{
167 if (args->lxcpath_additional != -1 &&
168 args->lxcpath_cnt > args->lxcpath_additional) {
ea0eb48b
CB
169 fprintf(stderr,
170 "This command only accepts %d -P,--lxcpath arguments\n",
8d06bd13
DE
171 args->lxcpath_additional + 1);
172 exit(EXIT_FAILURE);
173 }
174
ea0eb48b
CB
175 args->lxcpath = realloc(
176 args->lxcpath, (args->lxcpath_cnt + 1) * sizeof(args->lxcpath[0]));
8d06bd13
DE
177 if (args->lxcpath == NULL) {
178 lxc_error(args, "no memory");
63c3090c 179 return -ENOMEM;
8d06bd13
DE
180 }
181 args->lxcpath[args->lxcpath_cnt++] = lxcpath;
182 return 0;
183}
184
ea0eb48b
CB
185extern int lxc_arguments_parse(struct lxc_arguments *args, int argc,
186 char *const argv[])
cda02a28 187{
ea0eb48b 188 int ret = 0;
cda02a28 189 char shortopts[256];
cda02a28
MN
190
191 ret = build_shortopts(args->options, shortopts, sizeof(shortopts));
192 if (ret < 0) {
193 lxc_error(args, "build_shortopts() failed : %s",
194 strerror(errno));
195 return ret;
196 }
197
ea0eb48b
CB
198 while (true) {
199 int c;
200 int index = 0;
cda02a28
MN
201
202 c = getopt_long(argc, argv, shortopts, args->options, &index);
203 if (c == -1)
204 break;
205 switch (c) {
ea0eb48b
CB
206 case 'n':
207 args->name = optarg;
208 break;
209 case 'o':
210 args->log_file = optarg;
211 break;
212 case 'l':
213 args->log_priority = optarg;
214 break;
215 case 'q':
216 args->quiet = 1;
217 break;
218 case OPT_RCFILE:
219 args->rcfile = optarg;
220 break;
8d06bd13 221 case 'P':
e555005b 222 remove_trailing_slashes(optarg);
8d06bd13
DE
223 ret = lxc_arguments_lxcpath_add(args, optarg);
224 if (ret < 0)
225 return ret;
226 break;
ea0eb48b
CB
227 case OPT_USAGE:
228 print_usage(args->options, args);
229 case OPT_VERSION:
230 print_version();
231 case '?':
232 print_help(args, 1);
233 case 'h':
234 print_help(args, 0);
cda02a28
MN
235 default:
236 if (args->parser) {
237 ret = args->parser(args, c, optarg);
238 if (ret)
239 goto error;
240 }
241 }
242 }
243
244 /*
245 * Reclaim the remaining command arguments
246 */
247 args->argv = &argv[optind];
248 args->argc = argc - optind;
249
8d06bd13
DE
250 /* If no lxcpaths were given, use default */
251 if (!args->lxcpath_cnt) {
ea0eb48b
CB
252 ret = lxc_arguments_lxcpath_add(
253 args, lxc_global_config_value("lxc.lxcpath"));
8d06bd13
DE
254 if (ret < 0)
255 return ret;
256 }
257
cda02a28
MN
258 /* Check the command options */
259
a6adab20 260 if (!args->name && strcmp(args->progname, "lxc-autostart") != 0) {
cda02a28
MN
261 lxc_error(args, "missing container name, use --name option");
262 return -1;
263 }
264
265 if (args->checker)
266 ret = args->checker(args);
267error:
268 if (ret)
269 lxc_error(args, "could not parse command line");
270 return ret;
271}
fa7eddbb 272
501cbc71
MN
273int lxc_arguments_str_to_int(struct lxc_arguments *args, const char *str)
274{
275 long val;
276 char *endptr;
277
278 errno = 0;
279 val = strtol(str, &endptr, 10);
280 if (errno) {
13277ec4 281 lxc_error(args, "invalid statefd '%s' : %s", str,
282 strerror(errno));
501cbc71
MN
283 return -1;
284 }
285
286 if (*endptr) {
287 lxc_error(args, "invalid digit for statefd '%s'", str);
288 return -1;
289 }
290
291 return (int)val;
292}
4be48327
TA
293
294bool lxc_setup_shared_ns(struct lxc_arguments *args, struct lxc_container *c)
295{
296 int i;
297
298 for (i = 0; i < LXC_NS_MAX; i++) {
299 const char *key, *value;
300
301 value = args->share_ns[i];
302 if (!value)
303 continue;
304
305 if (i == LXC_NS_NET)
306 key = "lxc.namespace.net";
307 else if (i == LXC_NS_IPC)
308 key = "lxc.namespace.ipc";
309 else if (i == LXC_NS_UTS)
310 key = "lxc.namespace.uts";
311 else if (i == LXC_NS_PID)
312 key = "lxc.namespace.pid";
313 else
314 continue;
315
316 if (!c->set_config_item(c, key, value)) {
c379af4c 317 lxc_error(args, "Failed to set \"%s = %s\"", key, value);
4be48327
TA
318 return false;
319 }
320 }
321
322 return true;
323}