1*57718be8SEnji Cooper /* $NetBSD: commands.c,v 1.4 2011/09/15 11:46:19 blymn Exp $ */ 2*57718be8SEnji Cooper 3*57718be8SEnji Cooper /*- 4*57718be8SEnji Cooper * Copyright 2009 Brett Lymn <blymn@NetBSD.org> 5*57718be8SEnji Cooper * 6*57718be8SEnji Cooper * All rights reserved. 7*57718be8SEnji Cooper * 8*57718be8SEnji Cooper * This code has been donated to The NetBSD Foundation by the Author. 9*57718be8SEnji Cooper * 10*57718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without 11*57718be8SEnji Cooper * modification, are permitted provided that the following conditions 12*57718be8SEnji Cooper * are met: 13*57718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright 14*57718be8SEnji Cooper * notice, this list of conditions and the following disclaimer. 15*57718be8SEnji Cooper * 2. The name of the author may not be used to endorse or promote products 16*57718be8SEnji Cooper * derived from this software withough specific prior written permission 17*57718be8SEnji Cooper * 18*57718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19*57718be8SEnji Cooper * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20*57718be8SEnji Cooper * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21*57718be8SEnji Cooper * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22*57718be8SEnji Cooper * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23*57718be8SEnji Cooper * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24*57718be8SEnji Cooper * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25*57718be8SEnji Cooper * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26*57718be8SEnji Cooper * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27*57718be8SEnji Cooper * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28*57718be8SEnji Cooper * 29*57718be8SEnji Cooper * 30*57718be8SEnji Cooper */ 31*57718be8SEnji Cooper 32*57718be8SEnji Cooper #include <curses.h> 33*57718be8SEnji Cooper #include <string.h> 34*57718be8SEnji Cooper #include <stdlib.h> 35*57718be8SEnji Cooper #include <stdio.h> 36*57718be8SEnji Cooper #include <unistd.h> 37*57718be8SEnji Cooper #include <err.h> 38*57718be8SEnji Cooper #include <sys/types.h> 39*57718be8SEnji Cooper #include "returns.h" 40*57718be8SEnji Cooper #include "slave.h" 41*57718be8SEnji Cooper #include "command_table.h" 42*57718be8SEnji Cooper 43*57718be8SEnji Cooper extern int cmdpipe[2]; 44*57718be8SEnji Cooper extern int slvpipe[2]; 45*57718be8SEnji Cooper 46*57718be8SEnji Cooper static void report_type(returns_enum_t); 47*57718be8SEnji Cooper static void report_message(int, const char *); 48*57718be8SEnji Cooper 49*57718be8SEnji Cooper /* 50*57718be8SEnji Cooper * Match the passed command string and execute the associated test 51*57718be8SEnji Cooper * function. 52*57718be8SEnji Cooper */ 53*57718be8SEnji Cooper void 54*57718be8SEnji Cooper command_execute(char *func, int nargs, char **args) 55*57718be8SEnji Cooper { 56*57718be8SEnji Cooper size_t i; 57*57718be8SEnji Cooper 58*57718be8SEnji Cooper i = 0; 59*57718be8SEnji Cooper while (i < ncmds) { 60*57718be8SEnji Cooper if (strcasecmp(func, commands[i].name) == 0) { 61*57718be8SEnji Cooper /* matched function */ 62*57718be8SEnji Cooper commands[i].func(nargs, args); 63*57718be8SEnji Cooper return; 64*57718be8SEnji Cooper } 65*57718be8SEnji Cooper i++; 66*57718be8SEnji Cooper } 67*57718be8SEnji Cooper 68*57718be8SEnji Cooper report_status("UNKNOWN_FUNCTION"); 69*57718be8SEnji Cooper } 70*57718be8SEnji Cooper 71*57718be8SEnji Cooper /* 72*57718be8SEnji Cooper * Report an pointer value back to the director 73*57718be8SEnji Cooper */ 74*57718be8SEnji Cooper void 75*57718be8SEnji Cooper report_ptr(void *ptr) 76*57718be8SEnji Cooper { 77*57718be8SEnji Cooper char *string; 78*57718be8SEnji Cooper 79*57718be8SEnji Cooper if (ptr == NULL) 80*57718be8SEnji Cooper asprintf(&string, "NULL"); 81*57718be8SEnji Cooper else 82*57718be8SEnji Cooper asprintf(&string, "%p", ptr); 83*57718be8SEnji Cooper report_status(string); 84*57718be8SEnji Cooper free(string); 85*57718be8SEnji Cooper } 86*57718be8SEnji Cooper 87*57718be8SEnji Cooper /* 88*57718be8SEnji Cooper * Report an integer value back to the director 89*57718be8SEnji Cooper */ 90*57718be8SEnji Cooper void 91*57718be8SEnji Cooper report_int(int value) 92*57718be8SEnji Cooper { 93*57718be8SEnji Cooper char *string; 94*57718be8SEnji Cooper 95*57718be8SEnji Cooper asprintf(&string, "%d", value); 96*57718be8SEnji Cooper report_status(string); 97*57718be8SEnji Cooper free(string); 98*57718be8SEnji Cooper } 99*57718be8SEnji Cooper 100*57718be8SEnji Cooper /* 101*57718be8SEnji Cooper * Report either an ERR or OK back to the director 102*57718be8SEnji Cooper */ 103*57718be8SEnji Cooper void 104*57718be8SEnji Cooper report_return(int status) 105*57718be8SEnji Cooper { 106*57718be8SEnji Cooper if (status == ERR) 107*57718be8SEnji Cooper report_type(ret_err); 108*57718be8SEnji Cooper else if (status == OK) 109*57718be8SEnji Cooper report_type(ret_ok); 110*57718be8SEnji Cooper else 111*57718be8SEnji Cooper report_status("INVALID_RETURN"); 112*57718be8SEnji Cooper } 113*57718be8SEnji Cooper 114*57718be8SEnji Cooper /* 115*57718be8SEnji Cooper * Report the type back to the director via the command pipe 116*57718be8SEnji Cooper */ 117*57718be8SEnji Cooper static void 118*57718be8SEnji Cooper report_type(returns_enum_t return_type) 119*57718be8SEnji Cooper { 120*57718be8SEnji Cooper int type; 121*57718be8SEnji Cooper 122*57718be8SEnji Cooper type = return_type; 123*57718be8SEnji Cooper if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) 124*57718be8SEnji Cooper err(1, "command pipe write for status type failed"); 125*57718be8SEnji Cooper 126*57718be8SEnji Cooper } 127*57718be8SEnji Cooper 128*57718be8SEnji Cooper /* 129*57718be8SEnji Cooper * Report the number of returns back to the director via the command pipe 130*57718be8SEnji Cooper */ 131*57718be8SEnji Cooper void 132*57718be8SEnji Cooper report_count(int count) 133*57718be8SEnji Cooper { 134*57718be8SEnji Cooper int type; 135*57718be8SEnji Cooper 136*57718be8SEnji Cooper type = ret_count; 137*57718be8SEnji Cooper if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) 138*57718be8SEnji Cooper err(1, "command pipe write for count type failed"); 139*57718be8SEnji Cooper 140*57718be8SEnji Cooper if (write(slvpipe[WRITE_PIPE], &count, sizeof(int)) < 0) 141*57718be8SEnji Cooper err(1, "command pipe write for count"); 142*57718be8SEnji Cooper } 143*57718be8SEnji Cooper 144*57718be8SEnji Cooper /* 145*57718be8SEnji Cooper * Report the status back to the director via the command pipe 146*57718be8SEnji Cooper */ 147*57718be8SEnji Cooper void 148*57718be8SEnji Cooper report_status(const char *status) 149*57718be8SEnji Cooper { 150*57718be8SEnji Cooper report_message(ret_string, status); 151*57718be8SEnji Cooper } 152*57718be8SEnji Cooper 153*57718be8SEnji Cooper /* 154*57718be8SEnji Cooper * Report an error message back to the director via the command pipe. 155*57718be8SEnji Cooper */ 156*57718be8SEnji Cooper void 157*57718be8SEnji Cooper report_error(const char *status) 158*57718be8SEnji Cooper { 159*57718be8SEnji Cooper report_message(ret_slave_error, status); 160*57718be8SEnji Cooper } 161*57718be8SEnji Cooper 162*57718be8SEnji Cooper /* 163*57718be8SEnji Cooper * Report the message with the given type back to the director via the 164*57718be8SEnji Cooper * command pipe. 165*57718be8SEnji Cooper */ 166*57718be8SEnji Cooper static void 167*57718be8SEnji Cooper report_message(int type, const char *status) 168*57718be8SEnji Cooper { 169*57718be8SEnji Cooper int len; 170*57718be8SEnji Cooper 171*57718be8SEnji Cooper len = strlen(status); 172*57718be8SEnji Cooper 173*57718be8SEnji Cooper if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) 174*57718be8SEnji Cooper err(1, "command pipe write for message type failed"); 175*57718be8SEnji Cooper 176*57718be8SEnji Cooper if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0) 177*57718be8SEnji Cooper err(1, "command pipe write for message length failed"); 178*57718be8SEnji Cooper 179*57718be8SEnji Cooper if (write(slvpipe[WRITE_PIPE], status, len) < 0) 180*57718be8SEnji Cooper err(1, "command pipe write of message data failed"); 181*57718be8SEnji Cooper } 182*57718be8SEnji Cooper 183*57718be8SEnji Cooper /* 184*57718be8SEnji Cooper * Report a string of chtype back to the director via the command pipe. 185*57718be8SEnji Cooper */ 186*57718be8SEnji Cooper void 187*57718be8SEnji Cooper report_byte(chtype c) 188*57718be8SEnji Cooper { 189*57718be8SEnji Cooper chtype string[2]; 190*57718be8SEnji Cooper 191*57718be8SEnji Cooper string[0] = c; 192*57718be8SEnji Cooper string[1] = A_NORMAL | '\0'; 193*57718be8SEnji Cooper report_nstr(string); 194*57718be8SEnji Cooper } 195*57718be8SEnji Cooper 196*57718be8SEnji Cooper /* 197*57718be8SEnji Cooper * Report a string of chtype back to the director via the command pipe. 198*57718be8SEnji Cooper */ 199*57718be8SEnji Cooper void 200*57718be8SEnji Cooper report_nstr(chtype *string) 201*57718be8SEnji Cooper { 202*57718be8SEnji Cooper int len, type; 203*57718be8SEnji Cooper chtype *p; 204*57718be8SEnji Cooper 205*57718be8SEnji Cooper len = 0; 206*57718be8SEnji Cooper p = string; 207*57718be8SEnji Cooper 208*57718be8SEnji Cooper while ((*p++ & __CHARTEXT) != 0) { 209*57718be8SEnji Cooper len++; 210*57718be8SEnji Cooper } 211*57718be8SEnji Cooper 212*57718be8SEnji Cooper len++; /* add in the termination chtype */ 213*57718be8SEnji Cooper len *= sizeof(chtype); 214*57718be8SEnji Cooper 215*57718be8SEnji Cooper type = ret_byte; 216*57718be8SEnji Cooper if (write(slvpipe[WRITE_PIPE], &type, sizeof(int)) < 0) 217*57718be8SEnji Cooper err(1, "%s: command pipe write for status type failed", 218*57718be8SEnji Cooper __func__); 219*57718be8SEnji Cooper 220*57718be8SEnji Cooper if (write(slvpipe[WRITE_PIPE], &len, sizeof(int)) < 0) 221*57718be8SEnji Cooper err(1, "%s: command pipe write for status length failed", 222*57718be8SEnji Cooper __func__); 223*57718be8SEnji Cooper 224*57718be8SEnji Cooper if (write(slvpipe[WRITE_PIPE], string, len) < 0) 225*57718be8SEnji Cooper err(1, "%s: command pipe write of status data failed", 226*57718be8SEnji Cooper __func__); 227*57718be8SEnji Cooper } 228*57718be8SEnji Cooper 229*57718be8SEnji Cooper /* 230*57718be8SEnji Cooper * Check the number of args we received are what we expect. Return an 231*57718be8SEnji Cooper * error if they do not match. 232*57718be8SEnji Cooper */ 233*57718be8SEnji Cooper int 234*57718be8SEnji Cooper check_arg_count(int nargs, int expected) 235*57718be8SEnji Cooper { 236*57718be8SEnji Cooper if (nargs != expected) { 237*57718be8SEnji Cooper report_count(1); 238*57718be8SEnji Cooper report_error("INCORRECT_ARGUMENT_NUMBER"); 239*57718be8SEnji Cooper return(1); 240*57718be8SEnji Cooper } 241*57718be8SEnji Cooper 242*57718be8SEnji Cooper return(0); 243*57718be8SEnji Cooper } 244