3 * Bare-bones Moira client
5 * Copyright (C) 1987-1998 by the Massachusetts Institute of Technology
6 * For copying and distribution information, please see the file
10 #include <mit-copyright.h>
29 int recursion = 0, quote_output = 0, interactive;
30 int count, quit = 0, cancel = 0;
36 void discard_input(void);
37 char *mr_gets(char *prompt, char *buf, size_t len);
38 void execute_line(char *cmdbuf);
39 int parse(char *buf, char *argv[MAXARGS]);
40 int print_reply(int argc, char **argv, void *help);
42 void test_connect(int argc, char **argv);
43 void test_disconnect(void);
46 void test_query(int argc, char **argv);
48 void test_access(int argc, char **argv);
50 void test_script(int argc, char **argv);
51 void test_list_requests(void);
53 int main(int argc, char **argv)
56 struct sigaction action;
60 interactive = (isatty(0) && isatty(1));
62 while ((c = getopt(argc, argv, "q")) != -1)
71 fprintf(stderr, "Usage: mrtest [-q]\n");
76 initialize_sms_error_table();
77 initialize_krb_error_table();
80 /* we don't want filename completion */
81 rl_bind_key('\t', rl_insert);
84 action.sa_handler = discard_input;
86 sigemptyset(&action.sa_mask);
87 sigaction(SIGINT, &action, NULL);
92 if (!mr_gets("moira: ", cmdbuf, BUFSIZ))
100 void discard_input(void)
104 /* if we're inside a script, we have to clean up file descriptors,
105 so don't jump out yet */
112 char *mr_gets(char *prompt, char *buf, size_t len)
118 in = readline(prompt);
124 strncpy(buf, in, len - 1);
131 printf("%s", prompt);
133 in = fgets(buf, len, stdin);
136 if (strchr(buf, '\n'))
137 *(strchr(buf, '\n')) = '\0';
141 void execute_line(char *cmdbuf)
146 argc = parse(cmdbuf, argv);
149 if (!strcmp(argv[0], "noop"))
151 else if (!strcmp(argv[0], "connect") || !strcmp(argv[0], "c"))
152 test_connect(argc, argv);
153 else if (!strcmp(argv[0], "disconnect") || !strcmp(argv[0], "d"))
155 else if (!strcmp(argv[0], "host"))
157 else if (!strcmp(argv[0], "motd"))
159 else if (!strcmp(argv[0], "query") || !strcmp(argv[0], "qy"))
160 test_query(argc, argv);
161 else if (!strcmp(argv[0], "auth") || !strcmp(argv[0], "a"))
163 else if (!strcmp(argv[0], "access"))
164 test_access(argc, argv);
165 else if (!strcmp(argv[0], "dcm"))
167 else if (!strcmp(argv[0], "script") || !strcmp(argv[0], "s"))
168 test_script(argc, argv);
169 else if (!strcmp(argv[0], "list_requests") ||
170 !strcmp(argv[0], "lr") || !strcmp(argv[0], "?"))
171 test_list_requests();
172 else if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "Q"))
176 fprintf(stderr, "moira: Unknown request \"%s\". "
177 "Type \"?\" for a request list.\n", argv[0]);
181 int parse(char *buf, char *argv[MAXARGS])
189 for (p = buf, argc = 0, argv[0] = buf; *p && *p != '\n'; p++)
194 /* skip to close-quote, copying back over open-quote */
197 if (!*p || *p == '\n')
200 "moira: Unbalanced quotes in command line\n");
203 /* deal with \### or \\ */
206 if (*++p != '"' && (*p < '0' || *p > '9') && (*p != '\\'))
208 fprintf(stderr, "moira: Bad use of \\\n");
211 else if (*p >= '0' && *p <= '9')
213 num = (*p - '0') * 64 + (*++p - '0') * 8 + (*++p - '0');
230 if (*p == ' ' || *p == '\t')
232 /* skip whitespace */
233 for (*p++ = '\0'; *p == ' ' || *p == '\t'; p++)
235 if (*p && *p != '\n')
246 int status = mr_noop();
248 com_err("moira (noop)", status, "");
251 void test_connect(int argc, char *argv[])
258 status = mr_connect(server);
260 com_err("moira (connect)", status, "");
263 void test_disconnect(void)
265 int status = mr_disconnect();
267 com_err("moira (disconnect)", status, "");
275 memset(host, 0, sizeof(host));
277 if ((status = mr_host(host, sizeof(host) - 1)))
278 com_err("moira (host)", status, "");
280 printf("You are connected to host %s\n", host);
287 status = mr_auth("mrtest");
289 com_err("moira (auth)", status, "");
292 void test_script(int argc, char *argv[])
295 char input[BUFSIZ], *cp;
296 int status, oldstdout, oldstderr;
300 com_err("moira (script)", 0, "too many levels deep in script files\n");
306 com_err("moira (script)", 0, "Usage: script input_file [ output_file ]");
310 inp = fopen(argv[1], "r");
313 sprintf(input, "Cannot open input file %s", argv[1]);
314 com_err("moira (script)", 0, input);
320 printf("Redirecting output to %s\n", argv[2]);
324 status = open(argv[2], O_CREAT|O_WRONLY|O_APPEND, 0664);
330 sprintf(input, "Unable to redirect output to %s\n", argv[2]);
331 com_err("moira (script)", errno, input);
346 if (!fgets(input, BUFSIZ, inp))
348 if ((cp = strchr(input, '\n')))
357 for (cp = &input[1]; *cp && isspace(*cp); cp++)
359 printf("Comment: %s\n", cp);
362 printf("Executing: %s\n", input);
384 int print_reply(int argc, char **argv, void *help)
387 for (i = 0; i < argc; i++)
391 if (quote_output && !*(int *)help)
395 for (p = (unsigned char *)argv[i]; *p; p++)
397 if (isprint(*p) && *p != '\\' && *p != ',')
400 printf("\\%03o", *p);
404 printf("%s", argv[i]);
411 void test_query(int argc, char **argv)
413 int status, help = !strcmp(argv[1], "_help");
418 com_err("moira (query)", 0, "Usage: query handle [ args ... ]");
423 /* Don't allow ^C during the query: it will confuse libmoira's
424 internal state. (Yay static variables) */
426 sigaddset(&sigs, SIGINT);
427 sigprocmask(SIG_BLOCK, &sigs, NULL);
428 status = mr_query(argv[1], argc - 2, argv + 2, print_reply, &help);
429 sigprocmask(SIG_UNBLOCK, &sigs, NULL);
430 printf("%d tuple%s\n", count, ((count == 1) ? "" : "s"));
432 com_err("moira (query)", status, "");
435 void test_access(int argc, char **argv)
440 com_err("moira (access)", 0, "Usage: access handle [ args ... ]");
443 status = mr_access(argv[1], argc - 2, argv + 2);
445 com_err("moira (access)", status, "");
452 if ((status = mr_do_update()))
453 com_err("moira (dcm)", status, " while triggering dcm");
461 if ((status = mr_motd(&motd)))
462 com_err("moira (motd)", status, " while getting motd");
464 printf("%s\n", motd);
466 printf("No message of the day.\n");
469 void test_list_requests(void)
471 printf("Available moira requests:\n");
473 printf("noop\t\t\tAsk Moira to do nothing\n");
474 printf("connect, c\t\tConnect to Moira server\n");
475 printf("disconnect, d\t\tDisconnect from server\n");
476 printf("host\t\t\tIdentify the server host\n");
477 printf("motd, m\t\t\tGet the Message of the Day\n");
478 printf("query, qy\t\tMake a query.\n");
479 printf("auth, a\t\t\tAuthenticate to Moira.\n");
480 printf("access\t\t\tCheck access to a Moira query.\n");
481 printf("dcm\t\t\tTrigger the DCM\n");
482 printf("script, s\t\tRead commands from a script.\n");
483 printf("list_requests, lr, ?\tList available commands.\n");
484 printf("quit, Q\t\t\tLeave the subsystem.\n");