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