commands.c revision 1.1 1 /* $NetBSD: commands.c,v 1.1 2011/04/10 09:55:10 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 <sys/types.h>
37 #include "returns.h"
38 #include "slave.h"
39 #include "command_table.h"
40
41 extern int cmdpipe[2];
42 extern int slvpipe[2];
43
44 static void report_type(returns_enum_t);
45 static void report_message(int, char *);
46
47 /*
48 * Match the passed command string and execute the associated test
49 * function.
50 */
51 void
52 command_execute(char *func, int nargs, char **args)
53 {
54 size_t i;
55
56 i = 0;
57 while (i < ncmds) {
58 if (strcasecmp(func, commands[i].name) == 0) {
59 /* matched function */
60 commands[i].func(nargs, args);
61 return;
62 }
63 i++;
64 }
65
66 report_status("UNKNOWN_FUNCTION");
67 }
68
69 /*
70 * Report an pointer value back to the director
71 */
72 void
73 report_ptr(void *ptr)
74 {
75 char *string;
76
77 asprintf(&string, "%td", ptr);
78 report_status(string);
79 free(string);
80 }
81
82 /*
83 * Report an integer value back to the director
84 */
85 void
86 report_int(int value)
87 {
88 char *string;
89
90 asprintf(&string, "%d", value);
91 report_status(string);
92 free(string);
93 }
94
95 /*
96 * Report either an ERR or OK back to the director
97 */
98 void
99 report_return(int status)
100 {
101 if (status == ERR)
102 report_type(ret_err);
103 else if (status == OK)
104 report_type(ret_ok);
105 else
106 report_status("INVALID_RETURN");
107 }
108
109 /*
110 * Report the type back to the director via the command pipe
111 */
112 static void
113 report_type(returns_enum_t return_type)
114 {
115 int type;
116
117 type = return_type;
118 if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) {
119 perror("command pipe write for status type failed");
120 exit(1);
121 }
122
123 }
124
125 /*
126 * Report the number of returns back to the director via the command pipe
127 */
128 void
129 report_count(int count)
130 {
131 int type;
132
133 type = ret_count;
134 if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) {
135 perror("command pipe write for count type failed");
136 exit(1);
137 }
138
139 if (write(slvpipe[WRITE_PIPE], &count, sizeof(int)) < 0) {
140 perror("command pipe write for count");
141 exit(1);
142 }
143 }
144
145 /*
146 * Report the status back to the director via the command pipe
147 */
148 void
149 report_status(char *status)
150 {
151 report_message(ret_string, status);
152 }
153
154 /*
155 * Report an error message back to the director via the command pipe.
156 */
157 void
158 report_error(char *status)
159 {
160 report_message(ret_slave_error, status);
161 }
162
163 /*
164 * Report the message with the given type back to the director via the
165 * command pipe.
166 */
167 static void
168 report_message(int type, char *status)
169 {
170 int len;
171
172 len = strlen(status);
173
174 if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) {
175 perror("command pipe write for message type failed");
176 exit(1);
177 }
178
179 if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0) {
180 perror("command pipe write for message length failed");
181 exit(1);
182 }
183
184 if (write(slvpipe[WRITE_PIPE], status, len) < 0) {
185 perror("command pipe write of message data failed");
186 exit(1);
187 }
188 }
189
190 /*
191 * Report a string of chtype back to the director via the command pipe.
192 */
193 void
194 report_nstr(chtype *string)
195 {
196 int len, type;
197 chtype *p;
198
199 len = 0;
200 p = string;
201
202 while ((*p++ & __CHARTEXT) != 0) {
203 len++;
204 }
205
206 type = ret_byte;
207 if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) {
208 perror("report_nstr: command pipe write for status type failed");
209 exit(1);
210 }
211
212 if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0) {
213 perror("report_nstr: command pipe write for status length failed");
214 exit(1);
215 }
216
217 if (write(slvpipe[WRITE_PIPE], string, len) < 0) {
218 perror("report_nstr: command pipe write of status data failed");
219 exit(1);
220 }
221 }
222
223 /*
224 * Check the number of args we received are what we expect. Return an
225 * error if they do not match.
226 */
227 int
228 check_arg_count(int nargs, int expected)
229 {
230 if (nargs != expected) {
231 report_count(1);
232 report_error("INCORRECT_ARGUMENT_NUMBER");
233 return(1);
234 }
235
236 return(0);
237 }
238