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