]>
git.saurik.com Git - apple/configd.git/blob - scutil.tproj/commands.c
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
25 #include <sys/errno.h>
29 #include "dictionary.h"
35 #include "SCDPrivate.h"
37 const cmdInfo commands
[] = {
38 /* cmd minArgs maxArgs func */
41 { "help", 0, 0, do_help
, 0,
42 " help : list available commands" },
44 { "f.read", 1, 1, do_readFile
, 0,
45 " f.read file : process commands from file" },
47 /* local dictionary manipulation commands */
49 { "d.init", 0, 0, do_dictInit
, 1,
50 " d.init : initialize (empty) dictionary" },
52 { "d.show", 0, 0, do_dictShow
, 1,
53 " d.show : show dictionary contents" },
55 { "d.add", 2, 101, do_dictSetKey
, 1,
56 " d.add key [*#?] val [v2 ...] : add information to dictionary\n"
57 " (*=array, #=number, ?=boolean)" },
59 { "d.remove", 1, 1, do_dictRemoveKey
, 1,
60 " d.remove key : remove key from dictionary" },
62 /* data store manipulation commands */
64 { "open", 0, 0, do_open
, 2,
65 " open : open a session with \"configd\"" },
67 { "close", 0, 0, do_close
, 2,
68 " close : close current \"configd\" session" },
70 { "lock", 0, 0, do_lock
, 3,
71 " lock : secures write access to data store" },
73 { "unlock", 0, 0, do_unlock
, 3,
74 " unlock : secures write access to data store" },
76 { "list", 0, 2, do_list
, 4,
77 " list [prefix] [regex] : list keys in data store" },
79 { "add", 1, 2, do_add
, 4,
80 " add key [session] : add key in data store w/current dict" },
82 { "get", 1, 1, do_get
, 4,
83 " get key : get dict from data store w/key" },
85 { "set", 1, 1, do_set
, 4,
86 " set key : set key in data store w/current dict" },
88 { "remove", 1, 1, do_remove
, 4,
89 " remove key : remove key from data store" },
91 { "touch", 1, 1, do_touch
, 4,
92 " touch key : touch key in data store" },
94 { "n.list", 0, 1, do_notify_list
, 5,
95 " n.list [regex] : list notification keys" },
97 { "n.add", 1, 2, do_notify_add
, 5,
98 " n.add key [regex] : add notification key" },
100 { "n.remove", 1, 2, do_notify_remove
, 5,
101 " n.remove key [regex] : remove notification key" },
103 { "n.changes", 0, 0, do_notify_changes
, 5,
104 " n.changes : list changed keys" },
106 { "n.wait", 0, 0, do_notify_wait
, 5,
107 " n.wait : wait for changes" },
109 { "n.watch", 0, 1, do_notify_callback
, 5,
110 " n.watch [verbose] : watch for changes" },
112 { "n.signal", 1, 2, do_notify_signal
, 5,
113 " n.signal sig [pid] : signal changes" },
115 { "n.file", 0, 1, do_notify_file
, 5,
116 " n.file [identifier] : watch for changes via file" },
118 { "n.cancel", 0, 1, do_notify_cancel
, 5,
119 " n.cancel : cancel notification requests" },
121 { "snapshot", 0, 0, do_snapshot
, 9,
122 " snapshot : save snapshot of cache and session data" },
125 { "t.ocleak", 0, 1, test_openCloseLeak
, 9,
126 " t.ocleak [#] : test for leaks (open/close)" },
130 const int nCommands
= (sizeof(commands
)/sizeof(cmdInfo
));
134 do_command(int argc
, char **argv
)
139 for (i
=0; i
<nCommands
; i
++) {
140 if (strcasecmp(cmd
, commands
[i
].cmd
) == 0) {
143 if (argc
< commands
[i
].minArgs
) {
144 SCDLog(LOG_INFO
, CFSTR("%s: too few arguments"), cmd
);
146 } else if (argc
> commands
[i
].maxArgs
) {
147 SCDLog(LOG_INFO
, CFSTR("%s: too many arguments"), cmd
);
150 commands
[i
].func(argc
, argv
);
155 SCDLog(LOG_INFO
, CFSTR("%s: unknown, type \"help\" for command info"), cmd
);
161 do_help(int argc
, char **argv
)
163 int g
= -1; /* current group */
166 SCDLog(LOG_NOTICE
, CFSTR(""));
167 SCDLog(LOG_NOTICE
, CFSTR("Available commands:"));
168 for (i
=0; i
<nCommands
; i
++) {
169 if (g
!= commands
[i
].group
) {
170 SCDLog(LOG_NOTICE
, CFSTR(""));
171 g
= commands
[i
].group
;
173 SCDLog(LOG_NOTICE
, CFSTR("%s"), commands
[i
].usage
);
175 SCDLog(LOG_NOTICE
, CFSTR(""));
182 do_readFile(int argc
, char **argv
)
184 FILE *fp
= fopen(argv
[0], "r");
188 SCDLog(LOG_INFO
, CFSTR("f.read: could not open file (%s)."), strerror(errno
));
192 /* open file, increase nesting level */
193 SCDLog(LOG_DEBUG
, CFSTR("f.read: reading file (%s)."), argv
[0]);
196 if (SCDOptionGet(NULL
, kSCDOptionUseCFRunLoop
)) {
198 CFSocketContext context
= { 0, fp
, NULL
, NULL
, NULL
};
199 CFRunLoopSourceRef rls
;
201 /* create a "socket" reference with the file descriptor associated with stdin */
202 in
= CFSocketCreateWithNative(NULL
,
204 kCFSocketReadCallBack
,
208 /* Create and add a run loop source for the file descriptor */
209 rls
= CFSocketCreateRunLoopSource(NULL
, in
, nesting
);
212 * Remove the current input file from the run loop sources. We
213 * will reactivate the current input file source when we are
214 * finished reading data from the new file.
216 CFRunLoopRemoveSource(CFRunLoopGetCurrent(),
217 (CFRunLoopSourceRef
) CFArrayGetValueAtIndex(sources
, 0),
218 kCFRunLoopDefaultMode
);
220 /* keep track of this new source */
221 CFArrayInsertValueAtIndex(sources
, 0, rls
);
223 /* add this source to the run loop */
224 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls
, kCFRunLoopDefaultMode
);
230 /* debug information, diagnostics */
231 _showMachPortStatus();
233 /* process command */
234 ok
= process_line(fp
);
237 /* decrement the nesting level */