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