]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/net_set.c
configd-888.1.2.tar.gz
[apple/configd.git] / scutil.tproj / net_set.c
1 /*
2 * Copyright (c) 2004, 2005, 2009-2011, 2013-2015 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 if (strcmp(command, "current") == 0) {
489 ok = SCNetworkSetSetCurrent(net_set);
490 if (!ok) {
491 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
492 return;
493 }
494
495 _prefs_changed = TRUE;
496 } else if (strcmp(command, "id") == 0) {
497 char *newID;
498 CFStringRef setID;
499
500 if ((argc < 1) || (strlen(argv[0]) == 0)) {
501 SCPrint(TRUE, stdout, CFSTR("set id not specified\n"));
502 return;
503 }
504
505 newID = argv[0];
506 setID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
507 argv++;
508 argc--;
509
510 ok = _SCNetworkSetSetSetID(net_set, setID);
511 CFRelease(setID);
512 if (!ok) {
513 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
514 return;
515 }
516
517 _prefs_changed = TRUE;
518
519 if (sets != NULL) {
520 /*
521 * since the (displayed) ordering may have changed, refresh sets
522 */
523 CFRelease(net_set);
524 net_set = NULL;
525
526 CFRelease(sets);
527 sets = NULL;
528
529 net_set = _find_set(newID);
530 if (net_set != NULL) {
531 CFRetain(net_set);
532 }
533 }
534 } else {
535 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
536 }
537
538 if (net_set == NULL) {
539 break;
540 }
541 }
542
543 return;
544 }
545
546
547 __private_extern__
548 void
549 show_set(int argc, char **argv)
550 {
551 CFArrayRef interfaces;
552 CFArrayRef services;
553 SCNetworkSetRef set = NULL;
554 CFStringRef setName;
555
556 if (argc == 1) {
557 set = _find_set(argv[0]);
558 } else {
559 if (net_set != NULL) {
560 set = net_set;
561 } else {
562 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
563 return;
564 }
565 }
566
567 if (set == NULL) {
568 return;
569 }
570
571 SCPrint(TRUE, stdout, CFSTR("set id = %@\n"), SCNetworkSetGetSetID(set));
572
573 setName = SCNetworkSetGetName(set);
574 SCPrint(TRUE, stdout, CFSTR("name = %@\n"),
575 (setName != NULL) ? setName : CFSTR(""));
576
577 services = SCNetworkSetCopyServices(set);
578 if (services != NULL) {
579 CFIndex i;
580 CFIndex n;
581 CFIndex nOrder = 0;
582 CFArrayRef order;
583
584 order = SCNetworkSetGetServiceOrder(set);
585 if (order != NULL) {
586 nOrder = CFArrayGetCount(order);
587 }
588
589 n = CFArrayGetCount(services);
590 if (n > 1) {
591 CFMutableArrayRef sorted;
592
593 sorted = CFArrayCreateMutableCopy(NULL, 0, services);
594 CFArraySortValues(sorted,
595 CFRangeMake(0, CFArrayGetCount(sorted)),
596 _SCNetworkServiceCompare,
597 (void *)order);
598 CFRelease(services);
599 services = sorted;
600 }
601
602 SCPrint(TRUE, stdout, CFSTR("services =\n"));
603
604 for (i = 0; i < n; i++) {
605 CFIndex orderIndex = kCFNotFound;
606 SCNetworkServiceRef service;
607 CFStringRef serviceName;
608 CFStringRef serviceID;
609
610 service = CFArrayGetValueAtIndex(services, i);
611 serviceID = SCNetworkServiceGetServiceID(service);
612 serviceName = SCNetworkServiceGetName(service);
613 if (serviceName == NULL) serviceName = CFSTR("");
614
615 if (order != NULL) {
616 orderIndex = CFArrayGetFirstIndexOfValue(order,
617 CFRangeMake(0, nOrder),
618 serviceID);
619 }
620 if (orderIndex != kCFNotFound) {
621 SCPrint(TRUE, stdout, CFSTR("%c%2ld: %@%-*s (%@)\n"),
622 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
623 orderIndex + 1,
624 serviceName,
625 (int)(30 - CFStringGetLength(serviceName)),
626 " ",
627 serviceID);
628 } else {
629 SCPrint(TRUE, stdout, CFSTR("%c : %@%-*s (%@)\n"),
630 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
631 serviceName,
632 (int)(30 - CFStringGetLength(serviceName)),
633 " ",
634 serviceID);
635 }
636 }
637
638 CFRelease(services);
639 }
640
641 interfaces = SCNetworkSetCopyAvailableInterfaces(set);
642 if (interfaces != NULL) {
643 CFIndex i;
644 SCNetworkInterfaceRef interface;
645 CFIndex n;
646
647 SCPrint(TRUE, stdout, CFSTR("available interfaces =\n"));
648
649 n = CFArrayGetCount(interfaces);
650 for (i = 0; i < n; i++) {
651 interface = CFArrayGetValueAtIndex(interfaces, i);
652 SCPrint(TRUE, stdout, CFSTR(" %2ld: %@ \n"),
653 i + 1,
654 SCNetworkInterfaceGetLocalizedDisplayName(interface));
655 }
656
657 CFRelease(interfaces);
658 }
659
660 if (_sc_debug) {
661 SCPrint(TRUE, stdout, CFSTR("\n%@\n"), set);
662 }
663
664 return;
665 }
666
667
668 __private_extern__
669 void
670 show_sets(int argc, char **argv)
671 {
672 SCNetworkSetRef current;
673 CFIndex i;
674 CFIndex n;
675
676 if (prefs == NULL) {
677 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
678 return;
679 }
680
681 if (sets == NULL) {
682 sets = _copy_sets();
683 if (sets == NULL) {
684 return;
685 }
686 }
687
688 current = SCNetworkSetCopyCurrent(prefs);
689
690 n = CFArrayGetCount(sets);
691 for (i = 0; i < n; i++) {
692 SCNetworkSetRef set;
693 CFStringRef setID;
694 CFStringRef setName;
695
696 set = CFArrayGetValueAtIndex(sets, i);
697 setID = SCNetworkSetGetSetID(set);
698 setName = SCNetworkSetGetName(set);
699 if (setName == NULL) setName = CFSTR("");
700
701 SCPrint(TRUE, stdout, CFSTR(" %c%c%2ld: %@%-*s (%@)\n"),
702 ((current != NULL) && CFEqual(set, current)) ? '*' : ' ',
703 ((net_set != NULL) && CFEqual(set, net_set)) ? '>' : ' ',
704 i + 1,
705 setName,
706 (int)(30 - CFStringGetLength(setName)),
707 " ",
708 setID);
709 }
710
711 if (current != NULL) CFRelease(current);
712
713 return;
714 }