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__ 64CF_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__ 81CFIndex 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__ 97CFIndex 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__ 120Boolean 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__ 374void 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 438static 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__ 491void 492do_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__ 505void 506do_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__ 553void 554do_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__ 567void 568do_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__ 578void 579do_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__ 593void 594do_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 611typedef void (*net_func) (int argc, char **argv); 612 613static 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 660static int 661findNetKey(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__ 679void 680do_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__ 706void 707do_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__ 733void 734do_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__ 760void 761do_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__ 787void 788do_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__ 814void 815do_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__ 836void 837do_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__ 858void 859do_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__ 969void 970do_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} 1011