]> andersk Git - moira.git/blob - clients/mrtest/mrtest.c
Code style cleanup. (No functional changes)
[moira.git] / clients / mrtest / mrtest.c
1 /*
2  *      $Source$
3  *      $Author$
4  *      $Header$
5  *
6  *      Copyright (C) 1987 by the Massachusetts Institute of Technology
7  *      For copying and distribution information, please see the file
8  *      <mit-copyright.h>.
9  *
10  */
11
12 #ifndef lint
13 static char *rcsid_test_c = "$Header$";
14 #endif /* lint */
15
16 #include <mit-copyright.h>
17 #include <stdio.h>
18 #include <sys/types.h>
19 #include <sys/file.h>
20 #include <fcntl.h>
21 #include <ctype.h>
22 #include <string.h>
23 #include <moira.h>
24 #include <com_err.h>
25 #include <setjmp.h>
26 #include <signal.h>
27
28 #ifdef USE_READLINE
29 #include "readline.h"
30 #endif
31
32 int recursion = 0, interactive;
33 extern int errno;
34 extern int sending_version_no;
35 int count, quit = 0, cancel = 0;
36 char *whoami;
37 sigjmp_buf jb;
38
39 #define MAXARGS 20
40
41 void discard_input();
42 char *mr_gets();
43
44 int main(int argc, char **argv)
45 {
46   char cmdbuf[BUFSIZ];
47   struct sigaction action;
48
49   whoami = argv[0];
50   interactive = (isatty(0) && isatty(1));
51
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);
58 #endif
59
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);
74 }
75
76 void discard_input(void)
77 {
78   putc('\n', stdout);
79
80   /* if we're inside a script, we have to clean up file descriptors,
81      so don't jump out yet */
82   if (recursion)
83     cancel = 1;
84   else
85     siglongjmp(jb, 1);
86 }
87
88 char *mr_gets(char *prompt, char *buf, size_t len)
89 {
90   char *in;
91 #ifdef USE_READLINE
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;
105     }
106 #endif
107   printf("%s", prompt);
108   fflush(stdout);
109   in = fgets(buf, len, stdin);
110   if (!in)
111     return in;
112   if (strchr(buf, '\n'))
113     *(strchr(buf, '\n')) = '\0';
114   return buf;
115 }
116
117 int execute_line(char *cmdbuf)
118 {
119   int argc;
120   char *argv[MAXARGS];
121
122   argc = parse(cmdbuf, argv);
123   if (argc == 0)
124     return;
125   if (!strcmp(argv[0], "noop"))
126     test_noop();
127   else if (!strcmp(argv[0], "connect") || !strcmp(argv[0], "c"))
128     test_connect(argc, argv);
129   else if (!strcmp(argv[0], "disconnect") || !strcmp(argv[0], "d"))
130     test_disconnect();
131   else if (!strcmp(argv[0], "host"))
132     test_host();
133   else if (!strcmp(argv[0], "new") || !strcmp(argv[0], "2"))
134     test_new();
135   else if (!strcmp(argv[0], "old") || !strcmp(argv[0], "1"))
136     test_old();
137   else if (!strcmp(argv[0], "motd"))
138     test_motd();
139   else if (!strcmp(argv[0], "query") || !strcmp(argv[0], "qy"))
140     test_query(argc, argv);
141   else if (!strcmp(argv[0], "auth") || !strcmp(argv[0], "a"))
142     test_auth(argc, argv);
143   else if (!strcmp(argv[0], "access"))
144     test_access(argc, argv);
145   else if (!strcmp(argv[0], "dcm"))
146     test_dcm();
147   else if (!strcmp(argv[0], "script") || !strcmp(argv[0], "s"))
148     test_script(argc, argv);
149   else if (!strcmp(argv[0], "list_requests") ||
150           !strcmp(argv[0], "lr") || !strcmp(argv[0], "?"))
151     test_list_requests();
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     }
159 }
160
161 int parse(char *buf, char *argv[MAXARGS])
162 {
163   char *p;
164   int argc, num;
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             }
209         }
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--;
217         }
218     }
219   if (*p == '\n')
220     *p = '\0';
221   return argc + 1;
222 }
223
224 int test_noop(void)
225 {
226   int status = mr_noop();
227   if (status)
228     com_err("moira (noop)", status, "");
229 }
230
231 int test_new(void)
232 {
233   sending_version_no = MR_VERSION_2;
234 }
235
236 int test_old(void)
237 {
238   sending_version_no = MR_VERSION_1;
239 }
240
241 int test_connect(int argc, char *argv[])
242 {
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, "");
251 }
252
253 int test_disconnect(void)
254 {
255   int status = mr_disconnect();
256   if (status)
257     com_err("moira (disconnect)", status, "");
258 }
259
260 int test_host(void)
261 {
262   char host[BUFSIZ];
263   int status;
264
265   memset(host, 0, sizeof(host));
266
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);
271 }
272
273 int test_auth(int argc, char *argv[])
274 {
275   int status;
276
277   status = mr_auth("mrtest");
278   if (status)
279     com_err("moira (auth)", status, "");
280 }
281
282 int test_script(int argc, char *argv[])
283 {
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;
292     }
293
294   if (argc < 2)
295     {
296       com_err("moira (script)", 0, "Usage: script input_file [ output_file ]");
297       return;
298     }
299
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;
306     }
307
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);
329         }
330     }
331
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;
344         }
345       if (input[0] == '%')
346         {
347           for (cp = &input[1]; *cp && isspace(*cp); cp++)
348             ;
349           printf("Comment: %s\n", cp);
350           continue;
351         }
352       printf("Executing: %s\n", input);
353       execute_line(input);
354     }
355
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);
371     }
372 }
373
374 int print_reply(int argc, char **argv)
375 {
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;
386 }
387
388 int test_query(int argc, char **argv)
389 {
390   int status;
391   sigset_t sigs;
392
393   if (argc < 2)
394     {
395       com_err("moira (query)", 0, "Usage: query handle [ args ... ]");
396       return;
397     }
398
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, "");
410 }
411
412 int test_access(int argc, char **argv)
413 {
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, "");
423 }
424
425 int test_dcm(int argc, char **argv)
426 {
427   int status;
428
429   if ((status = mr_do_update()))
430     com_err("moira (dcm)", status, " while triggering dcm");
431 }
432
433 int test_motd(int argc, char **argv)
434 {
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");
444 }
445
446 int test_list_requests(void)
447 {
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");
464 }
This page took 0.247559 seconds and 5 git commands to generate.