]>
Commit | Line | Data |
---|---|---|
0b69dcc8 | 1 | /* omshell.c |
d142e03f | 2 | |
4bce547e | 3 | Examine and modify omapi objects. */ |
d142e03f TL |
4 | |
5 | /* | |
9121bf67 | 6 | * Copyright (c) 2004-2020 by Internet Systems Consortium, Inc. ("ISC") |
98311e4b | 7 | * Copyright (c) 2001-2003 by Internet Software Consortium |
d142e03f | 8 | * |
7512d88b TM |
9 | * This Source Code Form is subject to the terms of the Mozilla Public |
10 | * License, v. 2.0. If a copy of the MPL was not distributed with this | |
11 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
d142e03f | 12 | * |
98311e4b DH |
13 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES |
14 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | |
15 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR | |
16 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | |
17 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | |
18 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | |
19 | * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |
d142e03f | 20 | * |
98311e4b | 21 | * Internet Systems Consortium, Inc. |
429a56d7 TM |
22 | * PO Box 360 |
23 | * Newmarket, NH 03857 USA | |
98311e4b | 24 | * <info@isc.org> |
2c85ac9b | 25 | * https://www.isc.org/ |
49733f31 | 26 | * |
d142e03f TL |
27 | */ |
28 | ||
d1f31a00 FD |
29 | #include "config.h" |
30 | ||
6a4c4be8 | 31 | #include <time.h> |
0f6bb7e1 | 32 | #include <sys/time.h> |
6a4c4be8 TL |
33 | #include <stdio.h> |
34 | #include <stdlib.h> | |
35 | #include <stdarg.h> | |
06f0ed06 | 36 | #include <string.h> |
98bf1607 | 37 | //#include "result.h" |
fe5b0fdd | 38 | #include <syslog.h> |
d142e03f | 39 | #include "dhcpctl.h" |
4bce547e | 40 | #include "dhcpd.h" |
7acd8753 | 41 | #include <isc/file.h> |
d142e03f | 42 | |
4bce547e TL |
43 | /* Fixups */ |
44 | isc_result_t find_class (struct class **c, const char *n, const char *f, int l) | |
45 | { | |
46 | return 0; | |
47 | } | |
48 | int parse_allow_deny (struct option_cache **oc, struct parse *cfile, int flag) | |
49 | { | |
50 | return 0; | |
51 | } | |
52 | void dhcp (struct packet *packet) { } | |
53 | void bootp (struct packet *packet) { } | |
98bd7ca0 | 54 | |
fe5b0fdd | 55 | #ifdef DHCPv6 |
98bd7ca0 DH |
56 | /* XXX: should we warn or something here? */ |
57 | void dhcpv6(struct packet *packet) { } | |
e4dcd805 FD |
58 | #ifdef DHCP4o6 |
59 | isc_result_t dhcpv4o6_handler(omapi_object_t *h) | |
60 | { | |
61 | return ISC_R_NOTIMPLEMENTED; | |
62 | } | |
63 | #endif /* DHCP4o6 */ | |
fe5b0fdd | 64 | #endif /* DHCPv6 */ |
98bd7ca0 | 65 | |
4bce547e TL |
66 | int check_collection (struct packet *p, struct lease *l, struct collection *c) |
67 | { | |
68 | return 0; | |
69 | } | |
70 | void classify (struct packet *packet, struct class *class) { } | |
d142e03f | 71 | |
7acd8753 | 72 | static void usage (const char *s) { |
d758ad8c | 73 | fprintf (stderr, "Usage: %s\n", s); |
58941de4 DN |
74 | exit (1); |
75 | } | |
76 | ||
031d30b7 DN |
77 | static void check (isc_result_t status, const char *func) { |
78 | if (status != ISC_R_SUCCESS) { | |
79 | fprintf (stderr, "%s: %s\n", func, isc_result_totext (status)); | |
80 | exit (1); | |
81 | } | |
82 | } | |
83 | ||
f6b8f48d | 84 | int |
98bd7ca0 | 85 | main(int argc, char **argv) { |
d142e03f TL |
86 | isc_result_t status, waitstatus; |
87 | dhcpctl_handle connection; | |
58941de4 | 88 | dhcpctl_handle authenticator; |
4bce547e | 89 | dhcpctl_handle oh; |
f27f6d6c TL |
90 | struct data_string secret; |
91 | const char *name = 0, *algorithm = "hmac-md5"; | |
28868515 | 92 | int i; |
4bce547e TL |
93 | int port = 7911; |
94 | const char *server = "127.0.0.1"; | |
95 | struct parse *cfile; | |
96 | enum dhcp_token token; | |
97 | const char *val; | |
f27f6d6c | 98 | char *s; |
031d30b7 DN |
99 | char buf[1024]; |
100 | char s1[1024]; | |
f27f6d6c | 101 | int connected = 0; |
786f2e79 | 102 | char hex_buf[1025]; |
7acd8753 FD |
103 | char *progname; |
104 | ||
105 | #ifdef OLD_LOG_NAME | |
106 | progname = "omshell"; | |
107 | #else | |
108 | progname = argv[0]; | |
109 | #endif | |
d142e03f | 110 | |
58941de4 | 111 | for (i = 1; i < argc; i++) { |
7acd8753 | 112 | usage(isc_file_basename(progname)); |
f27f6d6c | 113 | } |
58941de4 | 114 | |
31bbee78 | 115 | /* Initially, log errors to stderr as well as to syslogd. */ |
7acd8753 FD |
116 | openlog (isc_file_basename(progname), |
117 | DHCP_LOG_OPTIONS, DHCPD_LOG_FACILITY); | |
d142e03f TL |
118 | status = dhcpctl_initialize (); |
119 | if (status != ISC_R_SUCCESS) { | |
120 | fprintf (stderr, "dhcpctl_initialize: %s\n", | |
121 | isc_result_totext (status)); | |
122 | exit (1); | |
123 | } | |
124 | ||
4bce547e TL |
125 | memset (&oh, 0, sizeof oh); |
126 | ||
4bce547e | 127 | do { |
f27f6d6c TL |
128 | if (!connected) { |
129 | } else if (oh == NULL) { | |
130 | printf ("obj: <null>\n"); | |
131 | } else { | |
132 | dhcpctl_remote_object_t *r = (dhcpctl_remote_object_t *)oh; | |
133 | omapi_generic_object_t *g = | |
134 | (omapi_generic_object_t *)(r -> inner); | |
f6b8f48d | 135 | |
031d30b7 | 136 | printf ("obj: "); |
031d30b7 | 137 | |
f27f6d6c TL |
138 | if (r -> rtype -> type != omapi_datatype_string) { |
139 | printf ("?\n"); | |
140 | } else { | |
141 | printf ("%.*s\n", | |
142 | (int)(r -> rtype -> u . buffer . len), | |
143 | r -> rtype -> u . buffer . value); | |
144 | } | |
f6b8f48d | 145 | |
f27f6d6c TL |
146 | for (i = 0; i < g -> nvalues; i++) { |
147 | omapi_value_t *v = g -> values [i]; | |
f6b8f48d | 148 | |
d758ad8c TL |
149 | if (!g -> values [i]) |
150 | continue; | |
151 | ||
f27f6d6c TL |
152 | printf ("%.*s = ", (int)v -> name -> len, |
153 | v -> name -> value); | |
f6b8f48d | 154 | |
d758ad8c TL |
155 | if (!v -> value) { |
156 | printf ("<null>\n"); | |
157 | continue; | |
158 | } | |
f27f6d6c TL |
159 | switch (v -> value -> type) { |
160 | case omapi_datatype_int: | |
161 | printf ("%d\n", | |
162 | v -> value -> u . integer); | |
163 | break; | |
f6b8f48d | 164 | |
f27f6d6c TL |
165 | case omapi_datatype_string: |
166 | printf ("\"%.*s\"\n", | |
167 | (int) v -> value -> u.buffer.len, | |
168 | v -> value -> u.buffer.value); | |
169 | break; | |
f6b8f48d | 170 | |
f27f6d6c | 171 | case omapi_datatype_data: |
39196512 SR |
172 | print_hex_or_string(v->value->u.buffer.len, |
173 | v->value->u.buffer.value, | |
174 | sizeof(hex_buf), hex_buf); | |
6aaaf6a4 | 175 | printf("%s\n", hex_buf); |
f27f6d6c | 176 | break; |
f6b8f48d | 177 | |
f27f6d6c TL |
178 | case omapi_datatype_object: |
179 | printf ("<obj>\n"); | |
180 | break; | |
181 | } | |
031d30b7 | 182 | } |
f27f6d6c TL |
183 | } |
184 | ||
185 | fputs ("> ", stdout); | |
186 | fflush (stdout); | |
187 | if (fgets (buf, sizeof(buf), stdin) == NULL) | |
188 | break; | |
189 | ||
88cd8aca | 190 | status = new_parse (&cfile, -1, buf, strlen(buf), "<STDIN>", 1); |
f27f6d6c | 191 | check(status, "new_parse()"); |
f6b8f48d | 192 | |
f27f6d6c TL |
193 | token = next_token (&val, (unsigned *)0, cfile); |
194 | switch (token) { | |
195 | default: | |
196 | parse_warn (cfile, "unknown token: %s", val); | |
197 | skip_to_semi (cfile); | |
198 | break; | |
f6b8f48d | 199 | |
f27f6d6c | 200 | case END_OF_FILE: |
c616de4f | 201 | case ENDOFLINE: /* EOL: */ |
f27f6d6c | 202 | break; |
f6b8f48d | 203 | |
f27f6d6c | 204 | case TOKEN_HELP: |
c616de4f | 205 | case QUESTIONMARK: /* '?': */ |
f27f6d6c TL |
206 | printf ("Commands:\n"); |
207 | printf (" port <server omapi port>\n"); | |
208 | printf (" server <server address>\n"); | |
209 | printf (" key <key name> <key value>\n"); | |
210 | printf (" connect\n"); | |
7f152466 | 211 | printf (" disconnect\n"); |
f27f6d6c TL |
212 | printf (" new <object-type>\n"); |
213 | printf (" set <name> = <value>\n"); | |
214 | printf (" create\n"); | |
215 | printf (" open\n"); | |
98311e4b DH |
216 | printf (" update\n"); |
217 | printf (" unset <name>\n"); | |
218 | printf (" refresh\n"); | |
219 | printf (" remove\n"); | |
f27f6d6c TL |
220 | skip_to_semi (cfile); |
221 | break; | |
f6b8f48d | 222 | |
f27f6d6c TL |
223 | case PORT: |
224 | token = next_token (&val, (unsigned *)0, cfile); | |
225 | if (is_identifier (token)) { | |
226 | struct servent *se; | |
227 | se = getservbyname (val, "tcp"); | |
228 | if (se) | |
229 | port = ntohs (se -> s_port); | |
230 | else { | |
31bbee78 | 231 | printf ("unknown service name: %s\n", val); |
f27f6d6c TL |
232 | break; |
233 | } | |
234 | } else if (token == NUMBER) { | |
235 | port = atoi (val); | |
236 | } else { | |
237 | skip_to_semi (cfile); | |
238 | printf ("usage: port <port>\n"); | |
239 | break; | |
240 | } | |
241 | token = next_token (&val, (unsigned *)0, cfile); | |
242 | if (token != END_OF_FILE && token != EOL) { | |
243 | printf ("usage: port <server>\n"); | |
244 | skip_to_semi (cfile); | |
245 | break; | |
246 | } | |
247 | break; | |
248 | ||
8da06bb1 | 249 | case TOKEN_SERVER: |
f27f6d6c TL |
250 | token = next_token (&val, (unsigned *)0, cfile); |
251 | if (token == NUMBER) { | |
252 | int alen = (sizeof buf) - 1; | |
253 | int len; | |
254 | ||
255 | s = &buf [0]; | |
256 | len = strlen (val); | |
257 | if (len + 1 > alen) { | |
258 | baddq: | |
259 | printf ("usage: server <server>\n"); | |
260 | skip_to_semi (cfile); | |
031d30b7 | 261 | break; |
f27f6d6c TL |
262 | } strcpy (buf, val); |
263 | s += len; | |
264 | token = next_token (&val, (unsigned *)0, cfile); | |
265 | if (token != DOT) | |
266 | goto baddq; | |
267 | *s++ = '.'; | |
268 | token = next_token (&val, (unsigned *)0, cfile); | |
269 | if (token != NUMBER) | |
270 | goto baddq; | |
271 | len = strlen (val); | |
272 | if (len + 1 > alen) | |
273 | goto baddq; | |
274 | strcpy (s, val); | |
275 | s += len; | |
276 | token = next_token (&val, (unsigned *)0, cfile); | |
277 | if (token != DOT) | |
278 | goto baddq; | |
279 | *s++ = '.'; | |
280 | token = next_token (&val, (unsigned *)0, cfile); | |
281 | if (token != NUMBER) | |
282 | goto baddq; | |
283 | len = strlen (val); | |
284 | if (len + 1 > alen) | |
285 | goto baddq; | |
286 | strcpy (s, val); | |
287 | s += len; | |
288 | token = next_token (&val, (unsigned *)0, cfile); | |
289 | if (token != DOT) | |
290 | goto baddq; | |
291 | *s++ = '.'; | |
292 | token = next_token (&val, (unsigned *)0, cfile); | |
293 | if (token != NUMBER) | |
294 | goto baddq; | |
295 | len = strlen (val); | |
296 | if (len + 1 > alen) | |
297 | goto baddq; | |
298 | strcpy (s, val); | |
299 | val = &buf [0]; | |
300 | } else if (is_identifier (token)) { | |
301 | /* Use val directly. */ | |
302 | } else { | |
303 | printf ("usage: server <server>\n"); | |
304 | skip_to_semi (cfile); | |
305 | break; | |
306 | } | |
307 | ||
308 | s = dmalloc (strlen (val) + 1, MDL); | |
309 | if (!server) { | |
31bbee78 | 310 | printf ("no memory to store server name.\n"); |
f27f6d6c TL |
311 | skip_to_semi (cfile); |
312 | break; | |
313 | } | |
314 | strcpy (s, val); | |
315 | server = s; | |
316 | ||
317 | token = next_token (&val, (unsigned *)0, cfile); | |
318 | if (token != END_OF_FILE && token != EOL) { | |
319 | printf ("usage: server <server>\n"); | |
320 | skip_to_semi (cfile); | |
321 | break; | |
322 | } | |
323 | break; | |
324 | ||
e6ffc27f TM |
325 | case KEY_ALGORITHM: |
326 | /* Algorithm is optional */ | |
327 | token = next_token (&val, (unsigned *)0, cfile); | |
328 | if (token != NAME || !is_identifier(token)) { | |
329 | printf ("missing or invalid algorithm name\n"); | |
330 | printf ("usage: key-algoritm <algorithm name>\n"); | |
331 | skip_to_semi (cfile); | |
332 | break; | |
333 | } | |
334 | ||
335 | s = dmalloc (strlen (val) + 1, MDL); | |
336 | if (!s) { | |
337 | printf ("no memory for algorithm name.\n"); | |
338 | skip_to_semi (cfile); | |
339 | break; | |
340 | } | |
341 | ||
342 | strcpy (s, val); | |
343 | algorithm = s; | |
344 | ||
345 | token = next_token (&val, (unsigned *)0, cfile); | |
346 | if (token != END_OF_FILE && token != EOL) { | |
347 | printf ("extra information after %s\n", algorithm); | |
348 | printf ("usage: key-algorithm <algorithm name>\n"); | |
349 | skip_to_semi (cfile); | |
350 | break; | |
351 | } | |
352 | ||
353 | break; | |
354 | ||
f27f6d6c | 355 | case KEY: |
98bf1607 SR |
356 | token = peek_token(&val, (unsigned *)0, cfile); |
357 | if (token == STRING) { | |
358 | token = next_token (&val, (unsigned *)0, cfile); | |
359 | if (!is_identifier (token)) { | |
e6ffc27f | 360 | printf ("usage: key <name> <value>\n"); |
98bf1607 SR |
361 | skip_to_semi (cfile); |
362 | break; | |
363 | } | |
364 | s = dmalloc (strlen (val) + 1, MDL); | |
365 | if (!s) { | |
366 | printf ("no memory for key name.\n"); | |
367 | skip_to_semi (cfile); | |
368 | break; | |
369 | } | |
370 | strcpy (s, val); | |
371 | } else { | |
372 | s = parse_host_name(cfile); | |
373 | if (s == NULL) { | |
e6ffc27f | 374 | printf ("usage: key <name> <value>\n"); |
98bf1607 SR |
375 | skip_to_semi(cfile); |
376 | break; | |
377 | } | |
f27f6d6c | 378 | } |
f27f6d6c | 379 | name = s; |
98bf1607 | 380 | |
f27f6d6c TL |
381 | memset (&secret, 0, sizeof secret); |
382 | if (!parse_base64 (&secret, cfile)) { | |
383 | skip_to_semi (cfile); | |
384 | break; | |
385 | } | |
e6ffc27f | 386 | |
f27f6d6c TL |
387 | token = next_token (&val, (unsigned *)0, cfile); |
388 | if (token != END_OF_FILE && token != EOL) { | |
7b4f284e | 389 | printf ("usage: key <name> <value>\n"); |
f27f6d6c TL |
390 | skip_to_semi (cfile); |
391 | break; | |
392 | } | |
e6ffc27f | 393 | |
f27f6d6c TL |
394 | break; |
395 | ||
396 | case CONNECT: | |
397 | token = next_token (&val, (unsigned *)0, cfile); | |
398 | if (token != END_OF_FILE && token != EOL) { | |
399 | printf ("usage: connect\n"); | |
400 | skip_to_semi (cfile); | |
401 | break; | |
402 | } | |
403 | ||
404 | authenticator = dhcpctl_null_handle; | |
405 | ||
406 | if (name) { | |
407 | status = dhcpctl_new_authenticator (&authenticator, | |
408 | name, algorithm, | |
409 | secret.data, | |
410 | secret.len); | |
472c048a | 411 | |
031d30b7 | 412 | if (status != ISC_R_SUCCESS) { |
f27f6d6c TL |
413 | fprintf (stderr, |
414 | "Cannot create authenticator: %s\n", | |
415 | isc_result_totext (status)); | |
416 | break; | |
031d30b7 | 417 | } |
f27f6d6c TL |
418 | } |
419 | ||
420 | memset (&connection, 0, sizeof connection); | |
421 | status = dhcpctl_connect (&connection, | |
422 | server, port, authenticator); | |
423 | if (status != ISC_R_SUCCESS) { | |
424 | fprintf (stderr, "dhcpctl_connect: %s\n", | |
425 | isc_result_totext (status)); | |
426 | break; | |
427 | } | |
428 | connected = 1; | |
429 | break; | |
430 | ||
7f152466 TM |
431 | case DISCONNECT: |
432 | token = next_token (&val, (unsigned *)0, cfile); | |
433 | if (token != END_OF_FILE && token != EOL) { | |
434 | printf ("usage: disconnect\n"); | |
435 | skip_to_semi (cfile); | |
436 | break; | |
437 | } | |
438 | ||
439 | if (!connected || !connection) { | |
440 | fprintf (stderr, "not connected\n"); | |
441 | break; | |
442 | } | |
443 | ||
444 | status = dhcpctl_disconnect (&connection, 0); | |
445 | if (status != ISC_R_SUCCESS) { | |
446 | fprintf (stderr, "dhcpctl_disconnect: %s\n", | |
447 | isc_result_totext (status)); | |
448 | break; | |
449 | } | |
450 | connected = 0; | |
451 | break; | |
452 | ||
f27f6d6c TL |
453 | case TOKEN_NEW: |
454 | token = next_token (&val, (unsigned *)0, cfile); | |
455 | if ((!is_identifier (token) && token != STRING)) { | |
456 | printf ("usage: new <object-type>\n"); | |
457 | break; | |
458 | } | |
f6b8f48d | 459 | |
f27f6d6c TL |
460 | if (oh) { |
461 | printf ("an object is already open.\n"); | |
462 | skip_to_semi (cfile); | |
463 | break; | |
464 | } | |
f6b8f48d | 465 | |
f27f6d6c | 466 | if (!connected) { |
31bbee78 | 467 | printf ("not connected.\n"); |
f27f6d6c TL |
468 | skip_to_semi (cfile); |
469 | break; | |
470 | } | |
471 | ||
472 | status = dhcpctl_new_object (&oh, connection, val); | |
473 | if (status != ISC_R_SUCCESS) { | |
474 | printf ("can't create object: %s\n", | |
475 | isc_result_totext (status)); | |
476 | break; | |
477 | } | |
f6b8f48d | 478 | |
f27f6d6c TL |
479 | token = next_token (&val, (unsigned *)0, cfile); |
480 | if (token != END_OF_FILE && token != EOL) { | |
481 | printf ("usage: new <object-type>\n"); | |
482 | skip_to_semi (cfile); | |
483 | break; | |
484 | } | |
485 | break; | |
486 | ||
487 | case TOKEN_CLOSE: | |
488 | token = next_token (&val, (unsigned *)0, cfile); | |
489 | if (token != END_OF_FILE && token != EOL) { | |
490 | printf ("usage: close\n"); | |
491 | skip_to_semi (cfile); | |
492 | break; | |
493 | } | |
494 | ||
495 | if (!connected) { | |
31bbee78 | 496 | printf ("not connected.\n"); |
f27f6d6c TL |
497 | skip_to_semi (cfile); |
498 | break; | |
499 | } | |
500 | ||
98311e4b DH |
501 | if (!oh) { |
502 | printf ("not open.\n"); | |
503 | skip_to_semi (cfile); | |
504 | break; | |
505 | } | |
f27f6d6c | 506 | omapi_object_dereference (&oh, MDL); |
f6b8f48d | 507 | |
f27f6d6c TL |
508 | break; |
509 | ||
510 | case TOKEN_SET: | |
511 | token = next_token (&val, (unsigned *)0, cfile); | |
512 | ||
513 | if ((!is_identifier (token) && token != STRING)) { | |
514 | set_usage: | |
515 | printf ("usage: set <name> = <value>\n"); | |
516 | skip_to_semi (cfile); | |
517 | break; | |
518 | } | |
f6b8f48d | 519 | |
f27f6d6c TL |
520 | if (oh == NULL) { |
521 | printf ("no open object.\n"); | |
522 | skip_to_semi (cfile); | |
523 | break; | |
524 | } | |
f6b8f48d | 525 | |
f27f6d6c | 526 | if (!connected) { |
31bbee78 | 527 | printf ("not connected.\n"); |
f27f6d6c TL |
528 | skip_to_semi (cfile); |
529 | break; | |
530 | } | |
531 | ||
dc9d7b08 MA |
532 | #ifdef HAVE_STRLCPY |
533 | strlcpy (s1, val, sizeof(s1)); | |
534 | #else | |
535 | s1[0] = 0; | |
536 | strncat (s1, val, sizeof(s1)-strlen(s1)-1); | |
537 | #endif | |
f6b8f48d | 538 | |
f27f6d6c TL |
539 | token = next_token (&val, (unsigned *)0, cfile); |
540 | if (token != EQUAL) | |
541 | goto set_usage; | |
542 | ||
543 | token = next_token (&val, (unsigned *)0, cfile); | |
544 | switch (token) { | |
545 | case STRING: | |
546 | dhcpctl_set_string_value (oh, val, s1); | |
31bbee78 | 547 | token = next_token (&val, (unsigned *)0, cfile); |
f27f6d6c | 548 | break; |
f6b8f48d | 549 | |
f27f6d6c | 550 | case NUMBER: |
31bbee78 TL |
551 | strcpy (buf, val); |
552 | token = peek_token (&val, (unsigned *)0, cfile); | |
c57db45c | 553 | /* Colon-separated hex list? */ |
31bbee78 TL |
554 | if (token == COLON) |
555 | goto cshl; | |
556 | else if (token == DOT) { | |
557 | s = buf; | |
558 | val = buf; | |
559 | do { | |
560 | int intval = atoi (val); | |
561 | if (intval > 255) { | |
562 | parse_warn (cfile, | |
563 | "dotted octet > 255: %s", | |
564 | val); | |
565 | skip_to_semi (cfile); | |
566 | goto badnum; | |
567 | } | |
568 | *s++ = intval; | |
569 | token = next_token (&val, | |
570 | (unsigned *)0, cfile); | |
571 | if (token != DOT) | |
572 | break; | |
98311e4b DH |
573 | /* DOT is zero. */ |
574 | while ((token = next_token (&val, | |
575 | (unsigned *)0, cfile)) == DOT) | |
576 | *s++ = 0; | |
31bbee78 TL |
577 | } while (token == NUMBER); |
578 | dhcpctl_set_data_value (oh, buf, | |
579 | (unsigned)(s - buf), | |
580 | s1); | |
581 | break; | |
582 | } | |
583 | dhcpctl_set_int_value (oh, atoi (buf), s1); | |
584 | token = next_token (&val, (unsigned *)0, cfile); | |
585 | badnum: | |
f27f6d6c | 586 | break; |
f6b8f48d | 587 | |
31bbee78 TL |
588 | case NUMBER_OR_NAME: |
589 | strcpy (buf, val); | |
590 | cshl: | |
591 | s = buf; | |
592 | val = buf; | |
593 | do { | |
d758ad8c TL |
594 | convert_num (cfile, (unsigned char *)s, |
595 | val, 16, 8); | |
31bbee78 TL |
596 | ++s; |
597 | token = next_token (&val, | |
598 | (unsigned *)0, cfile); | |
599 | if (token != COLON) | |
600 | break; | |
601 | token = next_token (&val, | |
602 | (unsigned *)0, cfile); | |
603 | } while (token == NUMBER || | |
604 | token == NUMBER_OR_NAME); | |
605 | dhcpctl_set_data_value (oh, buf, | |
606 | (unsigned)(s - buf), s1); | |
607 | break; | |
608 | ||
f27f6d6c TL |
609 | default: |
610 | printf ("invalid value.\n"); | |
31bbee78 | 611 | skip_to_semi (cfile); |
f27f6d6c | 612 | } |
f6b8f48d | 613 | |
f27f6d6c TL |
614 | if (token != END_OF_FILE && token != EOL) |
615 | goto set_usage; | |
616 | break; | |
f6b8f48d | 617 | |
d758ad8c TL |
618 | case UNSET: |
619 | token = next_token (&val, (unsigned *)0, cfile); | |
620 | ||
621 | if ((!is_identifier (token) && token != STRING)) { | |
622 | unset_usage: | |
623 | printf ("usage: unset <name>\n"); | |
624 | skip_to_semi (cfile); | |
625 | break; | |
626 | } | |
f6b8f48d | 627 | |
d758ad8c TL |
628 | if (!oh) { |
629 | printf ("no open object.\n"); | |
630 | skip_to_semi (cfile); | |
631 | break; | |
632 | } | |
f6b8f48d | 633 | |
d758ad8c TL |
634 | if (!connected) { |
635 | printf ("not connected.\n"); | |
636 | skip_to_semi (cfile); | |
637 | break; | |
638 | } | |
639 | ||
dc9d7b08 MA |
640 | #if HAVE_STRLCPY |
641 | strlcpy (s1, val, sizeof(s1)); | |
642 | #else | |
643 | s1[0] = 0; | |
644 | strncat (s1, val, sizeof(s1)-strlen(s1)-1); | |
645 | #endif | |
f6b8f48d | 646 | |
d758ad8c TL |
647 | token = next_token (&val, (unsigned *)0, cfile); |
648 | if (token != END_OF_FILE && token != EOL) | |
649 | goto unset_usage; | |
650 | ||
651 | dhcpctl_set_null_value (oh, s1); | |
652 | break; | |
653 | ||
f6b8f48d | 654 | |
f27f6d6c TL |
655 | case TOKEN_CREATE: |
656 | case TOKEN_OPEN: | |
31bbee78 | 657 | i = token; |
f27f6d6c TL |
658 | token = next_token (&val, (unsigned *)0, cfile); |
659 | if (token != END_OF_FILE && token != EOL) { | |
660 | printf ("usage: %s\n", val); | |
661 | skip_to_semi (cfile); | |
662 | break; | |
663 | } | |
f6b8f48d | 664 | |
f27f6d6c | 665 | if (!connected) { |
31bbee78 | 666 | printf ("not connected.\n"); |
f27f6d6c TL |
667 | skip_to_semi (cfile); |
668 | break; | |
669 | } | |
670 | ||
31bbee78 TL |
671 | if (!oh) { |
672 | printf ("you must make a new object first!\n"); | |
673 | skip_to_semi (cfile); | |
674 | break; | |
675 | } | |
676 | ||
677 | if (i == TOKEN_CREATE) | |
f27f6d6c | 678 | i = DHCPCTL_CREATE | DHCPCTL_EXCL; |
31bbee78 TL |
679 | else |
680 | i = 0; | |
f6b8f48d | 681 | |
f27f6d6c TL |
682 | status = dhcpctl_open_object (oh, connection, i); |
683 | if (status == ISC_R_SUCCESS) | |
684 | status = dhcpctl_wait_for_completion | |
685 | (oh, &waitstatus); | |
686 | if (status == ISC_R_SUCCESS) | |
687 | status = waitstatus; | |
688 | if (status != ISC_R_SUCCESS) { | |
689 | printf ("can't open object: %s\n", | |
690 | isc_result_totext (status)); | |
691 | break; | |
692 | } | |
f6b8f48d | 693 | |
f27f6d6c TL |
694 | break; |
695 | ||
696 | case UPDATE: | |
697 | token = next_token (&val, (unsigned *)0, cfile); | |
698 | if (token != END_OF_FILE && token != EOL) { | |
699 | printf ("usage: %s\n", val); | |
700 | skip_to_semi (cfile); | |
701 | break; | |
702 | } | |
f6b8f48d | 703 | |
f27f6d6c | 704 | if (!connected) { |
31bbee78 | 705 | printf ("not connected.\n"); |
f27f6d6c TL |
706 | skip_to_semi (cfile); |
707 | break; | |
708 | } | |
709 | ||
d758ad8c TL |
710 | if (!oh) { |
711 | printf ("you haven't opened an object yet!\n"); | |
712 | skip_to_semi (cfile); | |
713 | break; | |
714 | } | |
715 | ||
f27f6d6c TL |
716 | status = dhcpctl_object_update(connection, oh); |
717 | if (status == ISC_R_SUCCESS) | |
718 | status = dhcpctl_wait_for_completion | |
719 | (oh, &waitstatus); | |
720 | if (status == ISC_R_SUCCESS) | |
721 | status = waitstatus; | |
722 | if (status != ISC_R_SUCCESS) { | |
723 | printf ("can't update object: %s\n", | |
724 | isc_result_totext (status)); | |
725 | break; | |
726 | } | |
f6b8f48d | 727 | |
31bbee78 TL |
728 | break; |
729 | ||
730 | case REMOVE: | |
731 | token = next_token (&val, (unsigned *)0, cfile); | |
732 | if (token != END_OF_FILE && token != EOL) { | |
d758ad8c | 733 | printf ("usage: remove\n"); |
31bbee78 TL |
734 | skip_to_semi (cfile); |
735 | break; | |
736 | } | |
f6b8f48d | 737 | |
31bbee78 TL |
738 | if (!connected) { |
739 | printf ("not connected.\n"); | |
d758ad8c TL |
740 | break; |
741 | } | |
742 | ||
743 | if (!oh) { | |
744 | printf ("no object.\n"); | |
31bbee78 TL |
745 | break; |
746 | } | |
747 | ||
748 | status = dhcpctl_object_remove(connection, oh); | |
749 | if (status == ISC_R_SUCCESS) | |
750 | status = dhcpctl_wait_for_completion | |
751 | (oh, &waitstatus); | |
752 | if (status == ISC_R_SUCCESS) | |
753 | status = waitstatus; | |
754 | if (status != ISC_R_SUCCESS) { | |
755 | printf ("can't destroy object: %s\n", | |
756 | isc_result_totext (status)); | |
757 | break; | |
758 | } | |
d758ad8c TL |
759 | omapi_object_dereference (&oh, MDL); |
760 | break; | |
761 | ||
762 | case REFRESH: | |
763 | token = next_token (&val, (unsigned *)0, cfile); | |
764 | if (token != END_OF_FILE && token != EOL) { | |
765 | printf ("usage: refresh\n"); | |
766 | skip_to_semi (cfile); | |
767 | break; | |
768 | } | |
f6b8f48d | 769 | |
d758ad8c TL |
770 | if (!connected) { |
771 | printf ("not connected.\n"); | |
772 | break; | |
773 | } | |
774 | ||
775 | if (!oh) { | |
776 | printf ("no object.\n"); | |
777 | break; | |
778 | } | |
779 | ||
780 | status = dhcpctl_object_refresh(connection, oh); | |
781 | if (status == ISC_R_SUCCESS) | |
782 | status = dhcpctl_wait_for_completion | |
783 | (oh, &waitstatus); | |
784 | if (status == ISC_R_SUCCESS) | |
785 | status = waitstatus; | |
786 | if (status != ISC_R_SUCCESS) { | |
787 | printf ("can't refresh object: %s\n", | |
788 | isc_result_totext (status)); | |
789 | break; | |
790 | } | |
f6b8f48d | 791 | |
f27f6d6c TL |
792 | break; |
793 | } | |
98311e4b | 794 | end_parse (&cfile); |
31bbee78 | 795 | } while (1); |
eadee396 | 796 | |
d142e03f TL |
797 | exit (0); |
798 | } | |
d758ad8c TL |
799 | |
800 | /* Sigh */ | |
801 | isc_result_t dhcp_set_control_state (control_object_state_t oldstate, | |
802 | control_object_state_t newstate) | |
803 | { | |
0895c955 SR |
804 | if (newstate != server_shutdown) |
805 | return ISC_R_SUCCESS; | |
806 | exit (0); | |
d758ad8c | 807 | } |