]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/arguments.c
Makefile.am: use right .h file name for seccomp
[mirror_lxc.git] / src / lxc / arguments.c
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 /*---------------------------------------------------------------------------*/
37 static 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 /*---------------------------------------------------------------------------*/
86 static 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 if (!uppername)
100 exit(-ENOMEM);
101
102 for (j = 0; uppername[j]; j++)
103 uppername[j] = toupper(uppername[j]);
104
105 fprintf(stderr, "[");
106
107 if (isprint(opt->val))
108 fprintf(stderr, "-%c|", opt->val);
109
110 fprintf(stderr, "--%s", opt->name);
111
112 if (opt->has_arg == required_argument)
113 fprintf(stderr, "=%s", uppername);
114
115 if (opt->has_arg == optional_argument)
116 fprintf(stderr, "[=%s]", uppername);
117
118 fprintf(stderr, "] ");
119
120 if (!(i % 4))
121 fprintf(stderr, "\n\t");
122
123 free(uppername);
124 }
125
126 fprintf(stderr, "\n");
127 exit(0);
128 }
129
130 static void print_help(const struct lxc_arguments *args, int code)
131 {
132 fprintf(stderr, "\
133 Usage: %s %s\
134 \n\
135 Common options :\n\
136 -o, --logfile=FILE Output log to FILE instead of stderr\n\
137 -l, --logpriority=LEVEL Set log priority to LEVEL\n\
138 -q, --quiet Don't produce any output\n\
139 -?, --help Give this help list\n\
140 --usage Give a short usage message\n\
141 \n\
142 Mandatory or optional arguments to long options are also mandatory or optional\n\
143 for any corresponding short options.\n\
144 \n\
145 See the %s man page for further information.\n\n",
146 args->progname, args->help, args->progname);
147
148 exit(code);
149 }
150
151 extern int lxc_arguments_parse(struct lxc_arguments *args,
152 int argc, char * const argv[])
153 {
154 char shortopts[256];
155 int ret = 0;
156
157 ret = build_shortopts(args->options, shortopts, sizeof(shortopts));
158 if (ret < 0) {
159 lxc_error(args, "build_shortopts() failed : %s",
160 strerror(errno));
161 return ret;
162 }
163
164 while (1) {
165 int c, index = 0;
166
167 c = getopt_long(argc, argv, shortopts, args->options, &index);
168 if (c == -1)
169 break;
170 switch (c) {
171 case 'n': args->name = optarg; break;
172 case 'o': args->log_file = optarg; break;
173 case 'l': args->log_priority = optarg; break;
174 case 'c': args->console = optarg; break;
175 case 'q': args->quiet = 1; break;
176 case OPT_USAGE: print_usage(args->options, args);
177 case '?': print_help(args, 1);
178 case 'h': print_help(args, 0);
179 default:
180 if (args->parser) {
181 ret = args->parser(args, c, optarg);
182 if (ret)
183 goto error;
184 }
185 }
186 }
187
188 /*
189 * Reclaim the remaining command arguments
190 */
191 args->argv = &argv[optind];
192 args->argc = argc - optind;
193
194 /* Check the command options */
195
196 if (!args->name) {
197 lxc_error(args, "missing container name, use --name option");
198 return -1;
199 }
200
201 if (args->checker)
202 ret = args->checker(args);
203 error:
204 if (ret)
205 lxc_error(args, "could not parse command line");
206 return ret;
207 }
208
209 int lxc_arguments_str_to_int(struct lxc_arguments *args, const char *str)
210 {
211 long val;
212 char *endptr;
213
214 errno = 0;
215 val = strtol(str, &endptr, 10);
216 if (errno) {
217 lxc_error(args, "invalid statefd '%s' : %m", str);
218 return -1;
219 }
220
221 if (*endptr) {
222 lxc_error(args, "invalid digit for statefd '%s'", str);
223 return -1;
224 }
225
226 return (int)val;
227 }