]> diplodocus.org Git - nmh/blob - uip/vmhtest.c
Added first cut at nmh.spec, along with rpm: target in Makefile.in.
[nmh] / 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 }