]> git.saurik.com Git - apple/configd.git/blob - scutil.tproj/net.c
configd-453.16.tar.gz
[apple/configd.git] / scutil.tproj / net.c
1 /*
2 * Copyright (c) 2004-2007, 2009-2011 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 isBoolean :
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), CFNumberRef_0);
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), CFNumberRef_1);
262 } else {
263 SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
264 return FALSE;
265 }
266
267 argv++;
268 argc--;
269 break;
270 case isNumber :
271 if (argc < 1) {
272 SCPrint(TRUE, stdout,
273 CFSTR("%s not specified\n"),
274 options[optionIndex].description != NULL ? options[optionIndex].description : "value");
275 return FALSE;
276 }
277
278 if (strlen(argv[0]) > 0) {
279 CFNumberRef num;
280
281 num = _copy_number(argv[0]);
282 if (num != NULL) {
283 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), num);
284 CFRelease(num);
285 } else {
286 SCPrint(TRUE, stdout, CFSTR("invalid value\n"));
287 return FALSE;
288 }
289 } else {
290 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
291 }
292
293 argv++;
294 argc--;
295 break;
296 case isString :
297 if (argc < 1) {
298 SCPrint(TRUE, stdout,
299 CFSTR("%s not specified\n"),
300 options[optionIndex].description != NULL ? options[optionIndex].description : "value");
301 return FALSE;
302 }
303
304 if (strlen(argv[0]) > 0) {
305 CFStringRef str;
306
307 str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
308 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), str);
309 CFRelease(str);
310 } else {
311 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
312 }
313
314 argv++;
315 argc--;
316 break;
317 case isStringArray :
318 if (argc < 1) {
319 SCPrint(TRUE, stdout,
320 CFSTR("%s(s) not specified\n"),
321 options[optionIndex].description != NULL ? options[optionIndex].description : "value");
322 return FALSE;
323 }
324
325 if (strlen(argv[0]) > 0) {
326 CFStringRef str;
327 CFArrayRef str_array;
328
329 str = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
330 str_array = CFStringCreateArrayBySeparatingStrings(NULL, str, CFSTR(","));
331 CFRelease(str);
332
333 CFDictionarySetValue(newConfiguration, *(options[optionIndex].key), str_array);
334 CFRelease(str_array);
335 } else {
336 CFDictionaryRemoveValue(newConfiguration, *(options[optionIndex].key));
337 }
338
339 argv++;
340 argc--;
341 break;
342 }
343
344 if (options[optionIndex].handler != NULL) {
345 CFStringRef key;
346 int nArgs;
347
348 key = options[optionIndex].key != NULL ? *(options[optionIndex].key) : NULL;
349 nArgs = (*options[optionIndex].handler)(key,
350 options[optionIndex].description,
351 options[optionIndex].info,
352 argc,
353 argv,
354 newConfiguration);
355 if (nArgs < 0) {
356 return FALSE;
357 }
358
359 argv += nArgs;
360 argc -= nArgs;
361 }
362 }
363
364 return TRUE;
365 }
366
367
368 /* -------------------- */
369
370
371 #define N_QUICK 32
372
373 __private_extern__
374 void
375 _show_entity(CFDictionaryRef entity, CFStringRef prefix)
376 {
377 CFArrayRef array;
378 const void * keys_q[N_QUICK];
379 const void ** keys = keys_q;
380 CFIndex i;
381 CFIndex n;
382 CFMutableArrayRef sorted;
383
384 n = CFDictionaryGetCount(entity);
385 if (n > (CFIndex)(sizeof(keys_q) / sizeof(CFTypeRef))) {
386 keys = CFAllocatorAllocate(NULL, n * sizeof(CFTypeRef), 0);
387 }
388 CFDictionaryGetKeysAndValues(entity, keys, NULL);
389
390 array = CFArrayCreate(NULL, keys, n, &kCFTypeArrayCallBacks);
391 sorted = CFArrayCreateMutableCopy(NULL, n, array);
392 if (n > 1) {
393 CFArraySortValues(sorted,
394 CFRangeMake(0, n),
395 (CFComparatorFunction)CFStringCompare,
396 NULL);
397 }
398
399 for (i = 0; i < n; i++) {
400 CFStringRef key;
401 CFTypeRef value;
402
403 key = CFArrayGetValueAtIndex(sorted, i);
404 value = CFDictionaryGetValue(entity, key);
405 if (isA_CFArray(value)) {
406 CFIndex i;
407 CFIndex n = CFArrayGetCount(value);
408
409 SCPrint(TRUE, stdout, CFSTR("%@ %@ = ("), prefix, key);
410 for (i = 0; i < n; i++) {
411 CFTypeRef val;
412
413 val = CFArrayGetValueAtIndex(value, i);
414 SCPrint(TRUE, stdout,
415 CFSTR("%s%@"),
416 (i > 0) ? ", " : "",
417 val);
418 }
419 SCPrint(TRUE, stdout, CFSTR(")\n"));
420 } else {
421 SCPrint(TRUE, stdout, CFSTR("%@ %@ = %@\n"), prefix, key, value);
422 }
423 }
424
425 CFRelease(sorted);
426 CFRelease(array);
427 if (keys != keys_q) {
428 CFAllocatorDeallocate(NULL, keys);
429 }
430
431 return;
432 }
433
434
435 /* -------------------- */
436
437
438 static void
439 _net_close()
440 {
441 if (net_interface != NULL) {
442 CFRelease(net_interface);
443 net_interface = NULL;
444 }
445
446 if (net_service != NULL) {
447 CFRelease(net_service);
448 net_service = NULL;
449 }
450
451 if (net_protocol != NULL) {
452 CFRelease(net_protocol);
453 net_protocol = NULL;
454 }
455
456 if (net_set != NULL) {
457 CFRelease(net_set);
458 net_set = NULL;
459 }
460
461 if (interfaces != NULL) {
462 CFRelease(interfaces);
463 interfaces = NULL;
464 }
465
466 if (services != NULL) {
467 CFRelease(services);
468 services = NULL;
469 }
470
471 if (protocols != NULL) {
472 CFRelease(protocols);
473 protocols = NULL;
474 }
475
476 if (sets != NULL) {
477 CFRelease(sets);
478 sets = NULL;
479 }
480
481 if (new_interfaces != NULL) {
482 CFRelease(new_interfaces);
483 new_interfaces = NULL;
484 }
485
486 return;
487 }
488
489
490 __private_extern__
491 void
492 do_net_init()
493 {
494 int one = 1;
495 int zero = 0;
496
497 CFNumberRef_0 = CFNumberCreate(NULL, kCFNumberIntType, &zero);
498 CFNumberRef_1 = CFNumberCreate(NULL, kCFNumberIntType, &one);
499
500 return;
501 }
502
503
504 __private_extern__
505 void
506 do_net_open(int argc, char **argv)
507 {
508 Boolean ok;
509 CFStringRef prefsID = NULL;
510
511 if (prefs != NULL) {
512 if (_prefs_commitRequired(argc, argv, "close")) {
513 return;
514 }
515
516 _net_close();
517 _prefs_close();
518 }
519
520 if (argc > 0) {
521 prefsID = CFStringCreateWithCString(NULL, argv[0], kCFStringEncodingUTF8);
522 }
523
524 ok = _prefs_open(CFSTR("scutil --net"), prefsID);
525 if (prefsID != NULL) CFRelease(prefsID);
526 if (!ok) {
527 SCPrint(TRUE,
528 stdout,
529 CFSTR("Could not open prefs: %s\n"),
530 SCErrorString(SCError()));
531 return;
532 }
533
534 net_set = SCNetworkSetCopyCurrent(prefs);
535 if (net_set != NULL) {
536 CFStringRef setName;
537
538 setName = SCNetworkSetGetName(net_set);
539 if (setName != NULL) {
540 SCPrint(TRUE, stdout, CFSTR("set \"%@\" selected\n"), setName);
541 } else {
542 SCPrint(TRUE, stdout,
543 CFSTR("set ID \"%@\" selected\n"),
544 SCNetworkSetGetSetID(net_set));
545 }
546 }
547
548 return;
549 }
550
551
552 __private_extern__
553 void
554 do_net_commit(int argc, char **argv)
555 {
556 if (!SCPreferencesCommitChanges(prefs)) {
557 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
558 return;
559 }
560
561 _prefs_changed = FALSE;
562 return;
563 }
564
565
566 __private_extern__
567 void
568 do_net_apply(int argc, char **argv)
569 {
570 if (!SCPreferencesApplyChanges(prefs)) {
571 SCPrint(TRUE, stdout, CFSTR("%s\n"), SCErrorString(SCError()));
572 }
573 return;
574 }
575
576
577 __private_extern__
578 void
579 do_net_close(int argc, char **argv)
580 {
581 if (_prefs_commitRequired(argc, argv, "close")) {
582 return;
583 }
584
585 _net_close();
586 _prefs_close();
587
588 return;
589 }
590
591
592 __private_extern__
593 void
594 do_net_quit(int argc, char **argv)
595 {
596 if (_prefs_commitRequired(argc, argv, "quit")) {
597 return;
598 }
599
600 _net_close();
601 _prefs_close();
602
603 termRequested = TRUE;
604 return;
605 }
606
607
608 /* -------------------- */
609
610
611 typedef void (*net_func) (int argc, char **argv);
612
613 static const struct {
614 char *key;
615 net_func create;
616 net_func disable;
617 net_func enable;
618 net_func select;
619 net_func set;
620 net_func show;
621 net_func remove;
622 } net_keys[] = {
623
624 { "interfaces", NULL , NULL , NULL ,
625 NULL , NULL , show_interfaces ,
626 NULL },
627
628 { "interface", create_interface, NULL , NULL ,
629 select_interface, set_interface , show_interface ,
630 NULL },
631
632 { "services", NULL , NULL , NULL ,
633 NULL , NULL , show_services ,
634 NULL },
635
636 { "service", create_service , disable_service , enable_service ,
637 select_service , set_service , show_service ,
638 remove_service },
639
640 { "protocols", NULL , NULL , NULL ,
641 NULL , NULL , show_protocols ,
642 NULL },
643
644 { "protocol", create_protocol , disable_protocol, enable_protocol ,
645 select_protocol , set_protocol , show_protocol ,
646 remove_protocol },
647
648 { "sets", NULL , NULL , NULL ,
649 NULL , NULL , show_sets ,
650 NULL },
651
652 { "set", create_set , NULL , NULL ,
653 select_set , set_set , show_set ,
654 remove_set }
655
656 };
657 #define N_NET_KEYS (sizeof(net_keys) / sizeof(net_keys[0]))
658
659
660 static int
661 findNetKey(char *key)
662 {
663 int i;
664
665 for (i = 0; i < (int)N_NET_KEYS; i++) {
666 if (strcmp(key, net_keys[i].key) == 0) {
667 return i;
668 }
669 }
670
671 return -1;
672 }
673
674
675 /* -------------------- */
676
677
678 __private_extern__
679 void
680 do_net_create(int argc, char **argv)
681 {
682 char *key;
683 int i;
684
685 key = argv[0];
686 argv++;
687 argc--;
688
689 i = findNetKey(key);
690 if (i < 0) {
691 SCPrint(TRUE, stderr, CFSTR("create what?\n"));
692 return;
693 }
694
695 if (net_keys[i].create == NULL) {
696 SCPrint(TRUE, stderr, CFSTR("create what?\n"));
697 return;
698 }
699
700 (*net_keys[i].create)(argc, argv);
701 return;
702 }
703
704
705 __private_extern__
706 void
707 do_net_disable(int argc, char **argv)
708 {
709 char *key;
710 int i;
711
712 key = argv[0];
713 argv++;
714 argc--;
715
716 i = findNetKey(key);
717 if (i < 0) {
718 SCPrint(TRUE, stderr, CFSTR("disable what?\n"));
719 return;
720 }
721
722 if (net_keys[i].disable == NULL) {
723 SCPrint(TRUE, stderr, CFSTR("disable what?\n"));
724 return;
725 }
726
727 (*net_keys[i].disable)(argc, argv);
728 return;
729 }
730
731
732 __private_extern__
733 void
734 do_net_enable(int argc, char **argv)
735 {
736 char *key;
737 int i;
738
739 key = argv[0];
740 argv++;
741 argc--;
742
743 i = findNetKey(key);
744 if (i < 0) {
745 SCPrint(TRUE, stderr, CFSTR("enable what?\n"));
746 return;
747 }
748
749 if (net_keys[i].enable == NULL) {
750 SCPrint(TRUE, stderr, CFSTR("enable what?\n"));
751 return;
752 }
753
754 (*net_keys[i].enable)(argc, argv);
755 return;
756 }
757
758
759 __private_extern__
760 void
761 do_net_remove(int argc, char **argv)
762 {
763 char *key;
764 int i;
765
766 key = argv[0];
767 argv++;
768 argc--;
769
770 i = findNetKey(key);
771 if (i < 0) {
772 SCPrint(TRUE, stderr, CFSTR("remove what?\n"));
773 return;
774 }
775
776 if (net_keys[i].remove == NULL) {
777 SCPrint(TRUE, stderr, CFSTR("remove what?\n"));
778 return;
779 }
780
781 (*net_keys[i].remove)(argc, argv);
782 return;
783 }
784
785
786 __private_extern__
787 void
788 do_net_select(int argc, char **argv)
789 {
790 char *key;
791 int i;
792
793 key = argv[0];
794 argv++;
795 argc--;
796
797 i = findNetKey(key);
798 if (i < 0) {
799 SCPrint(TRUE, stderr, CFSTR("select what?\n"));
800 return;
801 }
802
803 if (*net_keys[i].select == NULL) {
804 SCPrint(TRUE, stderr, CFSTR("select what?\n"));
805 return;
806 }
807
808 (*net_keys[i].select)(argc, argv);
809 return;
810 }
811
812
813 __private_extern__
814 void
815 do_net_set(int argc, char **argv)
816 {
817 char *key;
818 int i;
819
820 key = argv[0];
821 argv++;
822 argc--;
823
824 i = findNetKey(key);
825 if (i < 0) {
826 SCPrint(TRUE, stderr, CFSTR("set what?\n"));
827 return;
828 }
829
830 (*net_keys[i].set)(argc, argv);
831 return;
832 }
833
834
835 __private_extern__
836 void
837 do_net_show(int argc, char **argv)
838 {
839 char *key;
840 int i;
841
842 key = argv[0];
843 argv++;
844 argc--;
845
846 i = findNetKey(key);
847 if (i < 0) {
848 SCPrint(TRUE, stderr, CFSTR("show what?\n"));
849 return;
850 }
851
852 (*net_keys[i].show)(argc, argv);
853 return;
854 }
855
856
857 __private_extern__
858 void
859 do_net_update(int argc, char **argv)
860 {
861 SCNetworkSetRef set;
862 Boolean setCreated = FALSE;
863 Boolean setUpdated = FALSE;
864
865 if (prefs == NULL) {
866 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
867 return;
868 }
869
870 if (net_set != NULL) {
871 set = CFRetain(net_set);
872 } else {
873 set = SCNetworkSetCopyCurrent(prefs);
874 if (set == NULL) {
875 CFBundleRef bundle;
876 Boolean ok;
877 CFArrayRef sets;
878 CFStringRef setName = NULL;
879
880 sets = SCNetworkSetCopyAll(prefs);
881 if (sets != NULL) {
882 CFIndex n;
883
884 n = CFArrayGetCount(sets);
885 CFRelease(sets);
886 sets = NULL;
887 if (n > 0) {
888 SCPrint(TRUE, stdout, CFSTR("no current set\n"));
889 return;
890 }
891 }
892
893 bundle = _SC_CFBundleGet();
894 if (bundle != NULL) {
895 setName = CFBundleCopyLocalizedString(bundle,
896 CFSTR("DEFAULT_SET_NAME"),
897 CFSTR("Automatic"),
898 NULL);
899 }
900 if (setName == NULL) {
901 setName = CFSTR("Automatic");
902 CFRetain(setName);
903 }
904
905 set = SCNetworkSetCreate(prefs);
906 if (set == NULL) {
907 SCPrint(TRUE, stdout,
908 CFSTR("could not initialize \"%@\": %s\n"),
909 setName,
910 SCErrorString(SCError()));
911 CFRelease(setName);
912 return;
913 }
914
915 (void) SCNetworkSetSetName(set, setName);
916
917 ok = SCNetworkSetSetCurrent(set);
918 if (!ok) {
919 SCPrint(TRUE, stdout,
920 CFSTR("could not initialize \"%@\": %s\n"),
921 setName,
922 SCErrorString(SCError()));
923 (void) SCNetworkSetRemove(set);
924 CFRelease(setName);
925 CFRelease(set);
926 return;
927 }
928
929 if (net_set != NULL) CFRelease(net_set);
930 net_set = set;
931
932 setCreated = TRUE;
933
934 CFRelease(setName);
935 CFRetain(set);
936 }
937 }
938
939 setUpdated = SCNetworkSetEstablishDefaultConfiguration(set);
940 if (setUpdated) {
941 CFStringRef setName;
942
943 _prefs_changed = TRUE;
944
945 setName = SCNetworkSetGetName(set);
946 if (setName != NULL) {
947 SCPrint(TRUE, stdout,
948 CFSTR("set \"%@\" (%@) %supdated\n"),
949 setName,
950 SCNetworkSetGetSetID(set),
951 setCreated ? "created, selected, and " : "");
952 } else {
953 SCPrint(TRUE, stdout,
954 CFSTR("set ID \"%@\" %supdated\n"),
955 SCNetworkSetGetSetID(set),
956 setCreated ? "created, selected, and " : "");
957 }
958 }
959
960 CFRelease(set);
961 return;
962 }
963
964
965 #include "SCPreferencesInternal.h"
966 #include <fcntl.h>
967 #include <unistd.h>
968 __private_extern__
969 void
970 do_net_snapshot(int argc, char **argv)
971 {
972 if (prefs == NULL) {
973 SCPrint(TRUE, stdout, CFSTR("network configuration not open\n"));
974 return;
975 }
976
977 if (prefs != NULL) {
978 SCPreferencesPrivateRef prefsPrivate = (SCPreferencesPrivateRef)prefs;
979
980 if (prefsPrivate->prefs != NULL) {
981 int fd;
982 static int n_snapshot = 0;
983 char *path;
984 CFDataRef xmlData;
985
986 asprintf(&path, "/tmp/prefs_snapshot_%d", n_snapshot++);
987 (void)unlink(path);
988 fd = open(path, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, 0644);
989 free(path);
990 if (fd == -1) {
991 SCPrint(TRUE, stdout, CFSTR("could not write snapshot: open() failed : %s\n"), strerror(errno));
992 return;
993 }
994
995 xmlData = CFPropertyListCreateData(NULL, prefsPrivate->prefs, kCFPropertyListXMLFormat_v1_0, 0, NULL);
996 if (xmlData != NULL) {
997 (void) write(fd, CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData));
998 CFRelease(xmlData);
999 } else {
1000 SCPrint(TRUE, stdout, CFSTR("could not write snapshot: CFPropertyListCreateData() failed\n"));
1001 }
1002
1003 (void) close(fd);
1004 } else {
1005 SCPrint(TRUE, stdout, CFSTR("prefs have not been accessed\n"));
1006 }
1007 }
1008
1009 return;
1010 }