1/* 2 * $FreeBSD$ 3 * 4 * Copyright (c) 1995 5 * Jordan Hubbard. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer, 12 * verbatim and that no modifications are made prior to this 13 * point in the file. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY JORDAN HUBBARD ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL JORDAN HUBBARD OR HIS PETS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, LIFE OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32#include "sade.h" 33#include <ctype.h> 34#include <errno.h> 35#include <sys/signal.h> 36#include <sys/fcntl.h> 37 38#include "list.h" 39 40static int dispatch_systemExecute(dialogMenuItem *unused); 41static int dispatch_msgConfirm(dialogMenuItem *unused); 42 43static struct _word { 44 char *name; 45 int (*handler)(dialogMenuItem *self); 46} resWords[] = { 47#ifdef WITH_SLICES 48 { "diskPartitionEditor", diskPartitionEditor }, 49#endif 50 { "diskPartitionWrite", diskPartitionWrite }, 51 { "diskLabelEditor", diskLabelEditor }, 52 { "diskLabelCommit", diskLabelCommit }, 53 { "msgConfirm", dispatch_msgConfirm }, 54 { "system", dispatch_systemExecute }, 55 { "dumpVariables", dump_variables }, 56 { NULL, NULL }, 57}; 58 59/* 60 * Helper routines for buffering data. 61 * 62 * We read an entire configuration into memory before executing it 63 * so that we are truely standalone and can do things like nuke the 64 * file or disk we're working on. 65 */ 66 67typedef struct command_buffer_ { 68 qelement queue; 69 char * string; 70} command_buffer; 71 72/* 73 * Command processing 74 */ 75 76static int 77dispatch_systemExecute(dialogMenuItem *unused) 78{ 79 char *cmd = variable_get(VAR_COMMAND); 80 81 if (cmd) 82 return systemExecute(cmd) ? DITEM_FAILURE : DITEM_SUCCESS; 83 else 84 msgDebug("_systemExecute: No command passed in `command' variable.\n"); 85 return DITEM_FAILURE; 86} 87 88static int 89dispatch_msgConfirm(dialogMenuItem *unused) 90{ 91 char *msg = variable_get(VAR_COMMAND); 92 93 if (msg) { 94 msgConfirm("%s", msg); 95 return DITEM_SUCCESS; 96 } 97 98 msgDebug("_msgConfirm: No message passed in `command' variable.\n"); 99 return DITEM_FAILURE; 100} 101 102static int 103call_possible_resword(char *name, dialogMenuItem *value, int *status) 104{ 105 int i, rval; 106 107 rval = 0; 108 for (i = 0; resWords[i].name; i++) { 109 if (!strcmp(name, resWords[i].name)) { 110 *status = resWords[i].handler(value); 111 rval = 1; 112 break; 113 } 114 } 115 return rval; 116} 117 118/* For a given string, call it or spit out an undefined command diagnostic */ 119int 120dispatchCommand(char *str) 121{ 122 int i; 123 char *cp; 124 125 if (!str || !*str) { 126 msgConfirm("Null or zero-length string passed to dispatchCommand"); 127 return DITEM_FAILURE; 128 } 129 /* If it's got a newline, trim it */ 130 if ((cp = index(str, '\n')) != NULL) 131 *cp = '\0'; 132 133 /* If it's got a `=' sign in there, assume it's a variable setting */ 134 if (index(str, '=')) { 135 if (isDebug()) 136 msgDebug("dispatch: setting variable `%s'\n", str); 137 variable_set(str, 0); 138 i = DITEM_SUCCESS; 139 } 140 else { 141 /* A command might be a pathname if it's encoded in argv[0], which 142 we also support */ 143 if ((cp = rindex(str, '/')) != NULL) 144 str = cp + 1; 145 if (isDebug()) 146 msgDebug("dispatch: calling resword `%s'\n", str); 147 if (!call_possible_resword(str, NULL, &i)) { 148 msgNotify("Warning: No such command ``%s''", str); 149 i = DITEM_FAILURE; 150 } 151 /* 152 * Allow a user to prefix a command with "noError" to cause 153 * us to ignore any errors for that one command. 154 */ 155 if (i != DITEM_SUCCESS && variable_get(VAR_NO_ERROR)) 156 i = DITEM_SUCCESS; 157 variable_unset(VAR_NO_ERROR); 158 } 159 return i; 160} 161 162