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, interactive;
30 extern int sending_version_no;
31 int count, quit = 0, cancel = 0;
37 void discard_input(void);
38 char *mr_gets(char *prompt, char *buf, size_t len);
39 void execute_line(char *cmdbuf);
40 int parse(char *buf, char *argv[MAXARGS]);
41 int print_reply(int argc, char **argv, void *hint);
43 void test_connect(int argc, char **argv);
44 void test_disconnect(void);
49 void test_query(int argc, char **argv);
51 void test_access(int argc, char **argv);
53 void test_script(int argc, char **argv);
54 void test_list_requests(void);
56 int main(int argc, char **argv)
59 struct sigaction action;
62 interactive = (isatty(0) && isatty(1));
64 initialize_sms_error_table();
65 initialize_krb_error_table();
68 /* we don't want filename completion */
69 rl_bind_key('\t', rl_insert);
72 action.sa_handler = discard_input;
74 sigemptyset(&action.sa_mask);
75 sigaction(SIGINT, &action, NULL);
80 if (!mr_gets("moira: ", cmdbuf, BUFSIZ))
88 void discard_input(void)
92 /* if we're inside a script, we have to clean up file descriptors,
93 so don't jump out yet */
100 char *mr_gets(char *prompt, char *buf, size_t len)
106 in = readline(prompt);
112 strncpy(buf, in, len - 1);
119 printf("%s", prompt);
121 in = fgets(buf, len, stdin);
124 if (strchr(buf, '\n'))
125 *(strchr(buf, '\n')) = '\0';
129 void execute_line(char *cmdbuf)
134 argc = parse(cmdbuf, argv);
137 if (!strcmp(argv[0], "noop"))
139 else if (!strcmp(argv[0], "connect") || !strcmp(argv[0], "c"))
140 test_connect(argc, argv);
141 else if (!strcmp(argv[0], "disconnect") || !strcmp(argv[0], "d"))
143 else if (!strcmp(argv[0], "host"))
145 else if (!strcmp(argv[0], "new") || !strcmp(argv[0], "2"))
147 else if (!strcmp(argv[0], "old") || !strcmp(argv[0], "1"))
149 else if (!strcmp(argv[0], "motd"))
151 else if (!strcmp(argv[0], "query") || !strcmp(argv[0], "qy"))
152 test_query(argc, argv);
153 else if (!strcmp(argv[0], "auth") || !strcmp(argv[0], "a"))
155 else if (!strcmp(argv[0], "access"))
156 test_access(argc, argv);
157 else if (!strcmp(argv[0], "dcm"))
159 else if (!strcmp(argv[0], "script") || !strcmp(argv[0], "s"))
160 test_script(argc, argv);
161 else if (!strcmp(argv[0], "list_requests") ||
162 !strcmp(argv[0], "lr") || !strcmp(argv[0], "?"))
163 test_list_requests();
164 else if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "Q"))
168 fprintf(stderr, "moira: Unknown request \"%s\". "
169 "Type \"?\" for a request list.\n", argv[0]);
173 int parse(char *buf, char *argv[MAXARGS])
181 for (p = buf, argc = 0, argv[0] = buf; *p && *p != '\n'; p++)
186 /* skip to close-quote, copying back over open-quote */
189 if (!*p || *p == '\n')
192 "moira: Unbalanced quotes in command line\n");
195 /* deal with \### or \\ */
198 if (*++p != '"' && (*p < '0' || *p > '9') && (*p != '\\'))
200 fprintf(stderr, "moira: Bad use of \\\n");
203 else if (*p >= '0' && *p <= '9')
205 num = (*p - '0') * 64 + (*++p - '0') * 8 + (*++p - '0');
222 if (*p == ' ' || *p == '\t')
224 /* skip whitespace */
225 for (*p++ = '\0'; *p == ' ' || *p == '\t'; p++)
227 if (*p && *p != '\n')
238 int status = mr_noop();
240 com_err("moira (noop)", status, "");
245 sending_version_no = MR_VERSION_2;
250 sending_version_no = MR_VERSION_1;
253 void test_connect(int argc, char *argv[])
260 status = mr_connect(server);
262 com_err("moira (connect)", status, "");
265 void test_disconnect(void)
267 int status = mr_disconnect();
269 com_err("moira (disconnect)", status, "");
277 memset(host, 0, sizeof(host));
279 if ((status = mr_host(host, sizeof(host) - 1)))
280 com_err("moira (host)", status, "");
282 printf("You are connected to host %s\n", host);
289 status = mr_auth("mrtest");
291 com_err("moira (auth)", status, "");
294 void test_script(int argc, char *argv[])
297 char input[BUFSIZ], *cp;
298 int status, oldstdout, oldstderr;
302 com_err("moira (script)", 0, "too many levels deep in script files\n");
308 com_err("moira (script)", 0, "Usage: script input_file [ output_file ]");
312 inp = fopen(argv[1], "r");
315 sprintf(input, "Cannot open input file %s", argv[1]);
316 com_err("moira (script)", 0, input);
322 printf("Redirecting output to %s\n", argv[2]);
326 status = open(argv[2], O_CREAT|O_WRONLY|O_APPEND, 0664);
332 sprintf(input, "Unable to redirect output to %s\n", argv[2]);
333 com_err("moira (script)", errno, input);
348 if (!fgets(input, BUFSIZ, inp))
350 if ((cp = strchr(input, '\n')))
359 for (cp = &input[1]; *cp && isspace(*cp); cp++)
361 printf("Comment: %s\n", cp);
364 printf("Executing: %s\n", input);
386 int print_reply(int argc, char **argv, void *hint)
389 for (i = 0; i < argc; i++)
393 printf("%s", argv[i]);
400 void test_query(int argc, char **argv)
407 com_err("moira (query)", 0, "Usage: query handle [ args ... ]");
412 /* Don't allow ^C during the query: it will confuse libmoira's
413 internal state. (Yay static variables) */
415 sigaddset(&sigs, SIGINT);
416 sigprocmask(SIG_BLOCK, &sigs, NULL);
417 status = mr_query(argv[1], argc - 2, argv + 2, print_reply, NULL);
418 sigprocmask(SIG_UNBLOCK, &sigs, NULL);
419 printf("%d tuple%s\n", count, ((count == 1) ? "" : "s"));
421 com_err("moira (query)", status, "");
424 void test_access(int argc, char **argv)
429 com_err("moira (access)", 0, "Usage: access handle [ args ... ]");
432 status = mr_access(argv[1], argc - 2, argv + 2);
434 com_err("moira (access)", status, "");
441 if ((status = mr_do_update()))
442 com_err("moira (dcm)", status, " while triggering dcm");
450 if ((status = mr_motd(&motd)))
451 com_err("moira (motd)", status, " while getting motd");
453 printf("%s\n", motd);
455 printf("No message of the day.\n");
458 void test_list_requests(void)
460 printf("Available moira requests:\n");
462 printf("noop\t\t\tAsk Moira to do nothing\n");
463 printf("connect, c\t\tConnect to Moira server\n");
464 printf("disconnect, d\t\tDisconnect from server\n");
465 printf("host\t\t\tIdentify the server host\n");
466 printf("new, 2\t\t\tUse new protocol\n");
467 printf("old, 1\t\t\tUse old protocol\n");
468 printf("motd, m\t\t\tGet the Message of the Day\n");
469 printf("query, qy\t\tMake a query.\n");
470 printf("auth, a\t\t\tAuthenticate to Moira.\n");
471 printf("access\t\t\tCheck access to a Moira query.\n");
472 printf("dcm\t\t\tTrigger the DCM\n");
473 printf("script, s\t\tRead commands from a script.\n");
474 printf("list_requests, lr, ?\tList available commands.\n");
475 printf("quit, Q\t\t\tLeave the subsystem.\n");