commands.c revision 1.6 1 /* $NetBSD: commands.c,v 1.6 2020/10/24 04:46:17 blymn Exp $ */
2
3 /*-
4 * Copyright 2009 Brett Lymn <blymn (at) 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
32 #include <curses.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <err.h>
38 #include <sys/types.h>
39 #include "returns.h"
40 #include "slave.h"
41 #include "command_table.h"
42
43 extern int cmdpipe[2];
44 extern int slvpipe[2];
45 extern int initdone;
46
47 static void report_type(data_enum_t);
48 static void report_message(int, const char *);
49
50 /*
51 * Match the passed command string and execute the associated test
52 * function.
53 */
54 void
55 command_execute(char *func, int nargs, char **args)
56 {
57 size_t i, j;
58
59 i = 0;
60 while (i < ncmds) {
61 if (strcasecmp(func, commands[i].name) == 0) {
62 /* Check only restricted set of functions is called before
63 * initscr/newterm */
64 if(!initdone){
65 j = 0;
66 while(j < nrcmds) {
67 if(strcasecmp(func, restricted_commands[j]) == 0){
68 if(strcasecmp(func, "initscr") == 0 ||
69 strcasecmp(func, "newterm") == 0)
70 initdone = 1;
71 /* matched function */
72 commands[i].func(nargs, args);
73 return;
74 }
75 j++;
76 }
77 report_status("YOU NEED TO CALL INITSCR/NEWTERM FIRST");
78 return;
79 }
80 /* matched function */
81 commands[i].func(nargs, args);
82 return;
83 }
84 i++;
85 }
86
87 report_status("UNKNOWN_FUNCTION");
88 }
89
90 /*
91 * Report an pointer value back to the director
92 */
93 void
94 report_ptr(void *ptr)
95 {
96 char *string;
97
98 if (ptr == NULL)
99 asprintf(&string, "NULL");
100 else
101 asprintf(&string, "%p", ptr);
102 report_status(string);
103 free(string);
104 }
105
106 /*
107 * Report an integer value back to the director
108 */
109 void
110 report_int(int value)
111 {
112 char *string;
113
114 asprintf(&string, "%d", value);
115 report_status(string);
116 free(string);
117 }
118
119 /*
120 * Report either an ERR or OK back to the director
121 */
122 void
123 report_return(int status)
124 {
125 if (status == ERR)
126 report_type(data_err);
127 else if (status == OK)
128 report_type(data_ok);
129 else if (status == KEY_CODE_YES)
130 report_int(status);
131 else
132 report_status("INVALID_RETURN");
133 }
134
135 /*
136 * Report the type back to the director via the command pipe
137 */
138 static void
139 report_type(data_enum_t return_type)
140 {
141 int type;
142
143 type = return_type;
144 if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0)
145 err(1, "command pipe write for status type failed");
146
147 }
148
149 /*
150 * Report the number of returns back to the director via the command pipe
151 */
152 void
153 report_count(int count)
154 {
155 int type;
156
157 type = data_count;
158 if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0)
159 err(1, "command pipe write for count type failed");
160
161 if (write(slvpipe[WRITE_PIPE], &count, sizeof(int)) < 0)
162 err(1, "command pipe write for count");
163 }
164
165 /*
166 * Report the status back to the director via the command pipe
167 */
168 void
169 report_status(const char *status)
170 {
171 report_message(data_string, status);
172 }
173
174 /*
175 * Report an error message back to the director via the command pipe.
176 */
177 void
178 report_error(const char *status)
179 {
180 report_message(data_slave_error, status);
181 }
182
183 /*
184 * Report the message with the given type back to the director via the
185 * command pipe.
186 */
187 static void
188 report_message(int type, const char *status)
189 {
190 int len;
191
192 len = strlen(status);
193
194 if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0)
195 err(1, "command pipe write for message type failed");
196
197 if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0)
198 err(1, "command pipe write for message length failed");
199
200 if (write(slvpipe[WRITE_PIPE], status, len) < 0)
201 err(1, "command pipe write of message data failed");
202 }
203
204 /*
205 * Report a string of chtype back to the director via the command pipe.
206 */
207 void
208 report_byte(chtype c)
209 {
210 chtype string[2];
211
212 string[0] = c;
213 string[1] = A_NORMAL | '\0';
214 report_nstr(string);
215 }
216
217 /*
218 * Report a string of chtype back to the director via the command pipe.
219 */
220 void
221 report_nstr(chtype *string)
222 {
223 int len, type;
224 chtype *p;
225
226 len = 0;
227 p = string;
228
229 while ((*p++ & __CHARTEXT) != 0) {
230 len++;
231 }
232
233 len++; /* add in the termination chtype */
234 len *= sizeof(chtype);
235
236 type = data_byte;
237 if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0)
238 err(1, "%s: command pipe write for status type failed",
239 __func__);
240
241 if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0)
242 err(1, "%s: command pipe write for status length failed",
243 __func__);
244
245 if (write(slvpipe[WRITE_PIPE], string, len) < 0)
246 err(1, "%s: command pipe write of status data failed",
247 __func__);
248 }
249
250 /*
251 * Report a cchar_t back to the director via the command pipe.
252 */
253 void
254 report_cchar(cchar_t c)
255 {
256 int len, type;
257 len = sizeof(cchar_t);
258 type = data_cchar;
259
260 if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0)
261 err(1, "%s: command pipe write for status type failed",
262 __func__);
263
264 if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0)
265 err(1, "%s: command pipe write for status length failed",
266 __func__);
267
268 if (write(slvpipe[WRITE_PIPE], &c, len) < 0)
269 err(1, "%s: command pipe write of status data failed",
270 __func__);
271 }
272
273 /*
274 * Report a wchar_t back to the director via the command pipe.
275 */
276 void
277 report_wchar(wchar_t ch)
278 {
279 wchar_t wstr[2];
280
281 wstr[0] = ch;
282 wstr[1] = L'\0';
283 report_wstr(wstr);
284 }
285
286
287 /*
288 * Report a string of wchar_t back to the director via the command pipe.
289 */
290 void
291 report_wstr(wchar_t *wstr)
292 {
293 int len, type;
294 wchar_t *p;
295
296 len = 0;
297 p = wstr;
298
299 while (*p++ != L'\0')
300 len++;
301
302 len++; /* add in the termination chtype */
303 len *= sizeof(wchar_t);
304
305 type = data_wchar;
306 if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0)
307 err(1, "%s: command pipe write for status type failed",
308 __func__);
309
310 if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0)
311 err(1, "%s: command pipe write for status length failed",
312 __func__);
313
314 if (write(slvpipe[WRITE_PIPE], wstr, len) < 0)
315 err(1, "%s: command pipe write of status data failed",
316 __func__);
317 }
318
319 /*
320 * Check the number of args we received are what we expect. Return an
321 * error if they do not match.
322 */
323 int
324 check_arg_count(int nargs, int expected)
325 {
326 if (nargs != expected) {
327 report_count(1);
328 report_error("INCORRECT_ARGUMENT_NUMBER");
329 return(1);
330 }
331
332 return(0);
333 }
334