]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
Revamp parsing, do connections interactively, support base64 keys.
authorTed Lemon <source@isc.org>
Wed, 2 May 2001 06:45:58 +0000 (06:45 +0000)
committerTed Lemon <source@isc.org>
Wed, 2 May 2001 06:45:58 +0000 (06:45 +0000)
dhcpctl/omshell.c

index 5402e67e20f3eb4aa05ef3abee1ef1929caffb51..24d2b6bfd14146f2ccfdf8f82e9dae301b620618 100644 (file)
@@ -90,44 +90,22 @@ int main (int argc, char **argv, char **envp)
        dhcpctl_handle oh;
        dhcpctl_data_string cid, ip_addr;
        dhcpctl_data_string result, groupname, identifier;
-       const char *name = 0, *pass = 0, *algorithm = "hmac-md5";
+       struct data_string secret;
+       const char *name = 0, *algorithm = "hmac-md5";
        int i, j;
        int port = 7911;
        const char *server = "127.0.0.1";
        struct parse *cfile;
        enum dhcp_token token;
        const char *val;
+       char *s;
        char buf[1024];
        char s1[1024];
+       int connected = 0;
 
        for (i = 1; i < argc; i++) {
-               if (!strcmp (argv[i], "-n")) {
-                       if (++i == argc)
-                               usage(argv[0]);
-                       name = argv[i];
-               } else if (!strcmp (argv[i], "-p")) {
-                       if (++i == argc)
-                               usage(argv[0]);
-                       pass = argv[i];
-               } else if (!strcmp (argv[i], "-a")) {
-                       if (++i == argc)
-                               usage(argv[0]);
-                       algorithm = argv[i];
-               } else if (!strcmp (argv[i], "-s")) {
-                       if (++i == argc)
-                               usage(argv[0]);
-                       server = argv[i];
-               } else if (!strcmp (argv[i], "-P")) {
-                       if (++i == argc)
-                               usage(argv[0]);
-                       port = atoi (argv[i]);
-               } else {
-                       usage(argv[0]);
-               }
-       }
-
-       if ((name || pass) && !(name && pass))
                usage(argv[0]);
+       }
 
        status = dhcpctl_initialize ();
        if (status != ISC_R_SUCCESS) {
@@ -136,220 +114,419 @@ int main (int argc, char **argv, char **envp)
                exit (1);
        }
 
-       authenticator = dhcpctl_null_handle;
-
-       if (name) {
-               status = dhcpctl_new_authenticator (&authenticator,
-                                                   name, algorithm, pass,
-                                                   strlen (pass) + 1);
-               if (status != ISC_R_SUCCESS) {
-                       fprintf (stderr, "Cannot create authenticator: %s\n",
-                                isc_result_totext (status));
-                       exit (1);
-               }
-       }
-
-       memset (&connection, 0, sizeof connection);
-       status = dhcpctl_connect (&connection, server, port, authenticator);
-       if (status != ISC_R_SUCCESS) {
-               fprintf (stderr, "dhcpctl_connect: %s\n",
-                        isc_result_totext (status));
-               exit (1);
-       }
-
        memset (&oh, 0, sizeof oh);
 
        do {
+           if (!connected) {
+           } else if (oh == NULL) {
+               printf ("obj: <null>\n");
+           } else {
+               dhcpctl_remote_object_t *r = (dhcpctl_remote_object_t *)oh;
+               omapi_generic_object_t *g =
+                       (omapi_generic_object_t *)(r -> inner);
+               
                printf ("obj: ");
-               if (oh == NULL) {
-                       printf ("<null>\n");
-               } else {
-                       dhcpctl_remote_object_t *r =
-                               (dhcpctl_remote_object_t *)oh;
-                       omapi_generic_object_t *g =
-                               (omapi_generic_object_t *)(r -> inner);
-
-                       if (r -> rtype -> type != omapi_datatype_string) {
-                               printf ("?\n");
-                       } else {
-                               printf ("%.*s\n",
-                                       (int)(r -> rtype -> u . buffer . len),
-                                       r -> rtype -> u . buffer . value);
-                       }
-
-                       for (i = 0; i < g -> nvalues; i++) {
-                               omapi_value_t *v = g -> values [i];
 
-                               printf ("%.*s = ", (int)v -> name -> len,
-                                       v -> name -> value);
-
-                               switch (v -> value -> type) {
-                               case omapi_datatype_int:
-                                       printf ("%d\n",
-                                               v -> value -> u . integer);
-                                       break;
-
-                               case omapi_datatype_string:
-                                       printf ("\"%.*s\"\n",
-                                               (int)v -> value -> u.buffer.len,
-                                               v -> value -> u.buffer.value);
-                                       break;
-
-                               case omapi_datatype_data:
-                                       printf ("%s\n",
-                                               print_hex_1
-                                               (v -> value -> u.buffer.len,
+               if (r -> rtype -> type != omapi_datatype_string) {
+                       printf ("?\n");
+               } else {
+                       printf ("%.*s\n",
+                               (int)(r -> rtype -> u . buffer . len),
+                               r -> rtype -> u . buffer . value);
+               }
+               
+               for (i = 0; i < g -> nvalues; i++) {
+                   omapi_value_t *v = g -> values [i];
+                       
+                   printf ("%.*s = ", (int)v -> name -> len,
+                           v -> name -> value);
+                       
+                   switch (v -> value -> type) {
+                         case omapi_datatype_int:
+                           printf ("%d\n",
+                                   v -> value -> u . integer);
+                           break;
+                        
+                         case omapi_datatype_string:
+                           printf ("\"%.*s\"\n",
+                                   (int) v -> value -> u.buffer.len,
+                                   v -> value -> u.buffer.value);
+                           break;
+                               
+                         case omapi_datatype_data:
+                           printf ("%s\n",
+                                   print_hex_1 (v -> value -> u.buffer.len,
                                                 v -> value -> u.buffer.value,
                                                 60));
-                                       break;
-
-                               case omapi_datatype_object:
-                                       printf ("<obj>\n");
-                                       break;
-                               }
-                       }
+                           break;
+                           
+                         case omapi_datatype_object:
+                           printf ("<obj>\n");
+                           break;
+                   }
                }
-
-               fputs ("> ", stdout);
-               fflush (stdout);
-               if (fgets (buf, sizeof(buf), stdin) == NULL)
-                       break;
-
-               status = new_parse (&cfile, 0, buf, strlen(buf), "<STDIN>");
-               check(status, "new_parse()");
-
-               token = next_token (&val, (unsigned *)0, cfile);
-               switch (token) {
-                     default:
-                       parse_warn (cfile, "unknown token: %s", val);
-                       break;
-
-                     case END_OF_FILE:
-                       break;
-
-                     case TOKEN_HELP:
-                     case '?':
-                       printf ("Commands:\n");
-                       printf ("  new <object-type>\n");
-                       printf ("  set <name> = <value>\n");
-                       printf ("  create\n");
-                       printf ("  open\n");
-                       break;
-
-                     case TOKEN_NEW:
-                       token = next_token (&val, (unsigned *)0, cfile);
-                       if ((!is_identifier (token) && token != STRING) ||
-                           next_token (NULL,
-                                       (unsigned *)0, cfile) != END_OF_FILE)
-                       {
-                               printf ("usage: new <object-type>\n");
-                               break;
-                       }
-
-                       if (oh) {
-                               printf ("an object is already open.\n");
-                               break;
-                       }
-
-                       status = dhcpctl_new_object (&oh, connection, val);
-                       if (status != ISC_R_SUCCESS) {
-                               printf ("can't create object: %s\n",
-                                       isc_result_totext (status));
-                               break;
-                       }
-
-                       break;
-
-                     case TOKEN_CLOSE:
-                       if (next_token (NULL,
-                                       (unsigned *)0, cfile) != END_OF_FILE) {
-                               printf ("usage: close\n");
-                       }
-
-                       omapi_object_dereference (&oh, MDL);
-
-                       break;
-
-                     case TOKEN_SET:
-                       token = next_token (&val, (unsigned *)0, cfile);
-
-                       if ((!is_identifier (token) && token != STRING) ||
-                           next_token (NULL, (unsigned *)0, cfile) != '=')
-                       {
-                               printf ("usage: set <name> = <value>\n");
-                               break;
-                       }
-
-                       if (oh == NULL) {
-                               printf ("no open object.\n");
-                               break;
-                       }
-
-                       s1[0] = '\0';
-                       strncat (s1, val, sizeof(s1)-1);
-
-                       token = next_token (&val, (unsigned *)0, cfile);
-                       switch (token) {
-                       case STRING:
-                               dhcpctl_set_string_value (oh, val, s1);
-                               break;
-
-                       case NUMBER:
-                               dhcpctl_set_int_value (oh, atoi (val), s1);
+           }
+
+           fputs ("> ", stdout);
+           fflush (stdout);
+           if (fgets (buf, sizeof(buf), stdin) == NULL)
+               break;
+
+           status = new_parse (&cfile, 0, buf, strlen(buf), "<STDIN>", 1);
+           check(status, "new_parse()");
+           
+           token = next_token (&val, (unsigned *)0, cfile);
+           switch (token) {
+                 default:
+                   parse_warn (cfile, "unknown token: %s", val);
+                   skip_to_semi (cfile);
+                   break;
+                   
+                 case END_OF_FILE:
+                 case EOL:
+                   break;
+                   
+                 case TOKEN_HELP:
+                 case '?':
+                   printf ("Commands:\n");
+                   printf ("  port <server omapi port>\n");
+                   printf ("  server <server address>\n");
+                   printf ("  key <key name> <key value>\n");
+                   printf ("  connect\n");
+                   printf ("  new <object-type>\n");
+                   printf ("  set <name> = <value>\n");
+                   printf ("  create\n");
+                   printf ("  open\n");
+                   skip_to_semi (cfile);
+                   break;
+                   
+                 case PORT:
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (is_identifier (token)) {
+                           struct servent *se;
+                           se = getservbyname (val, "tcp");
+                           if (se)
+                                   port = ntohs (se -> s_port);
+                           else {
+                                   printf ("unknown service name: %s", val);
+                                   break;
+                           }
+                   } else if (token == NUMBER) {
+                           port = atoi (val);
+                   } else {
+                           skip_to_semi (cfile);
+                           printf ("usage: port <port>\n");
+                           break;
+                   }
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token != END_OF_FILE && token != EOL) {
+                           printf ("usage: port <server>\n");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   break;
+
+                 case SERVER:
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token == NUMBER) {
+                           int alen = (sizeof buf) - 1;
+                           int len;
+
+                           s = &buf [0];
+                           len = strlen (val);
+                           if (len + 1 > alen) {
+                             baddq:
+                               printf ("usage: server <server>\n");
+                               skip_to_semi (cfile);
                                break;
+                           }                       strcpy (buf, val);
+                           s += len;
+                           token = next_token (&val, (unsigned *)0, cfile);
+                           if (token != DOT)
+                                   goto baddq;
+                           *s++ = '.';
+                           token = next_token (&val, (unsigned *)0, cfile);
+                           if (token != NUMBER)
+                                   goto baddq;
+                           len = strlen (val);
+                           if (len + 1 > alen)
+                                   goto baddq;
+                           strcpy (s, val);
+                           s += len;
+                           token = next_token (&val, (unsigned *)0, cfile);
+                           if (token != DOT)
+                                   goto baddq;
+                           *s++ = '.';
+                           token = next_token (&val, (unsigned *)0, cfile);
+                           if (token != NUMBER)
+                                   goto baddq;
+                           len = strlen (val);
+                           if (len + 1 > alen)
+                                   goto baddq;
+                           strcpy (s, val);
+                           s += len;
+                           token = next_token (&val, (unsigned *)0, cfile);
+                           if (token != DOT)
+                                   goto baddq;
+                           *s++ = '.';
+                           token = next_token (&val, (unsigned *)0, cfile);
+                           if (token != NUMBER)
+                                   goto baddq;
+                           len = strlen (val);
+                           if (len + 1 > alen)
+                                   goto baddq;
+                           strcpy (s, val);
+                           val = &buf [0];
+                   } else if (is_identifier (token)) {
+                           /* Use val directly. */
+                   } else {
+                           printf ("usage: server <server>\n");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+
+                   s = dmalloc (strlen (val) + 1, MDL);
+                   if (!server) {
+                           printf ("no memory to store server name.");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   strcpy (s, val);
+                   server = s;
+
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token != END_OF_FILE && token != EOL) {
+                           printf ("usage: server <server>\n");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   break;
+
+                 case KEY:
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (!is_identifier (token)) {
+                           printf ("usage: key <name> <value>");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   s = dmalloc (strlen (val) + 1, MDL);
+                   if (!s) {
+                           printf ("no memory for key name.");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   strcpy (s, val);
+                   name = s;
+                   memset (&secret, 0, sizeof secret);
+                   if (!parse_base64 (&secret, cfile)) {
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token != END_OF_FILE && token != EOL) {
+                           printf ("usage: key <name> <secret>\n");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   break;
+
+                 case CONNECT:
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token != END_OF_FILE && token != EOL) {
+                           printf ("usage: connect\n");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+
+                   authenticator = dhcpctl_null_handle;
+
+                   if (name) {
+                       status = dhcpctl_new_authenticator (&authenticator,
+                                                           name, algorithm,
+                                                           secret.data,
+                                                           secret.len);
 
-                       default:
-                               printf ("invalid value.\n");
-                       }
-
-                       break;
-
-                     case TOKEN_CREATE:
-                     case TOKEN_OPEN:
-                       if (next_token (NULL,
-                                       (unsigned *)0, cfile) != END_OF_FILE) {
-                               printf ("usage: %s\n", val);
-                       }
-
-                       i = 0;
-                       if (token == TOKEN_CREATE)
-                               i = DHCPCTL_CREATE | DHCPCTL_EXCL;
-
-                       status = dhcpctl_open_object (oh, connection, i);
-                       if (status == ISC_R_SUCCESS)
-                               status = dhcpctl_wait_for_completion
-                                       (oh, &waitstatus);
-                       if (status == ISC_R_SUCCESS)
-                               status = waitstatus;
-                       if (status != ISC_R_SUCCESS) {
-                               printf ("can't open object: %s\n",
-                                       isc_result_totext (status));
-                               break;
-                       }
-
-                       break;
-
-                     case UPDATE:
-                       if (next_token (NULL, (unsigned *)0,
-                                       cfile) != END_OF_FILE) {
-                               printf ("usage: %s\n", val);
-                       }
-
-                       status = dhcpctl_object_update(connection, oh);
-                       if (status == ISC_R_SUCCESS)
-                               status = dhcpctl_wait_for_completion
-                                       (oh, &waitstatus);
-                       if (status == ISC_R_SUCCESS)
-                               status = waitstatus;
                        if (status != ISC_R_SUCCESS) {
-                               printf ("can't update object: %s\n",
-                                       isc_result_totext (status));
-                               break;
+                           fprintf (stderr,
+                                    "Cannot create authenticator: %s\n",
+                                    isc_result_totext (status));
+                           break;
                        }
-
-                       break;
-               }
-       } while (1);
+                   }
+
+                   memset (&connection, 0, sizeof connection);
+                   status = dhcpctl_connect (&connection,
+                                             server, port, authenticator);
+                   if (status != ISC_R_SUCCESS) {
+                           fprintf (stderr, "dhcpctl_connect: %s\n",
+                                    isc_result_totext (status));
+                           break;
+                   }
+                   connected = 1;
+                   break;
+
+                 case TOKEN_NEW:
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if ((!is_identifier (token) && token != STRING)) {
+                           printf ("usage: new <object-type>\n");
+                           break;
+                   }
+                   
+                   if (oh) {
+                           printf ("an object is already open.\n");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   
+                   if (!connected) {
+                           printf ("not connected.");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+
+                   status = dhcpctl_new_object (&oh, connection, val);
+                   if (status != ISC_R_SUCCESS) {
+                           printf ("can't create object: %s\n",
+                                   isc_result_totext (status));
+                           break;
+                   }
+                   
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token != END_OF_FILE && token != EOL) {
+                           printf ("usage: new <object-type>\n");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   break;
+
+                 case TOKEN_CLOSE:
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token != END_OF_FILE && token != EOL) {
+                           printf ("usage: close\n");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+
+                   if (!connected) {
+                           printf ("not connected.");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+
+                   omapi_object_dereference (&oh, MDL);
+                   
+                   break;
+
+                 case TOKEN_SET:
+                   token = next_token (&val, (unsigned *)0, cfile);
+
+                   if ((!is_identifier (token) && token != STRING)) {
+                         set_usage:
+                           printf ("usage: set <name> = <value>\n");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   
+                   if (oh == NULL) {
+                           printf ("no open object.\n");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   
+                   if (!connected) {
+                           printf ("not connected.");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+
+                   s1[0] = '\0';
+                   strncat (s1, val, sizeof(s1)-1);
+                   
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token != EQUAL)
+                           goto set_usage;
+
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   switch (token) {
+                         case STRING:
+                           dhcpctl_set_string_value (oh, val, s1);
+                           break;
+                           
+                         case NUMBER:
+                           dhcpctl_set_int_value (oh, atoi (val), s1);
+                           break;
+                           
+                         default:
+                           printf ("invalid value.\n");
+                   }
+                   
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token != END_OF_FILE && token != EOL)
+                           goto set_usage;
+                   break;
+                   
+                 case TOKEN_CREATE:
+                 case TOKEN_OPEN:
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token != END_OF_FILE && token != EOL) {
+                           printf ("usage: %s\n", val);
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   
+                   if (!connected) {
+                           printf ("not connected.");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+
+                   i = 0;
+                   if (token == TOKEN_CREATE)
+                           i = DHCPCTL_CREATE | DHCPCTL_EXCL;
+                   
+                   status = dhcpctl_open_object (oh, connection, i);
+                   if (status == ISC_R_SUCCESS)
+                           status = dhcpctl_wait_for_completion
+                                   (oh, &waitstatus);
+                   if (status == ISC_R_SUCCESS)
+                           status = waitstatus;
+                   if (status != ISC_R_SUCCESS) {
+                           printf ("can't open object: %s\n",
+                                   isc_result_totext (status));
+                           break;
+                   }
+                   
+                   break;
+
+                 case UPDATE:
+                   token = next_token (&val, (unsigned *)0, cfile);
+                   if (token != END_OF_FILE && token != EOL) {
+                           printf ("usage: %s\n", val);
+                           skip_to_semi (cfile);
+                           break;
+                   }
+                   
+                   if (!connected) {
+                           printf ("not connected.");
+                           skip_to_semi (cfile);
+                           break;
+                   }
+
+                   status = dhcpctl_object_update(connection, oh);
+                   if (status == ISC_R_SUCCESS)
+                           status = dhcpctl_wait_for_completion
+                                   (oh, &waitstatus);
+                   if (status == ISC_R_SUCCESS)
+                           status = waitstatus;
+                   if (status != ISC_R_SUCCESS) {
+                           printf ("can't update object: %s\n",
+                                   isc_result_totext (status));
+                           break;
+                   }
+                   
+                   break;
+           }
+       } while (token != END_OF_FILE);
 
        exit (0);
 }