]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/commands.c
configd-212.2.tar.gz
[apple/configd.git] / scutil.tproj / commands.c
1 /*
2 * Copyright (c) 2000-2007 Apple 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 #include "prefs.h"
47
48 #include "SCDynamicStoreInternal.h"
49
50
51 __private_extern__
52 const cmdInfo commands_store[] = {
53 /* cmd minArgs maxArgs func group ctype */
54 /* usage */
55
56 { "help", 0, 0, do_help, 0, 0,
57 " help : list available commands" },
58
59 { "f.read", 1, 1, do_readFile, 0, 0,
60 " f.read file : process commands from file" },
61
62 { "quit", 0, 0, do_quit, 0, 0,
63 " quit : quit" },
64
65 { "q", 0, 0, do_quit, 0, -1,
66 NULL },
67
68 { "exit", 0, 0, do_quit, 0, -1,
69 NULL },
70
71 /* local dictionary manipulation commands */
72
73 { "d.init", 0, 0, do_dictInit, 1, 0,
74 " d.init : initialize (empty) dictionary" },
75
76 { "d.show", 0, 0, do_dictShow, 1, 0,
77 " d.show : show dictionary contents" },
78
79 { "d.add", 2, 101, do_dictSetKey, 1, 0,
80 " d.add key [*#?] val [v2 ...] : add information to dictionary\n"
81 " (*=array, #=number, ?=boolean)" },
82
83 { "d.remove", 1, 1, do_dictRemoveKey, 1, 0,
84 " d.remove key : remove key from dictionary" },
85
86 /* dynamic store manipulation commands */
87
88 { "open", 0, 1, do_open, 2, 1,
89 " open [\"temporary\"] : open a session with \"configd\"" },
90
91 { "close", 0, 0, do_close, 2, 1,
92 " close : close current \"configd\" session" },
93
94 { "lock", 0, 0, do_lock, 3, 1,
95 " lock : locks write access to data store" },
96
97 { "unlock", 0, 0, do_unlock, 3, 1,
98 " unlock : unlocks write access to data store" },
99
100 { "list", 0, 2, do_list, 4, 0,
101 " list [pattern] : list keys in data store" },
102
103 { "add", 1, 2, do_add, 4, 0,
104 " add key [\"temporary\"] : add key in data store w/current dict" },
105
106 { "get", 1, 1, do_get, 4, 0,
107 " get key : get dict from data store w/key" },
108
109 { "set", 1, 1, do_set, 4, 0,
110 " set key : set key in data store w/current dict" },
111
112 { "show", 1, 2, do_show, 4, 0,
113 " show key [\"pattern\"] : show values in data store w/key" },
114
115 { "remove", 1, 1, do_remove, 4, 0,
116 " remove key : remove key from data store" },
117
118 { "notify", 1, 1, do_notify, 4, 0,
119 " notify key : notify key in data store" },
120
121 { "touch", 1, 1, do_touch, 4, 1,
122 " touch key : touch key in data store" },
123
124 { "n.list", 0, 1, do_notify_list, 5, 0,
125 " n.list [\"pattern\"] : list notification keys" },
126
127 { "n.add", 1, 2, do_notify_add, 5, 0,
128 " n.add key [\"pattern\"] : add notification key" },
129
130 { "n.remove", 1, 2, do_notify_remove, 5, 0,
131 " n.remove key [\"pattern\"] : remove notification key" },
132
133 { "n.changes", 0, 0, do_notify_changes, 5, 0,
134 " n.changes : list changed keys" },
135
136 { "n.watch", 0, 1, do_notify_watch, 5, 0,
137 " n.watch [verbose] : watch for changes" },
138
139 { "n.wait", 0, 0, do_notify_wait, 5, 2,
140 " n.wait : wait for changes" },
141
142 { "n.callback", 0, 1, do_notify_callback, 5, 2,
143 " n.callback [\"verbose\"] : watch for changes" },
144
145 { "n.signal", 1, 2, do_notify_signal, 5, 2,
146 " n.signal sig [pid] : signal changes" },
147
148 { "n.file", 0, 1, do_notify_file, 5, 2,
149 " n.file [identifier] : watch for changes via file" },
150
151 { "n.cancel", 0, 1, do_notify_cancel, 5, 0,
152 " n.cancel : cancel notification requests" },
153
154 { "snapshot", 0, 0, do_snapshot, 99, 2,
155 " snapshot : save snapshot of store and session data" }
156 };
157 __private_extern__
158 const int nCommands_store = (sizeof(commands_store)/sizeof(cmdInfo));
159
160
161 __private_extern__
162 const cmdInfo commands_net[] = {
163 /* cmd minArgs maxArgs func group ctype */
164 /* usage */
165
166 { "help", 0, 0, do_help, 0, 0,
167 " help : list available commands" },
168
169 { "f.read", 1, 1, do_readFile, 0, 0,
170 " f.read file : process commands from file" },
171
172 { "quit", 0, 1, do_net_quit, 0, 0,
173 " quit [!] : quit" },
174
175 { "q", 0, 1, do_net_quit, 0, -1,
176 NULL },
177
178 { "exit", 0, 1, do_net_quit, 0, -1,
179 NULL },
180
181 /* network configuration manipulation commands */
182
183 { "open", 0, 1, do_net_open, 2, 1,
184 " open : open the network configuration" },
185
186 { "commit", 0, 0, do_net_commit, 2, 0,
187 " commit : commit any changes" },
188
189 { "apply", 0, 0, do_net_apply, 2, 0,
190 " apply : apply any changes" },
191
192 { "close", 0, 1, do_net_close, 2, 1,
193 " close [!] : close the network configuration" },
194
195 { "create", 1, 3, do_net_create, 3, 0,
196 " create interface <interfaceType> [ <interfaceName> | <interface#> ]\n"
197 " create protocol <protocolType>\n"
198 " create service [ <interfaceName> | <interface#> [ <serviceName> ]]\n"
199 " create set [setName]" },
200
201 { "disable", 1, 2, do_net_disable, 4, 0,
202 " disable protocol [ <protocolType> ]\n"
203 " disable service [ <serviceName> | <service#> ]" },
204
205 { "enable", 1, 2, do_net_enable, 5, 0,
206 " enable protocol [ <protocolType> ]\n"
207 " enable service [ <serviceName> | <service#> ]" },
208
209 { "remove", 1, 2, do_net_remove, 6, 0,
210 " remove protocol [ <protocolType> ]\n"
211 " remove service [ <serviceName> | <service#> ]\n"
212 " remove set [ <setName> | <set#> ]" },
213
214 { "select", 2, 2, do_net_select, 7, 0,
215 " select interface <interfaceName> | <interface#> | $child | $service\n"
216 " select protocol <protocolType>\n"
217 " select service <serviceName> | <service#>\n"
218 " select set <setName> | <set#>" },
219
220 { "set", 2, 101, do_net_set, 8, 0,
221 " set interface context-sensitive-arguments (or ? for help)\n"
222 " set protocol context-sensitive-arguments (or ? for help)\n"
223 " set service [ name <serviceName> ] [ order new-order ]\n"
224 " set set [ name setName ]" },
225
226 { "show", 1, 2, do_net_show, 9, 0,
227 " show interfaces\n"
228 " show interface [ <interfaceName> | <interface#> ]\n"
229 " show protocols\n"
230 " show protocol [ <protocolType> ]\n"
231 " show services [ all ]\n"
232 " show service [ <serviceName> | <service#> ]\n"
233 " show sets\n\n"
234 " show set [ <setName> | <set#> ]" },
235
236 { "update", 0, 1, do_net_update, 10, 0,
237 " update : update the network configuration" },
238
239 { "snapshot", 0, 0, do_net_snapshot, 99, 2,
240 " snapshot" }
241
242 };
243 __private_extern__
244 const int nCommands_net = (sizeof(commands_net)/sizeof(cmdInfo));
245
246
247 __private_extern__
248 const cmdInfo commands_prefs[] = {
249 /* cmd minArgs maxArgs func group ctype */
250 /* usage */
251
252 { "help", 0, 0, do_help, 0, 0,
253 " help : list available commands" },
254
255 { "f.read", 1, 1, do_readFile, 0, 0,
256 " f.read file : process commands from file" },
257
258 { "quit", 0, 1, do_prefs_quit, 0, 0,
259 " quit [!] : quit" },
260
261 { "q", 0, 1, do_prefs_quit, 0, -1,
262 NULL },
263
264 { "exit", 0, 1, do_prefs_quit, 0, -1,
265 NULL },
266
267 /* local dictionary manipulation commands */
268
269 { "d.init", 0, 0, do_dictInit, 1, 0,
270 " d.init : initialize (empty) dictionary" },
271
272 { "d.show", 0, 0, do_dictShow, 1, 0,
273 " d.show : show dictionary contents" },
274
275 { "d.add", 2, 101, do_dictSetKey, 1, 0,
276 " d.add key [*#?] val [v2 ...] : add information to dictionary\n"
277 " (*=array, #=number, ?=boolean)" },
278
279 { "d.remove", 1, 1, do_dictRemoveKey, 1, 0,
280 " d.remove key : remove key from dictionary" },
281
282 /* data store manipulation commands */
283
284 { "open", 0, 1, do_prefs_open, 2, 1,
285 " open [\"prefsID\"] : open a \"preferences\" session" },
286
287 { "lock", 0, 1, do_prefs_lock, 3, 1,
288 " lock [wait] : locks write access to preferences" },
289
290 { "commit", 0, 0, do_prefs_commit, 2, 0,
291 " commit : commit any changes" },
292
293 { "apply", 0, 0, do_prefs_apply, 2, 0,
294 " apply : apply any changes" },
295
296 { "unlock", 0, 0, do_prefs_unlock, 3, 1,
297 " unlock : unlocks write access to preferences" },
298
299 { "close", 0, 1, do_prefs_close, 2, 1,
300 " close [!] : close current \"preference\" session" },
301
302 { "synchronize",0, 1, do_prefs_synchronize, 2, 0,
303 " synchronize : synchronize a \"preferences\" session" },
304
305 { "list", 0, 1, do_prefs_list, 4, 0,
306 " list [path] : list preference paths" },
307
308 { "get", 1, 1, do_prefs_get, 4, 0,
309 " get path : get dict from preferences w/path" },
310
311 { "set", 1, 2, do_prefs_set, 4, 0,
312 " set path : set path in preferences w/current dict\n"
313 " set path link : set path in preferences w/link" },
314
315 { "remove", 1, 1, do_prefs_remove, 4, 0,
316 " remove path : remove path from preferences" }
317 };
318 __private_extern__
319 const int nCommands_prefs = (sizeof(commands_prefs)/sizeof(cmdInfo));
320
321
322 __private_extern__ cmdInfo *commands = NULL;
323 __private_extern__ int nCommands = 0;
324 __private_extern__ Boolean enablePrivateAPI = FALSE;
325 __private_extern__ Boolean termRequested = FALSE;
326
327
328 __private_extern__
329 void
330 do_command(int argc, char **argv)
331 {
332 int i;
333 char *cmd = argv[0];
334
335 for (i = 0; i < nCommands; i++) {
336 if ((commands[i].ctype > 1) && !enablePrivateAPI) {
337 continue; /* if "private" API and access has not been enabled */
338 }
339
340 if (strcasecmp(cmd, commands[i].cmd) == 0) {
341 --argc;
342 argv++;
343 if (argc < commands[i].minArgs) {
344 SCPrint(TRUE, stdout, CFSTR("%s: too few arguments\n"), cmd);
345 return;
346 } else if (argc > commands[i].maxArgs) {
347 SCPrint(TRUE, stdout, CFSTR("%s: too many arguments\n"), cmd);
348 return;
349 }
350 (*commands[i].func)(argc, argv);
351 return;
352 }
353 }
354
355 SCPrint(TRUE, stdout, CFSTR("%s: unknown, type \"help\" for command info\n"), cmd);
356 return;
357 }
358
359
360 __private_extern__
361 void
362 do_help(int argc, char **argv)
363 {
364 int g = -1; /* current group */
365 int i;
366
367 SCPrint(TRUE, stdout, CFSTR("\nAvailable commands:\n"));
368 for (i = 0; i < nCommands; i++) {
369 if (commands[i].ctype < 0) {
370 continue; /* if "hidden" */
371 }
372
373 if ((commands[i].ctype > 0) && !enablePrivateAPI) {
374 continue; /* if "private" API and access has not been enabled */
375 }
376
377 /* check if this is a new command group */
378 if (g != commands[i].group) {
379 SCPrint(TRUE, stdout, CFSTR("\n"));
380 g = commands[i].group;
381 }
382
383 /* display the command */
384 SCPrint(TRUE, stdout, CFSTR("%s\n"), commands[i].usage);
385 }
386 SCPrint(TRUE, stdout, CFSTR("\n"));
387
388 return;
389 }
390
391
392 __private_extern__
393 void
394 do_readFile(int argc, char **argv)
395 {
396 InputRef src;
397
398 /* allocate command input stream */
399 src = (InputRef)CFAllocatorAllocate(NULL, sizeof(Input), 0);
400 src->el = NULL;
401 src->fp = fopen(argv[0], "r");
402
403 if (src->fp == NULL) {
404 SCPrint(TRUE, stdout, CFSTR("f.read: could not open file (%s).\n"), strerror(errno));
405 CFAllocatorDeallocate(NULL, src);
406 return;
407 }
408
409 /* open file, increase nesting level */
410 SCPrint(TRUE, stdout, CFSTR("f.read: reading file (%s).\n"), argv[0]);
411 nesting++;
412
413 while (process_line(src) == TRUE) {
414 /* debug information, diagnostics */
415 __showMachPortStatus();
416 }
417
418 (void)fclose(src->fp);
419 CFAllocatorDeallocate(NULL, src);
420
421 return;
422 }
423
424
425 __private_extern__
426 void
427 do_quit(int argc, char **argv)
428 {
429 termRequested = TRUE;
430 return;
431 }