]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/arguments.c
add --statefd option to lxc-checkpoint/restart
[mirror_lxc.git] / src / lxc / arguments.c
CommitLineData
cda02a28
MN
1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <dlezcano at fr.ibm.com>
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
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24#include <stdio.h>
25#include <stdlib.h>
26#include <limits.h>
27#include <string.h>
28#include <ctype.h> /* for isprint() */
29#include <errno.h>
30#include <sys/stat.h>
31#include <sys/types.h>
32#include <unistd.h>
33
34#include "arguments.h"
35
36/*---------------------------------------------------------------------------*/
37static int build_shortopts(const struct option *a_options,
38 char *a_shortopts, size_t a_size)
39{
40 const struct option *opt;
41 int i = 0;
42
43 if (!a_options || !a_shortopts || !a_size)
44 return -1;
45
46 for (opt = a_options; opt->name; opt++) {
47
48 if (!isascii(opt->val))
49 continue;
50
51 if (i < a_size)
52 a_shortopts[i++] = opt->val;
53 else
54 goto is2big;
55
56 if (opt->has_arg == no_argument)
57 continue;
58
59 if (i < a_size)
60 a_shortopts[i++] = ':';
61 else
62 goto is2big;
63
64 if (opt->has_arg == required_argument)
65 continue;
66
67 if (i < a_size)
68 a_shortopts[i++] = ':';
69 else
70 goto is2big;
71 }
72
73 if (i < a_size)
74 a_shortopts[i] = '\0';
75 else
76 goto is2big;
77
78 return 0;
79
80 is2big:
81 errno = E2BIG;
82 return -1;
83}
84
85/*---------------------------------------------------------------------------*/
86static void print_usage(const struct option longopts[],
87 const struct lxc_arguments *a_args)
88
89{
90 int i;
91 const struct option *opt;
92
93 fprintf(stderr, "Usage: %s ", a_args->progname);
94
95 for (opt = longopts, i = 1; opt->name; opt++, i++) {
96 int j;
97 char *uppername = strdup(opt->name);
98
99 for (j = 0; uppername[j]; j++)
100 uppername[j] = toupper(uppername[j]);
101
102 fprintf(stderr, "[");
103
104 if (isprint(opt->val))
105 fprintf(stderr, "-%c|", opt->val);
106
107 fprintf(stderr, "--%s", opt->name);
108
109 if (opt->has_arg == required_argument)
110 fprintf(stderr, "=%s", uppername);
111
112 if (opt->has_arg == optional_argument)
113 fprintf(stderr, "[=%s]", uppername);
114
115 fprintf(stderr, "] ");
116
117 if (!(i % 4))
118 fprintf(stderr, "\n\t");
119
120 free(uppername);
121 }
122
123 fprintf(stderr, "\n");
124 exit(0);
125}
126
127static void print_help(const struct lxc_arguments *args, int code)
128{
129 fprintf(stderr, "\
130Usage: %s %s\
131\n\
132Common options :\n\
133 -o, --logfile=FILE Output log to FILE instead of stderr\n\
134 -l, --logpriority=LEVEL Set log priority to LEVEL\n\
135 -q, --quiet Don't produce any output\n\
136 -?, --help Give this help list\n\
137 --usage Give a short usage message\n\
138\n\
139Mandatory or optional arguments to long options are also mandatory or optional\n\
140for any corresponding short options.\n\
141\n\
142See the %s man page for further information.\n\n",
143 args->progname, args->help, args->progname);
144
145 exit(code);
146}
147
148extern int lxc_arguments_parse(struct lxc_arguments *args,
149 int argc, char * const argv[])
150{
151 char shortopts[256];
152 int ret = 0;
153
154 ret = build_shortopts(args->options, shortopts, sizeof(shortopts));
155 if (ret < 0) {
156 lxc_error(args, "build_shortopts() failed : %s",
157 strerror(errno));
158 return ret;
159 }
160
161 while (1) {
162 int c, index = 0;
163
164 c = getopt_long(argc, argv, shortopts, args->options, &index);
165 if (c == -1)
166 break;
167 switch (c) {
168 case 'n': args->name = optarg; break;
169 case 'o': args->log_file = optarg; break;
170 case 'l': args->log_priority = optarg; break;
171 case 'q': args->quiet = 1; break;
172 case OPT_USAGE: print_usage(args->options, args);
173 case '?': print_help(args, 1);
174 case 'h': print_help(args, 0);
175 default:
176 if (args->parser) {
177 ret = args->parser(args, c, optarg);
178 if (ret)
179 goto error;
180 }
181 }
182 }
183
184 /*
185 * Reclaim the remaining command arguments
186 */
187 args->argv = &argv[optind];
188 args->argc = argc - optind;
189
190 /* Check the command options */
191
192 if (!args->name) {
193 lxc_error(args, "missing container name, use --name option");
194 return -1;
195 }
196
197 if (args->checker)
198 ret = args->checker(args);
199error:
200 if (ret)
201 lxc_error(args, "could not parse command line");
202 return ret;
203}
fa7eddbb
DL
204
205extern char **lxc_arguments_dup(const char *file, struct lxc_arguments *args)
206{
207 char **argv;
208 int opt, nbargs = args->argc + 2;
209
fa7eddbb
DL
210 if (args->quiet)
211 nbargs += 1;
212
d685aa80 213 argv = malloc((nbargs + 1) * sizeof(*argv));
fa7eddbb
DL
214 if (!argv)
215 return NULL;
216
217 nbargs = 0;
218
219 argv[nbargs++] = strdup(file);
220
fa7eddbb
DL
221 if (args->quiet)
222 argv[nbargs++] = "--quiet";
223
224 argv[nbargs++] = "--";
225
226 for (opt = 0; opt < args->argc; opt++)
227 argv[nbargs++] = strdup(args->argv[opt]);
228
229 argv[nbargs] = NULL;
230
231 return argv;
232}