]> andersk Git - moira.git/blame - clients/mrtest/mrtest.c
Code style cleanup. (No functional changes)
[moira.git] / clients / mrtest / mrtest.c
CommitLineData
6e6374cb 1/*
2 * $Source$
3 * $Author$
4 * $Header$
5 *
6 * Copyright (C) 1987 by the Massachusetts Institute of Technology
c801de4c 7 * For copying and distribution information, please see the file
8 * <mit-copyright.h>.
6e6374cb 9 *
6e6374cb 10 */
11
12#ifndef lint
13static char *rcsid_test_c = "$Header$";
74c84b52 14#endif /* lint */
6e6374cb 15
c801de4c 16#include <mit-copyright.h>
6e6374cb 17#include <stdio.h>
39de499f 18#include <sys/types.h>
58b825a4 19#include <sys/file.h>
a4fafd85 20#include <fcntl.h>
58b825a4 21#include <ctype.h>
f071d8a7 22#include <string.h>
8defc06b 23#include <moira.h>
1a5c774c 24#include <com_err.h>
f281aa29 25#include <setjmp.h>
26#include <signal.h>
27
28#ifdef USE_READLINE
29#include "readline.h"
30#endif
6e6374cb 31
fcb0b7fa 32int recursion = 0, interactive;
1a5c774c 33extern int errno;
59af7b90 34extern int sending_version_no;
5eaef520 35int count, quit = 0, cancel = 0;
1a5c774c 36char *whoami;
74c84b52 37sigjmp_buf jb;
1a5c774c 38
39#define MAXARGS 20
6e6374cb 40
5eaef520 41void discard_input();
21deca44 42char *mr_gets();
f281aa29 43
5eaef520 44int main(int argc, char **argv)
45{
46 char cmdbuf[BUFSIZ];
47 struct sigaction action;
6e6374cb 48
5eaef520 49 whoami = argv[0];
50 interactive = (isatty(0) && isatty(1));
3442308f 51
5eaef520 52 initialize_sms_error_table();
53 initialize_krb_error_table();
54
55#ifdef USE_READLINE
56 /* we don't want filename completion */
57 rl_bind_key('\t', rl_insert);
74c84b52 58#endif
f281aa29 59
5eaef520 60 action.sa_handler = discard_input;
61 action.sa_flags = 0;
62 sigemptyset(&action.sa_mask);
63 sigaction(SIGINT, &action, NULL);
64 sigsetjmp(jb, 1);
65
66 while (!quit)
67 {
68 if (!mr_gets("moira: ", cmdbuf, BUFSIZ))
69 break;
70 execute_line(cmdbuf);
71 }
72 mr_disconnect();
73 exit(0);
1a5c774c 74}
75
5eaef520 76void discard_input(void)
f281aa29 77{
78 putc('\n', stdout);
fcb0b7fa 79
80 /* if we're inside a script, we have to clean up file descriptors,
81 so don't jump out yet */
5eaef520 82 if (recursion)
83 cancel = 1;
84 else
fcb0b7fa 85 siglongjmp(jb, 1);
f281aa29 86}
87
5eaef520 88char *mr_gets(char *prompt, char *buf, size_t len)
f281aa29 89{
90 char *in;
91#ifdef USE_READLINE
5eaef520 92 if (interactive)
93 {
94 in = readline(prompt);
95
96 if (!in)
97 return NULL;
98 if (*in)
99 add_history(in);
100 strncpy(buf, in, len - 1);
101 buf[len] = 0;
102 free(in);
103
104 return buf;
f281aa29 105 }
f281aa29 106#endif
107 printf("%s", prompt);
108 fflush(stdout);
5eaef520 109 in = fgets(buf, len, stdin);
110 if (!in)
111 return in;
112 if (strchr(buf, '\n'))
113 *(strchr(buf, '\n')) = '\0';
f281aa29 114 return buf;
115}
116
5eaef520 117int execute_line(char *cmdbuf)
1a5c774c 118{
119 int argc;
120 char *argv[MAXARGS];
121
5eaef520 122 argc = parse(cmdbuf, argv);
123 if (argc == 0)
124 return;
125 if (!strcmp(argv[0], "noop"))
1a5c774c 126 test_noop();
5eaef520 127 else if (!strcmp(argv[0], "connect") || !strcmp(argv[0], "c"))
1a5c774c 128 test_connect(argc, argv);
5eaef520 129 else if (!strcmp(argv[0], "disconnect") || !strcmp(argv[0], "d"))
1a5c774c 130 test_disconnect();
5eaef520 131 else if (!strcmp(argv[0], "host"))
1a5c774c 132 test_host();
5eaef520 133 else if (!strcmp(argv[0], "new") || !strcmp(argv[0], "2"))
1a5c774c 134 test_new();
5eaef520 135 else if (!strcmp(argv[0], "old") || !strcmp(argv[0], "1"))
1a5c774c 136 test_old();
5eaef520 137 else if (!strcmp(argv[0], "motd"))
1a5c774c 138 test_motd();
5eaef520 139 else if (!strcmp(argv[0], "query") || !strcmp(argv[0], "qy"))
1a5c774c 140 test_query(argc, argv);
5eaef520 141 else if (!strcmp(argv[0], "auth") || !strcmp(argv[0], "a"))
1a5c774c 142 test_auth(argc, argv);
5eaef520 143 else if (!strcmp(argv[0], "access"))
1a5c774c 144 test_access(argc, argv);
5eaef520 145 else if (!strcmp(argv[0], "dcm"))
1a5c774c 146 test_dcm();
5eaef520 147 else if (!strcmp(argv[0], "script") || !strcmp(argv[0], "s"))
1a5c774c 148 test_script(argc, argv);
5eaef520 149 else if (!strcmp(argv[0], "list_requests") ||
150 !strcmp(argv[0], "lr") || !strcmp(argv[0], "?"))
1a5c774c 151 test_list_requests();
5eaef520 152 else if (!strcmp(argv[0], "quit") || !strcmp(argv[0], "Q"))
153 quit = 1;
154 else
155 {
156 fprintf(stderr, "moira: Unknown request \"%s\". "
157 "Type \"?\" for a request list.\n", argv[0]);
158 }
1a5c774c 159}
160
5eaef520 161int parse(char *buf, char *argv[MAXARGS])
1a5c774c 162{
163 char *p;
164 int argc, num;
5eaef520 165
166 if (!*buf)
167 return 0;
168
169 for (p = buf, argc = 0, argv[0] = buf; *p && *p != '\n'; p++)
170 {
171 if (*p == '"')
172 {
173 char *d = p++;
174 /* skip to close-quote, copying back over open-quote */
175 while (*p != '"')
176 {
177 if (!*p || *p == '\n')
178 {
179 fprintf(stderr,
180 "moira: Unbalanced quotes in command line\n");
181 return 0;
182 }
183 /* deal with \### or \\ */
184 if (*p == '\\')
185 {
186 if (*++p != '"' && (*p < '0' || *p > '9') && (*p != '\\'))
187 {
188 fprintf(stderr, "moira: Bad use of \\\n");
189 return 0;
190 }
191 else if (*p >= '0' && *p <= '9')
192 {
193 num = (*p - '0') * 64 + (*++p - '0') * 8 + (*++p - '0');
194 *p = num;
195 }
196 }
197 *d++ = *p++;
198 }
199 if (p == d + 1)
200 {
201 *d = '\0';
202 p++;
203 }
204 else
205 {
206 while (p >= d)
207 *p-- = ' ';
208 }
2c031a2a 209 }
5eaef520 210 if (*p == ' ' || *p == '\t')
211 {
212 /* skip whitespace */
213 for (*p++ = '\0'; *p == ' ' || *p == '\t'; p++)
214 ;
215 if (*p && *p != '\n')
216 argv[++argc] = p--;
6e6374cb 217 }
1a5c774c 218 }
5eaef520 219 if (*p == '\n')
220 *p = '\0';
221 return argc + 1;
6e6374cb 222}
223
5eaef520 224int test_noop(void)
6e6374cb 225{
5eaef520 226 int status = mr_noop();
227 if (status)
228 com_err("moira (noop)", status, "");
6e6374cb 229}
230
5eaef520 231int test_new(void)
59af7b90 232{
5eaef520 233 sending_version_no = MR_VERSION_2;
59af7b90 234}
235
5eaef520 236int test_old(void)
59af7b90 237{
5eaef520 238 sending_version_no = MR_VERSION_1;
59af7b90 239}
240
5eaef520 241int test_connect(int argc, char *argv[])
6e6374cb 242{
5eaef520 243 char *server = "";
244 int status;
245
246 if (argc > 1)
247 server = argv[1];
248 status = mr_connect(server);
249 if (status)
250 com_err("moira (connect)", status, "");
6e6374cb 251}
252
5eaef520 253int test_disconnect(void)
6e6374cb 254{
5eaef520 255 int status = mr_disconnect();
256 if (status)
257 com_err("moira (disconnect)", status, "");
6e6374cb 258}
259
5eaef520 260int test_host(void)
66848930 261{
5eaef520 262 char host[BUFSIZ];
263 int status;
66848930 264
5eaef520 265 memset(host, 0, sizeof(host));
66848930 266
5eaef520 267 if ((status = mr_host(host, sizeof(host) - 1)))
268 com_err("moira (host)", status, "");
269 else
270 printf("You are connected to host %s\n", host);
66848930 271}
272
5eaef520 273int test_auth(int argc, char *argv[])
6e6374cb 274{
5eaef520 275 int status;
59af7b90 276
5eaef520 277 status = mr_auth("mrtest");
278 if (status)
279 com_err("moira (auth)", status, "");
6e6374cb 280}
281
5eaef520 282int test_script(int argc, char *argv[])
58b825a4 283{
5eaef520 284 FILE *inp;
285 char input[BUFSIZ], *cp;
286 int status, oldstdout, oldstderr;
287
288 if (recursion > 8)
289 {
290 com_err("moira (script)", 0, "too many levels deep in script files\n");
291 return;
58b825a4 292 }
293
5eaef520 294 if (argc < 2)
295 {
296 com_err("moira (script)", 0, "Usage: script input_file [ output_file ]");
297 return;
58b825a4 298 }
299
5eaef520 300 inp = fopen(argv[1], "r");
301 if (!inp)
302 {
303 sprintf(input, "Cannot open input file %s", argv[1]);
304 com_err("moira (script)", 0, input);
305 return;
58b825a4 306 }
307
5eaef520 308 if (argc == 3)
309 {
310 printf("Redirecting output to %s\n", argv[2]);
311 fflush(stdout);
312 oldstdout = dup(1);
313 close(1);
314 status = open(argv[2], O_CREAT|O_WRONLY|O_APPEND, 0664);
315 if (status != 1)
316 {
317 close(status);
318 dup2(oldstdout, 1);
319 argc = 2;
320 sprintf(input, "Unable to redirect output to %s\n", argv[2]);
321 com_err("moira (script)", errno, input);
322 }
323 else
324 {
325 fflush(stderr);
326 oldstderr = dup(2);
327 close(2);
328 dup2(1, 2);
58b825a4 329 }
330 }
331
5eaef520 332 recursion++;
333
334 while (!cancel)
335 {
336 if (!fgets(input, BUFSIZ, inp))
337 break;
338 if ((cp = strchr(input, '\n')))
339 *cp = '\0';
340 if (input[0] == 0)
341 {
342 printf("\n");
343 continue;
6a592314 344 }
5eaef520 345 if (input[0] == '%')
346 {
347 for (cp = &input[1]; *cp && isspace(*cp); cp++)
348 ;
349 printf("Comment: %s\n", cp);
350 continue;
58b825a4 351 }
5eaef520 352 printf("Executing: %s\n", input);
353 execute_line(input);
58b825a4 354 }
355
5eaef520 356 recursion--;
357 if (!recursion)
358 cancel = 0;
359
360 fclose(inp);
361 if (argc == 3)
362 {
363 fflush(stdout);
364 close(1);
365 dup2(oldstdout, 1);
366 close(oldstdout);
367 fflush(stderr);
368 close(2);
369 dup2(oldstderr, 2);
370 close(oldstderr);
58b825a4 371 }
372}
373
5eaef520 374int print_reply(int argc, char **argv)
6e6374cb 375{
5eaef520 376 int i;
377 for (i = 0; i < argc; i++)
378 {
379 if (i != 0)
380 printf(", ");
381 printf("%s", argv[i]);
382 }
383 printf("\n");
384 count++;
385 return MR_CONT;
6e6374cb 386}
387
5eaef520 388int test_query(int argc, char **argv)
6e6374cb 389{
5eaef520 390 int status;
391 sigset_t sigs;
fcb0b7fa 392
5eaef520 393 if (argc < 2)
394 {
395 com_err("moira (query)", 0, "Usage: query handle [ args ... ]");
396 return;
397 }
59af7b90 398
5eaef520 399 count = 0;
400 /* Don't allow ^C during the query: it will confuse libmoira's
401 internal state. (Yay static variables) */
402 sigemptyset(&sigs);
403 sigaddset(&sigs, SIGINT);
404 sigprocmask(SIG_BLOCK, &sigs, NULL);
405 status = mr_query(argv[1], argc - 2, argv + 2, print_reply, NULL);
406 sigprocmask(SIG_UNBLOCK, &sigs, NULL);
407 printf("%d tuple%s\n", count, ((count == 1) ? "" : "s"));
408 if (status)
409 com_err("moira (query)", status, "");
6e6374cb 410}
411
5eaef520 412int test_access(int argc, char **argv)
6e6374cb 413{
5eaef520 414 int status;
415 if (argc < 2)
416 {
417 com_err("moira (access)", 0, "Usage: access handle [ args ... ]");
418 return;
419 }
420 status = mr_access(argv[1], argc - 2, argv + 2);
421 if (status)
422 com_err("moira (access)", status, "");
6e6374cb 423}
fc3ac28e 424
5eaef520 425int test_dcm(int argc, char **argv)
fc3ac28e 426{
5eaef520 427 int status;
fc3ac28e 428
5eaef520 429 if ((status = mr_do_update()))
430 com_err("moira (dcm)", status, " while triggering dcm");
fc3ac28e 431}
093b57b1 432
5eaef520 433int test_motd(int argc, char **argv)
093b57b1 434{
5eaef520 435 int status;
436 char *motd;
437
438 if ((status = mr_motd(&motd)))
439 com_err("moira (motd)", status, " while getting motd");
440 if (motd)
441 printf("%s\n", motd);
442 else
443 printf("No message of the day.\n");
093b57b1 444}
1a5c774c 445
5eaef520 446int test_list_requests(void)
1a5c774c 447{
5eaef520 448 printf("Available moira requests:\n");
449 printf("\n");
450 printf("noop\t\t\tAsk Moira to do nothing\n");
451 printf("connect, c\t\tConnect to Moira server\n");
452 printf("disconnect, d\t\tDisconnect from server\n");
453 printf("host\t\t\tIdentify the server host\n");
454 printf("new, 2\t\t\tUse new protocol\n");
455 printf("old, 1\t\t\tUse old protocol\n");
456 printf("motd, m\t\t\tGet the Message of the Day\n");
457 printf("query, qy\t\tMake a query.\n");
458 printf("auth, a\t\t\tAuthenticate to Moira.\n");
459 printf("access\t\t\tCheck access to a Moira query.\n");
460 printf("dcm\t\t\tTrigger the DCM\n");
461 printf("script, s\t\tRead commands from a script.\n");
462 printf("list_requests, lr, ?\tList available commands.\n");
463 printf("quit, Q\t\t\tLeave the subsystem.\n");
1a5c774c 464}
This page took 0.180168 seconds and 5 git commands to generate.