]> andersk Git - moira.git/blobdiff - clients/mrtest/mrtest.c
Switch from Imake-based build system to autoconf-based.
[moira.git] / clients / mrtest / mrtest.c
index 9f00056d9253c03e873a7e615ea1fc9b58b7742c..aa5252fe58300894569b45d7cad71ee9a93892f8 100644 (file)
-/*
- *     $Source$
- *     $Author$
- *     $Header$
+/* $Id$
  *
- *     Copyright (C) 1987 by the Massachusetts Institute of Technology
- *     For copying and distribution information, please see the file
- *     <mit-copyright.h>.
+ * Bare-bones Moira client
  *
+ * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
  */
 
-#ifndef lint
-static char *rcsid_test_c = "$Header$";
-#endif lint
-
 #include <mit-copyright.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/file.h>
+#include <moira.h>
+
+#include <errno.h>
 #include <fcntl.h>
-#include <ctype.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <moira.h>
-#include <ss/ss.h>
-
-int ss;
-int recursion = 0;
-extern ss_request_table moira_test;
-extern int sending_version_no;
-int count;
-
-main(argc, argv)
-       int argc;
-       char **argv;
-{      
-       int status;
-       char *whoami;
-       
-       whoami = argv[0];
-       
-       init_ss_err_tbl();
-       initialize_sms_error_table();
-       initialize_krb_error_table();
-
-       ss = ss_create_invocation("moira", "2.0", (char *)NULL,
-                                 &moira_test, &status);
-       if (status != 0) {
-               com_err(whoami, status, "Unable to create invocation");
-               exit(1);
-       }
-       if (argc > 1) {
-           argv++;
-           ss_execute_command(ss, argv);
-       }
-       ss_listen(ss, &status);
-       if (status != 0) {
-               com_err(whoami, status, 0);
-               exit(1);
-       }
-       exit(0);
+#include <unistd.h>
+
+#ifdef HAVE_READLINE
+#include "readline.h"
+#include "history.h"
+#endif
+
+RCSID("$Header$");
+
+int recursion = 0, interactive;
+int count, quit = 0, cancel = 0;
+char *whoami;
+sigjmp_buf jb;
+
+#define MAXARGS 20
+
+void discard_input(void);
+char *mr_gets(char *prompt, char *buf, size_t len);
+void execute_line(char *cmdbuf);
+int parse(char *buf, char *argv[MAXARGS]);
+int print_reply(int argc, char **argv, void *hint);
+void test_noop(void);
+void test_connect(int argc, char **argv);
+void test_disconnect(void);
+void test_host(void);
+void test_motd(void);
+void test_query(int argc, char **argv);
+void test_auth(void);
+void test_access(int argc, char **argv);
+void test_dcm(void);
+void test_script(int argc, char **argv);
+void test_list_requests(void);
+
+int main(int argc, char **argv)
+{
+  char cmdbuf[BUFSIZ];
+  struct sigaction action;
+
+  whoami = argv[0];
+  interactive = (isatty(0) && isatty(1));
+
+  initialize_sms_error_table();
+  initialize_krb_error_table();
+
+#ifdef HAVE_READLINE
+  /* we don't want filename completion */
+  rl_bind_key('\t', rl_insert);
+#endif
+
+  action.sa_handler = discard_input;
+  action.sa_flags = 0;
+  sigemptyset(&action.sa_mask);
+  sigaction(SIGINT, &action, NULL);
+  sigsetjmp(jb, 1);
+
+  while (!quit)
+    {
+      if (!mr_gets("moira:  ", cmdbuf, BUFSIZ))
+       break;
+      execute_line(cmdbuf);
+    }
+  mr_disconnect();
+  exit(0);
 }
 
-test_noop()
+void discard_input(void)
 {
-       int status = mr_noop();
-       if (status) ss_perror(ss, status, "");
+  putc('\n', stdout);
+
+  /* if we're inside a script, we have to clean up file descriptors,
+     so don't jump out yet */
+  if (recursion)
+    cancel = 1;
+  else
+    siglongjmp(jb, 1);
 }
 
-test_new()
+char *mr_gets(char *prompt, char *buf, size_t len)
 {
-       sending_version_no = MR_VERSION_2;
+  char *in;
+#ifdef HAVE_READLINE
+  if (interactive)
+    {
+      in = readline(prompt);
+
+      if (!in)
+       return NULL;
+      if (*in)
+       add_history(in);
+      strncpy(buf, in, len - 1);
+      buf[len] = 0;
+      free(in);
+
+      return buf;
+    }
+#endif
+  printf("%s", prompt);
+  fflush(stdout);
+  in = fgets(buf, len, stdin);
+  if (!in)
+    return in;
+  if (strchr(buf, '\n'))
+    *(strchr(buf, '\n')) = '\0';
+  return buf;
 }
 
-test_old()
+void execute_line(char *cmdbuf)
 {
-       sending_version_no = MR_VERSION_1;
+  int argc;
+  char *argv[MAXARGS];
+
+  argc = parse(cmdbuf, argv);
+  if (argc == 0)
+    return;
+  if (!strcmp(argv[0], "noop"))
+    test_noop();
+  else if (!strcmp(argv[0], "connect") || !strcmp(argv[0], "c"))
+    test_connect(argc, argv);
+  else if (!strcmp(argv[0], "disconnect") || !strcmp(argv[0], "d"))
+    test_disconnect();
+  else if (!strcmp(argv[0], "host"))
+    test_host();
+  else if (!strcmp(argv[0], "motd"))
+    test_motd();
+  else if (!strcmp(argv[0], "query") || !strcmp(argv[0], "qy"))
+    test_query(argc, argv);
+  else if (!strcmp(argv[0], "auth") || !strcmp(argv[0], "a"))
+    test_auth();
+  else if (!strcmp(argv[0], "access"))
+    test_access(argc, argv);
+  else if (!strcmp(argv[0], "dcm"))
+    test_dcm();
+  else if (!strcmp(argv[0], "script") || !strcmp(argv[0], "s"))
+    test_script(argc, argv);
+  else if (!strcmp(argv[0], "list_requests") ||
+         !strcmp(argv[0], "lr") || !strcmp(argv[0], "?"))
+    test_list_requests();
+  else if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "Q"))
+    quit = 1;
+  else
+    {
+      fprintf(stderr, "moira: Unknown request \"%s\".  "
+             "Type \"?\" for a request list.\n", argv[0]);
+    }
 }
 
-test_connect(argc, argv)
-int argc;
-char *argv[];
+int parse(char *buf, char *argv[MAXARGS])
 {
-       char *server = "";
-       int status;
-
-       if (argc > 1) {
-           server = argv[1];
+  char *p;
+  int argc, num;
+
+  if (!*buf)
+    return 0;
+
+  for (p = buf, argc = 0, argv[0] = buf; *p && *p != '\n'; p++)
+    {
+      if (*p == '"')
+       {
+         char *d = p++;
+         /* skip to close-quote, copying back over open-quote */
+         while (*p != '"')
+           {
+             if (!*p || *p == '\n')
+               {
+                 fprintf(stderr,
+                         "moira: Unbalanced quotes in command line\n");
+                 return 0;
+               }
+             /* deal with \### or \\ */
+             if (*p == '\\')
+               {
+                 if (*++p != '"' && (*p < '0' || *p > '9') && (*p != '\\'))
+                   {
+                     fprintf(stderr, "moira: Bad use of \\\n");
+                     return 0;
+                   }
+                 else if (*p >= '0' && *p <= '9')
+                   {
+                     num = (*p - '0') * 64 + (*++p - '0') * 8 + (*++p - '0');
+                     *p = num;
+                   }
+               }
+             *d++ = *p++;
+           }
+         if (p == d + 1)
+           {
+             *d = '\0';
+             p++;
+           }
+         else
+           {
+             while (p >= d)
+               *p-- = ' ';
+           }
+       }
+      if (*p == ' ' || *p == '\t')
+       {
+         /* skip whitespace */
+         for (*p++ = '\0'; *p == ' ' || *p == '\t'; p++)
+           ;
+         if (*p && *p != '\n')
+           argv[++argc] = p--;
        }
-       status = mr_connect(server);
-       if (status) ss_perror(ss, status, "");
+    }
+  if (*p == '\n')
+    *p = '\0';
+  return argc + 1;
 }
 
-test_disconnect()
+void test_noop(void)
 {
-       int status = mr_disconnect();
-       if (status) ss_perror(ss, status, "");
+  int status = mr_noop();
+  if (status)
+    com_err("moira (noop)", status, "");
 }
 
-test_host()
+void test_connect(int argc, char *argv[])
 {
-        char host[BUFSIZ];
-        int status;
-
-        memset(host, 0, sizeof(host));
+  char *server = "";
+  int status;
+
+  if (argc > 1)
+    server = argv[1];
+  status = mr_connect(server);
+  if (status)
+    com_err("moira (connect)", status, "");
+}
 
-       if (status = mr_host(host, sizeof(host) - 1))
-           ss_perror(ss, status, "");
-       else
-           printf("You are connected to host %s\n", host);
+void test_disconnect(void)
+{
+  int status = mr_disconnect();
+  if (status)
+    com_err("moira (disconnect)", status, "");
 }
 
-test_auth()
+void test_host(void)
 {
-       int status;
+  char host[BUFSIZ];
+  int status;
+
+  memset(host, 0, sizeof(host));
 
-       status = mr_auth("mrtest");
-       if (status) ss_perror(ss, status, "");
+  if ((status = mr_host(host, sizeof(host) - 1)))
+    com_err("moira (host)", status, "");
+  else
+    printf("You are connected to host %s\n", host);
 }
 
-test_script(argc, argv)
-int argc;
-char *argv[];
+void test_auth(void)
 {
-    FILE *inp;
-    char input[BUFSIZ], *cp;
-    int status, oldstdout, oldstderr;
+  int status;
 
-    if (recursion > 8) {
-       ss_perror(ss, 0, "too many levels deep in script files\n");
-       return;
+  status = mr_auth("mrtest");
+  if (status)
+    com_err("moira (auth)", status, "");
+}
+
+void test_script(int argc, char *argv[])
+{
+  FILE *inp;
+  char input[BUFSIZ], *cp;
+  int status, oldstdout, oldstderr;
+
+  if (recursion > 8)
+    {
+      com_err("moira (script)", 0, "too many levels deep in script files\n");
+      return;
     }
 
-    if (argc < 2) {
-       ss_perror(ss, 0, "Usage: script input_file [ output_file ]");
-       return;
+  if (argc < 2)
+    {
+      com_err("moira (script)", 0, "Usage: script input_file [ output_file ]");
+      return;
     }
 
-    inp = fopen(argv[1], "r");
-    if (inp == NULL) {
-       sprintf(input, "Cannot open input file %s", argv[1]);
-       ss_perror(ss, 0, input);
-       return;
+  inp = fopen(argv[1], "r");
+  if (!inp)
+    {
+      sprintf(input, "Cannot open input file %s", argv[1]);
+      com_err("moira (script)", 0, input);
+      return;
     }
 
-    if (argc == 3) {
-       printf("Redirecting output to %s\n", argv[2]);
-       fflush(stdout);
-       oldstdout = dup(1);
-       close(1);
-       status = open(argv[2], O_CREAT|O_WRONLY|O_APPEND, 0664);
-       if (status != 1) {
-           close(status);
-           dup2(oldstdout, 1);
-           argc = 2;
-           sprintf(input, "Unable to redirect output to %s\n", argv[2]);
-           ss_perror(ss, errno, input);
-       } else {
-           fflush(stderr);
-           oldstderr = dup(2);
-           close(2);
-           dup2(1, 2);
+  if (argc == 3)
+    {
+      printf("Redirecting output to %s\n", argv[2]);
+      fflush(stdout);
+      oldstdout = dup(1);
+      close(1);
+      status = open(argv[2], O_CREAT|O_WRONLY|O_APPEND, 0664);
+      if (status != 1)
+       {
+         close(status);
+         dup2(oldstdout, 1);
+         argc = 2;
+         sprintf(input, "Unable to redirect output to %s\n", argv[2]);
+         com_err("moira (script)", errno, input);
+       }
+      else
+       {
+         fflush(stderr);
+         oldstderr = dup(2);
+         close(2);
+         dup2(1, 2);
        }
     }
 
-    recursion++;
-
-    for(;;) {
-       if (fgets(input, BUFSIZ, inp) == NULL)
-         break;
-       if ((cp = strchr(input, '\n')) != (char *)NULL)
-         *cp = 0;
-       if (input[0] == 0) {
-           printf("\n");
-           continue;
+  recursion++;
+
+  while (!cancel)
+    {
+      if (!fgets(input, BUFSIZ, inp))
+       break;
+      if ((cp = strchr(input, '\n')))
+       *cp = '\0';
+      if (input[0] == 0)
+       {
+         printf("\n");
+         continue;
        }
-       if (input[0] == '%') {
-           for (cp = &input[1]; *cp && isspace(*cp); cp++);
-           printf("Comment: %s\n", cp);
-           continue;
-       }
-       printf("Executing: %s\n", input);
-       ss_execute_line(ss, input, &status);
-       if (status == SS_ET_COMMAND_NOT_FOUND) {
-           printf("Bad command: %s\n", input);
+      if (input[0] == '%')
+       {
+         for (cp = &input[1]; *cp && isspace(*cp); cp++)
+           ;
+         printf("Comment: %s\n", cp);
+         continue;
        }
+      printf("Executing: %s\n", input);
+      execute_line(input);
     }
 
-    recursion--;
-
-    fclose(inp);
-    if (argc == 3) {
-       fflush(stdout);
-       close(1);
-       dup2(oldstdout, 1);
-       close(oldstdout);
-       fflush(stderr);
-       close(2);
-       dup2(oldstderr, 2);
-       close(oldstderr);
+  recursion--;
+  if (!recursion)
+    cancel = 0;
+
+  fclose(inp);
+  if (argc == 3)
+    {
+      fflush(stdout);
+      close(1);
+      dup2(oldstdout, 1);
+      close(oldstdout);
+      fflush(stderr);
+      close(2);
+      dup2(oldstderr, 2);
+      close(oldstderr);
     }
 }
 
-char *concat(str1, str2)
-       char *str1, *str2;
+int print_reply(int argc, char **argv, void *hint)
 {
-       char *rtn;
-       extern char *malloc();
-       
-       if (!str1) {
-               int len = strlen(str2) + 1 ;
-               rtn = malloc(len);
-               memcpy(rtn, str2, len);
-       } else {
-               int len1 = strlen(str1);
-               int len2 = strlen(str2) + 1;
-               rtn = malloc(len1+len2);
-               memcpy(rtn, str1, len1);
-               memcpy(rtn+len1, str2, len2);
-       }
-       return rtn;
+  int i;
+  for (i = 0; i < argc; i++)
+    {
+      if (i != 0)
+       printf(", ");
+      printf("%s", argv[i]);
+    }
+  printf("\n");
+  count++;
+  return MR_CONT;
 }
 
-
-
-print_reply(argc, argv)
-       int argc;
-       char **argv;
+void test_query(int argc, char **argv)
 {
-       int i;
-       for (i = 0; i < argc; i++) {
-               if (i != 0) printf(", ");
-               printf("%s", argv[i]);
-       }
-       printf("\n");
-       count++;
-       return(MR_CONT);
-}
+  int status;
+  sigset_t sigs;
 
-test_query(argc, argv)
-       int argc;
-       char **argv;
-{
-       int status;
-       if (argc < 2) {
-               ss_perror(ss, 0, "Usage: query handle [ args ... ]");
-               return;
-       }
+  if (argc < 2)
+    {
+      com_err("moira (query)", 0, "Usage: query handle [ args ... ]");
+      return;
+    }
 
-       count = 0;
-       status = mr_query(argv[1], argc-2, argv+2, print_reply, (char *)NULL);
-       printf("%d tuple%s\n", count, ((count == 1) ? "" : "s"));
-       if (status) ss_perror(ss, status, "");
+  count = 0;
+  /* Don't allow ^C during the query: it will confuse libmoira's
+     internal state. (Yay static variables) */
+  sigemptyset(&sigs);
+  sigaddset(&sigs, SIGINT);
+  sigprocmask(SIG_BLOCK, &sigs, NULL);
+  status = mr_query(argv[1], argc - 2, argv + 2, print_reply, NULL);
+  sigprocmask(SIG_UNBLOCK, &sigs, NULL);
+  printf("%d tuple%s\n", count, ((count == 1) ? "" : "s"));
+  if (status)
+    com_err("moira (query)", status, "");
 }
 
-test_access(argc, argv)
-       int argc;
-       char **argv;
+void test_access(int argc, char **argv)
 {
-       int status;
-       if (argc < 2) {
-               ss_perror(ss, 0, "Usage: access handle [ args ... ]");
-               return;
-       }
-       status = mr_access(argv[1], argc-2, argv+2);
-       if (status) ss_perror(ss, status, "");
+  int status;
+  if (argc < 2)
+    {
+      com_err("moira (access)", 0, "Usage: access handle [ args ... ]");
+      return;
+    }
+  status = mr_access(argv[1], argc - 2, argv + 2);
+  if (status)
+    com_err("moira (access)", status, "");
 }
 
-
-test_dcm(argc, argv)
-       int argc;
-       char **argv;
+void test_dcm()
 {
-       int status;
+  int status;
 
-       if (status = mr_do_update())
-         ss_perror(ss, status, " while triggering dcm");
+  if ((status = mr_do_update()))
+    com_err("moira (dcm)", status, " while triggering dcm");
 }
 
+void test_motd()
+{
+  int status;
+  char *motd;
+
+  if ((status = mr_motd(&motd)))
+    com_err("moira (motd)", status, " while getting motd");
+  if (motd)
+    printf("%s\n", motd);
+  else
+    printf("No message of the day.\n");
+}
 
-test_motd(argc, argv)
-       int argc;
-       char **argv;
+void test_list_requests(void)
 {
-       int status;
-       char *motd;
-
-       if (status = mr_motd(&motd))
-         ss_perror(ss, status, " while getting motd");
-       if (motd)
-         printf("%s\n", motd);
-       else
-         printf("No message of the day.\n");
+  printf("Available moira requests:\n");
+  printf("\n");
+  printf("noop\t\t\tAsk Moira to do nothing\n");
+  printf("connect, c\t\tConnect to Moira server\n");
+  printf("disconnect, d\t\tDisconnect from server\n");
+  printf("host\t\t\tIdentify the server host\n");
+  printf("motd, m\t\t\tGet the Message of the Day\n");
+  printf("query, qy\t\tMake a query.\n");
+  printf("auth, a\t\t\tAuthenticate to Moira.\n");
+  printf("access\t\t\tCheck access to a Moira query.\n");
+  printf("dcm\t\t\tTrigger the DCM\n");
+  printf("script, s\t\tRead commands from a script.\n");
+  printf("list_requests, lr, ?\tList available commands.\n");
+  printf("quit, Q\t\t\tLeave the subsystem.\n");
 }
This page took 0.051886 seconds and 4 git commands to generate.