]> git.saurik.com Git - apple/configd.git/blob - scselect.tproj/scselect.c
configd-53.tar.gz
[apple/configd.git] / scselect.tproj / scselect.c
1 /*
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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.
11 *
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
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22
23 /*
24 * Modification History
25 *
26 * June 1, 2001 Allan Nathanson <ajn@apple.com>
27 * - public API conversion
28 *
29 * January 1, 2001 Allan Nathanson <ajn@apple.com>
30 * - initial revision
31 */
32
33 #include <unistd.h>
34
35 #include <SystemConfiguration/SystemConfiguration.h>
36 #include <SystemConfiguration/SCPrivate.h>
37
38
39 Boolean apply = TRUE;
40
41
42 void
43 usage(const char *command)
44 {
45 SCPrint(TRUE, stderr, CFSTR("usage: %s [-n] new-set-name\n"), command);
46 return;
47 }
48
49
50 int
51 main(int argc, char **argv)
52 {
53 const char *command = argv[0];
54 extern int optind;
55 int opt;
56 CFStringRef current = NULL;
57 int currentMatched = 0;
58 CFStringRef newSet = NULL; /* set key */
59 CFStringRef newSetUDN = NULL; /* user defined name */
60 CFStringRef prefix;
61 SCPreferencesRef session;
62 CFDictionaryRef sets;
63 CFIndex nSets;
64 const void **setKeys = NULL;
65 const void **setVals = NULL;
66 CFIndex i;
67
68 /* process any arguments */
69
70 while ((opt = getopt(argc, argv, "dvn")) != -1)
71 switch(opt) {
72 case 'd':
73 _sc_debug = TRUE;
74 _sc_log = FALSE; /* enable framework logging */
75 break;
76 case 'v':
77 _sc_verbose = TRUE;
78 break;
79 case 'n':
80 apply = FALSE;
81 break;
82 case '?':
83 default :
84 usage(command);
85 }
86 argc -= optind;
87 argv += optind;
88
89 prefix = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/"), kSCPrefSets);
90
91 newSet = (argc == 1)
92 ? CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman)
93 : CFSTR("");
94
95 session = SCPreferencesCreate(NULL, CFSTR("Select Set Command"), NULL);
96 if (!session) {
97 SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
98 exit (1);
99 }
100
101 /* check if a full path to the new "set" was specified */
102 if ((CFStringGetLength(newSet) > 0) && CFStringHasPrefix(newSet, prefix)) {
103 CFRange range;
104 CFMutableStringRef str;
105
106 str = CFStringCreateMutableCopy(NULL, 0, newSet);
107 CFStringDelete(str, CFRangeMake(0, CFStringGetLength(prefix)));
108
109 range = CFStringFind(str, CFSTR("/"), 0);
110 if (range.location != kCFNotFound) {
111 SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available\n."), newSet);
112 exit (1);
113 }
114
115 CFRelease(newSet);
116 newSet = str;
117 }
118
119 sets = SCPreferencesGetValue(session, kSCPrefSets);
120 if (!sets) {
121 SCPrint(TRUE, stderr, CFSTR("SCPreferencesGetValue(...,%s,...) failed\n"));
122 exit (1);
123 }
124
125 current = SCPreferencesGetValue(session, kSCPrefCurrentSet);
126 if (current) {
127 if (CFStringHasPrefix(current, prefix)) {
128 CFMutableStringRef tmp;
129
130 tmp = CFStringCreateMutableCopy(NULL, 0, current);
131 CFStringDelete(tmp, CFRangeMake(0, CFStringGetLength(prefix)));
132 current = tmp;
133 } else {
134 currentMatched = -1; /* not prefixed */
135 }
136 } else {
137 current = CFSTR("");
138 currentMatched = -2; /* not defined */
139 }
140
141 nSets = CFDictionaryGetCount(sets);
142 if (nSets > 0) {
143 setKeys = CFAllocatorAllocate(NULL, nSets * sizeof(CFStringRef), 0);
144 setVals = CFAllocatorAllocate(NULL, nSets * sizeof(CFDictionaryRef), 0);
145 CFDictionaryGetKeysAndValues(sets, setKeys, setVals);
146 }
147
148 /* check for set with matching name */
149 for (i=0; i<nSets; i++) {
150 CFStringRef key = (CFStringRef) setKeys[i];
151 CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
152
153 if ((currentMatched >= 0) && CFEqual(key, current)) {
154 currentMatched++;
155 }
156
157 if (CFEqual(newSet, key)) {
158 newSetUDN = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
159 if (newSetUDN) CFRetain(newSetUDN);
160 current = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), prefix, newSet);
161 goto found;
162 }
163 }
164
165 /* check for set with matching user-defined name */
166 for (i=0; i<nSets; i++) {
167 CFStringRef key = (CFStringRef) setKeys[i];
168 CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
169
170 newSetUDN = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
171 if ((newSetUDN != NULL) && CFEqual(newSet, newSetUDN)) {
172 CFRelease(newSet);
173 newSet = CFRetain(key);
174 CFRetain(newSetUDN);
175 current = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), prefix, newSet);
176 goto found;
177 }
178 }
179
180 if (argc == 2) {
181 SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available.\n"), newSet);
182 } else {
183 usage(command);
184 }
185
186 SCPrint(TRUE, stderr, CFSTR("\n"));
187 SCPrint(TRUE, stderr,
188 CFSTR("Defined sets include:%s\n"),
189 (currentMatched > 0) ? " (* == current set)" : "");
190
191 for (i=0; i<nSets; i++) {
192 CFStringRef key = (CFStringRef) setKeys[i];
193 CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
194 CFStringRef udn = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
195
196 SCPrint(TRUE, stderr,
197 CFSTR(" %s %@\t(%@)\n"),
198 ((currentMatched > 0) && CFEqual(key, current)) ? "*" : " ",
199 key,
200 udn ? udn : CFSTR(""));
201 }
202
203 switch (currentMatched) {
204 case -2 :
205 SCPrint(TRUE, stderr, CFSTR("\nCurrentSet not defined.\n"));
206 break;
207 case -1 :
208 SCPrint(TRUE, stderr, CFSTR("\nCurrentSet \"%@\" may not be valid\n"), current);
209 break;
210 case 0 :
211 SCPrint(TRUE, stderr, CFSTR("\nCurrentSet \"%@\" not valid\n"), current);
212 break;
213 default :
214 break;
215 }
216
217 exit (1);
218
219 found :
220
221 if (!SCPreferencesSetValue(session, kSCPrefCurrentSet, current)) {
222 SCPrint(TRUE, stderr,
223 CFSTR("SCPreferencesSetValue(...,%@,%@) failed\n"),
224 kSCPrefCurrentSet,
225 current);
226 exit (1);
227 }
228
229 if (!SCPreferencesCommitChanges(session)) {
230 SCPrint(TRUE, stderr, CFSTR("SCPreferencesCommitChanges() failed\n"));
231 exit (1);
232 }
233
234 if (apply) {
235 if (!SCPreferencesApplyChanges(session)) {
236 SCPrint(TRUE, stderr, CFSTR("SCPreferencesApplyChanges() failed\n"));
237 exit (1);
238 }
239 }
240
241 CFRelease(session);
242
243 SCPrint(TRUE, stdout,
244 CFSTR("%@ updated to %@ (%@)\n"),
245 kSCPrefCurrentSet,
246 newSet,
247 newSetUDN ? newSetUDN : CFSTR(""));
248
249 exit (0);
250 return 0;
251 }