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