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