]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/net_set.c
configd-699.1.5.tar.gz
[apple/configd.git] / scutil.tproj / net_set.c
1 /*
2 * Copyright (c) 2004, 2005, 2009-2011, 2013, 2014 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
539 return;
540 }
541
542
543 __private_extern__
544 void
545 show_set(int argc, char **argv)
546 {
547 CFArrayRef interfaces;
548 CFArrayRef services;
549 SCNetworkSetRef set = NULL;
550 CFStringRef setName;
551
552 if (argc == 1) {
553 set = _find_set(argv[0]);
554 } else {
555 if (net_set != NULL) {
556 set = net_set;
557 } else {
558 SCPrint(TRUE, stdout, CFSTR("set not selected\n"));
559 return;
560 }
561 }
562
563 if (set == NULL) {
564 return;
565 }
566
567 SCPrint(TRUE, stdout, CFSTR("set id = %@\n"), SCNetworkSetGetSetID(set));
568
569 setName = SCNetworkSetGetName(set);
570 SCPrint(TRUE, stdout, CFSTR("name = %@\n"),
571 (setName != NULL) ? setName : CFSTR(""));
572
573 services = SCNetworkSetCopyServices(set);
574 if (services != NULL) {
575 CFIndex i;
576 CFIndex n;
577 CFIndex nOrder = 0;
578 CFArrayRef order;
579
580 order = SCNetworkSetGetServiceOrder(set);
581 if (order != NULL) {
582 nOrder = CFArrayGetCount(order);
583 }
584
585 n = CFArrayGetCount(services);
586 if (n > 1) {
587 CFMutableArrayRef sorted;
588
589 sorted = CFArrayCreateMutableCopy(NULL, 0, services);
590 CFArraySortValues(sorted,
591 CFRangeMake(0, CFArrayGetCount(sorted)),
592 _SCNetworkServiceCompare,
593 (void *)order);
594 CFRelease(services);
595 services = sorted;
596 }
597
598 SCPrint(TRUE, stdout, CFSTR("services =\n"));
599
600 for (i = 0; i < n; i++) {
601 CFIndex orderIndex = kCFNotFound;
602 SCNetworkServiceRef service;
603 CFStringRef serviceName;
604 CFStringRef serviceID;
605
606 service = CFArrayGetValueAtIndex(services, i);
607 serviceID = SCNetworkServiceGetServiceID(service);
608 serviceName = SCNetworkServiceGetName(service);
609 if (serviceName == NULL) serviceName = CFSTR("");
610
611 if (order != NULL) {
612 orderIndex = CFArrayGetFirstIndexOfValue(order,
613 CFRangeMake(0, nOrder),
614 serviceID);
615 }
616 if (orderIndex != kCFNotFound) {
617 SCPrint(TRUE, stdout, CFSTR("%c%2ld: %@%-*s (%@)\n"),
618 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
619 orderIndex + 1,
620 serviceName,
621 (int)(30 - CFStringGetLength(serviceName)),
622 " ",
623 serviceID);
624 } else {
625 SCPrint(TRUE, stdout, CFSTR("%c : %@%-*s (%@)\n"),
626 ((net_service != NULL) && CFEqual(service, net_service)) ? '>' : ' ',
627 serviceName,
628 (int)(30 - CFStringGetLength(serviceName)),
629 " ",
630 serviceID);
631 }
632 }
633
634 CFRelease(services);
635 }
636
637 interfaces = SCNetworkSetCopyAvailableInterfaces(set);
638 if (interfaces != NULL) {
639 CFIndex i;
640 SCNetworkInterfaceRef interface;
641 CFIndex n;
642
643 SCPrint(TRUE, stdout, CFSTR("available interfaces =\n"));
644
645 n = CFArrayGetCount(interfaces);
646 for (i = 0; i < n; i++) {
647 interface = CFArrayGetValueAtIndex(interfaces, i);
648 SCPrint(TRUE, stdout, CFSTR(" %2ld: %@ \n"),
649 i + 1,
650 SCNetworkInterfaceGetLocalizedDisplayName(interface));
651 }
652
653 CFRelease(interfaces);
654 }
655
656 if (_sc_debug) {
657 SCPrint(TRUE, stdout, CFSTR("\n%@\n"), set);
658 }
659
660 return;
661 }
662
663
664 __private_extern__
665 void
666 show_sets(int argc, char **argv)
667 {
668 SCNetworkSetRef current;
669 CFIndex i;
670 CFIndex n;
671
672 if (prefs == NULL) {
673 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
674 return;
675 }
676
677 if (sets == NULL) {
678 sets = _copy_sets();
679 if (sets == NULL) {
680 return;
681 }
682 }
683
684 current = SCNetworkSetCopyCurrent(prefs);
685
686 n = CFArrayGetCount(sets);
687 for (i = 0; i < n; i++) {
688 SCNetworkSetRef set;
689 CFStringRef setID;
690 CFStringRef setName;
691
692 set = CFArrayGetValueAtIndex(sets, i);
693 setID = SCNetworkSetGetSetID(set);
694 setName = SCNetworkSetGetName(set);
695 if (setName == NULL) setName = CFSTR("");
696
697 SCPrint(TRUE, stdout, CFSTR(" %c%c%2ld: %@%-*s (%@)\n"),
698 ((current != NULL) && CFEqual(set, current)) ? '*' : ' ',
699 ((net_set != NULL) && CFEqual(set, net_set)) ? '>' : ' ',
700 i + 1,
701 setName,
702 (int)(30 - CFStringGetLength(setName)),
703 " ",
704 setID);
705 }
706
707 if (current != NULL) CFRelease(current);
708
709 return;
710 }