1 /*
2 * $FreeBSD: stable/9/usr.sbin/sade/dispatch.c 161099 2006-08-08 13:45:46Z delphij $
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
40 static int dispatch_systemExecute(dialogMenuItem *unused);
41 static int dispatch_msgConfirm(dialogMenuItem *unused);
42
43 static 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
67 typedef struct command_buffer_ {
68 qelement queue;
69 char * string;
70 } command_buffer;
71
72 /*
73 * Command processing
74 */
75
76 static int
dispatch_systemExecute(dialogMenuItem * unused)77 dispatch_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
88 static int
dispatch_msgConfirm(dialogMenuItem * unused)89 dispatch_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
102 static int
call_possible_resword(char * name,dialogMenuItem * value,int * status)103 call_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 */
119 int
dispatchCommand(char * str)120 dispatchCommand(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