]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/net_set.c
configd-289.tar.gz
[apple/configd.git] / scutil.tproj / net_set.c
1 /*
2 * Copyright (c) 2004, 2005, 2009 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 * August 5, 2004 Allan Nathanson <ajn@apple.com>
28 * - initial revision
29 */
30
31
32 #include "scutil.h"
33 #include "net.h"
34 #include "net_set.h"
35 #include "net_service.h"
36 #include "prefs.h"
37
38
39 /* -------------------- */
40
41
42 static CFComparisonResult
43 _compare_sets(const void *val1, const void *val2, void *context)
44 {
45 CFStringRef id1;
46 CFStringRef id2;
47 CFStringRef name1;
48 CFStringRef name2;
49 SCNetworkSetRef s1 = (SCNetworkSetRef)val1;
50 SCNetworkSetRef s2 = (SCNetworkSetRef)val2;
51
52 name1 = SCNetworkSetGetName(s1);
53 name2 = SCNetworkSetGetName(s2);
54
55 if (name1 != NULL) {
56 if (name2 != NULL) {
57 return CFStringCompare(name1, name2, 0);
58 } else {
59 return kCFCompareLessThan;
60 }
61 }
62
63 if (name2 != NULL) {
64 return kCFCompareGreaterThan;
65 }
66
67 id1 = SCNetworkSetGetSetID(s1);
68 id2 = SCNetworkSetGetSetID(s2);
69 return CFStringCompare(id1, id2, 0);
70 }
71
72
73 static CFArrayRef
74 _copy_sets()
75 {
76 CFArrayRef sets;
77 CFMutableArrayRef sorted;
78
79 sets = SCNetworkSetCopyAll(prefs);
80 if (sets == NULL) {
81 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
82 return NULL;
83 }
84
85 sorted = CFArrayCreateMutableCopy(NULL, 0, sets);
86 CFArraySortValues(sorted,
87 CFRangeMake(0, CFArrayGetCount(sorted)),
88 _compare_sets,
89 NULL);
90
91 CFRelease(sets);
92 sets = CFArrayCreateCopy(NULL, sorted);
93 CFRelease(sorted);
94 return sets;
95 }
96
97
98 static SCNetworkSetRef
99 _find_set(char *match)
100 {
101 Boolean allowIndex = TRUE;
102 CFIndex i;
103 CFIndex n;
104 CFStringRef select_name = NULL;
105 SCNetworkSetRef selected = NULL;
106
107 if (sets == NULL) {
108 if (prefs == NULL) {
109 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
110 return NULL;
111 }
112
113 sets = _copy_sets();
114 if (sets == NULL) {
115 return NULL;
116 }
117
118 allowIndex = FALSE;
119 }
120
121 // try to select the set by its setID
122
123 select_name = CFStringCreateWithCString(NULL, match, kCFStringEncodingUTF8);
124
125 n = CFArrayGetCount(sets);
126 for (i = 0; i < n; i++) {
127 SCNetworkSetRef set;
128 CFStringRef setID;
129
130 set = CFArrayGetValueAtIndex(sets, i);
131 setID = SCNetworkSetGetSetID(set);
132 if (CFEqual(select_name, setID)) {
133 selected = set;
134 goto done;
135
136 }
137 }
138
139 // try to select the set by its name
140
141 for (i = 0; i < n; i++) {
142 SCNetworkSetRef set;
143 CFStringRef setName;
144
145 set = CFArrayGetValueAtIndex(sets, i);
146 setName = SCNetworkSetGetName(set);
147 if ((setName != NULL) &&
148 CFEqual(select_name, setName)) {
149 if (selected == NULL) {
150 selected = set;
151 } else {
152 // if multiple sets match
153 selected = NULL;
154 SCPrint(TRUE, stdout, CFSTR("multiple sets match\n"));
155 goto done;
156 }
157 }
158 }
159
160 if (selected != NULL) {
161 goto done;
162 }
163
164 // try to select the set by its name (case insensitive)
165
166 for (i = 0; i < n; i++) {
167 SCNetworkSetRef set;
168 CFStringRef setName;
169
170 set = CFArrayGetValueAtIndex(sets, i);
171 setName = SCNetworkSetGetName(set);
172 if ((setName != NULL) &&
173 CFStringCompare(select_name,
174 setName,
175 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
176 if (selected == NULL) {
177 selected = set;
178 } else {
179 // if multiple sets match
180 selected = NULL;
181 SCPrint(TRUE, stdout, CFSTR("multiple sets match\n"));
182 goto done;
183 }
184 }
185 }
186
187 if (selected != NULL) {
188 goto done;
189 }
190
191 // try to select the set by its index
192
193 if (allowIndex) {
194 char *end;
195 char *str = match;
196 long val;
197
198 errno = 0;
199 val = strtol(str, &end, 10);
200 if ((*str != '\0') && (*end == '\0') && (errno == 0)) {
201 if ((val > 0) && (val <= n)) {
202 selected = CFArrayGetValueAtIndex(sets, val - 1);
203 }
204 }
205 }
206
207 if (selected != NULL) {
208 goto done;
209 }
210
211 SCPrint(TRUE, stdout, CFSTR("no match, which set?\n"));
212
213 done :
214
215 if (select_name != NULL) CFRelease(select_name);
216 return selected;
217 }
218
219
220 /* -------------------- */
221
222
223 __private_extern__
224 void
225 create_set(int argc, char **argv)
226 {
227 SCNetworkSetRef set;
228 CFStringRef setName;
229
230 if (prefs == NULL) {
231 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
232 return;
233 }
234
235 set = SCNetworkSetCreate(prefs);
236 if (set == NULL) {
237 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
238 return;
239 }
240
241 if ((argc > 0) && (strlen(argv[0]) > 0)) {
242 Boolean ok;
243
244 setName = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
245 // argv++;
246 // argc--;
247
248 ok = SCNetworkSetSetName(set, setName);
249 CFRelease(setName);
250 if (!ok) {
251 SCPrint(TRUE, stdout, CFSTR("set not created: %s\n"), SCErrorString(SCError()));
252 (void) SCNetworkSetRemove(set);
253 CFRelease(set);
254 return;
255 }
256 }
257
258 _prefs_changed = TRUE;
259
260 if (net_set != NULL) CFRelease(net_set);
261 net_set = set;
262
263 setName = SCNetworkSetGetName(set);
264 if (setName != NULL) {
265 SCPrint(TRUE, stdout,
266 CFSTR("set \"%@\" (%@) created and selected\n"),
267 setName,
268 SCNetworkSetGetSetID(set));
269 } else {
270 SCPrint(TRUE, stdout,
271 CFSTR("set ID \"%@\" created and selected\n"),
272 SCNetworkSetGetSetID(set));
273 }
274
275 if (net_service != NULL) {
276 CFRelease(net_service);
277 net_service = NULL;
278 SCPrint(TRUE, stdout, CFSTR("& no service selected\n"));
279 }
280
281 if (net_protocol != NULL) {
282 CFRelease(net_protocol);
283 net_protocol = NULL;
284 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
285 }
286
287 if (net_interface != NULL) {
288 CFRelease(net_interface);
289 net_interface = NULL;
290 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
291 }
292
293 if (sets != NULL) {
294 CFRelease(sets);
295 sets = NULL;
296 }
297
298 return;
299 }
300
301
302 __private_extern__
303 void
304 remove_set(int argc, char **argv)
305 {
306 SCNetworkSetRef set = NULL;
307 CFStringRef setName;
308
309 if (argc == 1) {
310 set = _find_set(argv[0]);
311 } else {
312 if (net_set != NULL) {
313 set = net_set;
314 }
315 }
316
317 if (set == NULL) {
318 return;
319 }
320
321 CFRetain(set);
322
323 if (!SCNetworkSetRemove(set)) {
324 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
325 goto done;
326 }
327
328 _prefs_changed = TRUE;
329
330 setName = SCNetworkSetGetName(set);
331 if (setName != NULL) {
332 SCPrint(TRUE, stdout, CFSTR("set \"%@\" removed\n"), setName);
333 } else {
334 SCPrint(TRUE, stdout,
335 CFSTR("set ID \"%@\" removed\n"),
336 SCNetworkSetGetSetID(set));
337 }
338
339 if (CFEqual(set, net_set)) {
340 if (net_service != NULL) {
341 CFRelease(net_service);
342 net_service = NULL;
343 SCPrint(TRUE, stdout, CFSTR("& no service selected\n"));
344 }
345
346 if (net_protocol != NULL) {
347 CFRelease(net_protocol);
348 net_protocol = NULL;
349 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
350 }
351
352 if (net_interface != NULL) {
353 CFRelease(net_interface);
354 net_interface = NULL;
355 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
356 }
357 }
358
359 if (sets != NULL) {
360 CFRelease(sets);
361 sets = NULL;
362 }
363
364 done :
365
366 CFRelease(set);
367 return;
368 }
369
370
371 __private_extern__
372 void
373 select_set(int argc, char **argv)
374 {
375 SCNetworkSetRef set;
376 CFStringRef setName;
377
378 set = _find_set(argv[0]);
379
380 if (set == NULL) {
381 return;
382 }
383
384 if (net_set != NULL) CFRelease(net_set);
385 net_set = CFRetain(set);
386
387 setName = SCNetworkSetGetName(set);
388 if (setName != NULL) {
389 SCPrint(TRUE, stdout, CFSTR("set \"%@\" selected\n"), setName);
390 } else {
391 SCPrint(TRUE, stdout,
392 CFSTR("set ID \"%@\" selected\n"),
393 SCNetworkSetGetSetID(set));
394 }
395
396 if (net_service != NULL) {
397 CFRelease(net_service);
398 net_service = NULL;
399 SCPrint(TRUE, stdout, CFSTR("& no service selected\n"));
400 }
401
402 if (net_protocol != NULL) {
403 CFRelease(net_protocol);
404 net_protocol = NULL;
405 SCPrint(TRUE, stdout, CFSTR("& no protocol selected\n"));
406 }
407
408 if (net_interface != NULL) {
409 CFRelease(net_interface);
410 net_interface = NULL;
411 SCPrint(TRUE, stdout, CFSTR("& no interface selected\n"));
412 }
413
414 return;
415 }
416
417
418 __private_extern__
419 void
420 set_set(int argc, char **argv)
421 {
422 Boolean ok;
423
424 if (net_set == NULL) {
425 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
426 return;
427 }
428
429 if (argc < 1) {
430 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
431 return;
432 }
433
434 while (argc > 0) {
435 char *command;
436
437 command = argv[0];
438 argv++;
439 argc--;
440
441 if (strcmp(command, "name") == 0) {
442 CFStringRef setName;
443
444 if (argc < 1) {
445 SCPrint(TRUE, stdout, CFSTR("name not specified\n"));
446 return;
447 }
448
449 setName = (strlen(argv[0]) > 0)
450 ? CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8)
451 : NULL;
452 argv++;
453 argc--;
454
455 ok = SCNetworkSetSetName(net_set, setName);
456 if (setName != NULL) CFRelease(setName);
457 if (!ok) {
458 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
459 return;
460 }
461
462 _prefs_changed = TRUE;
463
464 if (sets != NULL) {
465 /*
466 * since the (displayed) ordering may have changed, refresh sets
467 */
468 char *setID;
469
470 setID = _SC_cfstring_to_cstring(SCNetworkSetGetSetID(net_set),
471 NULL,
472 0,
473 kCFStringEncodingUTF8);
474
475 CFRelease(net_set);
476 net_set = NULL;
477
478 CFRelease(sets);
479 sets = NULL;
480
481 net_set = _find_set(setID);
482 if (net_set != NULL) {
483 CFRetain(net_set);
484 }
485
486 CFAllocatorDeallocate(NULL, setID);
487 }
488 } else {
489 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
490 }
491 }
492
493 return;
494 }
495
496
497 __private_extern__
498 void
499 show_set(int argc, char **argv)
500 {
501 CFArrayRef services;
502 SCNetworkSetRef set = NULL;
503 CFStringRef setName;
504
505 if (argc == 1) {
506 set = _find_set(argv[0]);
507 } else {
508 if (net_set != NULL) {
509 set = net_set;
510 } else {
511 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
512 return;
513 }
514 }
515
516 if (set == NULL) {
517 return;
518 }
519
520 SCPrint(TRUE, stdout, CFSTR("set id = %@\n"), SCNetworkSetGetSetID(set));
521
522 setName = SCNetworkSetGetName(set);
523 SCPrint(TRUE, stdout, CFSTR("name = %@\n"),
524 (setName != NULL) ? setName : CFSTR(""));
525
526 services = SCNetworkSetCopyServices(set);
527 if (services != NULL) {
528 CFIndex i;
529 CFIndex n;
530 CFIndex nOrder = 0;
531 CFArrayRef order;
532
533 order = SCNetworkSetGetServiceOrder(set);
534 if (order != NULL) {
535 nOrder = CFArrayGetCount(order);
536 }
537
538 n = CFArrayGetCount(services);
539 if (n > 1) {
540 CFMutableArrayRef sorted;
541
542 sorted = CFArrayCreateMutableCopy(NULL, 0, services);
543 CFArraySortValues(sorted,
544 CFRangeMake(0, CFArrayGetCount(sorted)),
545 _compare_services,
546 (void *)order);
547 CFRelease(services);
548 services = sorted;
549 }
550
551 SCPrint(TRUE, stdout, CFSTR("services =\n"));
552
553 for (i = 0; i < n; i++) {
554 CFIndex orderIndex = kCFNotFound;
555 SCNetworkServiceRef service;
556 CFStringRef serviceName;
557 CFStringRef serviceID;
558
559 service = CFArrayGetValueAtIndex(services, i);
560 serviceID = SCNetworkServiceGetServiceID(service);
561 serviceName = SCNetworkServiceGetName(service);
562 if (serviceName == NULL) serviceName = CFSTR("");
563
564 if (order != NULL) {
565 orderIndex = CFArrayGetFirstIndexOfValue(order,
566 CFRangeMake(0, nOrder),
567 serviceID);
568 }
569 if (orderIndex != kCFNotFound) {
570 SCPrint(TRUE, stdout, CFSTR("%c%2d: %@%-*s (%@)\n"),
571 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
572 orderIndex + 1,
573 serviceName,
574 30 - CFStringGetLength(serviceName),
575 " ",
576 serviceID);
577 } else {
578 SCPrint(TRUE, stdout, CFSTR("%c : %@%-*s (%@)\n"),
579 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
580 serviceName,
581 30 - CFStringGetLength(serviceName),
582 " ",
583 serviceID);
584 }
585 }
586
587 CFRelease(services);
588 }
589
590 if (_sc_debug) {
591 SCPrint(TRUE, stdout, CFSTR("\n%@\n"), set);
592 }
593
594 return;
595 }
596
597
598 __private_extern__
599 void
600 show_sets(int argc, char **argv)
601 {
602 SCNetworkSetRef current;
603 CFIndex i;
604 CFIndex n;
605
606 if (prefs == NULL) {
607 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
608 return;
609 }
610
611 if (sets == NULL) {
612 sets = _copy_sets();
613 if (sets == NULL) {
614 return;
615 }
616 }
617
618 current = SCNetworkSetCopyCurrent(prefs);
619
620 n = CFArrayGetCount(sets);
621 for (i = 0; i < n; i++) {
622 SCNetworkSetRef set;
623 CFStringRef setID;
624 CFStringRef setName;
625
626 set = CFArrayGetValueAtIndex(sets, i);
627 setID = SCNetworkSetGetSetID(set);
628 setName = SCNetworkSetGetName(set);
629 if (setName == NULL) setName = CFSTR("");
630
631 SCPrint(TRUE, stdout, CFSTR(" %c%c%2d: %@%-*s (%@)\n"),
632 ((current != NULL) && CFEqual(set, current)) ? '*' : ' ',
633 ((net_set != NULL) && CFEqual(set, net_set)) ? '>' : ' ',
634 i + 1,
635 setName,
636 30 - CFStringGetLength(setName),
637 " ",
638 setID);
639 }
640
641 if (current != NULL) CFRelease(current);
642
643 return;
644 }