]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/net.c
configd-1061.141.1.tar.gz
[apple/configd.git] / scutil.tproj / net.c
1 /*
2 * Copyright (c) 2004-2007, 2009-2011, 2014, 2016, 2017, 2019, 2020 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 "commands.h"
34 #include "prefs.h"
35 #include "net.h"
36 #include "net_interface.h"
37 #include "net_protocol.h"
38 #include "net_service.h"
39 #include "net_set.h"
40
41 #include "SCNetworkConfigurationInternal.h"
42 #include "SCPreferencesInternal.h"
43
44 #include <unistd.h>
45
46
47 __private_extern__ CFMutableArrayRef new_interfaces = NULL;
48
49 __private_extern__ CFArrayRef interfaces = NULL;
50 __private_extern__ CFArrayRef services = NULL;
51 __private_extern__ CFArrayRef protocols = NULL;
52 __private_extern__ CFArrayRef sets = NULL;
53
54 __private_extern__ SCNetworkInterfaceRef net_interface = NULL;
55 __private_extern__ SCNetworkServiceRef net_service = NULL;
56 __private_extern__ SCNetworkProtocolRef net_protocol = NULL;
57 __private_extern__ SCNetworkSetRef net_set = NULL;
58
59 __private_extern__ CFNumberRef CFNumberRef_0 = NULL;
60 __private_extern__ CFNumberRef CFNumberRef_1 = NULL;
61
62
63 /* -------------------- */
64
65
66 __private_extern__
67 CF_RETURNS_RETAINED CFNumberRef
68 _copy_number(const char *arg)
69 {
70 int val;
71
72 if (sscanf(arg, "%d", &val) != 1) {
73 return NULL;
74 }
75
76 return CFNumberCreate(NULL, kCFNumberIntType, &val);
77 }
78
79
80 /* -------------------- */
81
82
83 __private_extern__
84 CFIndex
85 _find_option(const char *option, optionsRef options, const int nOptions)
86 {
87 CFIndex i;
88
89 for (i = 0; i < nOptions; i++) {
90 if (strcasecmp(option, options[i].option) == 0) {
91 return i;
92 }
93 }
94
95 return kCFNotFound;
96 }
97
98
99 __private_extern__
100 CFIndex
101 _find_selection(CFStringRef choice, selections choices[], unsigned int *flags)
102 {
103 CFIndex i;
104
105 i = 0;
106 while (choices[i].selection != NULL) {
107 if (CFStringCompare(choice,
108 choices[i].selection,
109 kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
110 if (flags != NULL) {
111 *flags = choices[i].flags;
112 }
113 return i;
114 }
115 i++;
116 }
117
118 return kCFNotFound;
119 }
120
121
122 __private_extern__
123 Boolean
124 _process_options(optionsRef options, int nOptions, int argc, char **argv, CFMutableDictionaryRef newConfiguration)
125 {
126 while (argc > 0) {
127 CFIndex optionIndex = kCFNotFound;
128
129 optionIndex = _find_option(argv[0], options, nOptions);
130 if (optionIndex == kCFNotFound) {
131 SCPrint(TRUE, stdout, CFSTR("set what?\n"));
132 return FALSE;
133 }
134 argv++;
135 argc--;
136
137 switch (options[optionIndex].type) {
138 case isOther :
139 // all option processing is managed by the "handler"
140 break;
141 case isHelp :
142 SCPrint(TRUE, stdout, CFSTR("%s\n"), options[optionIndex].info);
143 return FALSE;
144 case isChooseOne : {
145 CFStringRef choice;
146 selections *choices = (selections *)options[optionIndex].info;
147 unsigned int flags;
148 CFIndex i;
149
150 if (argc < 1) {
151 SCPrint(TRUE, stdout,
152 CFSTR("%s not specified\n"),
153 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
154 return FALSE;
155 }
156
157 choice = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
158 i = _find_selection(choice, choices, &flags);
159 CFRelease(choice);
160
161 if (i != kCFNotFound) {
162 if (choices[i].flags & selectionNotAvailable) {
163 SCPrint(TRUE, stdout,
164 CFSTR("cannot select %s\n"),
165 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
166 return FALSE;
167 }
168
169 if (choices[i].key != NULL) {
170 CFDictionarySetValue(newConfiguration,
171 *(options[optionIndex].key),
172 *(choices[i].key));
173 } else {
174 CFDictionaryRemoveValue(newConfiguration,
175 *(options[optionIndex].key));
176 }
177 } else {
178 SCPrint(TRUE, stdout,
179 CFSTR("invalid %s\n"),
180 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
181 return FALSE;
182 }
183
184 argv++;
185 argc--;
186 break;
187 }
188 case isChooseMultiple :
189 if (argc < 1) {
190 SCPrint(TRUE, stdout,
191 CFSTR("%s(s) not specified\n"),
192 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
193 return FALSE;
194 }
195
196 if (strlen(argv[0]) > 0) {
197 CFIndex i;
198 CFIndex n;
199 CFMutableArrayRef chosen;
200 CFStringRef str;
201 CFArrayRef str_array;
202
203 str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
204 str_array = CFStringCreateArrayBySeparatingStrings(NULL, str, CFSTR(","));
205 CFRelease(str);
206
207 chosen = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
208
209 n = CFArrayGetCount(str_array);
210 for (i = 0; i < n; i++) {
211 CFStringRef choice;
212 selections *choices = (selections *)options[optionIndex].info;
213 unsigned int flags;
214 CFIndex j;
215
216 choice = CFArrayGetValueAtIndex(str_array, i);
217 j = _find_selection(choice, choices, &flags);
218
219 if (j != kCFNotFound) {
220 if (choices[j].flags & selectionNotAvailable) {
221 SCPrint(TRUE, stdout,
222 CFSTR("cannot select %s\n"),
223 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
224 CFArrayRemoveAllValues(chosen);
225 break;
226 }
227
228 CFArrayAppendValue(chosen, *(choices[j].key));
229 } else {
230 SCPrint(TRUE, stdout,
231 CFSTR("invalid %s\n"),
232 options[optionIndex].description != NULL ? options[optionIndex].description : "selection");
233 CFArrayRemoveAllValues(chosen);
234 break;
235 }
236 }
237 CFRelease(str_array);
238
239 if (CFArrayGetCount(chosen) > 0) {
240 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), chosen);
241 } else {
242 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
243 }
244 CFRelease(chosen);
245 } else {
246 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
247 }
248
249 argv++;
250 argc--;
251 break;
252 case isBool :
253 if (argc < 1) {
254 SCPrint(TRUE, stdout,
255 CFSTR("%s not specified\n"),
256 options[optionIndex].description != NULL ? options[optionIndex].description : "enable/disable");
257 return FALSE;
258 }
259
260 if ((strcasecmp(argv[0], "disable") == 0) ||
261 (strcasecmp(argv[0], "no" ) == 0) ||
262 (strcasecmp(argv[0], "off" ) == 0) ||
263 (strcasecmp(argv[0], "0" ) == 0)) {
264 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), kCFBooleanFalse);
265 } else if ((strcasecmp(argv[0], "enable") == 0) ||
266 (strcasecmp(argv[0], "yes" ) == 0) ||
267 (strcasecmp(argv[0], "on" ) == 0) ||
268 (strcasecmp(argv[0], "1" ) == 0)) {
269 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), kCFBooleanTrue);
270 } else if (strcmp(argv[0], "") == 0) {
271 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
272 } else {
273 SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
274 return FALSE;
275 }
276
277 argv++;
278 argc--;
279 break;
280 case isBoolean :
281 if (argc < 1) {
282 SCPrint(TRUE, stdout,
283 CFSTR("%s not specified\n"),
284 options[optionIndex].description != NULL ? options[optionIndex].description : "enable/disable");
285 return FALSE;
286 }
287
288 if ((strcasecmp(argv[0], "disable") == 0) ||
289 (strcasecmp(argv[0], "no" ) == 0) ||
290 (strcasecmp(argv[0], "off" ) == 0) ||
291 (strcasecmp(argv[0], "0" ) == 0)) {
292 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), CFNumberRef_0);
293 } else if ((strcasecmp(argv[0], "enable") == 0) ||
294 (strcasecmp(argv[0], "yes" ) == 0) ||
295 (strcasecmp(argv[0], "on" ) == 0) ||
296 (strcasecmp(argv[0], "1" ) == 0)) {
297 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), CFNumberRef_1);
298 } else if (strcmp(argv[0], "") == 0) {
299 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
300 } else {
301 SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
302 return FALSE;
303 }
304
305 argv++;
306 argc--;
307 break;
308 case isNumber :
309 if (argc < 1) {
310 SCPrint(TRUE, stdout,
311 CFSTR("%s not specified\n"),
312 options[optionIndex].description != NULL ? options[optionIndex].description : "value");
313 return FALSE;
314 }
315
316 if (strlen(argv[0]) > 0) {
317 CFNumberRef num;
318
319 num = _copy_number(argv[0]);
320 if (num != NULL) {
321 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), num);
322 CFRelease(num);
323 } else {
324 SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
325 return FALSE;
326 }
327 } else {
328 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
329 }
330
331 argv++;
332 argc--;
333 break;
334 case isString :
335 if (argc < 1) {
336 SCPrint(TRUE, stdout,
337 CFSTR("%s not specified\n"),
338 options[optionIndex].description != NULL ? options[optionIndex].description : "value");
339 return FALSE;
340 }
341
342 if (strlen(argv[0]) > 0) {
343 CFStringRef str;
344
345 str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
346 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), str);
347 CFRelease(str);
348 } else {
349 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
350 }
351
352 argv++;
353 argc--;
354 break;
355 case isStringArray :
356 if (argc < 1) {
357 SCPrint(TRUE, stdout,
358 CFSTR("%s(s) not specified\n"),
359 options[optionIndex].description != NULL ? options[optionIndex].description : "value");
360 return FALSE;
361 }
362
363 if (strlen(argv[0]) > 0) {
364 CFStringRef str;
365 CFArrayRef str_array;
366
367 str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
368 str_array = CFStringCreateArrayBySeparatingStrings(NULL, str, CFSTR(","));
369 CFRelease(str);
370
371 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), str_array);
372 CFRelease(str_array);
373 } else {
374 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
375 }
376
377 argv++;
378 argc--;
379 break;
380 }
381
382 if (options[optionIndex].handler != NULL) {
383 CFStringRef key;
384 int nArgs;
385
386 key = options[optionIndex].key != NULL ? *(options[optionIndex].key) : NULL;
387 nArgs = (*options[optionIndex].handler)(key,
388 options[optionIndex].description,
389 options[optionIndex].info,
390 argc,
391 argv,
392 newConfiguration);
393 if (nArgs < 0) {
394 return FALSE;
395 }
396
397 argv += nArgs;
398 argc -= nArgs;
399 }
400 }
401
402 return TRUE;
403 }
404
405
406 /* -------------------- */
407
408
409 #define N_QUICK 32
410
411 __private_extern__
412 void
413 _show_entity(CFDictionaryRef entity, CFStringRef prefix)
414 {
415 CFArrayRef array;
416 const void * keys_q[N_QUICK];
417 const void ** keys = keys_q;
418 CFIndex i;
419 CFIndex n;
420 CFMutableArrayRef sorted;
421
422 n = CFDictionaryGetCount(entity);
423 if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
424 keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0);
425 }
426 CFDictionaryGetKeysAndValues(entity, keys, NULL);
427
428 array = CFArrayCreate(NULL, keys, n, &kCFTypeArrayCallBacks);
429 sorted = CFArrayCreateMutableCopy(NULL, n, array);
430 if (n > 1) {
431 CFArraySortValues(sorted,
432 CFRangeMake(0, n),
433 (CFComparatorFunction)CFStringCompare,
434 NULL);
435 }
436
437 for (i = 0; i < n; i++) {
438 CFStringRef key;
439 CFTypeRef value;
440
441 key = CFArrayGetValueAtIndex(sorted, i);
442 value = CFDictionaryGetValue(entity, key);
443 if (isA_CFArray(value)) {
444 CFIndex i;
445 CFIndex n = CFArrayGetCount(value);
446
447 SCPrint(TRUE, stdout, CFSTR("%@ %@ = ("), prefix, key);
448 for (i = 0; i < n; i++) {
449 CFTypeRef val;
450
451 val = CFArrayGetValueAtIndex(value, i);
452 SCPrint(TRUE, stdout,
453 CFSTR("%s%@"),
454 (i > 0) ? ", " : "",
455 val);
456 }
457 SCPrint(TRUE, stdout, CFSTR(")\n"));
458 } else {
459 SCPrint(TRUE, stdout, CFSTR("%@ %@ = %@\n"), prefix, key, value);
460 }
461 }
462
463 CFRelease(sorted);
464 CFRelease(array);
465 if (keys != keys_q) {
466 CFAllocatorDeallocate(NULL, keys);
467 }
468
469 return;
470 }
471
472
473 /* -------------------- */
474
475
476 static void
477 _net_close()
478 {
479 if (net_interface != NULL) {
480 CFRelease(net_interface);
481 net_interface = NULL;
482 }
483
484 if (net_service != NULL) {
485 CFRelease(net_service);
486 net_service = NULL;
487 }
488
489 if (net_protocol != NULL) {
490 CFRelease(net_protocol);
491 net_protocol = NULL;
492 }
493
494 if (net_set != NULL) {
495 CFRelease(net_set);
496 net_set = NULL;
497 }
498
499 if (interfaces != NULL) {
500 CFRelease(interfaces);
501 interfaces = NULL;
502 }
503
504 if (services != NULL) {
505 CFRelease(services);
506 services = NULL;
507 }
508
509 if (protocols != NULL) {
510 CFRelease(protocols);
511 protocols = NULL;
512 }
513
514 if (sets != NULL) {
515 CFRelease(sets);
516 sets = NULL;
517 }
518
519 if (new_interfaces != NULL) {
520 CFRelease(new_interfaces);
521 new_interfaces = NULL;
522 }
523
524 return;
525 }
526
527
528 __private_extern__
529 void
530 do_net_init()
531 {
532 int one = 1;
533 int zero = 0;
534
535 CFNumberRef_0 = CFNumberCreate(NULL, kCFNumberIntType, &zero);
536 CFNumberRef_1 = CFNumberCreate(NULL, kCFNumberIntType, &one);
537
538 return;
539 }
540
541
542 __private_extern__
543 void
544 do_net_open(int argc, char **argv)
545 {
546 Boolean ok;
547
548 if (prefs != NULL) {
549 if (_prefs_commitRequired(argc, argv, "close")) {
550 return;
551 }
552
553 _net_close();
554 _prefs_close();
555 }
556
557 ok = _prefs_open(CFSTR("scutil --net"), (argc > 0) ? argv[0] : NULL);
558 if (!ok) {
559 SCPrint(TRUE,
560 stdout,
561 CFSTR("Could not open prefs: %s\n"),
562 SCErrorString(SCError()));
563 return;
564 }
565
566 net_set = SCNetworkSetCopyCurrent(prefs);
567 if (net_set != NULL) {
568 CFStringRef setName;
569
570 setName = SCNetworkSetGetName(net_set);
571 if (setName != NULL) {
572 SCPrint(TRUE, stdout, CFSTR("set \"%@\" selected\n"), setName);
573 } else {
574 SCPrint(TRUE, stdout,
575 CFSTR("set ID \"%@\" selected\n"),
576 SCNetworkSetGetSetID(net_set));
577 }
578 }
579
580 return;
581 }
582
583
584 __private_extern__
585 void
586 do_net_commit(int argc, char **argv)
587 {
588 #pragma unused(argc)
589 #pragma unused(argv)
590 if (!SCPreferencesCommitChanges(prefs)) {
591 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
592 return;
593 }
594
595 _prefs_changed = FALSE;
596 return;
597 }
598
599
600 __private_extern__
601 void
602 do_net_apply(int argc, char **argv)
603 {
604 #pragma unused(argc)
605 #pragma unused(argv)
606 if (!SCPreferencesApplyChanges(prefs)) {
607 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
608 }
609 return;
610 }
611
612
613 __private_extern__
614 void
615 do_net_close(int argc, char **argv)
616 {
617 if (_prefs_commitRequired(argc, argv, "close")) {
618 return;
619 }
620
621 _net_close();
622 _prefs_close();
623
624 return;
625 }
626
627
628 __private_extern__
629 void
630 do_net_quit(int argc, char **argv)
631 {
632 if (_prefs_commitRequired(argc, argv, "quit")) {
633 return;
634 }
635
636 _net_close();
637 _prefs_close();
638
639 termRequested = TRUE;
640 return;
641 }
642
643
644 /* -------------------- */
645
646
647 typedef void (*net_func) (int argc, char **argv);
648
649 static const struct {
650 char *key;
651 net_func create;
652 net_func disable;
653 net_func enable;
654 net_func select;
655 net_func set;
656 net_func show;
657 net_func remove;
658 } net_keys[] = {
659
660 { "interfaces", NULL , NULL , NULL ,
661 NULL , NULL , show_interfaces ,
662 NULL },
663
664 { "interface", create_interface, NULL , NULL ,
665 select_interface, set_interface , show_interface ,
666 NULL },
667
668 { "services", NULL , NULL , NULL ,
669 NULL , NULL , show_services ,
670 NULL },
671
672 { "service", create_service , disable_service , enable_service ,
673 select_service , set_service , show_service ,
674 remove_service },
675
676 { "protocols", NULL , NULL , NULL ,
677 NULL , NULL , show_protocols ,
678 NULL },
679
680 { "protocol", create_protocol , disable_protocol, enable_protocol ,
681 select_protocol , set_protocol , show_protocol ,
682 remove_protocol },
683
684 { "sets", NULL , NULL , NULL ,
685 NULL , NULL , show_sets ,
686 NULL },
687
688 { "set", create_set , NULL , NULL ,
689 select_set , set_set , show_set ,
690 remove_set }
691
692 };
693 #define N_NET_KEYS (sizeof(net_keys) / sizeof(net_keys[0]))
694
695
696 static int
697 findNetKey(char *key)
698 {
699 int i;
700
701 for (i = 0; i < (int)N_NET_KEYS; i++) {
702 if (strcmp(key, net_keys[i].key) == 0) {
703 return i;
704 }
705 }
706
707 return -1;
708 }
709
710
711 /* -------------------- */
712
713
714 __private_extern__
715 void
716 do_net_create(int argc, char **argv)
717 {
718 char *key;
719 int i;
720
721 key = argv[0];
722 argv++;
723 argc--;
724
725 i = findNetKey(key);
726 if (i < 0) {
727 SCPrint(TRUE, stderr, CFSTR("create what?\n"));
728 return;
729 }
730
731 if (net_keys[i].create == NULL) {
732 SCPrint(TRUE, stderr, CFSTR("create what?\n"));
733 return;
734 }
735
736 (*net_keys[i].create)(argc, argv);
737 return;
738 }
739
740
741 __private_extern__
742 void
743 do_net_disable(int argc, char **argv)
744 {
745 char *key;
746 int i;
747
748 key = argv[0];
749 argv++;
750 argc--;
751
752 i = findNetKey(key);
753 if (i < 0) {
754 SCPrint(TRUE, stderr, CFSTR("disable what?\n"));
755 return;
756 }
757
758 if (net_keys[i].disable == NULL) {
759 SCPrint(TRUE, stderr, CFSTR("disable what?\n"));
760 return;
761 }
762
763 (*net_keys[i].disable)(argc, argv);
764 return;
765 }
766
767
768 __private_extern__
769 void
770 do_net_enable(int argc, char **argv)
771 {
772 char *key;
773 int i;
774
775 key = argv[0];
776 argv++;
777 argc--;
778
779 i = findNetKey(key);
780 if (i < 0) {
781 SCPrint(TRUE, stderr, CFSTR("enable what?\n"));
782 return;
783 }
784
785 if (net_keys[i].enable == NULL) {
786 SCPrint(TRUE, stderr, CFSTR("enable what?\n"));
787 return;
788 }
789
790 (*net_keys[i].enable)(argc, argv);
791 return;
792 }
793
794
795 static void
796 do_net_migrate_perform(int argc, char **argv)
797 {
798 char * sourceConfiguration = NULL;
799 char * targetConfiguration = NULL;
800 char * currentConfiguration = NULL;
801 CFStringRef str = NULL;
802 CFURLRef sourceConfigurationURL = NULL;
803 CFURLRef targetConfigurationURL = NULL;
804 CFURLRef currentConfigurationURL = NULL;
805 CFArrayRef migrationFiles = NULL;
806
807 sourceConfiguration = argv[0];
808 targetConfiguration = argv[1];
809
810 if (argc == 3) {
811 currentConfiguration = argv[2];
812 }
813
814 SCPrint(_sc_debug, stdout, CFSTR("sourceConfiguration: %s\ntargetConfiguration: %s\ncurrentConfiguration: %s\n"),
815 sourceConfiguration, targetConfiguration, (currentConfiguration != NULL) ? currentConfiguration : "<current system>" );
816
817 str = CFStringCreateWithCString(NULL, sourceConfiguration, kCFStringEncodingUTF8);
818 sourceConfigurationURL = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, TRUE);
819 CFRelease(str);
820
821 str = CFStringCreateWithCString(NULL, targetConfiguration, kCFStringEncodingUTF8);
822 targetConfigurationURL = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, TRUE);
823 CFRelease(str);
824
825 if (currentConfiguration != NULL) {
826 str = CFStringCreateWithCString(NULL, currentConfiguration, kCFStringEncodingUTF8);
827 currentConfigurationURL = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, TRUE);
828 CFRelease(str);
829 }
830
831 migrationFiles = _SCNetworkConfigurationPerformMigration(sourceConfigurationURL, currentConfigurationURL, targetConfigurationURL, NULL);
832
833 if (migrationFiles != NULL) {
834 SCPrint(TRUE, stdout, CFSTR("Migration Successful: %@ \n"), migrationFiles);
835 }
836 else {
837 SCPrint(TRUE, stdout, CFSTR("Migration Unsuccessful \n"));
838 }
839
840 if (sourceConfigurationURL != NULL) {
841 CFRelease(sourceConfigurationURL);
842 }
843 if (targetConfigurationURL != NULL) {
844 CFRelease(targetConfigurationURL);
845 }
846 if (currentConfigurationURL != NULL) {
847 CFRelease(currentConfigurationURL);
848 }
849 if (migrationFiles != NULL) {
850 CFRelease(migrationFiles);
851 }
852 }
853
854
855 static void
856 do_net_migrate_validate(int argc, char **argv)
857 {
858 #pragma unused(argc)
859 char *configuration = NULL;
860 CFURLRef configurationURL = NULL;
861 char *expectedConfiguration = NULL;
862 CFURLRef expectedConfigurationURL = NULL;
863 Boolean isValid = FALSE;
864 CFStringRef str = NULL;
865
866 configuration = argv[0];
867 str = CFStringCreateWithCString(NULL, configuration, kCFStringEncodingUTF8);
868 configurationURL = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, TRUE);
869 CFRelease(str);
870
871 expectedConfiguration = argv[1];
872 str = CFStringCreateWithCString(NULL, expectedConfiguration, kCFStringEncodingUTF8);
873 expectedConfigurationURL = CFURLCreateWithFileSystemPath(NULL, str, kCFURLPOSIXPathStyle, TRUE);
874 CFRelease(str);
875
876 isValid = _SCNetworkMigrationAreConfigurationsIdentical(configurationURL, expectedConfigurationURL);
877
878 SCPrint(TRUE, stdout, CFSTR("Configuration at location %s %s\n"), configuration, isValid ? "is valid" : "is NOT valid");
879
880 if (configurationURL != NULL) {
881 CFRelease(configurationURL);
882 }
883 if (expectedConfigurationURL != NULL) {
884 CFRelease(expectedConfigurationURL);
885 }
886 }
887
888
889 __private_extern__
890 void
891 do_net_migrate(int argc, char **argv)
892 {
893 char *key;
894 SCPrint(TRUE, stdout, CFSTR("do_net_migrate called, %d\n"), argc);
895
896 key = argv[0];
897 argv++;
898 argc--;
899
900 if (strcmp(key, "perform") == 0) {
901 do_net_migrate_perform(argc, argv);
902 } else if (strcmp(key, "validate") == 0) {
903 do_net_migrate_validate(argc, argv);
904 } else {
905 SCPrint(TRUE, stderr, CFSTR("migrate what?\n"));
906 return;
907 }
908
909 }
910
911
912 __private_extern__
913 void
914 do_net_remove(int argc, char **argv)
915 {
916 char *key;
917 int i;
918
919 key = argv[0];
920 argv++;
921 argc--;
922
923 i = findNetKey(key);
924 if (i < 0) {
925 SCPrint(TRUE, stderr, CFSTR("remove what?\n"));
926 return;
927 }
928
929 if (net_keys[i].remove == NULL) {
930 SCPrint(TRUE, stderr, CFSTR("remove what?\n"));
931 return;
932 }
933
934 (*net_keys[i].remove)(argc, argv);
935 return;
936 }
937
938
939 __private_extern__
940 void
941 do_net_select(int argc, char **argv)
942 {
943 char *key;
944 int i;
945
946 key = argv[0];
947 argv++;
948 argc--;
949
950 i = findNetKey(key);
951 if (i < 0) {
952 SCPrint(TRUE, stderr, CFSTR("select what?\n"));
953 return;
954 }
955
956 if (*net_keys[i].select == NULL) {
957 SCPrint(TRUE, stderr, CFSTR("select what?\n"));
958 return;
959 }
960
961 (*net_keys[i].select)(argc, argv);
962 return;
963 }
964
965
966 __private_extern__
967 void
968 do_net_set(int argc, char **argv)
969 {
970 char *key;
971 int i;
972
973 key = argv[0];
974 argv++;
975 argc--;
976
977 i = findNetKey(key);
978 if (i < 0) {
979 SCPrint(TRUE, stderr, CFSTR("set what?\n"));
980 return;
981 }
982
983 (*net_keys[i].set)(argc, argv);
984 return;
985 }
986
987
988 __private_extern__
989 void
990 do_net_show(int argc, char **argv)
991 {
992 char *key;
993 int i;
994
995 key = argv[0];
996 argv++;
997 argc--;
998
999 i = findNetKey(key);
1000 if (i < 0) {
1001 SCPrint(TRUE, stderr, CFSTR("show what?\n"));
1002 return;
1003 }
1004
1005 (*net_keys[i].show)(argc, argv);
1006 return;
1007 }
1008
1009
1010 __private_extern__
1011 void
1012 do_net_clean(int argc, char **argv)
1013 {
1014 #pragma unused(argc)
1015 #pragma unused(argv)
1016 Boolean updated;
1017
1018 if (prefs == NULL) {
1019 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
1020 return;
1021 }
1022
1023 if (ni_prefs == NULL) {
1024 ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG);
1025 if (ni_prefs == NULL) {
1026 SC_log(LOG_NOTICE, "SCPreferencesCreate( <NetworkInterfaces.plist> ) failed: %s", SCErrorString(SCError()));
1027 }
1028 }
1029
1030 updated = __SCNetworkConfigurationClean(prefs, ni_prefs);
1031
1032 if (updated) {
1033 SCPrint(TRUE, stdout,
1034 CFSTR("network configuration updated, use \"commit\" to save\n"));
1035 if ((prefsPath == NULL) || (strcmp(prefsPath, PREFS_DEFAULT_CONFIG_PLIST) == 0)) {
1036 SCPrint(TRUE, stdout,
1037 CFSTR( "\n"
1038 "NOTE: because you have modified the system's \"live\" network configuration,\n"
1039 " a <reboot> is also REQUIRED.\n"
1040 "\n"));
1041 }
1042 _prefs_changed = TRUE;
1043 } else {
1044 SCPrint(TRUE, stdout, CFSTR("network configuration not updated\n"));
1045 }
1046
1047 return;
1048 }
1049
1050
1051 __private_extern__
1052 void
1053 do_net_update(int argc, char **argv)
1054 {
1055 #pragma unused(argc)
1056 #pragma unused(argv)
1057 SCNetworkSetRef set;
1058 Boolean setCreated = FALSE;
1059 Boolean setUpdated = FALSE;
1060
1061 if (prefs == NULL) {
1062 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
1063 return;
1064 }
1065
1066 if (net_set != NULL) {
1067 set = CFRetain(net_set);
1068 } else {
1069 set = SCNetworkSetCopyCurrent(prefs);
1070 if (set == NULL) {
1071 // if no "current" set, create a new/default ("Automatic") set
1072 set = _SCNetworkSetCreateDefault(prefs);
1073 if (set == NULL) {
1074 SCPrint(TRUE, stdout,
1075 CFSTR("could not initialize \"Automatic\" set: %s\n"),
1076 SCErrorString(SCError()));
1077 return;
1078 }
1079
1080 if (net_set != NULL) CFRelease(net_set);
1081 net_set = set;
1082 CFRetain(set);
1083
1084 setCreated = TRUE;
1085
1086 if (sets != NULL) {
1087 CFRelease(sets);
1088 sets = NULL;
1089 }
1090 }
1091 }
1092
1093 setUpdated = SCNetworkSetEstablishDefaultConfiguration(set);
1094 if (setUpdated) {
1095 CFStringRef setName;
1096
1097 _prefs_changed = TRUE;
1098
1099 setName = SCNetworkSetGetName(set);
1100 if (setName != NULL) {
1101 SCPrint(TRUE, stdout,
1102 CFSTR("set \"%@\" (%@) %supdated\n"),
1103 setName,
1104 SCNetworkSetGetSetID(set),
1105 setCreated ? "created, selected, and " : "");
1106 } else {
1107 SCPrint(TRUE, stdout,
1108 CFSTR("set ID \"%@\" %supdated\n"),
1109 SCNetworkSetGetSetID(set),
1110 setCreated ? "created, selected, and " : "");
1111 }
1112 _prefs_changed = TRUE;
1113 }
1114
1115 CFRelease(set);
1116 return;
1117 }
1118
1119
1120 __private_extern__
1121 void
1122 do_net_upgrade(int argc, char **argv)
1123 {
1124 Boolean do_commit = FALSE;
1125 Boolean upgraded;
1126
1127 if (prefs == NULL) {
1128 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
1129 return;
1130 }
1131
1132 if (prefsPath != NULL) {
1133 const char *prefs_plist;
1134
1135 prefs_plist = strrchr(prefsPath, '/');
1136 if (prefs_plist != NULL) {
1137 prefs_plist++;
1138 } else {
1139 prefs_plist = prefsPath;
1140 }
1141
1142 if (strcmp(prefs_plist, PREFS_DEFAULT_CONFIG_PLIST) != 0) {
1143 SCPrint(TRUE, stdout, CFSTR("not updating a \"preferences.plist\" file\n"));
1144 return;
1145 }
1146 }
1147
1148 if (argc > 0) {
1149 if (strcmp(argv[0], PREFS_DEFAULT_CONFIG_PLIST) == 0) {
1150 upgraded = __SCNetworkConfigurationUpgrade(&prefs, NULL, do_commit);
1151 } else if (strcmp(argv[0], INTERFACES_DEFAULT_CONFIG_PLIST) == 0) {
1152 if (ni_prefs == NULL) {
1153 ni_prefs = SCPreferencesCreateCompanion(prefs, INTERFACES_DEFAULT_CONFIG);
1154 if (ni_prefs == NULL) {
1155 SC_log(LOG_NOTICE, "SCPreferencesCreate( <NetworkInterfaces.plist> ) failed: %s", SCErrorString(SCError()));
1156 }
1157 }
1158
1159 do_commit = TRUE; // using alternate, created on-the-fly preferences.plist
1160
1161 upgraded = __SCNetworkConfigurationUpgrade(NULL, &ni_prefs, do_commit);
1162 } else {
1163 SCPrint(TRUE, stdout, CFSTR("invalid .plist (\"preferences.plist\", \"NetworkInterfaces.plist\"\n"));
1164 return;
1165 }
1166 } else {
1167 upgraded = __SCNetworkConfigurationUpgrade(&prefs, &ni_prefs, do_commit);
1168 }
1169
1170 if (upgraded) {
1171 SCPrint(TRUE, stdout,
1172 do_commit ? CFSTR("network configuration upgraded/saved\n")
1173 : CFSTR("network configuration upgraded, use \"commit\" to save\n"));
1174 if ((prefsPath == NULL) || (strcmp(prefsPath, PREFS_DEFAULT_CONFIG_PLIST) == 0)) {
1175 SCPrint(TRUE, stdout,
1176 do_commit ? CFSTR("\n"
1177 "NOTE: because you have modified the system's \"live\" network configuration,\n"
1178 " a <reboot> is also REQUIRED.\n"
1179 "\n")
1180
1181 : CFSTR("\n"
1182 "NOTE: because you are modifying the system's \"live\" network configuration,\n"
1183 " a <reboot> will also be REQUIRED.\n"
1184 "\n")
1185 );
1186 }
1187
1188 if (!do_commit) {
1189 _prefs_changed = TRUE;
1190 }
1191 } else {
1192 SCPrint(TRUE, stdout, CFSTR("network configuration upgrade not needed\n"));
1193 }
1194
1195 return;
1196 }
1197
1198
1199 #include "SCPreferencesInternal.h"
1200 #include <fcntl.h>
1201 #include <unistd.h>
1202 __private_extern__
1203 void
1204 do_net_snapshot(int argc, char **argv)
1205 {
1206 #pragma unused(argc)
1207 #pragma unused(argv)
1208 if (prefs == NULL) {
1209 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
1210 return;
1211 }
1212
1213 if (prefs != NULL) {
1214 SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs;
1215
1216 if (prefsPrivate->prefs != NULL) {
1217 int fd;
1218 static int n_snapshot = 0;
1219 char *path;
1220 CFDataRef xmlData;
1221
1222 asprintf(&path, "/tmp/prefs_snapshot_%d", n_snapshot++);
1223 (void)unlink(path);
1224 fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644);
1225 free(path);
1226 if (fd == -1) {
1227 SCPrint(TRUE, stdout, CFSTR("could not write snapshot: open() failed : %s\n"), strerror(errno));
1228 return;
1229 }
1230
1231 xmlData = CFPropertyListCreateData(NULL, prefsPrivate->prefs, kCFPropertyListXMLFormat_v1_0, 0, NULL);
1232 if (xmlData != NULL) {
1233 (void) write(fd, CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData));
1234 CFRelease(xmlData);
1235 } else {
1236 SCPrint(TRUE, stdout, CFSTR("could not write snapshot: CFPropertyListCreateData() failed\n"));
1237 }
1238
1239 (void) close(fd);
1240 } else {
1241 SCPrint(TRUE, stdout, CFSTR("prefs have not been accessed\n"));
1242 }
1243 }
1244
1245 return;
1246 }