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