2 * Copyright (c) 2006-2014 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 * June 26, 2006 Allan Nathanson <ajn@apple.com>
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
38 #include <sys/sysctl.h>
41 #include <net/if_dl.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h>
44 #include <netdb_async.h>
46 #include <smb_server_prefs.h>
48 #include <CoreFoundation/CoreFoundation.h>
49 #include <CoreFoundation/CFStringDefaultEncoding.h> // for __CFStringGetInstallationEncodingAndRegion()
50 #include <SystemConfiguration/SystemConfiguration.h>
51 #include <SystemConfiguration/SCValidation.h>
52 #include <SystemConfiguration/SCPrivate.h> // for SCLog(), SCPrint()
55 #define my_log(__level, fmt, ...) SCPrint(TRUE, stdout, CFSTR(fmt "\n"), ## __VA_ARGS__)
57 #include "ip_plugin.h"
60 #define HW_MODEL_LEN 64 // Note: must be >= NETBIOS_NAME_LEN (below)
62 #define NETBIOS_NAME_LEN 16
64 #define SMB_STARTUP_DELAY 60.0
65 #define SMB_DEBOUNCE_DELAY 5.0
67 static SCDynamicStoreRef store
= NULL
;
68 static CFRunLoopSourceRef rls
= NULL
;
70 static struct timeval ptrQueryStart
;
71 static SCNetworkReachabilityRef ptrTarget
= NULL
;
73 static CFRunLoopTimerRef timer
= NULL
;
75 static Boolean _verbose
= FALSE
;
81 static CFAbsoluteTime bt
= 0;
84 int mib
[2] = { CTL_KERN
, KERN_BOOTTIME
};
86 size_t tv_len
= sizeof(tv
);
88 if (sysctl(mib
, sizeof(mib
) / sizeof(mib
[0]), &tv
, &tv_len
, NULL
, 0) == -1) {
89 my_log(LOG_ERR
, "sysctl() CTL_KERN/KERN_BOOTTIME failed: %s", strerror(errno
));
90 return kCFAbsoluteTimeIntervalSince1970
;
93 // Note: we need to convert from Unix time to CF time.
94 bt
= (CFTimeInterval
)tv
.tv_sec
- kCFAbsoluteTimeIntervalSince1970
;
95 bt
+= (1.0E-6 * (CFTimeInterval
)tv
.tv_usec
);
103 copy_default_name(void)
107 CFMutableStringRef str
;
110 model
= _SC_hw_model(TRUE
);
115 // start off with the [trunated] HW model
116 str
= CFStringCreateMutable(NULL
, 0);
117 CFStringAppend(str
, model
);
119 // truncate as needed
120 n
= CFStringGetLength(str
);
121 if (n
> (NETBIOS_NAME_LEN
- 1)) {
123 CFRangeMake(NETBIOS_NAME_LEN
, n
- (NETBIOS_NAME_LEN
- 1)),
125 n
= NETBIOS_NAME_LEN
- 1;
129 // if there is room for at least one byte (two hex characters)
130 // of the MAC address than append that to the NetBIOS name.
132 // NETBIOS_NAME_LEN max length
133 // -1 the last byte is reserved
136 if (n
< (NETBIOS_NAME_LEN
- 1 - 3)) {
137 SCNetworkInterfaceRef interface
;
139 interface
= _SCNetworkInterfaceCreateWithBSDName(NULL
, CFSTR("en0"),
140 kIncludeNoVirtualInterfaces
);
141 if (interface
!= NULL
) {
142 CFMutableStringRef en0_MAC
;
144 en0_MAC
= (CFMutableStringRef
)SCNetworkInterfaceGetHardwareAddressString(interface
);
145 if (en0_MAC
!= NULL
) {
148 // remove ":" characters from MAC address string
149 en0_MAC
= CFStringCreateMutableCopy(NULL
, 0, en0_MAC
);
150 CFStringFindAndReplace(en0_MAC
,
153 CFRangeMake(0, CFStringGetLength(en0_MAC
)),
157 // compute how may bytes (characters) to append
158 // ... and limit that number to 6
160 // NETBIOS_NAME_LEN max length
161 // -1 the last byte is reserved
165 n
= ((NETBIOS_NAME_LEN
- 1 - n
- 1) / 2) * 2;
170 // remove what we don't want
171 en0_MAC_len
= CFStringGetLength(en0_MAC
);
172 if (en0_MAC_len
> n
) {
173 CFStringDelete(en0_MAC
, CFRangeMake(0, en0_MAC_len
- n
));
177 CFStringAppendFormat(str
, NULL
, CFSTR("-%@"), en0_MAC
);
181 CFRelease(interface
);
185 CFStringUppercase(str
, NULL
);
190 static CFDictionaryRef
191 smb_copy_global_configuration(SCDynamicStoreRef store
)
193 CFDictionaryRef dict
;
196 key
= SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL
,
197 kSCDynamicStoreDomainState
,
199 dict
= SCDynamicStoreCopyValue(store
, key
);
203 if (isA_CFDictionary(dict
)) {
210 dict
= CFDictionaryCreate(NULL
, // allocator
214 &kCFTypeDictionaryKeyCallBacks
,
215 &kCFTypeDictionaryValueCallBacks
);
221 update_pref(SCPreferencesRef prefs
, CFStringRef key
, CFTypeRef newVal
, Boolean
*changed
)
225 curVal
= SCPreferencesGetValue(prefs
, key
);
226 if (!_SC_CFEqual(curVal
, newVal
)) {
227 if (newVal
!= NULL
) {
228 SCPreferencesSetValue(prefs
, key
, newVal
);
230 SCPreferencesRemoveValue(prefs
, key
);
241 smb_set_configuration(SCDynamicStoreRef store
, CFDictionaryRef dict
)
244 Boolean changed
= FALSE
;
245 UInt32 dosCodepage
= 0;
246 CFStringEncoding dosEncoding
= 0;
247 CFStringEncoding macEncoding
= kCFStringEncodingMacRoman
;
248 uint32_t macRegion
= 0;
250 SCPreferencesRef prefs
;
253 prefs
= SCPreferencesCreate(NULL
, CFSTR("smb-configuration"), CFSTR(kSMBPreferencesAppID
));
256 "smb_set_configuration: SCPreferencesCreate() failed: %s",
257 SCErrorString(SCError()));
261 ok
= SCPreferencesLock(prefs
, TRUE
);
264 "smb_set_configuration: SCPreferencesLock() failed: %s",
265 SCErrorString(SCError()));
269 // Server description
270 str
= SCDynamicStoreCopyComputerName(store
, &macEncoding
);
271 update_pref(prefs
, CFSTR(kSMBPrefServerDescription
), str
, &changed
);
275 if (macEncoding
== kCFStringEncodingMacRoman
) {
277 CFDictionaryRef dict
;
280 key
= SCDynamicStoreKeyCreateComputerName(NULL
);
281 dict
= SCDynamicStoreCopyValue(store
, key
);
284 if (isA_CFDictionary(dict
)) {
288 num
= CFDictionaryGetValue(dict
, kSCPropSystemComputerNameRegion
);
289 if (isA_CFNumber(num
) &&
290 CFNumberGetValue(num
, kCFNumberSInt32Type
, &val
)) {
291 macRegion
= (uint32_t)val
;
301 // Important: must have root acccess (eUID==0) to access the config file!
302 __CFStringGetInstallationEncodingAndRegion((uint32_t *)&macEncoding
, &macRegion
);
304 _SC_dos_encoding_and_codepage(macEncoding
, macRegion
, &dosEncoding
, &dosCodepage
);
305 str
= CFStringCreateWithFormat(NULL
, NULL
, CFSTR("%d"), (unsigned int)dosCodepage
);
307 update_pref(prefs
, CFSTR(kSMBPrefDOSCodePage
), str
, &changed
);
311 str
= CFDictionaryGetValue(dict
, kSCPropNetSMBNetBIOSName
);
312 str
= isA_CFString(str
);
313 update_pref(prefs
, CFSTR(kSMBPrefNetBIOSName
), str
, &changed
);
316 str
= CFDictionaryGetValue(dict
, kSCPropNetSMBNetBIOSNodeType
);
317 str
= isA_CFString(str
);
319 if (CFEqual(str
, kSCValNetSMBNetBIOSNodeTypeBroadcast
)) {
321 str
= CFSTR(kSMBPrefNetBIOSNodeBroadcast
);
322 } else if (CFEqual(str
, kSCValNetSMBNetBIOSNodeTypePeer
)) {
324 str
= CFSTR(kSMBPrefNetBIOSNodePeer
);
325 } else if (CFEqual(str
, kSCValNetSMBNetBIOSNodeTypeMixed
)) {
327 str
= CFSTR(kSMBPrefNetBIOSNodeMixed
);
328 } else if (CFEqual(str
, kSCValNetSMBNetBIOSNodeTypeHybrid
)) {
330 str
= CFSTR(kSMBPrefNetBIOSNodeHybrid
);
335 update_pref(prefs
, CFSTR(kSMBPrefNetBIOSNodeType
), str
, &changed
);
337 #ifdef ADD_NETBIOS_SCOPE
339 str
= CFDictionaryGetValue(dict
, kSCPropNetSMBNetBIOSScope
);
340 str
= isA_CFString(str
);
341 update_pref(prefs
, CFSTR(kSMBPrefNetBIOSScope
), str
, &changed
);
342 #endif // ADD_NETBIOS_SCOPE
345 array
= CFDictionaryGetValue(dict
, kSCPropNetSMBWINSAddresses
);
346 array
= isA_CFArray(array
);
347 update_pref(prefs
, CFSTR(kSMBPrefWINSServerAddressList
), array
, &changed
);
349 // Workgroup (or domain)
350 str
= CFDictionaryGetValue(dict
, kSCPropNetSMBWorkgroup
);
351 str
= isA_CFString(str
);
352 update_pref(prefs
, CFSTR(kSMBPrefWorkgroup
), str
, &changed
);
355 ok
= SCPreferencesCommitChanges(prefs
);
357 if ((SCError() != EROFS
)) {
359 "smb_set_configuration: SCPreferencesCommitChanges() failed: %s",
360 SCErrorString(SCError()));
365 ok
= SCPreferencesApplyChanges(prefs
);
368 "smb_set_configuration: SCPreferencesApplyChanges() failed: %s",
369 SCErrorString(SCError()));
376 (void) SCPreferencesUnlock(prefs
);
383 copy_primary_service(SCDynamicStoreRef store
)
385 CFDictionaryRef dict
;
387 CFStringRef serviceID
= NULL
;
389 key
= SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL
,
390 kSCDynamicStoreDomainState
,
392 dict
= SCDynamicStoreCopyValue(store
, key
);
396 if (isA_CFDictionary(dict
)) {
397 serviceID
= CFDictionaryGetValue(dict
, kSCDynamicStorePropNetPrimaryService
);
398 if (isA_CFString(serviceID
)) {
412 copy_primary_ip(SCDynamicStoreRef store
, CFStringRef serviceID
)
414 CFStringRef address
= NULL
;
415 CFDictionaryRef dict
;
418 key
= SCDynamicStoreKeyCreateNetworkServiceEntity(NULL
,
419 kSCDynamicStoreDomainState
,
422 dict
= SCDynamicStoreCopyValue(store
, key
);
426 if (isA_CFDictionary(dict
)) {
427 CFArrayRef addresses
;
429 addresses
= CFDictionaryGetValue(dict
, kSCPropNetIPv4Addresses
);
430 if (isA_CFArray(addresses
) && (CFArrayGetCount(addresses
) > 0)) {
431 address
= CFArrayGetValueAtIndex(addresses
, 0);
432 if (isA_CFString(address
)) {
449 if (ptrTarget
== NULL
) {
453 SCNetworkReachabilitySetCallback(ptrTarget
, NULL
, NULL
);
454 SCNetworkReachabilityUnscheduleFromRunLoop(ptrTarget
, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode
);
455 CFRelease(ptrTarget
);
463 ptr_query_callback(SCNetworkReachabilityRef target
, SCNetworkReachabilityFlags flags
, void *info
)
465 CFDictionaryRef dict
;
467 CFMutableDictionaryRef newDict
;
468 struct timeval ptrQueryComplete
;
469 struct timeval ptrQueryElapsed
;
471 (void) gettimeofday(&ptrQueryComplete
, NULL
);
472 timersub(&ptrQueryComplete
, &ptrQueryStart
, &ptrQueryElapsed
);
474 my_log(LOG_DEBUG
, "ptr query complete%s (query time = %ld.%3.3d)",
475 (flags
& kSCNetworkReachabilityFlagsReachable
) ? "" : ", host not found",
476 ptrQueryElapsed
.tv_sec
,
477 ptrQueryElapsed
.tv_usec
/ 1000);
480 // get network configuration
481 dict
= smb_copy_global_configuration(store
);
483 // use NetBIOS name from network configuration (if available)
484 name
= CFDictionaryGetValue(dict
, kSCPropNetSMBNetBIOSName
);
485 if ((name
!= NULL
) && _SC_CFStringIsValidNetBIOSName(name
)) {
486 my_log(LOG_DEBUG
, "NetBIOS name (network configuration) = %@", name
);
490 // use reverse DNS name, if available
493 if (flags
& kSCNetworkReachabilityFlagsReachable
) {
498 * if [reverse] DNS query was successful
500 hosts
= SCNetworkReachabilityCopyResolvedAddress(target
, &error_num
);
502 if (CFArrayGetCount(hosts
) > 0) {
504 CFMutableStringRef ptrName
;
507 name
= CFArrayGetValueAtIndex(hosts
, 0);
508 ptrName
= CFStringCreateMutableCopy(NULL
, 0, name
);
509 ptrLen
= CFStringGetLength(ptrName
);
510 if (CFStringFindWithOptions(ptrName
,
512 CFRangeMake(0, ptrLen
),
515 CFStringDelete(ptrName
,
516 CFRangeMake(range
.location
, ptrLen
- range
.location
));
524 if (_SC_CFStringIsValidNetBIOSName(name
)) {
525 my_log(LOG_DEBUG
, "NetBIOS name (reverse DNS query) = %@", name
);
531 // try local (multicast DNS) name, if available
532 name
= SCDynamicStoreCopyLocalHostName(store
);
534 if (_SC_CFStringIsValidNetBIOSName(name
)) {
535 my_log(LOG_DEBUG
, "NetBIOS name (multicast DNS) = %@", name
);
541 // use "default" name
542 name
= copy_default_name();
544 my_log(LOG_DEBUG
, "NetBIOS name (default) = %@", name
);
552 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
553 CFDictionarySetValue(newDict
, kSCPropNetSMBNetBIOSName
, name
);
560 // update SMB configuration
561 smb_set_configuration(store
, dict
);
567 CFRunLoopStop(CFRunLoopGetCurrent());
575 ptr_query_start(CFStringRef address
)
579 struct sockaddr_in sin
;
580 struct sockaddr_in6 sin6
;
584 CFMutableDictionaryRef options
;
586 if (_SC_cfstring_to_cstring(address
, buf
, sizeof(buf
), kCFStringEncodingASCII
) == NULL
) {
587 my_log(LOG_ERR
, "could not convert [primary] address string");
591 if (_SC_string_to_sockaddr(buf
, AF_UNSPEC
, (void *)&addr
, sizeof(addr
)) == NULL
) {
592 my_log(LOG_ERR
, "could not convert [primary] address");
596 options
= CFDictionaryCreateMutable(NULL
,
598 &kCFTypeDictionaryKeyCallBacks
,
599 &kCFTypeDictionaryValueCallBacks
);
600 data
= CFDataCreate(NULL
, (const UInt8
*)&addr
.sa
, addr
.sa
.sa_len
);
601 CFDictionarySetValue(options
, kSCNetworkReachabilityOptionPTRAddress
, data
);
603 ptrTarget
= SCNetworkReachabilityCreateWithOptions(NULL
, options
);
605 if (ptrTarget
== NULL
) {
606 my_log(LOG_ERR
, "could not resolve [primary] address");
610 (void) SCNetworkReachabilitySetCallback(ptrTarget
, ptr_query_callback
, NULL
);
611 (void) SCNetworkReachabilityScheduleWithRunLoop(ptrTarget
, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode
);
618 smb_update_configuration(__unused CFRunLoopTimerRef _timer
, void *info
)
620 CFStringRef address
= NULL
;
621 CFDictionaryRef dict
;
623 CFStringRef serviceID
= NULL
;
624 SCDynamicStoreRef store
= (SCDynamicStoreRef
)info
;
626 // get network configuration
627 dict
= smb_copy_global_configuration(store
);
629 // use NetBIOS name from network configuration (if available)
630 name
= CFDictionaryGetValue(dict
, kSCPropNetSMBNetBIOSName
);
631 if ((name
!= NULL
) && _SC_CFStringIsValidNetBIOSName(name
)) {
632 my_log(LOG_DEBUG
, "NetBIOS name (network configuration) = %@", name
);
636 // get primary service ID
637 serviceID
= copy_primary_service(store
);
638 if (serviceID
== NULL
) {
639 // if no primary service
643 // get DNS name associated with primary IP, if available
644 address
= copy_primary_ip(store
, serviceID
);
645 if (address
!= NULL
) {
648 // start reverse DNS query using primary IP address
649 ok
= ptr_query_start(address
);
658 // get local (multicast DNS) name, if available
660 name
= SCDynamicStoreCopyLocalHostName(store
);
662 if (_SC_CFStringIsValidNetBIOSName(name
)) {
663 CFMutableDictionaryRef newDict
;
665 my_log(LOG_DEBUG
, "NetBIOS name (multicast DNS) = %@", name
);
666 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
667 CFDictionarySetValue(newDict
, kSCPropNetSMBNetBIOSName
, name
);
676 // get "default" name
677 name
= copy_default_name();
679 CFMutableDictionaryRef newDict
;
681 my_log(LOG_DEBUG
, "NetBIOS name (default) = %@", name
);
682 newDict
= CFDictionaryCreateMutableCopy(NULL
, 0, dict
);
683 CFDictionarySetValue(newDict
, kSCPropNetSMBNetBIOSName
, name
);
691 // update SMB configuration
692 smb_set_configuration(store
, dict
);
696 if (address
!= NULL
) CFRelease(address
);
697 if (dict
!= NULL
) CFRelease(dict
);
698 if (serviceID
!= NULL
) CFRelease(serviceID
);
701 CFRunLoopTimerInvalidate(timer
);
711 configuration_changed(SCDynamicStoreRef store
, CFArrayRef changedKeys
, void *info
)
713 CFRunLoopTimerContext context
= { 0, (void *)store
, CFRetain
, CFRelease
, NULL
};
714 CFAbsoluteTime time_boot
;
715 CFAbsoluteTime time_now
;
717 // if active, cancel any in-progress attempt to resolve the primary IP address
719 if (ptrTarget
!= NULL
) {
723 // if active, cancel any queued configuration change
725 CFRunLoopTimerInvalidate(timer
);
730 // queue configuration change
731 time_boot
= boottime() + SMB_STARTUP_DELAY
;
732 time_now
= CFAbsoluteTimeGetCurrent() + SMB_DEBOUNCE_DELAY
;
734 timer
= CFRunLoopTimerCreate(NULL
,
735 time_now
> time_boot
? time_now
: time_boot
,
739 smb_update_configuration
,
741 CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer
, kCFRunLoopDefaultMode
);
749 load_smb_configuration(Boolean verbose
)
752 CFMutableArrayRef keys
= NULL
;
753 CFMutableArrayRef patterns
= NULL
;
759 /* initialize a few globals */
761 store
= SCDynamicStoreCreate(NULL
, CFSTR("smb-configuration"), configuration_changed
, NULL
);
764 "SCDynamicStoreCreate() failed: %s",
765 SCErrorString(SCError()));
769 /* establish notification keys and patterns */
771 keys
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
772 patterns
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
);
774 /* ...watch for primary service / interface changes */
775 key
= SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL
,
776 kSCDynamicStoreDomainState
,
778 CFArrayAppendValue(keys
, key
);
781 /* ...watch for DNS configuration changes */
782 key
= SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL
,
783 kSCDynamicStoreDomainState
,
785 CFArrayAppendValue(keys
, key
);
788 /* ...watch for SMB configuration changes */
789 key
= SCDynamicStoreKeyCreateNetworkGlobalEntity(NULL
,
790 kSCDynamicStoreDomainState
,
792 CFArrayAppendValue(keys
, key
);
795 /* ...watch for ComputerName changes */
796 key
= SCDynamicStoreKeyCreateComputerName(NULL
);
797 CFArrayAppendValue(keys
, key
);
800 /* ...watch for local (multicast DNS) hostname changes */
801 key
= SCDynamicStoreKeyCreateHostNames(NULL
);
802 CFArrayAppendValue(keys
, key
);
805 /* register the keys/patterns */
806 if (!SCDynamicStoreSetNotificationKeys(store
, keys
, patterns
)) {
808 "SCDynamicStoreSetNotificationKeys() failed: %s",
809 SCErrorString(SCError()));
813 rls
= SCDynamicStoreCreateRunLoopSource(NULL
, store
, 0);
816 "SCDynamicStoreCreateRunLoopSource() failed: %s",
817 SCErrorString(SCError()));
820 CFRunLoopAddSource(CFRunLoopGetCurrent(), rls
, kCFRunLoopDefaultMode
);
828 if (keys
!= NULL
) CFRelease(keys
);
829 if (patterns
!= NULL
) CFRelease(patterns
);
830 if (store
!= NULL
) CFRelease(store
);
837 main(int argc
, char **argv
)
843 CFStringRef serviceID
;
844 SCDynamicStoreRef store
;
847 if ((argc
> 1) && (strcmp(argv
[1], "-d") == 0)) {
854 store
= SCDynamicStoreCreate(NULL
, CFSTR("smb-configuration"), NULL
, NULL
);
856 SCPrint(TRUE
, stdout
,
857 CFSTR("SCDynamicStoreCreate() failed: %s\n"),
858 SCErrorString(SCError()));
862 // get "default" name
863 name
= copy_default_name();
865 SCPrint(TRUE
, stdout
, CFSTR("default name = %@\n"), name
);
869 // get primary service
870 serviceID
= copy_primary_service(store
);
871 if (serviceID
!= NULL
) {
872 SCPrint(TRUE
, stdout
, CFSTR("primary service ID = %@\n"), serviceID
);
874 SCPrint(TRUE
, stdout
, CFSTR("No primary service\n"));
878 if ((argc
== (2+1)) && (argv
[1][0] == 's')) {
879 if (serviceID
!= NULL
) CFRelease(serviceID
);
880 serviceID
= CFStringCreateWithCString(NULL
, argv
[2], kCFStringEncodingUTF8
);
881 SCPrint(TRUE
, stdout
, CFSTR("alternate service ID = %@\n"), serviceID
);
884 // get primary IP address
885 address
= copy_primary_ip(store
, serviceID
);
886 CFRelease(serviceID
);
887 if (address
!= NULL
) {
888 SCPrint(TRUE
, stdout
, CFSTR("primary address = %@\n"), address
);
890 if ((argc
== (2+1)) && (argv
[1][0] == 'a')) {
891 if (address
!= NULL
) CFRelease(address
);
892 address
= CFStringCreateWithCString(NULL
, argv
[2], kCFStringEncodingUTF8
);
893 SCPrint(TRUE
, stdout
, CFSTR("alternate primary address = %@\n"), address
);
896 // start reverse DNS query using primary IP address
897 (void) ptr_query_start(address
);
903 smb_update_configuration(NULL
, (void *)store
);
912 _sc_verbose
= (argc
> 1) ? TRUE
: FALSE
;
914 load_smb_configuration((argc
> 1) ? TRUE
: FALSE
);