1/*	$NetBSD: slave.c,v 1.6 2011/09/15 11:46:19 blymn Exp $	*/
2
3/*-
4 * Copyright 2009 Brett Lymn <blymn@NetBSD.org>
5 *
6 * All rights reserved.
7 *
8 * This code has been donated to The NetBSD Foundation by the Author.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. The name of the author may not be used to endorse or promote products
16 *    derived from this software withough specific prior written permission
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 *
30 */
31#include <fcntl.h>
32#include <sys/ioctl.h>
33#include <unistd.h>
34#include <err.h>
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38#include <curses.h>
39#include "returns.h"
40#include "slave.h"
41
42int cmdpipe[2];
43int slvpipe[2];
44
45#if 0
46static const char *returns_enum_names[] = {
47	"unused", "numeric", "string", "byte", "ERR", "OK", "NULL", "not NULL",
48	"variable"
49};
50#endif
51
52/*
53 * Read the command pipe for the function to execute, gather the args
54 * and then process the command.
55 */
56static void
57process_commands(WINDOW *mainscr)
58{
59	int len, maxlen, argslen, i, ret, type;
60	char *cmdbuf, *tmpbuf, **args, **tmpargs;
61
62	len = maxlen = 30;
63	if ((cmdbuf = malloc(maxlen)) == NULL)
64		err(1, "slave cmdbuf malloc failed");
65
66	while(1) {
67		if (read(cmdpipe[READ_PIPE], &type, sizeof(int)) < 0)
68			err(1, "slave command type read failed");
69
70		if (type != ret_string)
71			errx(1, "Unexpected type for command, got %d", type);
72
73		if (read(cmdpipe[READ_PIPE], &len, sizeof(int)) < 0)
74			err(1, "slave command len read failed");
75
76		if ((len + 1) > maxlen) {
77			maxlen = len + 1;
78			if ((tmpbuf = realloc(cmdbuf, maxlen)) == NULL)
79				err(1, "slave cmdbuf realloc to %d "
80				    "bytes failed", maxlen);
81			cmdbuf = tmpbuf;
82		}
83
84		if (read(cmdpipe[READ_PIPE], cmdbuf, len) < 0)
85			err(1, "slave command read failed");
86		cmdbuf[len] = '\0';
87		argslen = 0;
88		args = NULL;
89
90		do {
91			if (read(cmdpipe[READ_PIPE], &type, sizeof(int)) < 0)
92				err(1, "slave arg type read failed");
93
94			if (read(cmdpipe[READ_PIPE], &len, sizeof(int)) < 0)
95				err(1, "slave arg len read failed");
96
97			if (len >= 0) {
98				tmpargs = realloc(args,
99				    (argslen + 1) * sizeof(char *));
100				if (tmpargs == NULL)
101					err(1, "slave realloc of args array "
102					    "failed");
103
104				args = tmpargs;
105				if (type != ret_null) {
106					args[argslen] = malloc(len + 1);
107
108					if (args[argslen] == NULL)
109						err(1, "slave alloc of %d bytes"
110						    " for args failed", len);
111				}
112
113				if (len == 0) {
114					if (type == ret_null)
115						args[argslen] = NULL;
116					else
117						args[argslen][0] = '\0';
118				} else {
119					read(cmdpipe[READ_PIPE], args[argslen],
120					     len);
121					if (type != ret_byte)
122						args[argslen][len] = '\0';
123
124					if (len == 6) {
125						if (strcmp(args[argslen],
126							   "STDSCR") == 0) {
127							ret = asprintf(&tmpbuf,
128								 "%p",
129								 stdscr);
130							if (ret < 0)
131								err(2,
132								    "asprintf of stdscr failed");
133							free(args[argslen]);
134							args[argslen] = tmpbuf;
135						}
136					}
137				}
138
139				argslen++;
140			}
141		}
142		while(len >= 0);
143
144		command_execute(cmdbuf, argslen, args);
145
146		if (args != NULL) {
147			for (i = 0; i < argslen; i++)
148				free(args[i]);
149
150			free(args);
151		}
152	}
153}
154
155int
156main(int argc, char *argv[])
157{
158	WINDOW *mainscr;
159
160	if (argc != 5) {
161		fprintf(stderr, "Usage: %s <cmdin> <cmdout> <slvin> slvout>\n",
162			getprogname());
163		return 0;
164	}
165	sscanf(argv[1], "%d", &cmdpipe[0]);
166	sscanf(argv[2], "%d", &cmdpipe[1]);
167	sscanf(argv[3], "%d", &slvpipe[0]);
168	sscanf(argv[4], "%d", &slvpipe[1]);
169
170	mainscr = initscr();
171	if (mainscr == NULL)
172		err(1, "initscr failed");
173
174	process_commands(mainscr);
175
176	return 0;
177}
178