+ p[len] = '\n';
+ errno = EIO;
+ if (write(fd, p, len + 1) != len + 1)
+ moan("write failed: %s", strerror(errno));
+ }
+}
+
+static void setup(const char *cmd)
+{
+ dstr d = DSTR_INIT;
+ char ch;
+ char *p, *q;
+ int n;
+
+ dstr_puts(&d, cmd);
+ dstr_putc(&d, '\n');
+ errno = EIO; /* Relax: be vague */
+ if (write(fd, d.buf, d.len) != d.len) {
+ die(EXIT_FAILURE, "error sending setup command `%s': %s",
+ cmd, strerror(errno));
+ }
+ dstr_reset(&d);
+ for (;;) {
+ n = read(fd, &ch, 1);
+ if (!n)
+ die(EXIT_FAILURE, "unexpected EOF during setup");
+ if (n < 0) {
+ die(EXIT_FAILURE, "error receiving reply to `%s': %s",
+ cmd, strerror(errno));
+ }
+ if (d.len < 256)
+ dstr_putc(&d, ch);
+ if (ch == '\n') {
+ p = d.buf;
+ q = str_getword(&p);
+ if (!q)
+ ;
+ else if (strcmp(q, "OK") == 0)
+ return;
+ else if (strcmp(q, "FAIL") == 0)
+ die(EXIT_FAILURE, "setup command `%s' failed: %s", cmd, p);
+ dstr_reset(&d);
+ }