]> git.saurik.com Git - apple/configd.git/blame - scselect.tproj/scselect.c
configd-84.1.tar.gz
[apple/configd.git] / scselect.tproj / scselect.c
CommitLineData
5958d7c0 1/*
009ee3c6 2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
5958d7c0
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
009ee3c6
A
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
5958d7c0
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
009ee3c6
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
5958d7c0
A
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
0fae82ee
A
26/*
27 * Modification History
28 *
29 * June 1, 2001 Allan Nathanson <ajn@apple.com>
30 * - public API conversion
31 *
32 * January 1, 2001 Allan Nathanson <ajn@apple.com>
33 * - initial revision
34 */
35
009ee3c6 36#include <getopt.h>
5958d7c0 37#include <unistd.h>
009ee3c6 38#include <sysexits.h>
5958d7c0 39
0fae82ee
A
40#include <SystemConfiguration/SystemConfiguration.h>
41#include <SystemConfiguration/SCPrivate.h>
42
5958d7c0 43
0fae82ee 44Boolean apply = TRUE;
5958d7c0
A
45
46
009ee3c6
A
47static struct option longopts[] = {
48// { "debug", no_argument, 0, 'd' },
49// { "verbose", no_argument, 0, 'v' },
50// { "do-not-apply", no_argument, 0, 'n' },
51 { "help", no_argument, 0, '?' },
52 { 0, 0, 0, 0 }
53};
54
55
5958d7c0
A
56void
57usage(const char *command)
58{
0fae82ee 59 SCPrint(TRUE, stderr, CFSTR("usage: %s [-n] new-set-name\n"), command);
009ee3c6 60 exit (EX_USAGE);
5958d7c0
A
61}
62
63
64int
65main(int argc, char **argv)
66{
67 const char *command = argv[0];
68 extern int optind;
69 int opt;
70 CFStringRef current = NULL;
71 int currentMatched = 0;
72 CFStringRef newSet = NULL; /* set key */
73 CFStringRef newSetUDN = NULL; /* user defined name */
74 CFStringRef prefix;
0fae82ee 75 SCPreferencesRef session;
5958d7c0
A
76 CFDictionaryRef sets;
77 CFIndex nSets;
a5f60add
A
78 const void **setKeys = NULL;
79 const void **setVals = NULL;
5958d7c0
A
80 CFIndex i;
81
82 /* process any arguments */
83
009ee3c6 84 while ((opt = getopt_long(argc, argv, "dvn", longopts, NULL)) != -1)
5958d7c0
A
85 switch(opt) {
86 case 'd':
0fae82ee
A
87 _sc_debug = TRUE;
88 _sc_log = FALSE; /* enable framework logging */
5958d7c0
A
89 break;
90 case 'v':
0fae82ee 91 _sc_verbose = TRUE;
5958d7c0
A
92 break;
93 case 'n':
94 apply = FALSE;
95 break;
96 case '?':
97 default :
98 usage(command);
99 }
100 argc -= optind;
101 argv += optind;
102
103 prefix = CFStringCreateWithFormat(NULL, NULL, CFSTR("/%@/"), kSCPrefSets);
104
105 newSet = (argc == 1)
106 ? CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingMacRoman)
107 : CFSTR("");
108
0fae82ee
A
109 session = SCPreferencesCreate(NULL, CFSTR("Select Set Command"), NULL);
110 if (!session) {
111 SCPrint(TRUE, stderr, CFSTR("SCPreferencesCreate() failed\n"));
5958d7c0
A
112 exit (1);
113 }
114
115 /* check if a full path to the new "set" was specified */
116 if ((CFStringGetLength(newSet) > 0) && CFStringHasPrefix(newSet, prefix)) {
117 CFRange range;
118 CFMutableStringRef str;
119
120 str = CFStringCreateMutableCopy(NULL, 0, newSet);
121 CFStringDelete(str, CFRangeMake(0, CFStringGetLength(prefix)));
122
123 range = CFStringFind(str, CFSTR("/"), 0);
124 if (range.location != kCFNotFound) {
0fae82ee 125 SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available\n."), newSet);
5958d7c0
A
126 exit (1);
127 }
128
129 CFRelease(newSet);
130 newSet = str;
131 }
132
0fae82ee
A
133 sets = SCPreferencesGetValue(session, kSCPrefSets);
134 if (!sets) {
135 SCPrint(TRUE, stderr, CFSTR("SCPreferencesGetValue(...,%s,...) failed\n"));
5958d7c0
A
136 exit (1);
137 }
138
0fae82ee
A
139 current = SCPreferencesGetValue(session, kSCPrefCurrentSet);
140 if (current) {
141 if (CFStringHasPrefix(current, prefix)) {
142 CFMutableStringRef tmp;
143
144 tmp = CFStringCreateMutableCopy(NULL, 0, current);
145 CFStringDelete(tmp, CFRangeMake(0, CFStringGetLength(prefix)));
146 current = tmp;
147 } else {
148 currentMatched = -1; /* not prefixed */
149 }
150 } else {
151 current = CFSTR("");
152 currentMatched = -2; /* not defined */
5958d7c0
A
153 }
154
155 nSets = CFDictionaryGetCount(sets);
a5f60add
A
156 if (nSets > 0) {
157 setKeys = CFAllocatorAllocate(NULL, nSets * sizeof(CFStringRef), 0);
158 setVals = CFAllocatorAllocate(NULL, nSets * sizeof(CFDictionaryRef), 0);
159 CFDictionaryGetKeysAndValues(sets, setKeys, setVals);
160 }
5958d7c0
A
161
162 /* check for set with matching name */
009ee3c6 163 for (i = 0; i < nSets; i++) {
5958d7c0
A
164 CFStringRef key = (CFStringRef) setKeys[i];
165 CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
166
167 if ((currentMatched >= 0) && CFEqual(key, current)) {
168 currentMatched++;
169 }
170
171 if (CFEqual(newSet, key)) {
172 newSetUDN = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
173 if (newSetUDN) CFRetain(newSetUDN);
174 current = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), prefix, newSet);
175 goto found;
176 }
177 }
178
179 /* check for set with matching user-defined name */
009ee3c6 180 for (i = 0; i < nSets; i++) {
5958d7c0
A
181 CFStringRef key = (CFStringRef) setKeys[i];
182 CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
183
184 newSetUDN = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
185 if ((newSetUDN != NULL) && CFEqual(newSet, newSetUDN)) {
186 CFRelease(newSet);
187 newSet = CFRetain(key);
188 CFRetain(newSetUDN);
189 current = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"), prefix, newSet);
190 goto found;
191 }
192 }
193
009ee3c6
A
194 if (argc == 1) {
195 SCPrint(TRUE, stderr, CFSTR("Set \"%@\" not available.\n\n"), newSet);
5958d7c0
A
196 }
197
0fae82ee
A
198 SCPrint(TRUE, stderr,
199 CFSTR("Defined sets include:%s\n"),
200 (currentMatched > 0) ? " (* == current set)" : "");
5958d7c0 201
009ee3c6 202 for (i = 0; i < nSets; i++) {
5958d7c0
A
203 CFStringRef key = (CFStringRef) setKeys[i];
204 CFDictionaryRef dict = (CFDictionaryRef)setVals[i];
205 CFStringRef udn = CFDictionaryGetValue(dict, kSCPropUserDefinedName);
206
0fae82ee
A
207 SCPrint(TRUE, stderr,
208 CFSTR(" %s %@\t(%@)\n"),
5958d7c0
A
209 ((currentMatched > 0) && CFEqual(key, current)) ? "*" : " ",
210 key,
211 udn ? udn : CFSTR(""));
212 }
213
214 switch (currentMatched) {
215 case -2 :
0fae82ee 216 SCPrint(TRUE, stderr, CFSTR("\nCurrentSet not defined.\n"));
5958d7c0
A
217 break;
218 case -1 :
0fae82ee 219 SCPrint(TRUE, stderr, CFSTR("\nCurrentSet \"%@\" may not be valid\n"), current);
5958d7c0
A
220 break;
221 case 0 :
0fae82ee 222 SCPrint(TRUE, stderr, CFSTR("\nCurrentSet \"%@\" not valid\n"), current);
5958d7c0
A
223 break;
224 default :
225 break;
226 }
227
228 exit (1);
229
230 found :
231
0fae82ee
A
232 if (!SCPreferencesSetValue(session, kSCPrefCurrentSet, current)) {
233 SCPrint(TRUE, stderr,
234 CFSTR("SCPreferencesSetValue(...,%@,%@) failed\n"),
5958d7c0 235 kSCPrefCurrentSet,
0fae82ee 236 current);
5958d7c0
A
237 exit (1);
238 }
239
0fae82ee
A
240 if (!SCPreferencesCommitChanges(session)) {
241 SCPrint(TRUE, stderr, CFSTR("SCPreferencesCommitChanges() failed\n"));
5958d7c0
A
242 exit (1);
243 }
244
245 if (apply) {
0fae82ee
A
246 if (!SCPreferencesApplyChanges(session)) {
247 SCPrint(TRUE, stderr, CFSTR("SCPreferencesApplyChanges() failed\n"));
5958d7c0
A
248 exit (1);
249 }
250 }
251
0fae82ee 252 CFRelease(session);
5958d7c0 253
0fae82ee
A
254 SCPrint(TRUE, stdout,
255 CFSTR("%@ updated to %@ (%@)\n"),
5958d7c0
A
256 kSCPrefCurrentSet,
257 newSet,
258 newSetUDN ? newSetUDN : CFSTR(""));
259
260 exit (0);
261 return 0;
262}