]> git.ipfire.org Git - thirdparty/dhcp.git/blame - dhcpctl/omshell.c
Update README - added section on Release status which was in the TOC
[thirdparty/dhcp.git] / dhcpctl / omshell.c
CommitLineData
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 */
44isc_result_t find_class (struct class **c, const char *n, const char *f, int l)
45{
46 return 0;
47}
48int parse_allow_deny (struct option_cache **oc, struct parse *cfile, int flag)
49{
50 return 0;
51}
52void dhcp (struct packet *packet) { }
53void bootp (struct packet *packet) { }
98bd7ca0 54
fe5b0fdd 55#ifdef DHCPv6
98bd7ca0
DH
56/* XXX: should we warn or something here? */
57void dhcpv6(struct packet *packet) { }
e4dcd805
FD
58#ifdef DHCP4o6
59isc_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
66int check_collection (struct packet *p, struct lease *l, struct collection *c)
67{
68 return 0;
69}
70void classify (struct packet *packet, struct class *class) { }
d142e03f 71
7acd8753 72static void usage (const char *s) {
d758ad8c 73 fprintf (stderr, "Usage: %s\n", s);
58941de4
DN
74 exit (1);
75}
76
031d30b7
DN
77static 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 84int
98bd7ca0 85main(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 */
801isc_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}