2 * Copyright (c) 2003-2008, 2011-2017, 2019, 2020 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 * Modification History
27 * May 29, 2003 Allan Nathanson <ajn@apple.com>
31 #include <TargetConditionals.h>
34 #include <sys/param.h>
35 #include <sys/types.h>
42 #include "SCNetworkConfigurationInternal.h"
45 #include <Security/Authorization.h>
46 #endif /* !TARGET_OS_IPHONE */
49 /* -------------------- */
54 __loadSecurity(void) {
55 static void *image
= NULL
;
56 static dispatch_once_t once
;
58 dispatch_once(&once
, ^{
59 image
= _SC_dlopen("/System/Library/Frameworks/Security.framework/Security");
67 _AuthorizationCreate(const AuthorizationRights
*rights
, const AuthorizationEnvironment
*environment
, AuthorizationFlags flags
, AuthorizationRef
*authorization
)
69 #undef AuthorizationCreate
70 static typeof (AuthorizationCreate
) *dyfunc
= NULL
;
72 void *image
= __loadSecurity();
73 if (image
) dyfunc
= dlsym(image
, "AuthorizationCreate");
75 return dyfunc
? dyfunc(rights
, environment
, flags
, authorization
) : -1;
77 #define AuthorizationCreate _AuthorizationCreate
81 _AuthorizationFree(AuthorizationRef authorization
, AuthorizationFlags flags
)
83 #undef AuthorizationFree
84 static typeof (AuthorizationFree
) *dyfunc
= NULL
;
86 void *image
= __loadSecurity();
87 if (image
) dyfunc
= dlsym(image
, "AuthorizationFree");
89 return dyfunc
? dyfunc(authorization
, flags
) : -1;
91 #define AuthorizationFree _AuthorizationFree
94 /* -------------------- */
98 _prefs_AuthorizationCreate()
100 AuthorizationRef authorization
= NULL
;
102 if (getenv("SCPREFERENCES_USE_ENTITLEMENTS") != NULL
) {
103 authorization
= kSCPreferencesUseEntitlementAuthorization
;
105 AuthorizationFlags flags
= kAuthorizationFlagDefaults
;
108 status
= AuthorizationCreate(NULL
,
109 kAuthorizationEmptyEnvironment
,
112 if (status
!= errAuthorizationSuccess
) {
115 CFSTR("AuthorizationCreate() failed: status = %d\n"),
121 return authorization
;
127 _prefs_AuthorizationFree(AuthorizationRef authorization
)
129 if (authorization
!= kSCPreferencesUseEntitlementAuthorization
) {
130 AuthorizationFree(authorization
, kAuthorizationFlagDefaults
);
131 // AuthorizationFree(authorization, kAuthorizationFlagDestroyRights);
137 #endif /* !TARGET_OS_IPHONE */
139 /* -------------------- */
142 __private_extern__ Boolean _prefs_changed
= FALSE
;
147 _prefs_open(CFStringRef name
, const char *path
)
150 CFMutableDictionaryRef options
= NULL
;
151 CFStringRef prefsID
= NULL
;
152 Boolean useHelper
= FALSE
;
153 Boolean useOptions
= FALSE
;
155 authorization
= NULL
;
157 if (geteuid() != 0) {
158 // if we need to use a helper
161 #if !TARGET_OS_IPHONE
162 authorization
= _prefs_AuthorizationCreate();
164 authorization
= kSCPreferencesUseEntitlementAuthorization
;
165 #endif /* !TARGET_OS_IPHONE */
168 if (getenv("SCPREFERENCES_REMOVE_WHEN_EMPTY") != NULL
) {
169 if (options
== NULL
) {
170 options
= CFDictionaryCreateMutable(NULL
,
172 &kCFTypeDictionaryKeyCallBacks
,
173 &kCFTypeDictionaryValueCallBacks
);
176 CFDictionarySetValue(options
, kSCPreferencesOptionRemoveWhenEmpty
, kCFBooleanTrue
);
179 env
= getenv("SCPREFERENCES_PROTECTION_CLASS");
183 if (options
== NULL
) {
184 options
= CFDictionaryCreateMutable(NULL
,
186 &kCFTypeDictionaryKeyCallBacks
,
187 &kCFTypeDictionaryValueCallBacks
);
190 str
= CFStringCreateWithCString(NULL
, env
, kCFStringEncodingASCII
);
191 CFDictionarySetValue(options
, kSCPreferencesOptionProtectionClass
, str
);
196 prefsPath
= strdup(path
);
197 prefsID
= CFStringCreateWithCString(NULL
, path
, kCFStringEncodingUTF8
);
200 if (!useHelper
&& !useOptions
) {
201 // if no helper/options needed
202 prefs
= SCPreferencesCreate(NULL
, name
, prefsID
);
203 } else if (!useOptions
) {
204 // if no options needed
205 prefs
= SCPreferencesCreateWithAuthorization(NULL
, name
, prefsID
, authorization
);
207 prefs
= SCPreferencesCreateWithOptions(NULL
, name
, prefsID
, authorization
, options
);
211 if (prefsID
!= NULL
) CFRelease(prefsID
);
213 if (prefsPath
!= NULL
) free(prefsPath
);
218 _prefs_changed
= FALSE
;
227 if (!SCPreferencesCommitChanges(prefs
)) {
229 case kSCStatusAccessError
:
230 SCPrint(TRUE
, stderr
, CFSTR("Permission denied.\n"));
235 CFSTR("SCPreferencesCommitChanges() failed: %s\n"),
236 SCErrorString(SCError()));
242 if (!SCPreferencesApplyChanges(prefs
)) {
245 CFSTR("SCPreferencesApplyChanges() failed: %s\n"),
246 SCErrorString(SCError()));
250 _prefs_changed
= FALSE
;
252 if (ni_prefs
!= NULL
) {
253 if (!SCPreferencesCommitChanges(ni_prefs
)) {
255 case kSCStatusAccessError
:
256 SCPrint(TRUE
, stderr
, CFSTR("Permission denied.\n"));
261 CFSTR("SCPreferencesCommitChanges( <NetworkInterfaces.plist> ) failed: %s\n"),
262 SCErrorString(SCError()));
268 if (!SCPreferencesApplyChanges(ni_prefs
)) {
271 CFSTR("SCPreferencesApplyChanges( <NetworkInterfaces.plist> ) failed: %s\n"),
272 SCErrorString(SCError()));
285 if (prefsPath
!= NULL
) {
293 _prefs_changed
= FALSE
;
296 if (ni_prefs
!= NULL
) {
301 if (authorization
!= NULL
) {
302 #if !TARGET_OS_IPHONE
303 _prefs_AuthorizationFree(authorization
);
304 #else /* !TARGET_OS_IPHONE */
305 // Uh...if authorization isn't NULL, something went horribly wrong.
306 #endif /* !TARGET_OS_IPHONE */
307 authorization
= NULL
;
316 _prefs_commitRequired(int argc
, char **argv
, const char *command
)
318 if (_prefs_changed
) {
319 if ((currentInput
!= NULL
) &&
320 isatty(fileno(currentInput
->fp
)) &&
321 ((argc
< 1) || (strcmp(argv
[0], "!") != 0))
323 SCPrint(TRUE
, stdout
,
324 CFSTR("preference changes have not been committed\n"
325 "use \"commit\" to save changes"));
326 if (command
!= NULL
) {
327 SCPrint(TRUE
, stdout
,
328 CFSTR(" or \"%s !\" to abandon changes"),
331 SCPrint(TRUE
, stdout
, CFSTR("\n"));
335 SCPrint(TRUE
, stdout
, CFSTR("preference changes abandoned\n"));
342 /* -------------------- */
346 get_ComputerName(int argc
, char **argv
)
350 CFStringEncoding encoding
;
351 CFStringRef hostname
;
353 hostname
= SCDynamicStoreCopyComputerName(NULL
, &encoding
);
354 if (hostname
== NULL
) {
355 int sc_status
= SCError();
358 case kSCStatusNoKey
:
361 CFSTR("ComputerName: not set\n"));
366 CFSTR("SCDynamicStoreCopyComputerName() failed: %s\n"),
367 SCErrorString(SCError()));
373 SCPrint(TRUE
, stdout
, CFSTR("%@\n"), hostname
);
381 set_ComputerName(int argc
, char **argv
)
383 CFStringRef hostname
= NULL
;
386 ok
= _prefs_open(CFSTR("scutil --set ComputerName"), NULL
);
390 CFSTR("Could not open prefs: %s\n"),
391 SCErrorString(SCError()));
396 CFStringEncoding old_encoding
;
397 CFStringRef old_hostname
;
399 old_hostname
= SCDynamicStoreCopyComputerName(NULL
, &old_encoding
);
400 hostname
= _copyStringFromSTDIN(CFSTR("ComputerName"), old_hostname
);
401 if (old_hostname
) CFRelease(old_hostname
);
402 } else if (strlen(argv
[0]) > 0) {
403 hostname
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
406 ok
= SCPreferencesSetComputerName(prefs
, hostname
, kCFStringEncodingUTF8
);
407 if (hostname
!= NULL
) CFRelease(hostname
);
411 CFSTR("Could not open prefs: %s\n"),
412 SCErrorString(SCError()));
424 get_HostName(int argc
, char **argv
)
428 CFStringRef hostname
;
431 ok
= _prefs_open(CFSTR("scutil --get HostName"), NULL
);
435 CFSTR("SCPreferencesCreate() failed: %s\n"),
436 SCErrorString(SCError()));
440 hostname
= SCPreferencesGetHostName(prefs
);
441 if (hostname
== NULL
) {
442 int sc_status
= SCError();
445 case kSCStatusNoKey
:
448 CFSTR("HostName: not set\n"));
453 CFSTR("SCPreferencesGetHostName() failed: %s\n"),
454 SCErrorString(SCError()));
461 SCPrint(TRUE
, stdout
, CFSTR("%@\n"), hostname
);
468 set_HostName(int argc
, char **argv
)
470 CFStringRef hostname
= NULL
;
473 ok
= _prefs_open(CFSTR("scutil --set HostName"), NULL
);
477 CFSTR("Could not open prefs: %s\n"),
478 SCErrorString(SCError()));
483 hostname
= _copyStringFromSTDIN(CFSTR("HostName"), SCPreferencesGetHostName(prefs
));
484 } else if (strlen(argv
[0]) > 0) {
485 hostname
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
488 ok
= SCPreferencesSetHostName(prefs
, hostname
);
489 if (hostname
!= NULL
) CFRelease(hostname
);
493 CFSTR("SCPreferencesSetHostName() failed: %s\n"),
494 SCErrorString(SCError()));
506 get_LocalHostName(int argc
, char **argv
)
510 CFStringRef hostname
;
512 hostname
= SCDynamicStoreCopyLocalHostName(NULL
);
513 if (hostname
== NULL
) {
514 int sc_status
= SCError();
517 case kSCStatusNoKey
:
520 CFSTR("LocalHostName: not set\n"));
525 CFSTR("SCDynamicStoreCopyLocalHostName() failed: %s\n"),
526 SCErrorString(SCError()));
532 SCPrint(TRUE
, stdout
, CFSTR("%@\n"), hostname
);
540 set_LocalHostName(int argc
, char **argv
)
542 CFStringRef hostname
= NULL
;
545 ok
= _prefs_open(CFSTR("scutil --set LocalHostName"), NULL
);
549 CFSTR("Could not open prefs: %s\n"),
550 SCErrorString(SCError()));
555 CFStringRef old_hostname
;
557 old_hostname
= SCDynamicStoreCopyLocalHostName(NULL
);
558 hostname
= _copyStringFromSTDIN(CFSTR("LocalHostName"), old_hostname
);
559 if (old_hostname
) CFRelease(old_hostname
);
560 } else if (strlen(argv
[0]) > 0) {
561 hostname
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
564 ok
= SCPreferencesSetLocalHostName(prefs
, hostname
);
565 if (hostname
!= NULL
) CFRelease(hostname
);
569 CFSTR("SCPreferencesSetLocalHostName() failed: %s\n"),
570 SCErrorString(SCError()));
581 /* -------------------- */
584 typedef void (*pref_func
) (int argc
, char **argv
);
586 static const struct {
591 { "ComputerName", get_ComputerName
, set_ComputerName
},
592 { "HostName", get_HostName
, set_HostName
},
593 { "LocalHostName", get_LocalHostName
, set_LocalHostName
}
595 #define N_PREF_KEYS (sizeof(pref_keys) / sizeof(pref_keys[0]))
604 for (i
= 0; i
< (int)N_PREF_KEYS
; i
++) {
605 if (strcmp(pref
, pref_keys
[i
].pref
) == 0) {
616 do_getPref(char *pref
, int argc
, char **argv
)
623 (*pref_keys
[i
].get
)(argc
, argv
);
628 // process extended get
629 // ie. scutil --get <filename> <prefs path> <key>
632 do_prefs_open(argc
, argv
);
633 if (SCError() != kSCStatusOK
) {
634 SCPrint(TRUE
, stderr
, CFSTR("%s\n"), SCErrorString(SCError()));
639 do_prefs_get(--argc
, ++argv
);
642 CFStringRef prefs_val
;
644 key
= CFStringCreateWithCString(NULL
, *(++argv
), kCFStringEncodingUTF8
);
645 prefs_val
= CFDictionaryGetValue(value
, key
);
648 if (prefs_val
!= NULL
) {
649 SCPrint(TRUE
, stdout
, CFSTR("%@\n"), prefs_val
);
655 // if path or key not found
663 do_setPref(char *pref
, int argc
, char **argv
)
669 (*pref_keys
[i
].set
)(argc
, argv
);
675 /* -------------------- */
688 do_prefs_open(int argc
, char **argv
)
693 if (_prefs_commitRequired(argc
, argv
, "close")) {
697 do_prefs_close(0, NULL
);
700 ok
= _prefs_open(CFSTR("scutil --prefs"), (argc
> 0) ? argv
[0] : NULL
);
704 CFSTR("Could not open prefs: %s\n"),
705 SCErrorString(SCError()));
715 do_prefs_lock(int argc
, char **argv
)
718 Boolean wait
= (argc
> 0) ? TRUE
: FALSE
;
720 if (!SCPreferencesLock(prefs
, wait
)) {
721 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
731 do_prefs_unlock(int argc
, char **argv
)
735 if (!SCPreferencesUnlock(prefs
)) {
736 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
746 do_prefs_commit(int argc
, char **argv
)
750 if (!SCPreferencesCommitChanges(prefs
)) {
751 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
755 _prefs_changed
= FALSE
;
762 do_prefs_apply(int argc
, char **argv
)
766 if (!SCPreferencesApplyChanges(prefs
)) {
767 SCPrint(TRUE
, stdout
, CFSTR("%s\n"), SCErrorString(SCError()));
776 do_prefs_close(int argc
, char **argv
)
778 if (_prefs_commitRequired(argc
, argv
, "close")) {
789 do_prefs_quit(int argc
, char **argv
)
791 if (_prefs_commitRequired(argc
, argv
, "quit")) {
797 termRequested
= TRUE
;
804 do_prefs_synchronize(int argc
, char **argv
)
808 SCPreferencesSynchronize(prefs
);
809 if (ni_prefs
!= NULL
) {
810 SCPreferencesSynchronize(ni_prefs
);
817 static CFComparisonResult
818 sort_paths(const void *p1
, const void *p2
, void *context
)
820 #pragma unused(context)
821 CFStringRef path1
= (CFStringRef
)p1
;
822 CFStringRef path2
= (CFStringRef
)p2
;
823 return CFStringCompare(path1
, path2
, 0);
829 do_prefs_list(int argc
, char **argv
)
833 CFMutableArrayRef paths
= NULL
;
835 CFDictionaryRef entity
;
837 prefix
= CFStringCreateWithCString(NULL
,
838 (argc
>= 1) ? argv
[0] : "/",
839 kCFStringEncodingUTF8
);
841 entity
= SCPreferencesPathGetValue(prefs
, prefix
);
842 if (entity
== NULL
) {
843 SCPrint(TRUE
, stdout
, CFSTR(" %s\n"), SCErrorString(SCError()));
847 paths
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
849 n
= isA_CFDictionary(entity
) ? CFDictionaryGetCount(entity
) : 0;
855 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFStringRef
), 0);
856 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFPropertyListRef
), 0);
857 CFDictionaryGetKeysAndValues(entity
, keys
, vals
);
858 for (i
= 0; i
< n
; i
++) {
859 if (isA_CFDictionary(vals
[i
])) {
860 CFArrayAppendValue(paths
, keys
[i
]);
863 CFAllocatorDeallocate(NULL
, keys
);
864 CFAllocatorDeallocate(NULL
, vals
);
867 n
= CFArrayGetCount(paths
);
868 CFArraySortValues(paths
,
874 for (i
= 0; i
< n
; i
++) {
877 CFSTR(" path [%d] = %@/%@\n"),
879 CFEqual(prefix
, CFSTR("/")) ? CFSTR("") : prefix
,
880 CFArrayGetValueAtIndex(paths
, i
));
883 SCPrint(TRUE
, stdout
, CFSTR(" no paths.\n"));
897 do_prefs_get(int argc
, char **argv
)
900 CFDictionaryRef dict
;
903 CFMutableDictionaryRef newDict
;
906 path
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
908 link
= SCPreferencesPathGetLink(prefs
, path
);
910 SCPrint(TRUE
, stdout
, CFSTR(" --> %@\n"), link
);
913 dict
= SCPreferencesPathGetValue(prefs
, path
);
916 SCPrint(TRUE
, stdout
, CFSTR(" %s\n"), SCErrorString(SCError()));
920 newDict
= CFDictionaryCreateMutable(NULL
,
922 &kCFTypeDictionaryKeyCallBacks
,
923 &kCFTypeDictionaryValueCallBacks
);
925 // remove [path] children
926 n
= isA_CFDictionary(dict
) ? CFDictionaryGetCount(dict
) : 0;
932 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFStringRef
), 0);
933 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFPropertyListRef
), 0);
934 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
935 for (i
= 0; i
< n
; i
++) {
936 if (!isA_CFDictionary(vals
[i
])) {
937 CFDictionaryAddValue(newDict
, keys
[i
], vals
[i
]);
940 CFAllocatorDeallocate(NULL
, keys
);
941 CFAllocatorDeallocate(NULL
, vals
);
945 CFRelease(value
); /* we have new information, release the old */
956 do_prefs_set(int argc
, char **argv
)
958 CFDictionaryRef dict
;
959 CFMutableDictionaryRef newDict
= NULL
;
962 path
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
963 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, value
);
965 dict
= SCPreferencesPathGetValue(prefs
, path
);
969 // retain [path] children
970 n
= CFDictionaryGetCount(dict
);
976 keys
= CFAllocatorAllocate(NULL
, n
* sizeof(CFStringRef
), 0);
977 vals
= CFAllocatorAllocate(NULL
, n
* sizeof(CFPropertyListRef
), 0);
978 CFDictionaryGetKeysAndValues(dict
, keys
, vals
);
979 for (i
= 0; i
< n
; i
++) {
980 if (isA_CFDictionary(vals
[i
])) {
981 if (CFDictionaryContainsKey(newDict
, keys
[i
])) {
982 SCPrint(TRUE
, stdout
, CFSTR(" key %@ is already a path component and cannot be replaced\n"), keys
[i
]);
985 CFDictionaryAddValue(newDict
, keys
[i
], vals
[i
]);
988 CFAllocatorDeallocate(NULL
, keys
);
989 CFAllocatorDeallocate(NULL
, vals
);
991 } else if (SCError() == kSCStatusInvalidArgument
) {
992 SCPrint(TRUE
, stdout
, CFSTR(" a path component is not a dictionary\n"));
994 } else if (SCError() != kSCStatusNoKey
) {
995 SCPrint(TRUE
, stdout
, CFSTR(" %s\n"), SCErrorString(SCError()));
1004 link
= CFStringCreateWithCString(NULL
, argv
[1], kCFStringEncodingUTF8
);
1005 ok
= SCPreferencesPathSetLink(prefs
, path
, link
);
1008 SCPrint(TRUE
, stdout
, CFSTR(" %s\n"), SCErrorString(SCError()));
1013 if (!SCPreferencesPathSetValue(prefs
, path
, newDict
)) {
1014 SCPrint(TRUE
, stdout
, CFSTR(" %s\n"), SCErrorString(SCError()));
1019 _prefs_changed
= TRUE
;
1031 do_prefs_remove(int argc
, char **argv
)
1033 #pragma unused(argc)
1036 path
= CFStringCreateWithCString(NULL
, argv
[0], kCFStringEncodingUTF8
);
1038 if (!SCPreferencesPathRemoveValue(prefs
, path
)) {
1039 SCPrint(TRUE
, stdout
, CFSTR(" %s\n"), SCErrorString(SCError()));
1043 _prefs_changed
= TRUE
;
1052 on_off_str(Boolean on
)
1054 return (on
? "on" : "off");
1057 /* -------------------- */
1059 #if !TARGET_OS_IPHONE
1061 #include "InterfaceNamerControlPrefs.h"
1064 allow_new_interfaces_usage(void)
1066 fprintf(stderr
, "usage: scutil --allow-new-interfaces [on|off|default]\n");
1072 do_ifnamer(char * pref
, int argc
, char **argv
)
1074 Boolean allow
= FALSE
;
1077 allow_new_interfaces_usage();
1081 if (strcmp(pref
, "allow-new-interfaces")) {
1086 SCPrint(TRUE
, stdout
, CFSTR("AllowNewInterfaces is %s\n"),
1087 on_off_str(InterfaceNamerControlPrefsAllowNewInterfaces()));
1091 if ((strcasecmp(argv
[0], "disable") == 0) ||
1092 (strcasecmp(argv
[0], "no" ) == 0) ||
1093 (strcasecmp(argv
[0], "off" ) == 0) ||
1094 (strcasecmp(argv
[0], "0" ) == 0)) {
1096 } else if ((strcasecmp(argv
[0], "enable") == 0) ||
1097 (strcasecmp(argv
[0], "yes" ) == 0) ||
1098 (strcasecmp(argv
[0], "on" ) == 0) ||
1099 (strcasecmp(argv
[0], "1" ) == 0)) {
1101 } else if (strcasecmp(argv
[0], "default") == 0) {
1104 allow_new_interfaces_usage();
1108 if (!InterfaceNamerControlPrefsSetAllowNewInterfaces(allow
)) {
1109 SCPrint(TRUE
, stderr
, CFSTR("failed to set preferences\n"));
1117 #endif // !TARGET_OS_IPHONE
1119 /* -------------------- */
1121 #include "IPMonitorControlPrefs.h"
1125 do_log(char * log
, int argc
, char **argv
)
1127 Boolean verbose
= FALSE
;
1129 if (strcmp(log
, "IPMonitor")) {
1134 SCPrint(TRUE
, stdout
, CFSTR("IPMonitor log is %s\n"),
1135 on_off_str(IPMonitorControlPrefsIsVerbose()));
1139 if ((strcasecmp(argv
[0], "disable") == 0) ||
1140 (strcasecmp(argv
[0], "no" ) == 0) ||
1141 (strcasecmp(argv
[0], "off" ) == 0) ||
1142 (strcasecmp(argv
[0], "0" ) == 0)) {
1144 } else if ((strcasecmp(argv
[0], "enable") == 0) ||
1145 (strcasecmp(argv
[0], "yes" ) == 0) ||
1146 (strcasecmp(argv
[0], "on" ) == 0) ||
1147 (strcasecmp(argv
[0], "1" ) == 0)) {
1150 SCPrint(TRUE
, stdout
, CFSTR("invalid value, must be 'on' or 'off'\n"));
1154 if (!IPMonitorControlPrefsSetVerbose(verbose
)) {
1155 SCPrint(TRUE
, stderr
, CFSTR("failed to set preferences\n"));
1164 /* -------------------- */
1166 static SCNetworkInterfaceRef
1167 copy_configured_interface(SCPreferencesRef prefs
, CFStringRef if_name
)
1169 SCNetworkSetRef current_set
= NULL
;
1172 SCNetworkInterfaceRef ret_if
= NULL
;
1173 CFArrayRef services
= NULL
;
1175 if (prefs
== NULL
) {
1178 current_set
= SCNetworkSetCopyCurrent(prefs
);
1179 if (current_set
== NULL
) {
1182 services
= SCNetworkSetCopyServices(current_set
);
1183 if (services
== NULL
) {
1187 count
= CFArrayGetCount(services
);
1188 for (i
= 0; i
< count
; i
++) {
1189 CFStringRef this_if_name
;
1190 SCNetworkInterfaceRef this_if
;
1191 SCNetworkServiceRef s
;
1193 s
= (SCNetworkServiceRef
)CFArrayGetValueAtIndex(services
, i
);
1194 if (!SCNetworkServiceGetEnabled(s
)) {
1195 /* skip disabled services */
1198 this_if
= SCNetworkServiceGetInterface(s
);
1199 if (this_if
== NULL
) {
1202 this_if_name
= SCNetworkInterfaceGetBSDName(this_if
);
1203 if (this_if_name
== NULL
) {
1206 if (CFEqual(this_if_name
, if_name
)) {
1214 if (current_set
!= NULL
) {
1215 CFRelease(current_set
);
1217 if (services
!= NULL
) {
1218 CFRelease(services
);
1224 disable_until_needed_usage(void)
1226 fprintf(stderr
, "usage: scutil --disable-until-needed <interfaceName> [on|off|default]\n");
1230 #include <SystemConfiguration/SCNetworkConfigurationPrivate.h>
1234 do_disable_until_needed(int argc
, char **argv
)
1236 const char * if_name
;
1237 CFStringRef if_name_cf
;
1238 SCNetworkInterfaceRef net_if
;
1240 const char * on_off
= "?";
1242 Boolean set_default
= FALSE
;
1243 Boolean set_value
= FALSE
;
1245 if (argc
< 1 || argc
> 2) {
1246 disable_until_needed_usage();
1252 if (strcasecmp(on_off
, "on") == 0) {
1254 } else if (strcasecmp(on_off
, "off") == 0) {
1256 } else if ((strcmp(on_off
, "") == 0) || (strcasecmp(on_off
, "default") == 0)) {
1260 disable_until_needed_usage();
1265 ok
= _prefs_open(CFSTR("scutil --disable-until-needed"), NULL
);
1269 CFSTR("Could not open prefs: %s\n"),
1270 SCErrorString(SCError()));
1273 if_name_cf
= CFStringCreateWithCStringNoCopy(NULL
,
1275 kCFStringEncodingASCII
,
1277 net_if
= copy_configured_interface(prefs
, if_name_cf
);
1278 if (net_if
== NULL
) {
1279 fprintf(stderr
, "%s is not configured\n", if_name
);
1284 ok
= SCNetworkInterfaceSetDisableUntilNeeded(net_if
, on
);
1286 ok
= __SCNetworkInterfaceSetDisableUntilNeededValue(net_if
, NULL
);
1289 fprintf(stderr
, "failed to turn disable-until-needed %s\n",
1295 on
= SCNetworkInterfaceGetDisableUntilNeeded(net_if
);
1296 printf("%s disable-until-needed is %s\n", if_name
, on_off_str(on
));