Remove RCS keywords, since they no longer work after git migration.
[mmh] / uip / vmhtest.c
1
2 /*
3  * vmhtest.c -- test out vmh protocol
4  *
5  * This code is Copyright (c) 2002, by the authors of nmh.  See the
6  * COPYRIGHT file in the root directory of the nmh distribution for
7  * complete copyright information.
8  */
9
10 #include <h/mh.h>
11 #include <h/vmhsbr.h>
12
13 static struct swit switches[] = {
14 #define READSW          0
15     { "vmhread fd", 7 },        
16 #define WRITESW         1
17     { "vmhwrite fd", 8 },       
18 #define VERSIONSW       2
19     { "version", 0 },
20 #define HELPSW          3
21     { "help", 0 },
22     { NULL, NULL }
23 };
24
25 #define NWIN 20
26 static int numwins = 0;
27 static int windows[NWIN + 1];
28
29
30 static int selcmds = 0;
31 #define selcmd()        (selcmds++ % 2)
32
33 static int selwins = 0;
34 #define selwin()        (selwins++ % 2 ? 3 : 1)
35
36
37 int
38 main (int argc, char **argv)
39 {
40     int fd1, fd2;
41     char *cp, buffer[BUFSIZ];
42     char **argp, **arguments;
43
44 #ifdef LOCALE
45     setlocale(LC_ALL, "");
46 #endif
47     invo_name = r1bindex (argv[0], '/');
48
49     /* foil search of user profile/context */
50     if (context_foil (NULL) == -1)
51         done (1);
52
53     arguments = getarguments (invo_name, argc, argv, 0);
54     argp = arguments;
55
56     while ((cp = *argp++))
57         if (*cp == '-')
58             switch (smatch (++cp, switches)) {
59                 case AMBIGSW: 
60                     ambigsw (cp, switches);
61                     done (1);
62                 case UNKWNSW: 
63                     adios (NULL, "-%s unknown", cp);
64
65                 case HELPSW: 
66                     snprintf (buffer, sizeof(buffer), "%s [switches]", invo_name);
67                     print_help (buffer, switches, 0);
68                     done (1);
69                 case VERSIONSW:
70                     print_version(invo_name);
71                     done (1);
72
73                 case READSW: 
74                     if (!(cp = *argp++) || *cp == '-')
75                         adios (NULL, "missing argument to %s", argp[-2]);
76                     if ((fd1 = atoi (cp)) < 1)
77                         adios (NULL, "bad argument %s %s", argp[-2], cp);
78                     continue;
79                 case WRITESW: 
80                     if (!(cp = *argp++) || *cp == '-')
81                         adios (NULL, "missing argument to %s", argp[-2]);
82                     if ((fd2 = atoi (cp)) < 1)
83                         adios (NULL, "bad argument %s %s", argp[-2], cp);
84                     continue;
85             }
86         else
87             adios (NULL, "usage: %s [switches]", invo_name);
88
89     rcinit (fd1, fd2);
90     pINI ();
91     pLOOP ();
92
93     return done (0);
94 }
95
96
97 static int  pINI () {
98     int     i,
99             vrsn;
100     char   *bp;
101     struct record   rcs,
102                    *rc = &rcs;
103
104     initrc (rc);
105
106     switch (peer2rc (rc)) {
107         case RC_INI: 
108             bp = rc->rc_data;
109             while (isspace (*bp))
110                 bp++;
111             if (sscanf (bp, "%d", &vrsn) != 1) {
112         bad_init: ;
113                 fmt2peer (RC_ERR, "bad init \"%s\"", rc->rc_data);
114                 done (1);
115             }
116             if (vrsn != RC_VRSN) {
117                 fmt2peer (RC_ERR, "version %d unsupported", vrsn);
118                 done (1);
119             }
120
121             while (*bp && !isspace (*bp))
122                 bp++;
123             while (isspace (*bp))
124                 bp++;
125             if (sscanf (bp, "%d", &numwins) != 1 || numwins <= 0)
126                 goto bad_init;
127             if (numwins > NWIN)
128                 numwins = NWIN;
129
130             for (i = 1; i <= numwins; i++) {
131                 while (*bp && !isspace (*bp))
132                     bp++;
133                 while (isspace (*bp))
134                     bp++;
135                 if (sscanf (bp, "%d", &windows[i]) != 1 || windows[i] <= 0)
136                     goto bad_init;
137             }
138             rc2peer (RC_ACK, 0, NULL);
139             return OK;
140
141         case RC_XXX: 
142             adios (NULL, "%s", rc->rc_data);
143
144         default: 
145             fmt2peer (RC_ERR, "pINI protocol screw-up");
146             done (1);           /* NOTREACHED */
147     }
148 }
149
150
151 static int  pLOOP () {
152     struct record   rcs,
153                    *rc = &rcs;
154
155     initrc (rc);
156
157     for (;;)
158         switch (peer2rc (rc)) {
159             case RC_QRY: 
160                 pQRY (rc->rc_data);
161                 break;
162
163             case RC_CMD: 
164                 pCMD (rc->rc_data);
165                 break;
166
167             case RC_FIN: 
168                 done (0);
169
170             case RC_XXX: 
171                 adios (NULL, "%s", rc->rc_data);
172
173             default: 
174                 fmt2peer (RC_ERR, "pLOOP protocol screw-up");
175                 done (1);
176         }
177 }
178
179
180 static int  pQRY (str)
181 char   *str;
182 {
183     rc2peer (RC_EOF, 0, NULL);
184     return OK;
185 }
186
187
188 static int  pCMD (str)
189 char   *str;
190 {
191     if ((selcmd () ? pTTY (str) : pWIN (str)) == NOTOK)
192         return NOTOK;
193     rc2peer (RC_EOF, 0, NULL);
194     return OK;
195 }
196
197
198 static int  pTTY (str)
199 char   *str;
200 {
201     struct record   rcs,
202                    *rc = &rcs;
203
204     initrc (rc);
205
206     switch (rc2rc (RC_TTY, 0, NULL, rc)) {
207         case RC_ACK: 
208             break;
209
210         case RC_ERR: 
211             return NOTOK;
212
213         case RC_XXX: 
214             adios (NULL, "%s", rc->rc_data);
215
216         default: 
217             fmt2peer (RC_ERR, "pTTY protocol screw-up");
218             done (1);
219     }
220
221     system (str);
222
223     switch (rc2rc (RC_EOF, 0, NULL, rc)) {
224         case RC_ACK: 
225             return OK;
226
227         case RC_XXX: 
228             adios (NULL, "%s", rc->rc_data);/* NOTREACHED */
229
230         default: 
231             fmt2peer (RC_ERR, "pTTY protocol screw-up");
232             done (1);           /* NOTREACHED */
233     }
234 }
235
236
237 static int  pWIN (str)
238 char   *str;
239 {
240     int     i,
241             pid,
242             pd[2];
243     char    buffer[BUFSIZ];
244     struct record   rcs,
245                    *rc = &rcs;
246
247     initrc (rc);
248
249     snprintf (buffer, sizeof(buffer), "%d", selwin ());
250     switch (str2rc (RC_WIN, buffer, rc)) {
251         case RC_ACK: 
252             break;
253
254         case RC_ERR: 
255             return NOTOK;
256
257         case RC_XXX: 
258             adios (NULL, "%s", rc->rc_data);
259
260         default: 
261             fmt2peer (RC_ERR, "pWIN protocol screw-up");
262             done (1);
263     }
264
265     if (pipe (pd) == NOTOK) {
266         fmt2peer (RC_ERR, "no pipes");
267         return NOTOK;
268     }
269
270     switch (pid = vfork ()) {
271         case NOTOK: 
272             fmt2peer (RC_ERR, "no forks");
273             return NOTOK;
274
275         case OK: 
276             close (0);
277             open ("/dev/null", O_RDONLY);
278             dup2 (pd[1], 1);
279             dup2 (pd[1], 2);
280             close (pd[0]);
281             close (pd[1]);
282             execlp ("/bin/sh", "sh", "-c", str, NULL);
283             write (2, "no shell\n", strlen ("no shell\n"));
284             _exit (1);
285
286         default: 
287             close (pd[1]);
288             while ((i = read (pd[0], buffer, sizeof buffer)) > 0)
289                 switch (rc2rc (RC_DATA, i, buffer, rc)) {
290                     case RC_ACK: 
291                         break;
292
293                     case RC_ERR: 
294                         close (pd[0]);
295                         pidwait (pid, OK);
296                         return NOTOK;
297
298                     case RC_XXX: 
299                         adios (NULL, "%s", rc->rc_data);
300
301                     default: 
302                         fmt2peer (RC_ERR, "pWIN protocol screw-up");
303                         done (1);
304                 }
305             if (i == OK)
306                 switch (rc2rc (RC_EOF, 0, NULL, rc)) {
307                     case RC_ACK: 
308                         break;
309
310                     case RC_XXX: 
311                         adios (NULL, "%s", rc->rc_data);
312
313                     default: 
314                         fmt2peer (RC_ERR, "pWIN protocol screw-up");
315                         done (1);
316                 }
317             if (i == NOTOK)
318                 fmt2peer (RC_ERR, "read from pipe lost");
319
320             close (pd[0]);
321             pidwait (pid, OK);
322             return (i != NOTOK ? OK : NOTOK);
323     }
324 }