]>
Commit | Line | Data |
---|---|---|
5958d7c0 | 1 | /* |
a5f60add | 2 | * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. |
5958d7c0 A |
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 | ||
0fae82ee A |
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 | ||
5958d7c0 A |
33 | #include <unistd.h> |
34 | ||
0fae82ee A |
35 | #include <SystemConfiguration/SystemConfiguration.h> |
36 | #include <SystemConfiguration/SCPrivate.h> | |
37 | ||
5958d7c0 | 38 | |
0fae82ee | 39 | Boolean apply = TRUE; |
5958d7c0 A |
40 | |
41 | ||
42 | void | |
43 | usage(const char *command) | |
44 | { | |
0fae82ee | 45 | SCPrint(TRUE, stderr, CFSTR("usage: %s [-n] new-set-name\n"), command); |
5958d7c0 A |
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; | |
0fae82ee | 61 | SCPreferencesRef session; |
5958d7c0 A |
62 | CFDictionaryRef sets; |
63 | CFIndex nSets; | |
a5f60add A |
64 | const void **setKeys = NULL; |
65 | const void **setVals = NULL; | |
5958d7c0 A |
66 | CFIndex i; |
67 | ||
68 | /* process any arguments */ | |
69 | ||
5958d7c0 A |
70 | while ((opt = getopt(argc, argv, "dvn")) != -1) |
71 | switch(opt) { | |
72 | case 'd': | |
0fae82ee A |
73 | _sc_debug = TRUE; |
74 | _sc_log = FALSE; /* enable framework logging */ | |
5958d7c0 A |
75 | break; |
76 | case 'v': | |
0fae82ee | 77 | _sc_verbose = TRUE; |
5958d7c0 A |
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 | ||
0fae82ee A |
95 | session = SCPreferencesCreate(NULL, CFSTR("Select Set Command"), NULL); |
96 | if (!session) { | |
97 | SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n")); | |
5958d7c0 A |
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) { | |
0fae82ee | 111 | SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available\n."), newSet); |
5958d7c0 A |
112 | exit (1); |
113 | } | |
114 | ||
115 | CFRelease(newSet); | |
116 | newSet = str; | |
117 | } | |
118 | ||
0fae82ee A |
119 | sets = SCPreferencesGetValue(session, kSCPrefSets); |
120 | if (!sets) { | |
121 | SCPrint(TRUE, stderr, CFSTR("SCPreferencesGetValue(...,%s,...) failed\n")); | |
5958d7c0 A |
122 | exit (1); |
123 | } | |
124 | ||
0fae82ee A |
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 */ | |
5958d7c0 A |
139 | } |
140 | ||
141 | nSets = CFDictionaryGetCount(sets); | |
a5f60add A |
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 | } | |
5958d7c0 A |
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) { | |
0fae82ee | 181 | SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available.\n"), newSet); |
5958d7c0 A |
182 | } else { |
183 | usage(command); | |
184 | } | |
185 | ||
0fae82ee A |
186 | SCPrint(TRUE, stderr, CFSTR("\n")); |
187 | SCPrint(TRUE, stderr, | |
188 | CFSTR("Defined sets include:%s\n"), | |
189 | (currentMatched > 0) ? " (* == current set)" : ""); | |
5958d7c0 A |
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 | ||
0fae82ee A |
196 | SCPrint(TRUE, stderr, |
197 | CFSTR(" %s %@\t(%@)\n"), | |
5958d7c0 A |
198 | ((currentMatched > 0) && CFEqual(key, current)) ? "*" : " ", |
199 | key, | |
200 | udn ? udn : CFSTR("")); | |
201 | } | |
202 | ||
203 | switch (currentMatched) { | |
204 | case -2 : | |
0fae82ee | 205 | SCPrint(TRUE, stderr, CFSTR("\nCurrentSet not defined.\n")); |
5958d7c0 A |
206 | break; |
207 | case -1 : | |
0fae82ee | 208 | SCPrint(TRUE, stderr, CFSTR("\nCurrentSet \"%@\" may not be valid\n"), current); |
5958d7c0 A |
209 | break; |
210 | case 0 : | |
0fae82ee | 211 | SCPrint(TRUE, stderr, CFSTR("\nCurrentSet \"%@\" not valid\n"), current); |
5958d7c0 A |
212 | break; |
213 | default : | |
214 | break; | |
215 | } | |
216 | ||
217 | exit (1); | |
218 | ||
219 | found : | |
220 | ||
0fae82ee A |
221 | if (!SCPreferencesSetValue(session, kSCPrefCurrentSet, current)) { |
222 | SCPrint(TRUE, stderr, | |
223 | CFSTR("SCPreferencesSetValue(...,%@,%@) failed\n"), | |
5958d7c0 | 224 | kSCPrefCurrentSet, |
0fae82ee | 225 | current); |
5958d7c0 A |
226 | exit (1); |
227 | } | |
228 | ||
0fae82ee A |
229 | if (!SCPreferencesCommitChanges(session)) { |
230 | SCPrint(TRUE, stderr, CFSTR("SCPreferencesCommitChanges() failed\n")); | |
5958d7c0 A |
231 | exit (1); |
232 | } | |
233 | ||
234 | if (apply) { | |
0fae82ee A |
235 | if (!SCPreferencesApplyChanges(session)) { |
236 | SCPrint(TRUE, stderr, CFSTR("SCPreferencesApplyChanges() failed\n")); | |
5958d7c0 A |
237 | exit (1); |
238 | } | |
239 | } | |
240 | ||
0fae82ee | 241 | CFRelease(session); |
5958d7c0 | 242 | |
0fae82ee A |
243 | SCPrint(TRUE, stdout, |
244 | CFSTR("%@ updated to %@ (%@)\n"), | |
5958d7c0 A |
245 | kSCPrefCurrentSet, |
246 | newSet, | |
247 | newSetUDN ? newSetUDN : CFSTR("")); | |
248 | ||
249 | exit (0); | |
250 | return 0; | |
251 | } |