]> andersk Git - moira.git/blob - clients/mrtest/mrtest.c
POSIXly better version of previous ^C handling code. (Use sigsetjmp,
[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;
33 extern int errno;
34 extern int sending_version_no;
35 int count, quit=0;
36 char *whoami;
37 #ifdef POSIX
38 sigjmp_buf jb;
39 #else
40 jmp_buf jb;
41 #endif
42
43 #define MAXARGS 20
44
45 void discard_input(void);
46 char *mr_gets(char *, char *, size_t);
47
48 main(argc, argv)
49         int argc;
50         char **argv;
51 {       
52         int status;
53         char cmdbuf[BUFSIZ];
54 #ifdef POSIX
55         struct sigaction action;
56 #endif
57         
58         whoami = argv[0];
59         
60         initialize_sms_error_table();
61         initialize_krb_error_table();
62
63 #ifdef POSIX
64         action.sa_handler = discard_input;
65         action.sa_flags = 0;
66         sigemptyset(&action.sa_mask);
67         sigaction(SIGINT, &action, NULL);
68         sigsetjmp(jb, 1);
69 #else
70         signal(SIGINT, discard_input);
71         setjmp(jb);
72 #endif
73
74         while(!quit) {
75                 if(!mr_gets("moira:  ",cmdbuf,BUFSIZ)) break;
76                 execute_line(cmdbuf);
77         }
78         mr_disconnect();
79         exit(0);
80 }
81
82 void discard_input(void)
83 {
84   putc('\n', stdout);
85 #ifdef POSIX
86   siglongjmp(jb, 1);
87 #else
88   longjmp(jb, 1);
89 #endif
90 }
91
92 char *mr_gets(char *prompt, char *buf, size_t len)
93 {
94   char *in;
95 #ifdef USE_READLINE
96   if(isatty(0)) {
97     in=readline(prompt);
98     
99     if (!in) return NULL;
100     if (*in) {
101       add_history(in);
102     }
103     strncpy(buf, in, len-1);
104     buf[len]=0;
105     
106     return buf;
107   }
108 #endif
109   printf("%s", prompt);
110   fflush(stdout);
111   in=fgets(buf, len, stdin);
112   if(!in) return in;
113   if(strchr(buf,'\n')) *(strchr(buf,'\n'))=0;
114   return buf;
115 }
116
117 execute_line(cmdbuf)
118      char *cmdbuf;
119 {
120   int argc;
121   char *argv[MAXARGS];
122
123   argc=parse(cmdbuf, argv);
124   if(argc==0) 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 fprintf(stderr, "moira: Unknown request \"%s\".  Type \"?\" for a request list.\n", argv[0]);
155 }
156
157 int
158 parse(buf, argv)
159      char *buf, *argv[MAXARGS];
160 {
161   char *p;
162   int argc, num;
163   
164   if(!*buf) return 0;
165
166   for(p=buf, argc=0, argv[0]=buf; *p && *p!='\n'; p++) {
167     if(*p=='"') {
168       char *d=p++;
169       /* skip to close-quote, copying back over open-quote */
170       while(*p!='"') {
171         if(!*p || *p=='\n') {
172           fprintf(stderr, "moira: Unbalanced quotes in command line\n");
173           return 0;
174         }
175         if(*p=='\\') {
176           if(*++p!='"' && (*p<'0' || *p>'9') && (*p!='\\')) {
177             fprintf(stderr, "moira: Bad use of \\\n");
178             return 0;
179           } else if (*p>='0' && *p<='9') {
180             num=(*p-'0')*64 + (*++p-'0')*8 + (*++p-'0');
181             *p=num;
182           }
183         }
184         *d++=*p++;
185       }
186       if(p==d+1) {*d='\0'; p++;}
187       else while(p>=d) *p--=' ';
188     }
189     if(*p==' ' || *p=='\t') {
190       /* skip whitespace */
191       for(*p++='\0'; *p==' ' || *p=='\t'; p++);
192       if(*p && *p!='\n') argv[++argc]=p--;
193     }
194   }
195   if(*p=='\n') *p='\0';
196   return argc+1;
197 }
198
199 test_noop()
200 {
201         int status = mr_noop();
202         if (status) com_err("moira (noop)", status, "");
203 }
204
205 test_new()
206 {
207         sending_version_no = MR_VERSION_2;
208 }
209
210 test_old()
211 {
212         sending_version_no = MR_VERSION_1;
213 }
214
215 test_connect(argc, argv)
216 int argc;
217 char *argv[];
218 {
219         char *server = "";
220         int status;
221
222         if (argc > 1) {
223             server = argv[1];
224         }
225         status = mr_connect(server);
226         if (status) com_err("moira (connect)", status, "");
227 }
228
229 test_disconnect()
230 {
231         int status = mr_disconnect();
232         if (status) com_err("moira (disconnect)", status, "");
233 }
234
235 test_host()
236 {
237         char host[BUFSIZ];
238         int status;
239
240         memset(host, 0, sizeof(host));
241
242         if (status = mr_host(host, sizeof(host) - 1))
243             com_err("moira (host)", status, "");
244         else
245             printf("You are connected to host %s\n", host);
246 }
247
248 test_auth(argc, argv)
249 int argc;
250 char *argv[];
251 {
252         int status;
253
254         status = mr_auth("mrtest");
255         if (status) com_err("moira (auth)", status, "");
256 }
257
258 test_script(argc, argv)
259 int argc;
260 char *argv[];
261 {
262     FILE *inp;
263     char input[BUFSIZ], *cp;
264     int status, oldstdout, oldstderr;
265
266     if (recursion > 8) {
267         com_err("moira (script)", 0, "too many levels deep in script files\n");
268         return;
269     }
270
271     if (argc < 2) {
272         com_err("moira (script)", 0, "Usage: script input_file [ output_file ]");
273         return;
274     }
275
276     inp = fopen(argv[1], "r");
277     if (inp == NULL) {
278         sprintf(input, "Cannot open input file %s", argv[1]);
279         com_err("moira (script)", 0, input);
280         return;
281     }
282
283     if (argc == 3) {
284         printf("Redirecting output to %s\n", argv[2]);
285         fflush(stdout);
286         oldstdout = dup(1);
287         close(1);
288         status = open(argv[2], O_CREAT|O_WRONLY|O_APPEND, 0664);
289         if (status != 1) {
290             close(status);
291             dup2(oldstdout, 1);
292             argc = 2;
293             sprintf(input, "Unable to redirect output to %s\n", argv[2]);
294             com_err("moira (script)", errno, input);
295         } else {
296             fflush(stderr);
297             oldstderr = dup(2);
298             close(2);
299             dup2(1, 2);
300         }
301     }
302
303     recursion++;
304
305     for(;;) {
306         if (fgets(input, BUFSIZ, inp) == NULL)
307           break;
308         if ((cp = strchr(input, '\n')) != (char *)NULL)
309           *cp = 0;
310         if (input[0] == 0) {
311             printf("\n");
312             continue;
313         }
314         if (input[0] == '%') {
315             for (cp = &input[1]; *cp && isspace(*cp); cp++);
316             printf("Comment: %s\n", cp);
317             continue;
318         }
319         printf("Executing: %s\n", input);
320         execute_line(input);
321     }
322
323     recursion--;
324
325     fclose(inp);
326     if (argc == 3) {
327         fflush(stdout);
328         close(1);
329         dup2(oldstdout, 1);
330         close(oldstdout);
331         fflush(stderr);
332         close(2);
333         dup2(oldstderr, 2);
334         close(oldstderr);
335     }
336 }
337
338 print_reply(argc, argv)
339         int argc;
340         char **argv;
341 {
342         int i;
343         for (i = 0; i < argc; i++) {
344                 if (i != 0) printf(", ");
345                 printf("%s", argv[i]);
346         }
347         printf("\n");
348         count++;
349         return(MR_CONT);
350 }
351
352 test_query(argc, argv)
353         int argc;
354         char **argv;
355 {
356         int status;
357         if (argc < 2) {
358                 com_err("moira (query)", 0, "Usage: query handle [ args ... ]");
359                 return;
360         }
361
362         count = 0;
363         status = mr_query(argv[1], argc-2, argv+2, print_reply, (char *)NULL);
364         printf("%d tuple%s\n", count, ((count == 1) ? "" : "s"));
365         if (status) com_err("moira (query)", status, "");
366 }
367
368 test_access(argc, argv)
369         int argc;
370         char **argv;
371 {
372         int status;
373         if (argc < 2) {
374                 com_err("moira (access)", 0, "Usage: access handle [ args ... ]");
375                 return;
376         }
377         status = mr_access(argv[1], argc-2, argv+2);
378         if (status) com_err("moira (access)", status, "");
379 }
380
381
382 test_dcm(argc, argv)
383         int argc;
384         char **argv;
385 {
386         int status;
387
388         if (status = mr_do_update())
389           com_err("moira (dcm)", status, " while triggering dcm");
390 }
391
392
393 test_motd(argc, argv)
394         int argc;
395         char **argv;
396 {
397         int status;
398         char *motd;
399
400         if (status = mr_motd(&motd))
401           com_err("moira (motd)", status, " while getting motd");
402         if (motd)
403           printf("%s\n", motd);
404         else
405           printf("No message of the day.\n");
406 }
407
408 test_list_requests()
409 {
410         printf("Available moira requests:\n");
411         printf("\n");
412         printf("noop\t\t\tAsk Moira to do nothing\n");
413         printf("connect, c\t\tConnect to Moira server\n");
414         printf("disconnect, d\t\tDisconnect from server\n");
415         printf("host\t\t\tIdentify the server host\n");
416         printf("new, 2\t\t\tUse new protocol\n");
417         printf("old, 1\t\t\tUse old protocol\n");
418         printf("motd, m\t\t\tGet the Message of the Day\n");
419         printf("query, qy\t\tMake a query.\n");
420         printf("auth, a\t\t\tAuthenticate to Moira.\n");
421         printf("access\t\t\tCheck access to a Moira query.\n");
422         printf("dcm\t\t\tTrigger the DCM\n");
423         printf("script, s\t\tRead commands from a script.\n");
424         printf("list_requests, lr, ?\tList available commands.\n");
425         printf("quit, Q\t\t\tLeave the subsystem.\n");
426 }
This page took 0.080096 seconds and 5 git commands to generate.