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