Bug Summary

File:src/usr.sbin/vmd/obj/parse.c
Warning:line 1246, column 18
Use of zero-allocated memory

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name parse.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/vmd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/vmd -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/vmd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c parse.c
1#include <stdlib.h>
2#include <string.h>
3#define YYBYACC1 1
4#define YYMAJOR1 1
5#define YYMINOR9 9
6#define YYLEXyylex() yylex()
7#define YYEMPTY-1 -1
8#define yyclearin(yychar=(-1)) (yychar=(YYEMPTY-1))
9#define yyerrok(yyerrflag=0) (yyerrflag=0)
10#define YYRECOVERING()(yyerrflag!=0) (yyerrflag!=0)
11#define YYPREFIX"yy" "yy"
12#line 26 "/usr/src/usr.sbin/vmd/parse.y"
13#include <sys/types.h>
14#include <sys/queue.h>
15#include <sys/socket.h>
16#include <sys/uio.h>
17
18#include <machine/vmmvar.h>
19
20#include <net/if.h>
21#include <netinet/in.h>
22#include <netinet/if_ether.h>
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <limits.h>
27#include <stdarg.h>
28#include <string.h>
29#include <unistd.h>
30#include <ctype.h>
31#include <netdb.h>
32#include <util.h>
33#include <errno(*__errno()).h>
34#include <err.h>
35#include <fcntl.h>
36#include <pwd.h>
37#include <grp.h>
38
39#include "vmd.h"
40
41TAILQ_HEAD(files, file)struct files { struct file *tqh_first; struct file **tqh_last
; }
files = TAILQ_HEAD_INITIALIZER(files){ ((void *)0), &(files).tqh_first };
42static struct file {
43 TAILQ_ENTRY(file)struct { struct file *tqe_next; struct file **tqe_prev; } entry;
44 FILE *stream;
45 char *name;
46 size_t ungetpos;
47 size_t ungetsize;
48 u_char *ungetbuf;
49 int eof_reached;
50 int lineno;
51 int errors;
52} *file, *topfile;
53struct file *pushfile(const char *, int);
54int popfile(void);
55int yyparse(void);
56int yylex(void);
57int yyerror(const char *, ...)
58 __attribute__((__format__ (printf, 1, 2)))
59 __attribute__((__nonnull__ (1)));
60int kw_cmp(const void *, const void *);
61int lookup(char *);
62int igetc(void);
63int lgetc(int);
64void lungetc(int);
65int findeol(void);
66
67TAILQ_HEAD(symhead, sym)struct symhead { struct sym *tqh_first; struct sym **tqh_last
; }
symhead = TAILQ_HEAD_INITIALIZER(symhead){ ((void *)0), &(symhead).tqh_first };
68struct sym {
69 TAILQ_ENTRY(sym)struct { struct sym *tqe_next; struct sym **tqe_prev; } entry;
70 int used;
71 int persist;
72 char *nam;
73 char *val;
74};
75int symset(const char *, const char *, int);
76char *symget(const char *);
77
78ssize_t parse_size(char *, int64_t);
79int parse_disk(char *, int);
80unsigned int parse_format(const char *);
81
82static struct vmop_create_params vmc;
83static struct vm_create_params *vcp;
84static struct vmd_switch *vsw;
85static char vsw_type[IF_NAMESIZE16];
86static int vcp_disable;
87static size_t vcp_nnics;
88static int errors;
89extern struct vmd *env;
90extern const char *vmd_descsw[];
91
92typedef struct {
93 union {
94 uint8_t lladdr[ETHER_ADDR_LEN6];
95 int64_t number;
96 char *string;
97 struct {
98 uid_t uid;
99 int64_t gid;
100 } owner;
101 } v;
102 int lineno;
103} YYSTYPE;
104
105#line 106 "parse.c"
106#define INCLUDE257 257
107#define ERROR258 258
108#define ADD259 259
109#define ALLOW260 260
110#define BOOT261 261
111#define CDROM262 262
112#define DEVICE263 263
113#define DISABLE264 264
114#define DISK265 265
115#define DOWN266 266
116#define ENABLE267 267
117#define FORMAT268 268
118#define GROUP269 269
119#define INET6270 270
120#define INSTANCE271 271
121#define INTERFACE272 272
122#define LLADDR273 273
123#define LOCAL274 274
124#define LOCKED275 275
125#define MEMORY276 276
126#define NET277 277
127#define NIFS278 278
128#define OWNER279 279
129#define PATH280 280
130#define PREFIX281 281
131#define RDOMAIN282 282
132#define SIZE283 283
133#define SOCKET284 284
134#define SWITCH285 285
135#define UP286 286
136#define VM287 287
137#define VMID288 288
138#define STAGGERED289 289
139#define START290 290
140#define PARALLEL291 291
141#define DELAY292 292
142#define NUMBER293 293
143#define STRING294 294
144#define YYERRCODE256 256
145const short yylhs[] =
146 { -1,
147 0, 0, 0, 0, 0, 0, 0, 0, 12, 13,
148 14, 14, 14, 14, 14, 17, 15, 19, 19, 20,
149 20, 20, 20, 20, 20, 22, 16, 11, 11, 23,
150 23, 24, 24, 24, 24, 24, 24, 24, 24, 24,
151 24, 24, 26, 26, 27, 27, 28, 28, 28, 28,
152 28, 28, 28, 8, 8, 4, 4, 25, 25, 25,
153 30, 30, 31, 31, 32, 32, 32, 32, 32, 9,
154 9, 10, 10, 1, 1, 5, 5, 6, 6, 7,
155 7, 3, 3, 2, 2, 2, 33, 33, 18, 18,
156 29, 29, 21,
157};
158const short yylen[] =
159 { 2,
160 0, 3, 2, 3, 3, 3, 3, 3, 2, 3,
161 2, 4, 3, 3, 6, 0, 7, 3, 2, 1,
162 2, 2, 2, 2, 1, 0, 8, 0, 2, 3,
163 2, 1, 3, 4, 2, 3, 2, 2, 2, 2,
164 2, 1, 6, 3, 3, 2, 1, 1, 1, 1,
165 1, 1, 2, 1, 1, 0, 2, 4, 1, 0,
166 3, 2, 3, 1, 2, 2, 3, 2, 1, 1,
167 0, 2, 1, 1, 0, 0, 1, 0, 1, 1,
168 1, 1, 1, 1, 1, 1, 1, 0, 2, 0,
169 2, 1, 2,
170};
171const short yydefred[] =
172 { 1,
173 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
174 0, 0, 0, 0, 0, 8, 0, 9, 0, 0,
175 0, 16, 0, 0, 0, 2, 4, 5, 6, 7,
176 72, 0, 13, 54, 55, 14, 0, 0, 26, 0,
177 10, 12, 0, 29, 0, 0, 0, 0, 0, 0,
178 89, 83, 81, 82, 0, 0, 0, 0, 80, 20,
179 25, 0, 0, 0, 15, 21, 22, 23, 24, 17,
180 0, 19, 0, 0, 0, 0, 77, 0, 0, 0,
181 32, 0, 0, 0, 42, 0, 18, 0, 0, 35,
182 37, 0, 39, 40, 38, 41, 0, 27, 0, 31,
183 93, 47, 51, 50, 52, 49, 48, 0, 0, 44,
184 84, 85, 86, 36, 0, 33, 70, 0, 30, 53,
185 0, 57, 0, 79, 0, 0, 0, 0, 69, 34,
186 0, 64, 0, 0, 66, 68, 65, 0, 0, 0,
187 43, 0, 0, 46, 92, 0, 0, 0, 74, 67,
188 87, 63, 0, 91, 45, 58, 0, 62, 61,
189};
190const short yydgoto[] =
191 { 1,
192 150, 114, 60, 116, 82, 128, 129, 36, 118, 18,
193 39, 11, 12, 13, 14, 15, 37, 48, 62, 63,
194 87, 45, 83, 84, 130, 85, 133, 134, 146, 147,
195 131, 132, 152,
196};
197const short yysindex[] =
198 { 0,
199 -10, 8, -270, -221, -222, -270, -270, -261, -2, 0,
200 51, 52, 54, 56, 60, 0, -270, 0, -210, -218,
201 -260, 0, -199, -213, -211, 0, 0, 0, 0, 0,
202 0, -205, 0, 0, 0, 0, -42, -270, 0, -203,
203 0, 0, 82, 0, -23, -191, 82, -247, 82, -186,
204 0, 0, 0, 0, -270, -270, -169, -183, 0, 0,
205 0, -124, 82, 307, 0, 0, 0, 0, 0, 0,
206 101, 0, -158, -252, -270, -270, 0, -242, -172, -260,
207 0, -148, 233, 82, 0, 82, 0, 188, -250, 0,
208 0, -142, 0, 0, 0, 0, -167, 0, 101, 0,
209 0, 0, 0, 0, 0, 0, 0, -260, 82, 0,
210 0, 0, 0, 0, -270, 0, 0, -119, 0, 0,
211 -156, 0, -270, 0, -165, -270, 82, -144, 0, 0,
212 -187, 0, 5, -8, 0, 0, 0, -187, -163, 88,
213 0, 82, 82, 0, 0, -156, 176, 82, 0, 0,
214 0, 0, 0, 0, 0, 0, 82, 0, 0,};
215const short yyrindex[] =
216 { 0,
217 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
218 0, 0, 0, 0, 0, 0, 21, 0, 123, 0,
219 0, 0, 11, 0, 0, 0, 0, 0, 0, 0,
220 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
221 0, 0, -219, 0, 0, 0, -84, 0, 287, 0,
222 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223 0, 0, -34, -137, 0, 0, 0, 0, 0, 0,
224 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
225 0, 0, -137, 213, 0, -57, 0, 0, 0, 0,
226 0, 151, 0, 0, 0, 0, 48, 0, 0, 0,
227 0, 0, 0, 0, 0, 0, 0, 0, 252, 0,
228 0, 0, 0, 0, 0, 0, 0, -7, 0, 0,
229 0, 0, 0, 0, 0, 0, -189, 0, 0, 0,
230 131, 0, 0, 12, 0, 0, 0, -135, 75, 102,
231 0, 254, 252, 0, 0, 0, -135, 153, 0, 0,
232 0, 0, 274, 0, 0, 0, 153, 0, 0,};
233const short yygindex[] =
234 { 0,
235 0, 0, -51, 0, 0, 0, -22, -70, 0, -1,
236 0, 0, 0, 0, 0, 0, 0, -40, 0, 74,
237 -91, 0, 0, 66, 0, 0, 6, 65, 0, 0,
238 0, -117, 0,
239};
240#define YYTABLESIZE586 586
241const short yytable[] =
242 { 10,
243 70, 142, 60, 127, 22, 23, 51, 119, 64, 96,
244 89, 111, 81, 140, 112, 31, 52, 16, 53, 54,
245 148, 55, 72, 17, 56, 61, 113, 57, 24, 157,
246 73, 81, 34, 35, 58, 143, 44, 120, 59, 61,
247 90, 17, 145, 100, 90, 101, 90, 90, 19, 90,
248 93, 94, 90, 66, 67, 90, 21, 71, 25, 20,
249 26, 27, 90, 28, 73, 29, 90, 90, 121, 30,
250 32, 38, 90, 91, 92, 33, 90, 40, 53, 90,
251 43, 123, 41, 90, 75, 90, 138, 124, 42, 46,
252 90, 47, 90, 144, 125, 90, 90, 126, 59, 49,
253 50, 153, 154, 68, 102, 103, 65, 158, 104, 69,
254 86, 88, 88, 122, 105, 106, 159, 60, 75, 107,
255 95, 135, 108, 97, 137, 115, 117, 136, 139, 141,
256 149, 151, 11, 28, 76, 71, 90, 78, 0, 52,
257 59, 53, 54, 73, 55, 73, 53, 56, 99, 123,
258 57, 155, 110, 0, 0, 124, 0, 58, 0, 0,
259 56, 59, 125, 0, 0, 126, 59, 0, 0, 0,
260 71, 0, 71, 0, 0, 90, 90, 90, 0, 90,
261 90, 90, 90, 0, 90, 0, 90, 90, 90, 90,
262 90, 90, 0, 90, 90, 0, 0, 90, 0, 75,
263 90, 90, 90, 90, 90, 0, 90, 90, 90, 90,
264 0, 90, 0, 0, 90, 0, 90, 90, 90, 0,
265 90, 90, 0, 0, 90, 0, 88, 0, 90, 90,
266 0, 90, 90, 0, 90, 0, 0, 90, 0, 0,
267 90, 0, 0, 0, 0, 2, 3, 90, 0, 0,
268 0, 90, 60, 60, 60, 59, 60, 60, 0, 60,
269 0, 0, 0, 4, 60, 78, 60, 0, 60, 0,
270 60, 60, 0, 5, 6, 56, 7, 90, 8, 0,
271 73, 73, 73, 9, 73, 73, 73, 73, 73, 73,
272 0, 73, 73, 73, 73, 73, 73, 0, 73, 73,
273 156, 0, 73, 0, 0, 73, 73, 71, 71, 71,
274 109, 71, 71, 71, 71, 0, 71, 0, 0, 71,
275 71, 71, 71, 71, 0, 71, 71, 0, 0, 71,
276 0, 0, 71, 71, 75, 75, 75, 90, 75, 75,
277 75, 75, 0, 75, 0, 0, 75, 75, 75, 75,
278 75, 0, 75, 75, 0, 0, 75, 98, 0, 75,
279 75, 88, 88, 88, 0, 88, 88, 88, 88, 0,
280 88, 0, 0, 88, 88, 88, 88, 88, 90, 88,
281 88, 0, 0, 88, 0, 0, 88, 88, 0, 0,
282 59, 59, 59, 0, 59, 59, 0, 59, 89, 0,
283 0, 0, 59, 78, 59, 0, 59, 0, 59, 59,
284 56, 56, 56, 0, 56, 56, 0, 56, 90, 0,
285 0, 90, 56, 0, 56, 90, 56, 90, 56, 56,
286 0, 0, 0, 0, 90, 0, 0, 90, 90, 0,
287 0, 53, 0, 0, 123, 0, 0, 0, 102, 103,
288 124, 0, 104, 0, 0, 0, 0, 125, 105, 106,
289 126, 59, 0, 107, 0, 0, 108, 0, 0, 0,
290 0, 0, 90, 90, 90, 0, 90, 90, 0, 90,
291 0, 0, 0, 0, 90, 0, 90, 0, 90, 0,
292 90, 90, 73, 74, 75, 0, 52, 76, 0, 54,
293 0, 0, 0, 0, 0, 0, 77, 0, 78, 0,
294 79, 80, 90, 90, 90, 90, 90, 0, 90, 0,
295 0, 0, 90, 90, 90, 90, 0, 90, 0, 90,
296 90, 0, 90, 0, 93, 93, 0, 0, 93, 0,
297 0, 0, 0, 0, 93, 93, 90, 90, 90, 93,
298 90, 90, 93, 90, 0, 0, 0, 0, 90, 0,
299 90, 0, 90, 0, 90, 90, 73, 74, 75, 0,
300 52, 76, 0, 54, 0, 0, 0, 0, 0, 0,
301 77, 0, 78, 0, 79, 80,
302};
303const short yycheck[] =
304 { 10,
305 125, 10, 10, 123, 6, 7, 47, 99, 49, 80,
306 263, 262, 64, 131, 265, 17, 264, 10, 266, 267,
307 138, 269, 63, 294, 272, 48, 277, 275, 290, 147,
308 10, 83, 293, 294, 282, 44, 38, 108, 286, 62,
309 125, 294, 134, 84, 264, 86, 266, 267, 270, 269,
310 293, 294, 272, 55, 56, 275, 279, 10, 61, 281,
311 10, 10, 282, 10, 44, 10, 286, 125, 109, 10,
312 281, 271, 74, 75, 76, 294, 266, 291, 266, 269,
313 123, 269, 294, 273, 10, 275, 127, 275, 294, 293,
314 125, 10, 282, 134, 282, 285, 286, 285, 286, 123,
315 292, 142, 143, 273, 261, 262, 293, 148, 265, 293,
316 10, 10, 271, 115, 271, 272, 157, 125, 44, 276,
317 293, 123, 279, 272, 126, 268, 294, 293, 273, 125,
318 294, 44, 10, 123, 272, 62, 125, 273, -1, 264,
319 10, 266, 267, 123, 269, 125, 266, 272, 83, 269,
320 275, 146, 88, -1, -1, 275, -1, 282, -1, -1,
321 10, 286, 282, -1, -1, 285, 286, -1, -1, -1,
322 123, -1, 125, -1, -1, 260, 261, 262, -1, 264,
323 265, 266, 267, -1, 269, -1, 271, 272, 273, 274,
324 275, 276, -1, 278, 279, -1, -1, 282, -1, 125,
325 285, 286, 260, 261, 262, -1, 264, 265, 266, 267,
326 -1, 269, -1, -1, 272, -1, 274, 275, 276, -1,
327 278, 279, -1, -1, 282, -1, 125, -1, 286, 264,
328 -1, 266, 267, -1, 269, -1, -1, 272, -1, -1,
329 275, -1, -1, -1, -1, 256, 257, 282, -1, -1,
330 -1, 286, 260, 261, 262, 125, 264, 265, -1, 267,
331 -1, -1, -1, 274, 272, 273, 274, -1, 276, -1,
332 278, 279, -1, 284, 285, 125, 287, 125, 289, -1,
333 260, 261, 262, 294, 264, 265, 266, 267, 268, 269,
334 -1, 271, 272, 273, 274, 275, 276, -1, 278, 279,
335 125, -1, 282, -1, -1, 285, 286, 260, 261, 262,
336 123, 264, 265, 266, 267, -1, 269, -1, -1, 272,
337 273, 274, 275, 276, -1, 278, 279, -1, -1, 282,
338 -1, -1, 285, 286, 260, 261, 262, 125, 264, 265,
339 266, 267, -1, 269, -1, -1, 272, 273, 274, 275,
340 276, -1, 278, 279, -1, -1, 282, 125, -1, 285,
341 286, 260, 261, 262, -1, 264, 265, 266, 267, -1,
342 269, -1, -1, 272, 273, 274, 275, 276, 125, 278,
343 279, -1, -1, 282, -1, -1, 285, 286, -1, -1,
344 260, 261, 262, -1, 264, 265, -1, 267, 125, -1,
345 -1, -1, 272, 273, 274, -1, 276, -1, 278, 279,
346 260, 261, 262, -1, 264, 265, -1, 267, 266, -1,
347 -1, 269, 272, -1, 274, 273, 276, 275, 278, 279,
348 -1, -1, -1, -1, 282, -1, -1, 285, 286, -1,
349 -1, 266, -1, -1, 269, -1, -1, -1, 261, 262,
350 275, -1, 265, -1, -1, -1, -1, 282, 271, 272,
351 285, 286, -1, 276, -1, -1, 279, -1, -1, -1,
352 -1, -1, 260, 261, 262, -1, 264, 265, -1, 267,
353 -1, -1, -1, -1, 272, -1, 274, -1, 276, -1,
354 278, 279, 260, 261, 262, -1, 264, 265, -1, 267,
355 -1, -1, -1, -1, -1, -1, 274, -1, 276, -1,
356 278, 279, 261, 262, 261, 262, 265, -1, 265, -1,
357 -1, -1, 271, 272, 271, 272, -1, 276, -1, 276,
358 279, -1, 279, -1, 261, 262, -1, -1, 265, -1,
359 -1, -1, -1, -1, 271, 272, 260, 261, 262, 276,
360 264, 265, 279, 267, -1, -1, -1, -1, 272, -1,
361 274, -1, 276, -1, 278, 279, 260, 261, 262, -1,
362 264, 265, -1, 267, -1, -1, -1, -1, -1, -1,
363 274, -1, 276, -1, 278, 279,
364};
365#define YYFINAL1 1
366#ifndef YYDEBUG0
367#define YYDEBUG0 0
368#endif
369#define YYMAXTOKEN294 294
370#if YYDEBUG0
371const char * const yyname[] =
372 {
373"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3740,0,0,0,0,0,0,0,0,0,0,0,0,"','",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'='",0,0,0,0,0,
3750,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3760,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3770,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
3790,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"INCLUDE",
380"ERROR","ADD","ALLOW","BOOT","CDROM","DEVICE","DISABLE","DISK","DOWN","ENABLE",
381"FORMAT","GROUP","INET6","INSTANCE","INTERFACE","LLADDR","LOCAL","LOCKED",
382"MEMORY","NET","NIFS","OWNER","PATH","PREFIX","RDOMAIN","SIZE","SOCKET",
383"SWITCH","UP","VM","VMID","STAGGERED","START","PARALLEL","DELAY","NUMBER",
384"STRING",
385};
386const char * const yyrule[] =
387 {"$accept : grammar",
388"grammar :",
389"grammar : grammar include '\\n'",
390"grammar : grammar '\\n'",
391"grammar : grammar varset '\\n'",
392"grammar : grammar main '\\n'",
393"grammar : grammar switch '\\n'",
394"grammar : grammar vm '\\n'",
395"grammar : grammar error '\\n'",
396"include : INCLUDE string",
397"varset : STRING '=' STRING",
398"main : LOCAL INET6",
399"main : LOCAL INET6 PREFIX STRING",
400"main : LOCAL PREFIX STRING",
401"main : SOCKET OWNER owner_id",
402"main : STAGGERED START PARALLEL NUMBER DELAY NUMBER",
403"$$1 :",
404"switch : SWITCH string $$1 '{' optnl switch_opts_l '}'",
405"switch_opts_l : switch_opts_l switch_opts nl",
406"switch_opts_l : switch_opts optnl",
407"switch_opts : disable",
408"switch_opts : GROUP string",
409"switch_opts : INTERFACE string",
410"switch_opts : LOCKED LLADDR",
411"switch_opts : RDOMAIN NUMBER",
412"switch_opts : updown",
413"$$2 :",
414"vm : VM string vm_instance $$2 '{' optnl vm_opts_l '}'",
415"vm_instance :",
416"vm_instance : INSTANCE string",
417"vm_opts_l : vm_opts_l vm_opts nl",
418"vm_opts_l : vm_opts optnl",
419"vm_opts : disable",
420"vm_opts : DISK string image_format",
421"vm_opts : local INTERFACE optstring iface_opts_o",
422"vm_opts : BOOT string",
423"vm_opts : BOOT DEVICE bootdevice",
424"vm_opts : CDROM string",
425"vm_opts : NIFS NUMBER",
426"vm_opts : MEMORY NUMBER",
427"vm_opts : MEMORY STRING",
428"vm_opts : OWNER owner_id",
429"vm_opts : instance",
430"instance : ALLOW INSTANCE '{' optnl instance_l '}'",
431"instance : ALLOW INSTANCE instance_flags",
432"instance_l : instance_flags optcommanl instance_l",
433"instance_l : instance_flags optnl",
434"instance_flags : BOOT",
435"instance_flags : MEMORY",
436"instance_flags : INTERFACE",
437"instance_flags : DISK",
438"instance_flags : CDROM",
439"instance_flags : INSTANCE",
440"instance_flags : OWNER owner_id",
441"owner_id : NUMBER",
442"owner_id : STRING",
443"image_format :",
444"image_format : FORMAT string",
445"iface_opts_o : '{' optnl iface_opts_l '}'",
446"iface_opts_o : iface_opts_c",
447"iface_opts_o :",
448"iface_opts_l : iface_opts_l iface_opts optnl",
449"iface_opts_l : iface_opts optnl",
450"iface_opts_c : iface_opts_c iface_opts optcomma",
451"iface_opts_c : iface_opts",
452"iface_opts : SWITCH string",
453"iface_opts : GROUP string",
454"iface_opts : locked LLADDR lladdr",
455"iface_opts : RDOMAIN NUMBER",
456"iface_opts : updown",
457"optstring : STRING",
458"optstring :",
459"string : STRING string",
460"string : STRING",
461"lladdr : STRING",
462"lladdr :",
463"local :",
464"local : LOCAL",
465"locked :",
466"locked : LOCKED",
467"updown : UP",
468"updown : DOWN",
469"disable : ENABLE",
470"disable : DISABLE",
471"bootdevice : CDROM",
472"bootdevice : DISK",
473"bootdevice : NET",
474"optcomma : ','",
475"optcomma :",
476"optnl : '\\n' optnl",
477"optnl :",
478"optcommanl : ',' optnl",
479"optcommanl : nl",
480"nl : '\\n' optnl",
481};
482#endif
483#ifdef YYSTACKSIZE10000
484#undef YYMAXDEPTH10000
485#define YYMAXDEPTH10000 YYSTACKSIZE10000
486#else
487#ifdef YYMAXDEPTH10000
488#define YYSTACKSIZE10000 YYMAXDEPTH10000
489#else
490#define YYSTACKSIZE10000 10000
491#define YYMAXDEPTH10000 10000
492#endif
493#endif
494#define YYINITSTACKSIZE200 200
495/* LINTUSED */
496int yydebug;
497int yynerrs;
498int yyerrflag;
499int yychar;
500short *yyssp;
501YYSTYPE *yyvsp;
502YYSTYPE yyval;
503YYSTYPE yylval;
504short *yyss;
505short *yysslim;
506YYSTYPE *yyvs;
507unsigned int yystacksize;
508int yyparse(void);
509#line 738 "/usr/src/usr.sbin/vmd/parse.y"
510
511struct keywords {
512 const char *k_name;
513 int k_val;
514};
515
516int
517yyerror(const char *fmt, ...)
518{
519 va_list ap;
520 char *msg;
521
522 file->errors++;
523 va_start(ap, fmt)__builtin_va_start(ap, fmt);
524 if (vasprintf(&msg, fmt, ap) == -1)
525 fatal("yyerror vasprintf");
526 va_end(ap)__builtin_va_end(ap);
527 log_warnx("%s:%d: %s", file->name, yylval.lineno, msg);
528 free(msg);
529 return (0);
530}
531
532int
533kw_cmp(const void *k, const void *e)
534{
535 return (strcmp(k, ((const struct keywords *)e)->k_name));
536}
537
538int
539lookup(char *s)
540{
541 /* this has to be sorted always */
542 static const struct keywords keywords[] = {
543 { "add", ADD259 },
544 { "allow", ALLOW260 },
545 { "boot", BOOT261 },
546 { "cdrom", CDROM262 },
547 { "delay", DELAY292 },
548 { "device", DEVICE263 },
549 { "disable", DISABLE264 },
550 { "disk", DISK265 },
551 { "down", DOWN266 },
552 { "enable", ENABLE267 },
553 { "format", FORMAT268 },
554 { "group", GROUP269 },
555 { "id", VMID288 },
556 { "include", INCLUDE257 },
557 { "inet6", INET6270 },
558 { "instance", INSTANCE271 },
559 { "interface", INTERFACE272 },
560 { "interfaces", NIFS278 },
561 { "lladdr", LLADDR273 },
562 { "local", LOCAL274 },
563 { "locked", LOCKED275 },
564 { "memory", MEMORY276 },
565 { "net", NET277 },
566 { "owner", OWNER279 },
567 { "parallel", PARALLEL291 },
568 { "prefix", PREFIX281 },
569 { "rdomain", RDOMAIN282 },
570 { "size", SIZE283 },
571 { "socket", SOCKET284 },
572 { "staggered", STAGGERED289 },
573 { "start", START290 },
574 { "switch", SWITCH285 },
575 { "up", UP286 },
576 { "vm", VM287 }
577 };
578 const struct keywords *p;
579
580 p = bsearch(s, keywords, sizeof(keywords)/sizeof(keywords[0]),
581 sizeof(keywords[0]), kw_cmp);
582
583 if (p)
584 return (p->k_val);
585 else
586 return (STRING294);
587}
588
589#define START_EXPAND1 1
590#define DONE_EXPAND2 2
591
592static int expanding;
593
594int
595igetc(void)
596{
597 int c;
598
599 while (1) {
600 if (file->ungetpos > 0)
601 c = file->ungetbuf[--file->ungetpos];
602 else
603 c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
;
604
605 if (c == START_EXPAND1)
606 expanding = 1;
607 else if (c == DONE_EXPAND2)
608 expanding = 0;
609 else
610 break;
611 }
612 return (c);
613}
614
615int
616lgetc(int quotec)
617{
618 int c, next;
619
620 if (quotec) {
621 if ((c = igetc()) == EOF(-1)) {
622 yyerror("reached end of file while parsing "
623 "quoted string");
624 if (file == topfile || popfile() == EOF(-1))
625 return (EOF(-1));
626 return (quotec);
627 }
628 return (c);
629 }
630
631 while ((c = igetc()) == '\\') {
632 next = igetc();
633 if (next != '\n') {
634 c = next;
635 break;
636 }
637 yylval.lineno = file->lineno;
638 file->lineno++;
639 }
640 if (c == '\t' || c == ' ') {
641 /* Compress blanks to a single space. */
642 do {
643 c = getc(file->stream)(!__isthreaded ? (--(file->stream)->_r < 0 ? __srget
(file->stream) : (int)(*(file->stream)->_p++)) : (getc
)(file->stream))
;
644 } while (c == '\t' || c == ' ');
645 ungetc(c, file->stream);
646 c = ' ';
647 }
648
649 if (c == EOF(-1)) {
650 /*
651 * Fake EOL when hit EOF for the first time. This gets line
652 * count right if last line in included file is syntactically
653 * invalid and has no newline.
654 */
655 if (file->eof_reached == 0) {
656 file->eof_reached = 1;
657 return ('\n');
658 }
659 while (c == EOF(-1)) {
660 if (file == topfile || popfile() == EOF(-1))
661 return (EOF(-1));
662 c = igetc();
663 }
664 }
665 return (c);
666}
667
668void
669lungetc(int c)
670{
671 if (c == EOF(-1))
672 return;
673
674 if (file->ungetpos >= file->ungetsize) {
675 void *p = reallocarray(file->ungetbuf, file->ungetsize, 2);
676 if (p == NULL((void *)0))
677 err(1, "%s", __func__);
678 file->ungetbuf = p;
679 file->ungetsize *= 2;
680 }
681 file->ungetbuf[file->ungetpos++] = c;
682}
683
684int
685findeol(void)
686{
687 int c;
688
689 /* skip to either EOF or the first real EOL */
690 while (1) {
691 c = lgetc(0);
692 if (c == '\n') {
693 file->lineno++;
694 break;
695 }
696 if (c == EOF(-1))
697 break;
698 }
699 return (ERROR258);
700}
701
702int
703yylex(void)
704{
705 char buf[8096];
706 char *p, *val;
707 int quotec, next, c;
708 int token;
709
710top:
711 p = buf;
712 while ((c = lgetc(0)) == ' ' || c == '\t')
713 ; /* nothing */
714
715 yylval.lineno = file->lineno;
716 if (c == '#')
717 while ((c = lgetc(0)) != '\n' && c != EOF(-1))
718 ; /* nothing */
719 if (c == '$' && !expanding) {
720 while (1) {
721 if ((c = lgetc(0)) == EOF(-1))
722 return (0);
723
724 if (p + 1 >= buf + sizeof(buf) - 1) {
725 yyerror("string too long");
726 return (findeol());
727 }
728 if (isalnum(c) || c == '_') {
729 *p++ = c;
730 continue;
731 }
732 *p = '\0';
733 lungetc(c);
734 break;
735 }
736 val = symget(buf);
737 if (val == NULL((void *)0)) {
738 yyerror("macro '%s' not defined", buf);
739 return (findeol());
740 }
741 p = val + strlen(val) - 1;
742 lungetc(DONE_EXPAND2);
743 while (p >= val) {
744 lungetc((unsigned char)*p);
745 p--;
746 }
747 lungetc(START_EXPAND1);
748 goto top;
749 }
750
751 switch (c) {
752 case '\'':
753 case '"':
754 quotec = c;
755 while (1) {
756 if ((c = lgetc(quotec)) == EOF(-1))
757 return (0);
758 if (c == '\n') {
759 file->lineno++;
760 continue;
761 } else if (c == '\\') {
762 if ((next = lgetc(quotec)) == EOF(-1))
763 return (0);
764 if (next == quotec || next == ' ' ||
765 next == '\t')
766 c = next;
767 else if (next == '\n') {
768 file->lineno++;
769 continue;
770 } else
771 lungetc(next);
772 } else if (c == quotec) {
773 *p = '\0';
774 break;
775 } else if (c == '\0') {
776 yyerror("syntax error");
777 return (findeol());
778 }
779 if (p + 1 >= buf + sizeof(buf) - 1) {
780 yyerror("string too long");
781 return (findeol());
782 }
783 *p++ = c;
784 }
785 yylval.v.string = strdup(buf);
786 if (yylval.v.string == NULL((void *)0))
787 fatal("yylex: strdup");
788 return (STRING294);
789 }
790
791#define allowed_to_end_number(x)(isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' ||
x == '=')
\
792 (isspace(x) || x == ')' || x ==',' || x == '/' || x == '}' || x == '=')
793
794 if (c == '-' || isdigit(c)) {
795 do {
796 *p++ = c;
797 if ((size_t)(p-buf) >= sizeof(buf)) {
798 yyerror("string too long");
799 return (findeol());
800 }
801 } while ((c = lgetc(0)) != EOF(-1) && isdigit(c));
802 lungetc(c);
803 if (p == buf + 1 && buf[0] == '-')
804 goto nodigits;
805 if (c == EOF(-1) || allowed_to_end_number(c)(isspace(c) || c == ')' || c ==',' || c == '/' || c == '}' ||
c == '=')
) {
806 const char *errstr = NULL((void *)0);
807
808 *p = '\0';
809 yylval.v.number = strtonum(buf, LLONG_MIN(-9223372036854775807LL -1LL),
810 LLONG_MAX9223372036854775807LL, &errstr);
811 if (errstr) {
812 yyerror("\"%s\" invalid number: %s",
813 buf, errstr);
814 return (findeol());
815 }
816 return (NUMBER293);
817 } else {
818nodigits:
819 while (p > buf + 1)
820 lungetc((unsigned char)*--p);
821 c = (unsigned char)*--p;
822 if (c == '-')
823 return (c);
824 }
825 }
826
827#define allowed_in_string(x)(isalnum(x) || (ispunct(x) && x != '(' && x !=
')' && x != '{' && x != '}' && x != '!'
&& x != '=' && x != '#' && x != ',')
)
\
828 (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \
829 x != '{' && x != '}' && \
830 x != '!' && x != '=' && x != '#' && \
831 x != ','))
832
833 if (isalnum(c) || c == ':' || c == '_' || c == '/') {
834 do {
835 *p++ = c;
836 if ((size_t)(p-buf) >= sizeof(buf)) {
837 yyerror("string too long");
838 return (findeol());
839 }
840 } while ((c = lgetc(0)) != EOF(-1) && (allowed_in_string(c)(isalnum(c) || (ispunct(c) && c != '(' && c !=
')' && c != '{' && c != '}' && c != '!'
&& c != '=' && c != '#' && c != ',')
)
));
841 lungetc(c);
842 *p = '\0';
843 if ((token = lookup(buf)) == STRING294)
844 if ((yylval.v.string = strdup(buf)) == NULL((void *)0))
845 fatal("yylex: strdup");
846 return (token);
847 }
848 if (c == '\n') {
849 yylval.lineno = file->lineno;
850 file->lineno++;
851 }
852 if (c == EOF(-1))
853 return (0);
854 return (c);
855}
856
857struct file *
858pushfile(const char *name, int secret)
859{
860 struct file *nfile;
861
862 if ((nfile = calloc(1, sizeof(struct file))) == NULL((void *)0)) {
863 log_warn("%s", __func__);
864 return (NULL((void *)0));
865 }
866 if ((nfile->name = strdup(name)) == NULL((void *)0)) {
867 log_warn("%s", __func__);
868 free(nfile);
869 return (NULL((void *)0));
870 }
871 if ((nfile->stream = fopen(nfile->name, "r")) == NULL((void *)0)) {
872 free(nfile->name);
873 free(nfile);
874 return (NULL((void *)0));
875 }
876 nfile->lineno = TAILQ_EMPTY(&files)(((&files)->tqh_first) == ((void *)0)) ? 1 : 0;
877 nfile->ungetsize = 16;
878 nfile->ungetbuf = malloc(nfile->ungetsize);
879 if (nfile->ungetbuf == NULL((void *)0)) {
880 log_warn("%s", __func__);
881 fclose(nfile->stream);
882 free(nfile->name);
883 free(nfile);
884 return (NULL((void *)0));
885 }
886 TAILQ_INSERT_TAIL(&files, nfile, entry)do { (nfile)->entry.tqe_next = ((void *)0); (nfile)->entry
.tqe_prev = (&files)->tqh_last; *(&files)->tqh_last
= (nfile); (&files)->tqh_last = &(nfile)->entry
.tqe_next; } while (0)
;
887 return (nfile);
888}
889
890int
891popfile(void)
892{
893 struct file *prev;
894
895 if ((prev = TAILQ_PREV(file, files, entry)(*(((struct files *)((file)->entry.tqe_prev))->tqh_last
))
) != NULL((void *)0))
896 prev->errors += file->errors;
897
898 TAILQ_REMOVE(&files, file, entry)do { if (((file)->entry.tqe_next) != ((void *)0)) (file)->
entry.tqe_next->entry.tqe_prev = (file)->entry.tqe_prev
; else (&files)->tqh_last = (file)->entry.tqe_prev;
*(file)->entry.tqe_prev = (file)->entry.tqe_next; ; ; }
while (0)
;
899 fclose(file->stream);
900 free(file->name);
901 free(file->ungetbuf);
902 free(file);
903 file = prev;
904 return (file ? 0 : EOF(-1));
905}
906
907int
908parse_config(const char *filename)
909{
910 struct sym *sym, *next;
911
912 if ((file = pushfile(filename, 0)) == NULL((void *)0)) {
913 log_warn("failed to open %s", filename);
914 if (errno(*__errno()) == ENOENT2)
915 return (0);
916 return (-1);
917 }
918 topfile = file;
919 setservent(1);
920
921 /* Set the default switch type */
922 (void)strlcpy(vsw_type, VMD_SWITCH_TYPE"bridge", sizeof(vsw_type));
923
924 yyparse();
925 errors = file->errors;
926 popfile();
927
928 endservent();
929
930 /* Free macros and check which have not been used. */
931 TAILQ_FOREACH_SAFE(sym, &symhead, entry, next)for ((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0) && ((next) = ((sym)->entry.tqe_next), 1); (sym
) = (next))
{
932 if (!sym->used)
933 fprintf(stderr(&__sF[2]), "warning: macro '%s' not "
934 "used\n", sym->nam);
935 if (!sym->persist) {
936 free(sym->nam);
937 free(sym->val);
938 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
939 free(sym);
940 }
941 }
942
943 if (errors)
944 return (-1);
945
946 return (0);
947}
948
949int
950symset(const char *nam, const char *val, int persist)
951{
952 struct sym *sym;
953
954 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0); (sym) = ((sym)->entry.tqe_next))
{
955 if (strcmp(nam, sym->nam) == 0)
956 break;
957 }
958
959 if (sym != NULL((void *)0)) {
960 if (sym->persist == 1)
961 return (0);
962 else {
963 free(sym->nam);
964 free(sym->val);
965 TAILQ_REMOVE(&symhead, sym, entry)do { if (((sym)->entry.tqe_next) != ((void *)0)) (sym)->
entry.tqe_next->entry.tqe_prev = (sym)->entry.tqe_prev;
else (&symhead)->tqh_last = (sym)->entry.tqe_prev;
*(sym)->entry.tqe_prev = (sym)->entry.tqe_next; ; ; } while
(0)
;
966 free(sym);
967 }
968 }
969 if ((sym = calloc(1, sizeof(*sym))) == NULL((void *)0))
970 return (-1);
971
972 sym->nam = strdup(nam);
973 if (sym->nam == NULL((void *)0)) {
974 free(sym);
975 return (-1);
976 }
977 sym->val = strdup(val);
978 if (sym->val == NULL((void *)0)) {
979 free(sym->nam);
980 free(sym);
981 return (-1);
982 }
983 sym->used = 0;
984 sym->persist = persist;
985 TAILQ_INSERT_TAIL(&symhead, sym, entry)do { (sym)->entry.tqe_next = ((void *)0); (sym)->entry.
tqe_prev = (&symhead)->tqh_last; *(&symhead)->tqh_last
= (sym); (&symhead)->tqh_last = &(sym)->entry.
tqe_next; } while (0)
;
986 return (0);
987}
988
989int
990cmdline_symset(char *s)
991{
992 char *sym, *val;
993 int ret;
994
995 if ((val = strrchr(s, '=')) == NULL((void *)0))
996 return (-1);
997 sym = strndup(s, val - s);
998 if (sym == NULL((void *)0))
999 fatal("%s: strndup", __func__);
1000 ret = symset(sym, val + 1, 1);
1001 free(sym);
1002
1003 return (ret);
1004}
1005
1006char *
1007symget(const char *nam)
1008{
1009 struct sym *sym;
1010
1011 TAILQ_FOREACH(sym, &symhead, entry)for((sym) = ((&symhead)->tqh_first); (sym) != ((void *
)0); (sym) = ((sym)->entry.tqe_next))
{
1012 if (strcmp(nam, sym->nam) == 0) {
1013 sym->used = 1;
1014 return (sym->val);
1015 }
1016 }
1017 return (NULL((void *)0));
1018}
1019
1020ssize_t
1021parse_size(char *word, int64_t val)
1022{
1023 ssize_t size;
1024 long long res;
1025
1026 if (word != NULL((void *)0)) {
1027 if (scan_scaled(word, &res) != 0) {
1028 log_warn("invalid size: %s", word);
1029 return (-1);
1030 }
1031 val = (int64_t)res;
1032 }
1033
1034 if (val < (1024 * 1024)) {
1035 log_warnx("size must be at least one megabyte");
1036 return (-1);
1037 } else
1038 size = val / 1024 / 1024;
1039
1040 if ((size * 1024 * 1024) != val)
1041 log_warnx("size rounded to %zd megabytes", size);
1042
1043 return ((ssize_t)size);
1044}
1045
1046int
1047parse_disk(char *word, int type)
1048{
1049 char buf[BUFSIZ1024], path[PATH_MAX1024];
1050 int fd;
1051 ssize_t len;
1052
1053 if (vcp->vcp_ndisks >= VMM_MAX_DISKS_PER_VM4) {
1054 log_warnx("too many disks");
1055 return (-1);
1056 }
1057
1058 if (realpath(word, path) == NULL((void *)0)) {
1059 log_warn("disk %s", word);
1060 return (-1);
1061 }
1062
1063 if (!type) {
1064 /* Use raw as the default format */
1065 type = VMDF_RAW0x01;
1066
1067 /* Try to derive the format from the file signature */
1068 if ((fd = open(path, O_RDONLY0x0000)) != -1) {
1069 len = read(fd, buf, sizeof(buf));
1070 close(fd);
1071 if (len >= (ssize_t)strlen(VM_MAGIC_QCOW"QFI\xfb") &&
1072 strncmp(buf, VM_MAGIC_QCOW"QFI\xfb",
1073 strlen(VM_MAGIC_QCOW"QFI\xfb")) == 0) {
1074 /* The qcow version will be checked later */
1075 type = VMDF_QCOW20x02;
1076 }
1077 }
1078 }
1079
1080 if (strlcpy(vcp->vcp_disks[vcp->vcp_ndisks], path,
1081 VMM_MAX_PATH_DISK128) >= VMM_MAX_PATH_DISK128) {
1082 log_warnx("disk path too long");
1083 return (-1);
1084 }
1085 vmc.vmc_disktypes[vcp->vcp_ndisks] = type;
1086
1087 vcp->vcp_ndisks++;
1088
1089 return (0);
1090}
1091
1092unsigned int
1093parse_format(const char *word)
1094{
1095 if (strcasecmp(word, "raw") == 0)
1096 return (VMDF_RAW0x01);
1097 else if (strcasecmp(word, "qcow2") == 0)
1098 return (VMDF_QCOW20x02);
1099 return (0);
1100}
1101
1102int
1103host(const char *str, struct address *h)
1104{
1105 struct addrinfo hints, *res;
1106 int prefixlen;
1107 char *s, *p;
1108 const char *errstr;
1109
1110 if ((s = strdup(str)) == NULL((void *)0)) {
1111 log_warn("%s", __func__);
1112 goto fail;
1113 }
1114
1115 if ((p = strrchr(s, '/')) != NULL((void *)0)) {
1116 *p++ = '\0';
1117 prefixlen = strtonum(p, 0, 128, &errstr);
1118 if (errstr) {
1119 log_warnx("prefixlen is %s: %s", errstr, p);
1120 goto fail;
1121 }
1122 } else
1123 prefixlen = 128;
1124
1125 memset(&hints, 0, sizeof(hints));
1126 hints.ai_family = AF_UNSPEC0;
1127 hints.ai_flags = AI_NUMERICHOST4;
1128 if (getaddrinfo(s, NULL((void *)0), &hints, &res) == 0) {
1129 memset(h, 0, sizeof(*h));
1130 memcpy(&h->ss, res->ai_addr, res->ai_addrlen);
1131 h->prefixlen = prefixlen;
1132 freeaddrinfo(res);
1133 free(s);
1134 return (0);
1135 }
1136
1137 fail:
1138 free(s);
1139 return (-1);
1140}
1141#line 1134 "parse.c"
1142/* allocate initial stack or double stack size, up to YYMAXDEPTH */
1143static int yygrowstack(void)
1144{
1145 unsigned int newsize;
1146 long sslen;
1147 short *newss;
1148 YYSTYPE *newvs;
1149
1150 if ((newsize = yystacksize) == 0)
22
Assuming the condition is false
23
Taking false branch
1151 newsize = YYINITSTACKSIZE200;
1152 else if (newsize >= YYMAXDEPTH10000)
24
Assuming 'newsize' is < YYMAXDEPTH
25
Taking false branch
1153 return -1;
1154 else if ((newsize *= 2) > YYMAXDEPTH10000)
26
Assuming the condition is false
27
Taking false branch
1155 newsize = YYMAXDEPTH10000;
1156 sslen = yyssp - yyss;
1157#ifdef SIZE_MAX0xffffffffffffffffUL
1158#define YY_SIZE_MAX0xffffffffffffffffUL SIZE_MAX0xffffffffffffffffUL
1159#else
1160#define YY_SIZE_MAX0xffffffffffffffffUL 0xffffffffU
1161#endif
1162 if (newsize && YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newss)
28
Assuming 'newsize' is 0
1163 goto bail;
1164 newss = (short *)realloc(yyss, newsize * sizeof *newss);
1165 if (newss == NULL((void *)0))
29
Assuming 'newss' is not equal to NULL
30
Taking false branch
1166 goto bail;
1167 yyss = newss;
1168 yyssp = newss + sslen;
1169 if (newsize
30.1
'newsize' is 0
&& YY_SIZE_MAX0xffffffffffffffffUL / newsize < sizeof *newvs)
1170 goto bail;
1171 newvs = (YYSTYPE *)realloc(yyvs, newsize * sizeof *newvs);
1172 if (newvs == NULL((void *)0))
31
Assuming 'newvs' is not equal to NULL
32
Taking false branch
1173 goto bail;
1174 yyvs = newvs;
1175 yyvsp = newvs + sslen;
1176 yystacksize = newsize;
1177 yysslim = yyss + newsize - 1;
1178 return 0;
1179bail:
1180 if (yyss)
1181 free(yyss);
1182 if (yyvs)
1183 free(yyvs);
1184 yyss = yyssp = NULL((void *)0);
1185 yyvs = yyvsp = NULL((void *)0);
1186 yystacksize = 0;
1187 return -1;
1188}
1189
1190#define YYABORTgoto yyabort goto yyabort
1191#define YYREJECTgoto yyabort goto yyabort
1192#define YYACCEPTgoto yyaccept goto yyaccept
1193#define YYERRORgoto yyerrlab goto yyerrlab
1194int
1195yyparse(void)
1196{
1197 int yym, yyn, yystate;
1198#if YYDEBUG0
1199 const char *yys;
1200
1201 if ((yys = getenv("YYDEBUG")))
1202 {
1203 yyn = *yys;
1204 if (yyn >= '0' && yyn <= '9')
1205 yydebug = yyn - '0';
1206 }
1207#endif /* YYDEBUG */
1208
1209 yynerrs = 0;
1210 yyerrflag = 0;
1211 yychar = (-1);
1212
1213 if (yyss == NULL((void *)0) && yygrowstack()) goto yyoverflow;
1
Assuming 'yyss' is not equal to NULL
1214 yyssp = yyss;
1215 yyvsp = yyvs;
1216 *yyssp = yystate = 0;
1217
1218yyloop:
1219 if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
2
Taking true branch
3
Control jumps to line 1326
13
Taking false branch
1220 if (yychar
13.1
'yychar' is >= 0
< 0)
14
Taking false branch
1221 {
1222 if ((yychar = yylex()) < 0) yychar = 0;
1223#if YYDEBUG0
1224 if (yydebug)
1225 {
1226 yys = 0;
1227 if (yychar <= YYMAXTOKEN294) yys = yyname[yychar];
1228 if (!yys) yys = "illegal-symbol";
1229 printf("%sdebug: state %d, reading %d (%s)\n",
1230 YYPREFIX"yy", yystate, yychar, yys);
1231 }
1232#endif
1233 }
1234 if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
15
Assuming 'yyn' is not equal to 0
16
Assuming the condition is true
19
Taking true branch
1235 yyn <= YYTABLESIZE586 && yycheck[yyn] == yychar)
17
Assuming 'yyn' is <= YYTABLESIZE
18
Assuming the condition is true
1236 {
1237#if YYDEBUG0
1238 if (yydebug)
1239 printf("%sdebug: state %d, shifting to state %d\n",
1240 YYPREFIX"yy", yystate, yytable[yyn]);
1241#endif
1242 if (yyssp >= yysslim && yygrowstack())
20
Assuming 'yyssp' is >= 'yysslim'
21
Calling 'yygrowstack'
33
Returning from 'yygrowstack'
34
Taking false branch
1243 {
1244 goto yyoverflow;
1245 }
1246 *++yyssp = yystate = yytable[yyn];
35
Use of zero-allocated memory
1247 *++yyvsp = yylval;
1248 yychar = (-1);
1249 if (yyerrflag > 0) --yyerrflag;
1250 goto yyloop;
1251 }
1252 if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
1253 yyn <= YYTABLESIZE586 && yycheck[yyn] == yychar)
1254 {
1255 yyn = yytable[yyn];
1256 goto yyreduce;
1257 }
1258 if (yyerrflag) goto yyinrecovery;
1259#if defined(__GNUC__4)
1260 goto yynewerror;
1261#endif
1262yynewerror:
1263 yyerror("syntax error");
1264#if defined(__GNUC__4)
1265 goto yyerrlab;
1266#endif
1267yyerrlab:
1268 ++yynerrs;
1269yyinrecovery:
1270 if (yyerrflag < 3)
1271 {
1272 yyerrflag = 3;
1273 for (;;)
1274 {
1275 if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE256) >= 0 &&
1276 yyn <= YYTABLESIZE586 && yycheck[yyn] == YYERRCODE256)
1277 {
1278#if YYDEBUG0
1279 if (yydebug)
1280 printf("%sdebug: state %d, error recovery shifting\
1281 to state %d\n", YYPREFIX"yy", *yyssp, yytable[yyn]);
1282#endif
1283 if (yyssp >= yysslim && yygrowstack())
1284 {
1285 goto yyoverflow;
1286 }
1287 *++yyssp = yystate = yytable[yyn];
1288 *++yyvsp = yylval;
1289 goto yyloop;
1290 }
1291 else
1292 {
1293#if YYDEBUG0
1294 if (yydebug)
1295 printf("%sdebug: error recovery discarding state %d\n",
1296 YYPREFIX"yy", *yyssp);
1297#endif
1298 if (yyssp <= yyss) goto yyabort;
1299 --yyssp;
1300 --yyvsp;
1301 }
1302 }
1303 }
1304 else
1305 {
1306 if (yychar == 0) goto yyabort;
1307#if YYDEBUG0
1308 if (yydebug)
1309 {
1310 yys = 0;
1311 if (yychar <= YYMAXTOKEN294) yys = yyname[yychar];
1312 if (!yys) yys = "illegal-symbol";
1313 printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
1314 YYPREFIX"yy", yystate, yychar, yys);
1315 }
1316#endif
1317 yychar = (-1);
1318 goto yyloop;
1319 }
1320yyreduce:
1321#if YYDEBUG0
1322 if (yydebug)
1323 printf("%sdebug: state %d, reducing by rule %d (%s)\n",
1324 YYPREFIX"yy", yystate, yyn, yyrule[yyn]);
1325#endif
1326 yym = yylen[yyn];
1327 if (yym
3.1
'yym' is 0
)
4
Taking false branch
1328 yyval = yyvsp[1-yym];
1329 else
1330 memset(&yyval, 0, sizeof yyval);
1331 switch (yyn)
5
'Default' branch taken. Execution continues on line 2023
1332 {
1333case 8:
1334#line 149 "/usr/src/usr.sbin/vmd/parse.y"
1335{ file->errors++; }
1336break;
1337case 9:
1338#line 152 "/usr/src/usr.sbin/vmd/parse.y"
1339{
1340 struct file *nfile;
1341
1342 if ((nfile = pushfile(yyvsp[0].v.string, 0)) == NULL((void *)0)) {
1343 yyerror("failed to include file %s", yyvsp[0].v.string);
1344 free(yyvsp[0].v.string);
1345 YYERRORgoto yyerrlab;
1346 }
1347 free(yyvsp[0].v.string);
1348
1349 file = nfile;
1350 lungetc('\n');
1351 }
1352break;
1353case 10:
1354#line 167 "/usr/src/usr.sbin/vmd/parse.y"
1355{
1356 char *s = yyvsp[-2].v.string;
1357 while (*s++) {
1358 if (isspace((unsigned char)*s)) {
1359 yyerror("macro name cannot contain "
1360 "whitespace");
1361 free(yyvsp[-2].v.string);
1362 free(yyvsp[0].v.string);
1363 YYERRORgoto yyerrlab;
1364 }
1365 }
1366 if (symset(yyvsp[-2].v.string, yyvsp[0].v.string, 0) == -1)
1367 fatalx("cannot store variable");
1368 free(yyvsp[-2].v.string);
1369 free(yyvsp[0].v.string);
1370 }
1371break;
1372case 11:
1373#line 185 "/usr/src/usr.sbin/vmd/parse.y"
1374{
1375 env->vmd_cfg.cfg_flags |= VMD_CFG_INET60x01;
1376 }
1377break;
1378case 12:
1379#line 188 "/usr/src/usr.sbin/vmd/parse.y"
1380{
1381 struct address h;
1382
1383 if (host(yyvsp[0].v.string, &h) == -1 ||
1384 h.ss.ss_family != AF_INET624 ||
1385 h.prefixlen > 64 || h.prefixlen < 0) {
1386 yyerror("invalid local inet6 prefix: %s", yyvsp[0].v.string);
1387 free(yyvsp[0].v.string);
1388 YYERRORgoto yyerrlab;
1389 }
1390
1391 env->vmd_cfg.cfg_flags |= VMD_CFG_INET60x01;
1392 env->vmd_cfg.cfg_flags &= ~VMD_CFG_AUTOINET60x02;
1393 memcpy(&env->vmd_cfg.cfg_localprefix6, &h, sizeof(h));
1394 }
1395break;
1396case 13:
1397#line 203 "/usr/src/usr.sbin/vmd/parse.y"
1398{
1399 struct address h;
1400
1401 if (host(yyvsp[0].v.string, &h) == -1 ||
1402 h.ss.ss_family != AF_INET2 ||
1403 h.prefixlen > 32 || h.prefixlen < 0) {
1404 yyerror("invalid local prefix: %s", yyvsp[0].v.string);
1405 free(yyvsp[0].v.string);
1406 YYERRORgoto yyerrlab;
1407 }
1408
1409 memcpy(&env->vmd_cfg.cfg_localprefix, &h, sizeof(h));
1410 }
1411break;
1412case 14:
1413#line 216 "/usr/src/usr.sbin/vmd/parse.y"
1414{
1415 env->vmd_ps.ps_csock.cs_uid = yyvsp[0].v.owner.uid;
1416 env->vmd_ps.ps_csock.cs_gid = yyvsp[0].v.owner.gid == -1 ? 0 : yyvsp[0].v.owner.gid;
1417 }
1418break;
1419case 15:
1420#line 220 "/usr/src/usr.sbin/vmd/parse.y"
1421{
1422 env->vmd_cfg.cfg_flags |= VMD_CFG_STAGGERED_START0x04;
1423 env->vmd_cfg.delay.tv_sec = yyvsp[0].v.number;
1424 env->vmd_cfg.parallelism = yyvsp[-2].v.number;
1425 }
1426break;
1427case 16:
1428#line 227 "/usr/src/usr.sbin/vmd/parse.y"
1429{
1430 if ((vsw = calloc(1, sizeof(*vsw))) == NULL((void *)0))
1431 fatal("could not allocate switch");
1432
1433 vsw->sw_id = env->vmd_nswitches + 1;
1434 vsw->sw_name = yyvsp[0].v.string;
1435 vsw->sw_flags = VMIFF_UP0x01;
1436
1437 vcp_disable = 0;
1438 }
1439break;
1440case 17:
1441#line 236 "/usr/src/usr.sbin/vmd/parse.y"
1442{
1443 if (strnlen(vsw->sw_ifname,
1444 sizeof(vsw->sw_ifname)) == 0) {
1445 yyerror("switch \"%s\" "
1446 "is missing interface name",
1447 vsw->sw_name);
1448 YYERRORgoto yyerrlab;
1449 }
1450
1451 if (vcp_disable) {
1452 log_debug("%s:%d: switch \"%s\""
1453 " skipped (disabled)",
1454 file->name, yylval.lineno, vsw->sw_name);
1455 } else if (!env->vmd_noaction) {
1456 TAILQ_INSERT_TAIL(env->vmd_switches,do { (vsw)->sw_entry.tqe_next = ((void *)0); (vsw)->sw_entry
.tqe_prev = (env->vmd_switches)->tqh_last; *(env->vmd_switches
)->tqh_last = (vsw); (env->vmd_switches)->tqh_last =
&(vsw)->sw_entry.tqe_next; } while (0)
1457 vsw, sw_entry)do { (vsw)->sw_entry.tqe_next = ((void *)0); (vsw)->sw_entry
.tqe_prev = (env->vmd_switches)->tqh_last; *(env->vmd_switches
)->tqh_last = (vsw); (env->vmd_switches)->tqh_last =
&(vsw)->sw_entry.tqe_next; } while (0)
;
1458 env->vmd_nswitches++;
1459 log_debug("%s:%d: switch \"%s\" registered",
1460 file->name, yylval.lineno, vsw->sw_name);
1461 }
1462 }
1463break;
1464case 20:
1465#line 263 "/usr/src/usr.sbin/vmd/parse.y"
1466{
1467 vcp_disable = yyvsp[0].v.number;
1468 }
1469break;
1470case 21:
1471#line 266 "/usr/src/usr.sbin/vmd/parse.y"
1472{
1473 if (priv_validgroup(yyvsp[0].v.string) == -1) {
1474 yyerror("invalid group name: %s", yyvsp[0].v.string);
1475 free(yyvsp[0].v.string);
1476 YYERRORgoto yyerrlab;
1477 }
1478 vsw->sw_group = yyvsp[0].v.string;
1479 }
1480break;
1481case 22:
1482#line 274 "/usr/src/usr.sbin/vmd/parse.y"
1483{
1484 if (priv_getiftype(yyvsp[0].v.string, vsw_type, NULL((void *)0)) == -1 ||
1485 priv_findname(vsw_type, vmd_descsw) == -1) {
1486 yyerror("invalid switch interface: %s", yyvsp[0].v.string);
1487 free(yyvsp[0].v.string);
1488 YYERRORgoto yyerrlab;
1489 }
1490
1491 if (strlcpy(vsw->sw_ifname, yyvsp[0].v.string,
1492 sizeof(vsw->sw_ifname)) >= sizeof(vsw->sw_ifname)) {
1493 yyerror("switch interface too long: %s", yyvsp[0].v.string);
1494 free(yyvsp[0].v.string);
1495 YYERRORgoto yyerrlab;
1496 }
1497 free(yyvsp[0].v.string);
1498 }
1499break;
1500case 23:
1501#line 290 "/usr/src/usr.sbin/vmd/parse.y"
1502{
1503 vsw->sw_flags |= VMIFF_LOCKED0x02;
1504 }
1505break;
1506case 24:
1507#line 293 "/usr/src/usr.sbin/vmd/parse.y"
1508{
1509 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RT_TABLEID_MAX255) {
1510 yyerror("invalid rdomain: %lld", yyvsp[0].v.number);
1511 YYERRORgoto yyerrlab;
1512 }
1513 vsw->sw_flags |= VMIFF_RDOMAIN0x08;
1514 vsw->sw_rdomain = yyvsp[0].v.number;
1515 }
1516break;
1517case 25:
1518#line 301 "/usr/src/usr.sbin/vmd/parse.y"
1519{
1520 if (yyvsp[0].v.number)
1521 vsw->sw_flags |= VMIFF_UP0x01;
1522 else
1523 vsw->sw_flags &= ~VMIFF_UP0x01;
1524 }
1525break;
1526case 26:
1527#line 309 "/usr/src/usr.sbin/vmd/parse.y"
1528{
1529 unsigned int i;
1530 char *name;
1531
1532 memset(&vmc, 0, sizeof(vmc));
1533 vcp = &vmc.vmc_params;
1534 vcp_disable = 0;
1535 vcp_nnics = 0;
1536
1537 if (yyvsp[0].v.string != NULL((void *)0)) {
1538 /* This is an instance of a pre-configured VM */
1539 if (strlcpy(vmc.vmc_instance, yyvsp[-1].v.string,
1540 sizeof(vmc.vmc_instance)) >=
1541 sizeof(vmc.vmc_instance)) {
1542 yyerror("vm %s name too long", yyvsp[-1].v.string);
1543 free(yyvsp[-1].v.string);
1544 free(yyvsp[0].v.string);
1545 YYERRORgoto yyerrlab;
1546 }
1547
1548 free(yyvsp[-1].v.string);
1549 name = yyvsp[0].v.string;
1550 vmc.vmc_flags |= VMOP_CREATE_INSTANCE0x40;
1551 } else
1552 name = yyvsp[-1].v.string;
1553
1554 for (i = 0; i < VMM_MAX_NICS_PER_VM4; i++) {
1555 /* Set the interface to UP by default */
1556 vmc.vmc_ifflags[i] |= IFF_UP0x1;
1557 }
1558
1559 if (strlcpy(vcp->vcp_name, name,
1560 sizeof(vcp->vcp_name)) >= sizeof(vcp->vcp_name)) {
1561 yyerror("vm name too long");
1562 free(yyvsp[-1].v.string);
1563 free(yyvsp[0].v.string);
1564 YYERRORgoto yyerrlab;
1565 }
1566
1567 /* set default user/group permissions */
1568 vmc.vmc_owner.uid = 0;
1569 vmc.vmc_owner.gid = -1;
1570 }
1571break;
1572case 27:
1573#line 351 "/usr/src/usr.sbin/vmd/parse.y"
1574{
1575 struct vmd_vm *vm;
1576 int ret;
1577
1578 /* configured interfaces vs. number of interfaces */
1579 if (vcp_nnics > vcp->vcp_nnics)
1580 vcp->vcp_nnics = vcp_nnics;
1581
1582 if (!env->vmd_noaction) {
1583 ret = vm_register(&env->vmd_ps, &vmc,
1584 &vm, 0, 0);
1585 if (ret == -1 && errno(*__errno()) == EALREADY37) {
1586 log_debug("%s:%d: vm \"%s\""
1587 " skipped (%s)",
1588 file->name, yylval.lineno,
1589 vcp->vcp_name,
1590 (vm->vm_state & VM_STATE_RUNNING0x01) ?
1591 "running" : "already exists");
1592 } else if (ret == -1) {
1593 yyerror("vm \"%s\" failed: %s",
1594 vcp->vcp_name, strerror(errno(*__errno())));
1595 YYERRORgoto yyerrlab;
1596 } else {
1597 if (vcp_disable)
1598 vm->vm_state |= VM_STATE_DISABLED0x02;
1599 else
1600 vm->vm_state |= VM_STATE_WAITING0x20;
1601 log_debug("%s:%d: vm \"%s\" "
1602 "registered (%s)",
1603 file->name, yylval.lineno,
1604 vcp->vcp_name,
1605 vcp_disable ?
1606 "disabled" : "enabled");
1607 }
1608 vm->vm_from_config = 1;
1609 }
1610 }
1611break;
1612case 28:
1613#line 390 "/usr/src/usr.sbin/vmd/parse.y"
1614{ yyval.v.string = NULL((void *)0); }
1615break;
1616case 29:
1617#line 391 "/usr/src/usr.sbin/vmd/parse.y"
1618{ yyval.v.string = yyvsp[0].v.string; }
1619break;
1620case 32:
1621#line 398 "/usr/src/usr.sbin/vmd/parse.y"
1622{
1623 vcp_disable = yyvsp[0].v.number;
1624 }
1625break;
1626case 33:
1627#line 401 "/usr/src/usr.sbin/vmd/parse.y"
1628{
1629 if (parse_disk(yyvsp[-1].v.string, yyvsp[0].v.number) != 0) {
1630 yyerror("failed to parse disks: %s", yyvsp[-1].v.string);
1631 free(yyvsp[-1].v.string);
1632 YYERRORgoto yyerrlab;
1633 }
1634 free(yyvsp[-1].v.string);
1635 vmc.vmc_flags |= VMOP_CREATE_DISK0x10;
1636 }
1637break;
1638case 34:
1639#line 410 "/usr/src/usr.sbin/vmd/parse.y"
1640{
1641 unsigned int i;
1642 char type[IF_NAMESIZE16];
1643
1644 i = vcp_nnics;
1645 if (++vcp_nnics > VMM_MAX_NICS_PER_VM4) {
1646 yyerror("too many interfaces: %zu", vcp_nnics);
1647 free(yyvsp[-1].v.string);
1648 YYERRORgoto yyerrlab;
1649 }
1650
1651 if (yyvsp[-3].v.number)
1652 vmc.vmc_ifflags[i] |= VMIFF_LOCAL0x04;
1653 if (yyvsp[-1].v.string != NULL((void *)0)) {
1654 if (strcmp(yyvsp[-1].v.string, "tap") != 0 &&
1655 (priv_getiftype(yyvsp[-1].v.string, type, NULL((void *)0)) == -1 ||
1656 strcmp(type, "tap") != 0)) {
1657 yyerror("invalid interface: %s", yyvsp[-1].v.string);
1658 free(yyvsp[-1].v.string);
1659 YYERRORgoto yyerrlab;
1660 }
1661
1662 if (strlcpy(vmc.vmc_ifnames[i], yyvsp[-1].v.string,
1663 sizeof(vmc.vmc_ifnames[i])) >=
1664 sizeof(vmc.vmc_ifnames[i])) {
1665 yyerror("interface name too long: %s",
1666 yyvsp[-1].v.string);
1667 free(yyvsp[-1].v.string);
1668 YYERRORgoto yyerrlab;
1669 }
1670 }
1671 free(yyvsp[-1].v.string);
1672 vmc.vmc_flags |= VMOP_CREATE_NETWORK0x08;
1673 }
1674break;
1675case 35:
1676#line 444 "/usr/src/usr.sbin/vmd/parse.y"
1677{
1678 char path[PATH_MAX1024];
1679
1680 if (vcp->vcp_kernel[0] != '\0') {
1681 yyerror("kernel specified more than once");
1682 free(yyvsp[0].v.string);
1683 YYERRORgoto yyerrlab;
1684
1685 }
1686 if (realpath(yyvsp[0].v.string, path) == NULL((void *)0)) {
1687 yyerror("kernel path not found: %s",
1688 strerror(errno(*__errno())));
1689 free(yyvsp[0].v.string);
1690 YYERRORgoto yyerrlab;
1691 }
1692 free(yyvsp[0].v.string);
1693 if (strlcpy(vcp->vcp_kernel, path,
1694 sizeof(vcp->vcp_kernel)) >=
1695 sizeof(vcp->vcp_kernel)) {
1696 yyerror("kernel name too long");
1697 YYERRORgoto yyerrlab;
1698 }
1699 vmc.vmc_flags |= VMOP_CREATE_KERNEL0x02;
1700 }
1701break;
1702case 36:
1703#line 468 "/usr/src/usr.sbin/vmd/parse.y"
1704{
1705 vmc.vmc_bootdevice = yyvsp[0].v.number;
1706 }
1707break;
1708case 37:
1709#line 471 "/usr/src/usr.sbin/vmd/parse.y"
1710{
1711 if (vcp->vcp_cdrom[0] != '\0') {
1712 yyerror("cdrom specified more than once");
1713 free(yyvsp[0].v.string);
1714 YYERRORgoto yyerrlab;
1715
1716 }
1717 if (strlcpy(vcp->vcp_cdrom, yyvsp[0].v.string,
1718 sizeof(vcp->vcp_cdrom)) >=
1719 sizeof(vcp->vcp_cdrom)) {
1720 yyerror("cdrom name too long");
1721 free(yyvsp[0].v.string);
1722 YYERRORgoto yyerrlab;
1723 }
1724 free(yyvsp[0].v.string);
1725 vmc.vmc_flags |= VMOP_CREATE_CDROM0x20;
1726 }
1727break;
1728case 38:
1729#line 488 "/usr/src/usr.sbin/vmd/parse.y"
1730{
1731 if (vcp->vcp_nnics != 0) {
1732 yyerror("interfaces specified more than once");
1733 YYERRORgoto yyerrlab;
1734 }
1735 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > VMM_MAX_NICS_PER_VM4) {
1736 yyerror("too many interfaces: %lld", yyvsp[0].v.number);
1737 YYERRORgoto yyerrlab;
1738 }
1739 vcp->vcp_nnics = (size_t)yyvsp[0].v.number;
1740 vmc.vmc_flags |= VMOP_CREATE_NETWORK0x08;
1741 }
1742break;
1743case 39:
1744#line 500 "/usr/src/usr.sbin/vmd/parse.y"
1745{
1746 ssize_t res;
1747 if (vcp->vcp_memranges[0].vmr_size != 0) {
1748 yyerror("memory specified more than once");
1749 YYERRORgoto yyerrlab;
1750 }
1751 if ((res = parse_size(NULL((void *)0), yyvsp[0].v.number)) == -1) {
1752 yyerror("failed to parse size: %lld", yyvsp[0].v.number);
1753 YYERRORgoto yyerrlab;
1754 }
1755 vcp->vcp_memranges[0].vmr_size = (size_t)res;
1756 vmc.vmc_flags |= VMOP_CREATE_MEMORY0x04;
1757 }
1758break;
1759case 40:
1760#line 513 "/usr/src/usr.sbin/vmd/parse.y"
1761{
1762 ssize_t res;
1763 if (vcp->vcp_memranges[0].vmr_size != 0) {
1764 yyerror("argument specified more than once");
1765 free(yyvsp[0].v.string);
1766 YYERRORgoto yyerrlab;
1767 }
1768 if ((res = parse_size(yyvsp[0].v.string, 0)) == -1) {
1769 yyerror("failed to parse size: %s", yyvsp[0].v.string);
1770 free(yyvsp[0].v.string);
1771 YYERRORgoto yyerrlab;
1772 }
1773 vcp->vcp_memranges[0].vmr_size = (size_t)res;
1774 vmc.vmc_flags |= VMOP_CREATE_MEMORY0x04;
1775 }
1776break;
1777case 41:
1778#line 528 "/usr/src/usr.sbin/vmd/parse.y"
1779{
1780 vmc.vmc_owner.uid = yyvsp[0].v.owner.uid;
1781 vmc.vmc_owner.gid = yyvsp[0].v.owner.gid;
1782 }
1783break;
1784case 47:
1785#line 543 "/usr/src/usr.sbin/vmd/parse.y"
1786{ vmc.vmc_insflags |= VMOP_CREATE_KERNEL0x02; }
1787break;
1788case 48:
1789#line 544 "/usr/src/usr.sbin/vmd/parse.y"
1790{ vmc.vmc_insflags |= VMOP_CREATE_MEMORY0x04; }
1791break;
1792case 49:
1793#line 545 "/usr/src/usr.sbin/vmd/parse.y"
1794{ vmc.vmc_insflags |= VMOP_CREATE_NETWORK0x08; }
1795break;
1796case 50:
1797#line 546 "/usr/src/usr.sbin/vmd/parse.y"
1798{ vmc.vmc_insflags |= VMOP_CREATE_DISK0x10; }
1799break;
1800case 51:
1801#line 547 "/usr/src/usr.sbin/vmd/parse.y"
1802{ vmc.vmc_insflags |= VMOP_CREATE_CDROM0x20; }
1803break;
1804case 52:
1805#line 548 "/usr/src/usr.sbin/vmd/parse.y"
1806{ vmc.vmc_insflags |= VMOP_CREATE_INSTANCE0x40; }
1807break;
1808case 53:
1809#line 549 "/usr/src/usr.sbin/vmd/parse.y"
1810{
1811 vmc.vmc_insowner.uid = yyvsp[0].v.owner.uid;
1812 vmc.vmc_insowner.gid = yyvsp[0].v.owner.gid;
1813 }
1814break;
1815case 54:
1816#line 555 "/usr/src/usr.sbin/vmd/parse.y"
1817{
1818 yyval.v.owner.uid = yyvsp[0].v.number;
1819 yyval.v.owner.gid = -1;
1820 }
1821break;
1822case 55:
1823#line 559 "/usr/src/usr.sbin/vmd/parse.y"
1824{
1825 char *user, *group;
1826 struct passwd *pw;
1827 struct group *gr;
1828
1829 yyval.v.owner.uid = 0;
1830 yyval.v.owner.gid = -1;
1831
1832 user = yyvsp[0].v.string;
1833 if ((group = strchr(user, ':')) != NULL((void *)0)) {
1834 if (group == user)
1835 user = NULL((void *)0);
1836 *group++ = '\0';
1837 }
1838
1839 if (user != NULL((void *)0) && *user) {
1840 if ((pw = getpwnam(user)) == NULL((void *)0)) {
1841 yyerror("failed to get user: %s",
1842 user);
1843 free(yyvsp[0].v.string);
1844 YYERRORgoto yyerrlab;
1845 }
1846 yyval.v.owner.uid = pw->pw_uid;
1847 }
1848
1849 if (group != NULL((void *)0) && *group) {
1850 if ((gr = getgrnam(group)) == NULL((void *)0)) {
1851 yyerror("failed to get group: %s",
1852 group);
1853 free(yyvsp[0].v.string);
1854 YYERRORgoto yyerrlab;
1855 }
1856 yyval.v.owner.gid = gr->gr_gid;
1857 }
1858
1859 free(yyvsp[0].v.string);
1860 }
1861break;
1862case 56:
1863#line 598 "/usr/src/usr.sbin/vmd/parse.y"
1864{
1865 yyval.v.number = 0;
1866 }
1867break;
1868case 57:
1869#line 601 "/usr/src/usr.sbin/vmd/parse.y"
1870{
1871 if ((yyval.v.number = parse_format(yyvsp[0].v.string)) == 0) {
1872 yyerror("unrecognized disk format %s", yyvsp[0].v.string);
1873 free(yyvsp[0].v.string);
1874 YYERRORgoto yyerrlab;
1875 }
1876 }
1877break;
1878case 65:
1879#line 623 "/usr/src/usr.sbin/vmd/parse.y"
1880{
1881 unsigned int i = vcp_nnics;
1882
1883 /* No need to check if the switch exists */
1884 if (strlcpy(vmc.vmc_ifswitch[i], yyvsp[0].v.string,
1885 sizeof(vmc.vmc_ifswitch[i])) >=
1886 sizeof(vmc.vmc_ifswitch[i])) {
1887 yyerror("switch name too long: %s", yyvsp[0].v.string);
1888 free(yyvsp[0].v.string);
1889 YYERRORgoto yyerrlab;
1890 }
1891 free(yyvsp[0].v.string);
1892 }
1893break;
1894case 66:
1895#line 636 "/usr/src/usr.sbin/vmd/parse.y"
1896{
1897 unsigned int i = vcp_nnics;
1898
1899 if (priv_validgroup(yyvsp[0].v.string) == -1) {
1900 yyerror("invalid group name: %s", yyvsp[0].v.string);
1901 free(yyvsp[0].v.string);
1902 YYERRORgoto yyerrlab;
1903 }
1904
1905 /* No need to check if the group exists */
1906 (void)strlcpy(vmc.vmc_ifgroup[i], yyvsp[0].v.string,
1907 sizeof(vmc.vmc_ifgroup[i]));
1908 free(yyvsp[0].v.string);
1909 }
1910break;
1911case 67:
1912#line 650 "/usr/src/usr.sbin/vmd/parse.y"
1913{
1914 if (yyvsp[-2].v.number)
1915 vmc.vmc_ifflags[vcp_nnics] |= VMIFF_LOCKED0x02;
1916 memcpy(vcp->vcp_macs[vcp_nnics], yyvsp[0].v.lladdr, ETHER_ADDR_LEN6);
1917 }
1918break;
1919case 68:
1920#line 655 "/usr/src/usr.sbin/vmd/parse.y"
1921{
1922 if (yyvsp[0].v.number < 0 || yyvsp[0].v.number > RT_TABLEID_MAX255) {
1923 yyerror("invalid rdomain: %lld", yyvsp[0].v.number);
1924 YYERRORgoto yyerrlab;
1925 }
1926 vmc.vmc_ifflags[vcp_nnics] |= VMIFF_RDOMAIN0x08;
1927 vmc.vmc_ifrdomain[vcp_nnics] = yyvsp[0].v.number;
1928 }
1929break;
1930case 69:
1931#line 663 "/usr/src/usr.sbin/vmd/parse.y"
1932{
1933 if (yyvsp[0].v.number)
1934 vmc.vmc_ifflags[vcp_nnics] |= VMIFF_UP0x01;
1935 else
1936 vmc.vmc_ifflags[vcp_nnics] &= ~VMIFF_UP0x01;
1937 }
1938break;
1939case 70:
1940#line 671 "/usr/src/usr.sbin/vmd/parse.y"
1941{ yyval.v.string = yyvsp[0].v.string; }
1942break;
1943case 71:
1944#line 672 "/usr/src/usr.sbin/vmd/parse.y"
1945{ yyval.v.string = NULL((void *)0); }
1946break;
1947case 72:
1948#line 675 "/usr/src/usr.sbin/vmd/parse.y"
1949{
1950 if (asprintf(&yyval.v.string, "%s%s", yyvsp[-1].v.string, yyvsp[0].v.string) == -1)
1951 fatal("asprintf string");
1952 free(yyvsp[-1].v.string);
1953 free(yyvsp[0].v.string);
1954 }
1955break;
1956case 74:
1957#line 684 "/usr/src/usr.sbin/vmd/parse.y"
1958{
1959 struct ether_addr *ea;
1960
1961 if ((ea = ether_aton(yyvsp[0].v.string)) == NULL((void *)0)) {
1962 yyerror("invalid address: %s\n", yyvsp[0].v.string);
1963 free(yyvsp[0].v.string);
1964 YYERRORgoto yyerrlab;
1965 }
1966 free(yyvsp[0].v.string);
1967
1968 memcpy(yyval.v.lladdr, ea, ETHER_ADDR_LEN6);
1969 }
1970break;
1971case 75:
1972#line 696 "/usr/src/usr.sbin/vmd/parse.y"
1973{
1974 memset(yyval.v.lladdr, 0, ETHER_ADDR_LEN6);
1975 }
1976break;
1977case 76:
1978#line 701 "/usr/src/usr.sbin/vmd/parse.y"
1979{ yyval.v.number = 0; }
1980break;
1981case 77:
1982#line 702 "/usr/src/usr.sbin/vmd/parse.y"
1983{ yyval.v.number = 1; }
1984break;
1985case 78:
1986#line 705 "/usr/src/usr.sbin/vmd/parse.y"
1987{ yyval.v.number = 0; }
1988break;
1989case 79:
1990#line 706 "/usr/src/usr.sbin/vmd/parse.y"
1991{ yyval.v.number = 1; }
1992break;
1993case 80:
1994#line 709 "/usr/src/usr.sbin/vmd/parse.y"
1995{ yyval.v.number = 1; }
1996break;
1997case 81:
1998#line 710 "/usr/src/usr.sbin/vmd/parse.y"
1999{ yyval.v.number = 0; }
2000break;
2001case 82:
2002#line 713 "/usr/src/usr.sbin/vmd/parse.y"
2003{ yyval.v.number = 0; }
2004break;
2005case 83:
2006#line 714 "/usr/src/usr.sbin/vmd/parse.y"
2007{ yyval.v.number = 1; }
2008break;
2009case 84:
2010#line 717 "/usr/src/usr.sbin/vmd/parse.y"
2011{ yyval.v.number = VMBOOTDEV_CDROM2; }
2012break;
2013case 85:
2014#line 718 "/usr/src/usr.sbin/vmd/parse.y"
2015{ yyval.v.number = VMBOOTDEV_DISK1; }
2016break;
2017case 86:
2018#line 719 "/usr/src/usr.sbin/vmd/parse.y"
2019{ yyval.v.number = VMBOOTDEV_NET3; }
2020break;
2021#line 2014 "parse.c"
2022 }
2023 yyssp -= yym;
2024 yystate = *yyssp;
2025 yyvsp -= yym;
2026 yym = yylhs[yyn];
2027 if (yystate
5.1
'yystate' is equal to 0
== 0 && yym
5.2
'yym' is equal to 0
== 0)
6
Taking true branch
2028 {
2029#if YYDEBUG0
2030 if (yydebug)
2031 printf("%sdebug: after reduction, shifting from state 0 to\
2032 state %d\n", YYPREFIX"yy", YYFINAL1);
2033#endif
2034 yystate = YYFINAL1;
2035 *++yyssp = YYFINAL1;
2036 *++yyvsp = yyval;
2037 if (yychar
6.1
'yychar' is < 0
< 0)
7
Taking true branch
2038 {
2039 if ((yychar = yylex()) < 0) yychar = 0;
8
Assuming the condition is false
9
Taking false branch
2040#if YYDEBUG0
2041 if (yydebug)
2042 {
2043 yys = 0;
2044 if (yychar <= YYMAXTOKEN294) yys = yyname[yychar];
2045 if (!yys) yys = "illegal-symbol";
2046 printf("%sdebug: state %d, reading %d (%s)\n",
2047 YYPREFIX"yy", YYFINAL1, yychar, yys);
2048 }
2049#endif
2050 }
2051 if (yychar == 0) goto yyaccept;
10
Assuming 'yychar' is not equal to 0
11
Taking false branch
2052 goto yyloop;
12
Control jumps to line 1219
2053 }
2054 if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
2055 yyn <= YYTABLESIZE586 && yycheck[yyn] == yystate)
2056 yystate = yytable[yyn];
2057 else
2058 yystate = yydgoto[yym];
2059#if YYDEBUG0
2060 if (yydebug)
2061 printf("%sdebug: after reduction, shifting from state %d \
2062to state %d\n", YYPREFIX"yy", *yyssp, yystate);
2063#endif
2064 if (yyssp >= yysslim && yygrowstack())
2065 {
2066 goto yyoverflow;
2067 }
2068 *++yyssp = yystate;
2069 *++yyvsp = yyval;
2070 goto yyloop;
2071yyoverflow:
2072 yyerror("yacc stack overflow");
2073yyabort:
2074 if (yyss)
2075 free(yyss);
2076 if (yyvs)
2077 free(yyvs);
2078 yyss = yyssp = NULL((void *)0);
2079 yyvs = yyvsp = NULL((void *)0);
2080 yystacksize = 0;
2081 return (1);
2082yyaccept:
2083 if (yyss)
2084 free(yyss);
2085 if (yyvs)
2086 free(yyvs);
2087 yyss = yyssp = NULL((void *)0);
2088 yyvs = yyvsp = NULL((void *)0);
2089 yystacksize = 0;
2090 return (0);
2091}