]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/commands.c
5a9046546c75c74658a8c85793a90a8ff6c7d945
[apple/configd.git] / scutil.tproj / commands.c
1 /*
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /*
25 * Modification History
26 *
27 * June 1, 2001 Allan Nathanson <ajn@apple.com>
28 * - public API conversion
29 *
30 * November 9, 2000 Allan Nathanson <ajn@apple.com>
31 * - initial revision
32 */
33
34 #include <stdio.h>
35 #include <string.h>
36 #include <sys/errno.h>
37
38 #include "scutil.h"
39 #include "commands.h"
40 #include "dictionary.h"
41 #include "session.h"
42 #include "cache.h"
43 #include "notifications.h"
44 #include "tests.h"
45 #include "net.h"
46
47 #include "SCDynamicStoreInternal.h"
48
49
50 __private_extern__
51 const cmdInfo commands_store[] = {
52 /* cmd minArgs maxArgs func group ctype */
53 /* usage */
54
55 { "help", 0, 0, do_help, 0, 0,
56 " help : list available commands" },
57
58 { "f.read", 1, 1, do_readFile, 0, 0,
59 " f.read file : process commands from file" },
60
61 { "quit", 0, 0, do_quit, 0, 0,
62 " quit : quit" },
63
64 { "q", 0, 0, do_quit, 0, -1,
65 NULL },
66
67 { "exit", 0, 0, do_quit, 0, -1,
68 NULL },
69
70 /* local dictionary manipulation commands */
71
72 { "d.init", 0, 0, do_dictInit, 1, 0,
73 " d.init : initialize (empty) dictionary" },
74
75 { "d.show", 0, 0, do_dictShow, 1, 0,
76 " d.show : show dictionary contents" },
77
78 { "d.add", 2, 101, do_dictSetKey, 1, 0,
79 " d.add key [*#?] val [v2 ...] : add information to dictionary\n"
80 " (*=array, #=number, ?=boolean)" },
81
82 { "d.remove", 1, 1, do_dictRemoveKey, 1, 0,
83 " d.remove key : remove key from dictionary" },
84
85 /* data store manipulation commands */
86
87 { "open", 0, 1, do_open, 2, 1,
88 " open [\"temporary\"] : open a session with \"configd\"" },
89
90 { "close", 0, 0, do_close, 2, 1,
91 " close : close current \"configd\" session" },
92
93 { "lock", 0, 0, do_lock, 3, 1,
94 " lock : secures write access to data store" },
95
96 { "unlock", 0, 0, do_unlock, 3, 1,
97 " unlock : secures write access to data store" },
98
99 { "list", 0, 2, do_list, 4, 0,
100 " list [pattern] : list keys in data store" },
101
102 { "add", 1, 2, do_add, 4, 0,
103 " add key [\"temporary\"] : add key in data store w/current dict" },
104
105 { "get", 1, 1, do_get, 4, 0,
106 " get key : get dict from data store w/key" },
107
108 { "set", 1, 1, do_set, 4, 0,
109 " set key : set key in data store w/current dict" },
110
111 { "show", 1, 2, do_show, 4, 0,
112 " show key [\"pattern\"] : show values in data store w/key" },
113
114 { "remove", 1, 1, do_remove, 4, 0,
115 " remove key : remove key from data store" },
116
117 { "notify", 1, 1, do_notify, 4, 0,
118 " notify key : notify key in data store" },
119
120 { "touch", 1, 1, do_touch, 4, 1,
121 " touch key : touch key in data store" },
122
123 { "n.list", 0, 1, do_notify_list, 5, 0,
124 " n.list [\"pattern\"] : list notification keys" },
125
126 { "n.add", 1, 2, do_notify_add, 5, 0,
127 " n.add key [\"pattern\"] : add notification key" },
128
129 { "n.remove", 1, 2, do_notify_remove, 5, 0,
130 " n.remove key [\"pattern\"] : remove notification key" },
131
132 { "n.changes", 0, 0, do_notify_changes, 5, 0,
133 " n.changes : list changed keys" },
134
135 { "n.watch", 0, 1, do_notify_watch, 5, 0,
136 " n.watch [verbose] : watch for changes" },
137
138 { "n.wait", 0, 0, do_notify_wait, 5, 2,
139 " n.wait : wait for changes" },
140
141 { "n.callback", 0, 1, do_notify_callback, 5, 2,
142 " n.callback [\"verbose\"] : watch for changes" },
143
144 { "n.signal", 1, 2, do_notify_signal, 5, 2,
145 " n.signal sig [pid] : signal changes" },
146
147 { "n.file", 0, 1, do_notify_file, 5, 2,
148 " n.file [identifier] : watch for changes via file" },
149
150 { "n.cancel", 0, 1, do_notify_cancel, 5, 0,
151 " n.cancel : cancel notification requests" },
152
153 { "snapshot", 0, 0, do_snapshot, 99, 2,
154 " snapshot : save snapshot of store and session data" }
155 };
156 __private_extern__
157 const int nCommands_store = (sizeof(commands_store)/sizeof(cmdInfo));
158
159
160 __private_extern__
161 const cmdInfo commands_prefs[] = {
162 /* cmd minArgs maxArgs func group ctype */
163 /* usage */
164
165 { "help", 0, 0, do_help, 0, 0,
166 " help : list available commands" },
167
168 { "f.read", 1, 1, do_readFile, 0, 0,
169 " f.read file : process commands from file" },
170
171 { "quit", 0, 1, do_net_quit, 0, 0,
172 " quit [!] : quit" },
173
174 { "q", 0, 1, do_net_quit, 0, -1,
175 NULL },
176
177 { "exit", 0, 1, do_net_quit, 0, -1,
178 NULL },
179
180 /* network configuration manipulation commands */
181
182 { "open", 0, 1, do_net_open, 2, 1,
183 " open : open the network configuration" },
184
185 { "commit", 0, 0, do_net_commit, 2, 0,
186 " commit : commit any changes" },
187
188 { "apply", 0, 0, do_net_apply, 2, 0,
189 " apply : apply any changes" },
190
191 { "close", 0, 1, do_net_close, 2, 1,
192 " close [!] : close the network configuration" },
193
194 { "create", 1, 3, do_net_create, 3, 0,
195 " create interface <interfaceType> [ <interfaceName> | <interface#> ]\n"
196 " create protocol <protocolType>\n"
197 " create service [ <interfaceName> | <interface#> [ <serviceName> ]]\n"
198 " create set [setName]" },
199
200 { "disable", 1, 2, do_net_disable, 5, 0,
201 " disable protocol [ <protocolType> ]\n"
202 " disable service [ <serviceName> | <service#> ]" },
203
204 { "enable", 1, 2, do_net_enable, 4, 0,
205 " enable protocol [ <protocolType> ]\n"
206 " enable service [ <serviceName> | <service#> ]" },
207
208 { "remove", 1, 2, do_net_remove, 6, 0,
209 " remove protocol [ <protocolType> ]\n"
210 " remove service [ <serviceName> | <service#> ]\n"
211 " remove set [ <setName> | <set#> ]" },
212
213 { "select", 2, 2, do_net_select, 7, 0,
214 " select interface <interfaceName> | <interface#> | $child | $service\n"
215 " select protocol <protocolType>\n"
216 " select service <serviceName> | <service#>\n"
217 " select set <setName> | <set#>" },
218
219 { "set", 2, 101, do_net_set, 8, 0,
220 " set interface context-sensitive-arguments (or ? for help)\n"
221 " set protocol context-sensitive-arguments (or ? for help)\n"
222 " set service [ name <serviceName> ] [ order new-order ]\n"
223 " set set [ name setName ]" },
224
225 { "show", 1, 2, do_net_show, 9, 0,
226 " show interfaces\n"
227 " show interface [ <interfaceName> | <interface#> ]\n"
228 " show protocols\n"
229 " show protocol [ <protocolType> ]\n"
230 " show services [ all ]\n"
231 " show service [ <serviceName> | <service#> ]\n"
232 " show sets\n\n"
233 " show set [ <setName> | <set#> ]" },
234
235 { "snapshot", 0, 0, do_net_snapshot, 99, 2,
236 " snapshot" }
237
238 };
239 __private_extern__
240 const int nCommands_prefs = (sizeof(commands_prefs)/sizeof(cmdInfo));
241
242
243 __private_extern__ cmdInfo *commands = NULL;
244 __private_extern__ int nCommands = 0;
245 __private_extern__ Boolean enablePrivateAPI = FALSE;
246 __private_extern__ Boolean termRequested = FALSE;
247
248
249 __private_extern__
250 void
251 do_command(int argc, char **argv)
252 {
253 int i;
254 char *cmd = argv[0];
255
256 for (i = 0; i < nCommands; i++) {
257 if ((commands[i].ctype > 1) && !enablePrivateAPI) {
258 continue; /* if "private" API and access has not been enabled */
259 }
260
261 if (strcasecmp(cmd, commands[i].cmd) == 0) {
262 --argc;
263 argv++;
264 if (argc < commands[i].minArgs) {
265 SCPrint(TRUE, stdout, CFSTR("%s: too few arguments\n"), cmd);
266 return;
267 } else if (argc > commands[i].maxArgs) {
268 SCPrint(TRUE, stdout, CFSTR("%s: too many arguments\n"), cmd);
269 return;
270 }
271 (*commands[i].func)(argc, argv);
272 return;
273 }
274 }
275
276 SCPrint(TRUE, stdout, CFSTR("%s: unknown, type \"help\" for command info\n"), cmd);
277 return;
278 }
279
280
281 __private_extern__
282 void
283 do_help(int argc, char **argv)
284 {
285 int g = -1; /* current group */
286 int i;
287
288 SCPrint(TRUE, stdout, CFSTR("\nAvailable commands:\n"));
289 for (i = 0; i < nCommands; i++) {
290 if (commands[i].ctype < 0) {
291 continue; /* if "hidden" */
292 }
293
294 if ((commands[i].ctype > 0) && !enablePrivateAPI) {
295 continue; /* if "private" API and access has not been enabled */
296 }
297
298 /* check if this is a new command group */
299 if (g != commands[i].group) {
300 SCPrint(TRUE, stdout, CFSTR("\n"));
301 g = commands[i].group;
302 }
303
304 /* display the command */
305 SCPrint(TRUE, stdout, CFSTR("%s\n"), commands[i].usage);
306 }
307 SCPrint(TRUE, stdout, CFSTR("\n"));
308
309 return;
310 }
311
312
313 __private_extern__
314 void
315 do_readFile(int argc, char **argv)
316 {
317 InputRef src;
318
319 /* allocate command input stream */
320 src = (InputRef)CFAllocatorAllocate(NULL, sizeof(Input), 0);
321 src->el = NULL;
322 src->fp = fopen(argv[0], "r");
323
324 if (src->fp == NULL) {
325 SCPrint(TRUE, stdout, CFSTR("f.read: could not open file (%s).\n"), strerror(errno));
326 CFAllocatorDeallocate(NULL, src);
327 return;
328 }
329
330 /* open file, increase nesting level */
331 SCPrint(TRUE, stdout, CFSTR("f.read: reading file (%s).\n"), argv[0]);
332 nesting++;
333
334 while (process_line(src) == TRUE) {
335 /* debug information, diagnostics */
336 __showMachPortStatus();
337 }
338
339 (void)fclose(src->fp);
340 CFAllocatorDeallocate(NULL, src);
341
342 return;
343 }
344
345
346 __private_extern__
347 void
348 do_quit(int argc, char **argv)
349 {
350 termRequested = TRUE;
351 return;
352 }