dhcpctl/omshell.c

Go to the documentation of this file.
00001 /* omshell.c
00002 
00003    Examine and modify omapi objects. */
00004 
00005 /*
00006  * Copyright (c) 2009-2011,2013,2014 by Internet Systems Consortium, Inc. ("ISC")
00007  * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
00008  * Copyright (c) 2001-2003 by Internet Software Consortium
00009  *
00010  * Permission to use, copy, modify, and distribute this software for any
00011  * purpose with or without fee is hereby granted, provided that the above
00012  * copyright notice and this permission notice appear in all copies.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
00015  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00016  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
00017  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00018  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00019  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
00020  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00021  *
00022  *   Internet Systems Consortium, Inc.
00023  *   950 Charter Street
00024  *   Redwood City, CA 94063
00025  *   <info@isc.org>
00026  *   https://www.isc.org/
00027  *
00028  */
00029 
00030 #include "config.h"
00031 
00032 #include <time.h>
00033 #include <sys/time.h>
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <stdarg.h>
00037 #include <string.h>
00038 //#include "result.h"
00039 #include <syslog.h>
00040 #include "dhcpctl.h"
00041 #include "dhcpd.h"
00042 
00043 /* Fixups */
00044 isc_result_t find_class (struct class **c, const char *n, const char *f, int l)
00045 {
00046         return 0;
00047 }
00048 int parse_allow_deny (struct option_cache **oc, struct parse *cfile, int flag)
00049 {
00050         return 0;
00051 }
00052 void dhcp (struct packet *packet) { }
00053 void bootp (struct packet *packet) { }
00054 
00055 #ifdef DHCPv6
00056 /* XXX: should we warn or something here? */
00057 void dhcpv6(struct packet *packet) { }
00058 #endif /* DHCPv6 */
00059 
00060 int check_collection (struct packet *p, struct lease *l, struct collection *c)
00061 {
00062         return 0;
00063 }
00064 void classify (struct packet *packet, struct class *class) { }
00065 
00066 static void usage (char *s) {
00067         fprintf (stderr, "Usage: %s\n", s);
00068         exit (1);
00069 }
00070 
00071 static void check (isc_result_t status, const char *func) {
00072         if (status != ISC_R_SUCCESS) {
00073                 fprintf (stderr, "%s: %s\n", func, isc_result_totext (status));
00074                 exit (1);
00075         }
00076 }
00077 
00078 int 
00079 main(int argc, char **argv) {
00080         isc_result_t status, waitstatus;
00081         dhcpctl_handle connection;
00082         dhcpctl_handle authenticator;
00083         dhcpctl_handle oh;
00084         struct data_string secret;
00085         const char *name = 0, *algorithm = "hmac-md5";
00086         int i;
00087         int port = 7911;
00088         const char *server = "127.0.0.1";
00089         struct parse *cfile;
00090         enum dhcp_token token;
00091         const char *val;
00092         char *s;
00093         char buf[1024];
00094         char s1[1024];
00095         int connected = 0;
00096         char hex_buf[1025];
00097 
00098         for (i = 1; i < argc; i++) {
00099                 usage(argv[0]);
00100         }
00101 
00102         /* Initially, log errors to stderr as well as to syslogd. */
00103         openlog ("omshell", LOG_NDELAY, DHCPD_LOG_FACILITY);
00104         status = dhcpctl_initialize ();
00105         if (status != ISC_R_SUCCESS) {
00106                 fprintf (stderr, "dhcpctl_initialize: %s\n",
00107                          isc_result_totext (status));
00108                 exit (1);
00109         }
00110 
00111         memset (&oh, 0, sizeof oh);
00112 
00113         do {
00114             if (!connected) {
00115             } else if (oh == NULL) {
00116                 printf ("obj: <null>\n");
00117             } else {
00118                 dhcpctl_remote_object_t *r = (dhcpctl_remote_object_t *)oh;
00119                 omapi_generic_object_t *g =
00120                         (omapi_generic_object_t *)(r -> inner);
00121                 
00122                 printf ("obj: ");
00123 
00124                 if (r -> rtype -> type != omapi_datatype_string) {
00125                         printf ("?\n");
00126                 } else {
00127                         printf ("%.*s\n",
00128                                 (int)(r -> rtype -> u . buffer . len),
00129                                 r -> rtype -> u . buffer . value);
00130                 }
00131                 
00132                 for (i = 0; i < g -> nvalues; i++) {
00133                     omapi_value_t *v = g -> values [i];
00134                         
00135                     if (!g -> values [i])
00136                             continue;
00137 
00138                     printf ("%.*s = ", (int)v -> name -> len,
00139                             v -> name -> value);
00140                         
00141                     if (!v -> value) {
00142                         printf ("<null>\n");
00143                         continue;
00144                     }
00145                     switch (v -> value -> type) {
00146                           case omapi_datatype_int:
00147                             printf ("%d\n",
00148                                     v -> value -> u . integer);
00149                             break;
00150                          
00151                           case omapi_datatype_string:
00152                             printf ("\"%.*s\"\n",
00153                                     (int) v -> value -> u.buffer.len,
00154                                     v -> value -> u.buffer.value);
00155                             break;
00156                                 
00157                           case omapi_datatype_data:
00158                             print_hex_or_string(v->value->u.buffer.len,
00159                                                 v->value->u.buffer.value,
00160                                                 sizeof(hex_buf), hex_buf);
00161                             printf("%s\n", hex_buf);
00162                             break;
00163                             
00164                           case omapi_datatype_object:
00165                             printf ("<obj>\n");
00166                             break;
00167                     }
00168                 }
00169             }
00170 
00171             fputs ("> ", stdout);
00172             fflush (stdout);
00173             if (fgets (buf, sizeof(buf), stdin) == NULL)
00174                 break;
00175 
00176             status = new_parse (&cfile, -1, buf, strlen(buf), "<STDIN>", 1);
00177             check(status, "new_parse()");
00178             
00179             token = next_token (&val, (unsigned *)0, cfile);
00180             switch (token) {
00181                   default:
00182                     parse_warn (cfile, "unknown token: %s", val);
00183                     skip_to_semi (cfile);
00184                     break;
00185                     
00186                   case END_OF_FILE:
00187                   case ENDOFLINE: /* EOL: */
00188                     break;
00189                     
00190                   case TOKEN_HELP:
00191                   case QUESTIONMARK: /* '?': */
00192                     printf ("Commands:\n");
00193                     printf ("  port <server omapi port>\n");
00194                     printf ("  server <server address>\n");
00195                     printf ("  key <key name> <key value>\n");
00196                     printf ("  connect\n");
00197                     printf ("  new <object-type>\n");
00198                     printf ("  set <name> = <value>\n");
00199                     printf ("  create\n");
00200                     printf ("  open\n");
00201                     printf ("  update\n");
00202                     printf ("  unset <name>\n");
00203                     printf ("  refresh\n");
00204                     printf ("  remove\n");
00205                     skip_to_semi (cfile);
00206                     break;
00207                     
00208                   case PORT:
00209                     token = next_token (&val, (unsigned *)0, cfile);
00210                     if (is_identifier (token)) {
00211                             struct servent *se;
00212                             se = getservbyname (val, "tcp");
00213                             if (se)
00214                                     port = ntohs (se -> s_port);
00215                             else {
00216                                     printf ("unknown service name: %s\n", val);
00217                                     break;
00218                             }
00219                     } else if (token == NUMBER) {
00220                             port = atoi (val);
00221                     } else {
00222                             skip_to_semi (cfile);
00223                             printf ("usage: port <port>\n");
00224                             break;
00225                     }
00226                     token = next_token (&val, (unsigned *)0, cfile);
00227                     if (token != END_OF_FILE && token != EOL) {
00228                             printf ("usage: port <server>\n");
00229                             skip_to_semi (cfile);
00230                             break;
00231                     }
00232                     break;
00233 
00234                   case TOKEN_SERVER:
00235                     token = next_token (&val, (unsigned *)0, cfile);
00236                     if (token == NUMBER) {
00237                             int alen = (sizeof buf) - 1;
00238                             int len;
00239 
00240                             s = &buf [0];
00241                             len = strlen (val);
00242                             if (len + 1 > alen) {
00243                               baddq:
00244                                 printf ("usage: server <server>\n");
00245                                 skip_to_semi (cfile);
00246                                 break;
00247                             }                       strcpy (buf, val);
00248                             s += len;
00249                             token = next_token (&val, (unsigned *)0, cfile);
00250                             if (token != DOT)
00251                                     goto baddq;
00252                             *s++ = '.';
00253                             token = next_token (&val, (unsigned *)0, cfile);
00254                             if (token != NUMBER)
00255                                     goto baddq;
00256                             len = strlen (val);
00257                             if (len + 1 > alen)
00258                                     goto baddq;
00259                             strcpy (s, val);
00260                             s += len;
00261                             token = next_token (&val, (unsigned *)0, cfile);
00262                             if (token != DOT)
00263                                     goto baddq;
00264                             *s++ = '.';
00265                             token = next_token (&val, (unsigned *)0, cfile);
00266                             if (token != NUMBER)
00267                                     goto baddq;
00268                             len = strlen (val);
00269                             if (len + 1 > alen)
00270                                     goto baddq;
00271                             strcpy (s, val);
00272                             s += len;
00273                             token = next_token (&val, (unsigned *)0, cfile);
00274                             if (token != DOT)
00275                                     goto baddq;
00276                             *s++ = '.';
00277                             token = next_token (&val, (unsigned *)0, cfile);
00278                             if (token != NUMBER)
00279                                     goto baddq;
00280                             len = strlen (val);
00281                             if (len + 1 > alen)
00282                                     goto baddq;
00283                             strcpy (s, val);
00284                             val = &buf [0];
00285                     } else if (is_identifier (token)) {
00286                             /* Use val directly. */
00287                     } else {
00288                             printf ("usage: server <server>\n");
00289                             skip_to_semi (cfile);
00290                             break;
00291                     }
00292 
00293                     s = dmalloc (strlen (val) + 1, MDL);
00294                     if (!server) {
00295                             printf ("no memory to store server name.\n");
00296                             skip_to_semi (cfile);
00297                             break;
00298                     }
00299                     strcpy (s, val);
00300                     server = s;
00301 
00302                     token = next_token (&val, (unsigned *)0, cfile);
00303                     if (token != END_OF_FILE && token != EOL) {
00304                             printf ("usage: server <server>\n");
00305                             skip_to_semi (cfile);
00306                             break;
00307                     }
00308                     break;
00309 
00310                   case KEY:
00311                     token = peek_token(&val, (unsigned *)0, cfile);
00312                     if (token == STRING) {
00313                             token = next_token (&val, (unsigned *)0, cfile);
00314                             if (!is_identifier (token)) {
00315                                     printf ("usage: key <name> <value>\n");
00316                                     skip_to_semi (cfile);
00317                                     break;
00318                             }
00319                             s = dmalloc (strlen (val) + 1, MDL);
00320                             if (!s) {
00321                                     printf ("no memory for key name.\n");
00322                                     skip_to_semi (cfile);
00323                                     break;
00324                             }
00325                             strcpy (s, val);
00326                     } else {
00327                             s = parse_host_name(cfile);
00328                             if (s == NULL) {
00329                                     printf ("usage: key <name> <value>\n");
00330                                     skip_to_semi(cfile);
00331                                     break;
00332                             }
00333                     }
00334                     name = s;
00335 
00336                     memset (&secret, 0, sizeof secret);
00337                     if (!parse_base64 (&secret, cfile)) {
00338                             skip_to_semi (cfile);
00339                             break;
00340                     }
00341                     token = next_token (&val, (unsigned *)0, cfile);
00342                     if (token != END_OF_FILE && token != EOL) {
00343                             printf ("usage: key <name> <secret>\n");
00344                             skip_to_semi (cfile);
00345                             break;
00346                     }
00347                     break;
00348 
00349                   case CONNECT:
00350                     token = next_token (&val, (unsigned *)0, cfile);
00351                     if (token != END_OF_FILE && token != EOL) {
00352                             printf ("usage: connect\n");
00353                             skip_to_semi (cfile);
00354                             break;
00355                     }
00356 
00357                     authenticator = dhcpctl_null_handle;
00358 
00359                     if (name) {
00360                         status = dhcpctl_new_authenticator (&authenticator,
00361                                                             name, algorithm,
00362                                                             secret.data,
00363                                                             secret.len);
00364 
00365                         if (status != ISC_R_SUCCESS) {
00366                             fprintf (stderr,
00367                                      "Cannot create authenticator: %s\n",
00368                                      isc_result_totext (status));
00369                             break;
00370                         }
00371                     }
00372 
00373                     memset (&connection, 0, sizeof connection);
00374                     status = dhcpctl_connect (&connection,
00375                                               server, port, authenticator);
00376                     if (status != ISC_R_SUCCESS) {
00377                             fprintf (stderr, "dhcpctl_connect: %s\n",
00378                                      isc_result_totext (status));
00379                             break;
00380                     }
00381                     connected = 1;
00382                     break;
00383 
00384                   case TOKEN_NEW:
00385                     token = next_token (&val, (unsigned *)0, cfile);
00386                     if ((!is_identifier (token) && token != STRING)) {
00387                             printf ("usage: new <object-type>\n");
00388                             break;
00389                     }
00390                     
00391                     if (oh) {
00392                             printf ("an object is already open.\n");
00393                             skip_to_semi (cfile);
00394                             break;
00395                     }
00396                     
00397                     if (!connected) {
00398                             printf ("not connected.\n");
00399                             skip_to_semi (cfile);
00400                             break;
00401                     }
00402 
00403                     status = dhcpctl_new_object (&oh, connection, val);
00404                     if (status != ISC_R_SUCCESS) {
00405                             printf ("can't create object: %s\n",
00406                                     isc_result_totext (status));
00407                             break;
00408                     }
00409                     
00410                     token = next_token (&val, (unsigned *)0, cfile);
00411                     if (token != END_OF_FILE && token != EOL) {
00412                             printf ("usage: new <object-type>\n");
00413                             skip_to_semi (cfile);
00414                             break;
00415                     }
00416                     break;
00417 
00418                   case TOKEN_CLOSE:
00419                     token = next_token (&val, (unsigned *)0, cfile);
00420                     if (token != END_OF_FILE && token != EOL) {
00421                             printf ("usage: close\n");
00422                             skip_to_semi (cfile);
00423                             break;
00424                     }
00425 
00426                     if (!connected) {
00427                             printf ("not connected.\n");
00428                             skip_to_semi (cfile);
00429                             break;
00430                     }
00431 
00432                     if (!oh) {
00433                             printf ("not open.\n");
00434                             skip_to_semi (cfile);
00435                             break;
00436                     }
00437                     omapi_object_dereference (&oh, MDL);
00438                     
00439                     break;
00440 
00441                   case TOKEN_SET:
00442                     token = next_token (&val, (unsigned *)0, cfile);
00443 
00444                     if ((!is_identifier (token) && token != STRING)) {
00445                           set_usage:
00446                             printf ("usage: set <name> = <value>\n");
00447                             skip_to_semi (cfile);
00448                             break;
00449                     }
00450                     
00451                     if (oh == NULL) {
00452                             printf ("no open object.\n");
00453                             skip_to_semi (cfile);
00454                             break;
00455                     }
00456                     
00457                     if (!connected) {
00458                             printf ("not connected.\n");
00459                             skip_to_semi (cfile);
00460                             break;
00461                     }
00462 
00463 #ifdef HAVE_STRLCPY
00464                     strlcpy (s1, val, sizeof(s1));
00465 #else
00466                     s1[0] = 0;
00467                     strncat (s1, val, sizeof(s1)-strlen(s1)-1);
00468 #endif
00469                     
00470                     token = next_token (&val, (unsigned *)0, cfile);
00471                     if (token != EQUAL)
00472                             goto set_usage;
00473 
00474                     token = next_token (&val, (unsigned *)0, cfile);
00475                     switch (token) {
00476                           case STRING:
00477                             dhcpctl_set_string_value (oh, val, s1);
00478                             token = next_token (&val, (unsigned *)0, cfile);
00479                             break;
00480                             
00481                           case NUMBER:
00482                             strcpy (buf, val);
00483                             token = peek_token (&val, (unsigned *)0, cfile);
00484                             /* Colon-separated hex list? */
00485                             if (token == COLON)
00486                                 goto cshl;
00487                             else if (token == DOT) {
00488                                 s = buf;
00489                                 val = buf;
00490                                 do {
00491                                     int intval = atoi (val);
00492                                     if (intval > 255) {
00493                                         parse_warn (cfile,
00494                                                     "dotted octet > 255: %s",
00495                                                     val);
00496                                         skip_to_semi (cfile);
00497                                         goto badnum;
00498                                     }
00499                                     *s++ = intval;
00500                                     token = next_token (&val,
00501                                                         (unsigned *)0, cfile);
00502                                     if (token != DOT)
00503                                             break;
00504                                     /* DOT is zero. */
00505                                     while ((token = next_token (&val,
00506                                         (unsigned *)0, cfile)) == DOT)
00507                                         *s++ = 0;
00508                                 } while (token == NUMBER);
00509                                 dhcpctl_set_data_value (oh, buf,
00510                                                         (unsigned)(s - buf),
00511                                                         s1);
00512                                 break;
00513                             }
00514                             dhcpctl_set_int_value (oh, atoi (buf), s1);
00515                             token = next_token (&val, (unsigned *)0, cfile);
00516                           badnum:
00517                             break;
00518                             
00519                           case NUMBER_OR_NAME:
00520                             strcpy (buf, val);
00521                           cshl:
00522                             s = buf;
00523                             val = buf;
00524                             do {
00525                                 convert_num (cfile, (unsigned char *)s,
00526                                              val, 16, 8);
00527                                 ++s;
00528                                 token = next_token (&val,
00529                                                     (unsigned *)0, cfile);
00530                                 if (token != COLON)
00531                                     break;
00532                                 token = next_token (&val,
00533                                                     (unsigned *)0, cfile);
00534                             } while (token == NUMBER ||
00535                                      token == NUMBER_OR_NAME);
00536                             dhcpctl_set_data_value (oh, buf,
00537                                                     (unsigned)(s - buf), s1);
00538                             break;
00539 
00540                           default:
00541                             printf ("invalid value.\n");
00542                             skip_to_semi (cfile);
00543                     }
00544                     
00545                     if (token != END_OF_FILE && token != EOL)
00546                             goto set_usage;
00547                     break;
00548                     
00549                   case UNSET:
00550                     token = next_token (&val, (unsigned *)0, cfile);
00551 
00552                     if ((!is_identifier (token) && token != STRING)) {
00553                           unset_usage:
00554                             printf ("usage: unset <name>\n");
00555                             skip_to_semi (cfile);
00556                             break;
00557                     }
00558                     
00559                     if (!oh) {
00560                             printf ("no open object.\n");
00561                             skip_to_semi (cfile);
00562                             break;
00563                     }
00564                     
00565                     if (!connected) {
00566                             printf ("not connected.\n");
00567                             skip_to_semi (cfile);
00568                             break;
00569                     }
00570 
00571 #if HAVE_STRLCPY
00572                     strlcpy (s1, val, sizeof(s1));
00573 #else
00574                     s1[0] = 0;
00575                     strncat (s1, val, sizeof(s1)-strlen(s1)-1);
00576 #endif
00577                     
00578                     token = next_token (&val, (unsigned *)0, cfile);
00579                     if (token != END_OF_FILE && token != EOL)
00580                             goto unset_usage;
00581 
00582                     dhcpctl_set_null_value (oh, s1);
00583                     break;
00584 
00585                             
00586                   case TOKEN_CREATE:
00587                   case TOKEN_OPEN:
00588                     i = token;
00589                     token = next_token (&val, (unsigned *)0, cfile);
00590                     if (token != END_OF_FILE && token != EOL) {
00591                             printf ("usage: %s\n", val);
00592                             skip_to_semi (cfile);
00593                             break;
00594                     }
00595                     
00596                     if (!connected) {
00597                             printf ("not connected.\n");
00598                             skip_to_semi (cfile);
00599                             break;
00600                     }
00601 
00602                     if (!oh) {
00603                             printf ("you must make a new object first!\n");
00604                             skip_to_semi (cfile);
00605                             break;
00606                     }
00607 
00608                     if (i == TOKEN_CREATE)
00609                             i = DHCPCTL_CREATE | DHCPCTL_EXCL;
00610                     else
00611                             i = 0;
00612                     
00613                     status = dhcpctl_open_object (oh, connection, i);
00614                     if (status == ISC_R_SUCCESS)
00615                             status = dhcpctl_wait_for_completion
00616                                     (oh, &waitstatus);
00617                     if (status == ISC_R_SUCCESS)
00618                             status = waitstatus;
00619                     if (status != ISC_R_SUCCESS) {
00620                             printf ("can't open object: %s\n",
00621                                     isc_result_totext (status));
00622                             break;
00623                     }
00624                     
00625                     break;
00626 
00627                   case UPDATE:
00628                     token = next_token (&val, (unsigned *)0, cfile);
00629                     if (token != END_OF_FILE && token != EOL) {
00630                             printf ("usage: %s\n", val);
00631                             skip_to_semi (cfile);
00632                             break;
00633                     }
00634                     
00635                     if (!connected) {
00636                             printf ("not connected.\n");
00637                             skip_to_semi (cfile);
00638                             break;
00639                     }
00640 
00641                     if (!oh) {
00642                             printf ("you haven't opened an object yet!\n");
00643                             skip_to_semi (cfile);
00644                             break;
00645                     }
00646 
00647                     status = dhcpctl_object_update(connection, oh);
00648                     if (status == ISC_R_SUCCESS)
00649                             status = dhcpctl_wait_for_completion
00650                                     (oh, &waitstatus);
00651                     if (status == ISC_R_SUCCESS)
00652                             status = waitstatus;
00653                     if (status != ISC_R_SUCCESS) {
00654                             printf ("can't update object: %s\n",
00655                                     isc_result_totext (status));
00656                             break;
00657                     }
00658                     
00659                     break;
00660 
00661                   case REMOVE:
00662                     token = next_token (&val, (unsigned *)0, cfile);
00663                     if (token != END_OF_FILE && token != EOL) {
00664                             printf ("usage: remove\n");
00665                             skip_to_semi (cfile);
00666                             break;
00667                     }
00668                     
00669                     if (!connected) {
00670                             printf ("not connected.\n");
00671                             break;
00672                     }
00673 
00674                     if (!oh) {
00675                             printf ("no object.\n");
00676                             break;
00677                     }
00678 
00679                     status = dhcpctl_object_remove(connection, oh);
00680                     if (status == ISC_R_SUCCESS)
00681                             status = dhcpctl_wait_for_completion
00682                                     (oh, &waitstatus);
00683                     if (status == ISC_R_SUCCESS)
00684                             status = waitstatus;
00685                     if (status != ISC_R_SUCCESS) {
00686                             printf ("can't destroy object: %s\n",
00687                                     isc_result_totext (status));
00688                             break;
00689                     }
00690                     omapi_object_dereference (&oh, MDL);
00691                     break;
00692 
00693                   case REFRESH:
00694                     token = next_token (&val, (unsigned *)0, cfile);
00695                     if (token != END_OF_FILE && token != EOL) {
00696                             printf ("usage: refresh\n");
00697                             skip_to_semi (cfile);
00698                             break;
00699                     }
00700                     
00701                     if (!connected) {
00702                             printf ("not connected.\n");
00703                             break;
00704                     }
00705 
00706                     if (!oh) {
00707                             printf ("no object.\n");
00708                             break;
00709                     }
00710 
00711                     status = dhcpctl_object_refresh(connection, oh);
00712                     if (status == ISC_R_SUCCESS)
00713                             status = dhcpctl_wait_for_completion
00714                                     (oh, &waitstatus);
00715                     if (status == ISC_R_SUCCESS)
00716                             status = waitstatus;
00717                     if (status != ISC_R_SUCCESS) {
00718                             printf ("can't refresh object: %s\n",
00719                                     isc_result_totext (status));
00720                             break;
00721                     }
00722                     
00723                     break;
00724             }
00725             end_parse (&cfile);
00726         } while (1);
00727 
00728         exit (0);
00729 }
00730 
00731 /* Sigh */
00732 isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
00733                                      control_object_state_t newstate)
00734 {
00735         if (newstate != server_shutdown)
00736                 return ISC_R_SUCCESS;
00737         exit (0);
00738 }

Generated on 5 Apr 2014 for ISC DHCP by  doxygen 1.6.1