summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.fetch1
-rw-r--r--RepositoryExternal.mk12
-rw-r--r--configure.ac5
-rwxr-xr-xdownload.lst2
-rw-r--r--external/Module_external.mk1
-rw-r--r--external/mdnsresponder/Makefile7
-rw-r--r--external/mdnsresponder/Module_mdnsresponder.mk20
-rw-r--r--external/mdnsresponder/README4
-rw-r--r--external/mdnsresponder/StaticLibrary_mDNSResponder.mk37
-rw-r--r--external/mdnsresponder/UnpackedTarball_mDNSResponder.mk14
-rw-r--r--sd/CppunitTest_sd_uimpress.mk1
-rw-r--r--sd/Library_sd.mk9
-rw-r--r--sd/source/ui/remotecontrol/WINNetworkService.cxx1
-rw-r--r--sd/source/ui/remotecontrol/WINNetworkService.hxx2
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/CommonServices.h1213
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/DebugServices.c2978
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/DebugServices.h1576
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList.c319
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList.h90
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/dllmain.c113
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/dns_sd.h2459
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientlib.c366
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientstub.c2219
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.c161
-rw-r--r--sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.h222
25 files changed, 105 insertions, 11727 deletions
diff --git a/Makefile.fetch b/Makefile.fetch
index 8b2da4ee2a05..cbc51b221672 100644
--- a/Makefile.fetch
+++ b/Makefile.fetch
@@ -165,6 +165,7 @@ $(WORKDIR)/download: $(BUILDDIR)/config_host.mk $(SRCDIR)/download.lst $(SRCDIR)
$(call fetch_Optional,LPSOLVE,LPSOLVE_TARBALL) \
$(call fetch_Optional,MARIADB,MARIADB_TARBALL) \
$(call fetch_Optional,MDDS,MDDS_TARBALL) \
+ $(call fetch_Optional,MDNSRESPONDER,MDNSRESPONDER_TARBALL) \
$(call fetch_Optional,MORE_FONTS,FONT_CALADEA_TARBALL) \
$(call fetch_Optional,MORE_FONTS,FONT_CARLITO_TARBALL) \
$(call fetch_Optional,MORE_FONTS,FONT_DEJAVU_TARBALL) \
diff --git a/RepositoryExternal.mk b/RepositoryExternal.mk
index 2c00a33f8cd6..cba5316d9ee1 100644
--- a/RepositoryExternal.mk
+++ b/RepositoryExternal.mk
@@ -2442,6 +2442,18 @@ gb_LinkTarget__use_coinmp :=
endif # ENABLE_COINMP
+ifneq (,$(filter MDNSRESPONDER,$(BUILD_TYPE)))
+
+define gb_LinkTarget__use_mDNSResponder
+$(call gb_LinkTarget_set_include,$(1),\
+ -I$(call gb_UnpackedTarball_get_dir,mDNSResponder)/mDNSShared \
+ $$(INCLUDE) \
+)
+$(call gb_LinkTarget_use_static_libraries,$(1),mDNSResponder)
+endef
+
+endif # MDNSRESPONDER
+
ifeq ($(ENABLE_GIO),TRUE)
define gb_LinkTarget__use_gio
diff --git a/configure.ac b/configure.ac
index 9a13921411ce..eb569d10afe7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -11805,7 +11805,10 @@ AC_SUBST(CAIRO_LIBS)
dnl ===================================================================
dnl Test whether to use avahi
dnl ===================================================================
-if test "$_os" != "WINNT" -a "$_os" != "Darwin" -a "$enable_avahi" = "yes"; then
+if test "$_os" = "WINNT"; then
+ # Windows uses bundled mDNSResponder
+ BUILD_TYPE="$BUILD_TYPE MDNSRESPONDER"
+elif test "$_os" != "Darwin" -a "$enable_avahi" = "yes"; then
PKG_CHECK_MODULES([AVAHI], [avahi-client >= 0.6.10],
[ENABLE_AVAHI="TRUE"])
AC_DEFINE(HAVE_FEATURE_AVAHI)
diff --git a/download.lst b/download.lst
index 8774343ea6f1..0201a61e0df1 100755
--- a/download.lst
+++ b/download.lst
@@ -95,6 +95,8 @@ export LPSOLVE_TARBALL := 26b3e95ddf3d9c077c480ea45874b3b8-lp_solve_5.5.tar.gz
export MARIADB_TARBALL := a233181e03d3c307668b4c722d881661-mariadb_client-2.0.0-src.tar.gz
export MDDS_MD5SUM := 74e0a81c5af4137285fe6a52217f71e4
export MDDS_TARBALL := mdds_1.0.0.tar.bz2
+export MDNSRESPONDER_MD5SUM := dd557e1058b51ac2f29cd01d67be0145
+export MDNSRESPONDER_TARBALL := mDNSResponder-379.37.tar.gz
export MSPUB_MD5SUM := ff9d0f9dd8fbc523408ea1953d5bde41
export MSPUB_TARBALL := libmspub-0.1.2.tar.bz2
export MWAW_MD5SUM := 4a8a53a9d997cf0e2bd208178797dbfb
diff --git a/external/Module_external.mk b/external/Module_external.mk
index 7c78c7df8c65..ccd758c4e08d 100644
--- a/external/Module_external.mk
+++ b/external/Module_external.mk
@@ -68,6 +68,7 @@ $(eval $(call gb_Module_add_moduledirs,external,\
$(call gb_Helper_optional,LPSOLVE,lpsolve) \
$(call gb_Helper_optional,MARIADB,libmariadb) \
$(call gb_Helper_optional,MDDS,mdds) \
+ $(call gb_Helper_optional,MDNSRESPONDER,mdnsresponder) \
$(if $(WITH_EXTRA_EXTENSIONS),misc_extensions) \
$(call gb_Helper_optional,MORE_FONTS,more_fonts) \
$(call gb_Helper_optional,MSPUB,libmspub) \
diff --git a/external/mdnsresponder/Makefile b/external/mdnsresponder/Makefile
new file mode 100644
index 000000000000..e4968cf85fb6
--- /dev/null
+++ b/external/mdnsresponder/Makefile
@@ -0,0 +1,7 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+
+module_directory:=$(dir $(realpath $(firstword $(MAKEFILE_LIST))))
+
+include $(module_directory)/../../solenv/gbuild/partial_build.mk
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mdnsresponder/Module_mdnsresponder.mk b/external/mdnsresponder/Module_mdnsresponder.mk
new file mode 100644
index 000000000000..b2996840bead
--- /dev/null
+++ b/external/mdnsresponder/Module_mdnsresponder.mk
@@ -0,0 +1,20 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_Module_Module,mdnsresponder))
+
+$(eval $(call gb_Module_add_targets,mdnsresponder,\
+ UnpackedTarball_mDNSResponder \
+))
+
+$(eval $(call gb_Module_add_targets,mdnsresponder,\
+ StaticLibrary_mDNSResponder \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mdnsresponder/README b/external/mdnsresponder/README
new file mode 100644
index 000000000000..d263b052181c
--- /dev/null
+++ b/external/mdnsresponder/README
@@ -0,0 +1,4 @@
+Apple's ZeroConf Multicast DNS implementation
+
+https://developer.apple.com/bonjour/
+http://www.opensource.apple.com/tarballs/mDNSResponder/
diff --git a/external/mdnsresponder/StaticLibrary_mDNSResponder.mk b/external/mdnsresponder/StaticLibrary_mDNSResponder.mk
new file mode 100644
index 000000000000..196b0c7baaf8
--- /dev/null
+++ b/external/mdnsresponder/StaticLibrary_mDNSResponder.mk
@@ -0,0 +1,37 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_StaticLibrary_StaticLibrary,mDNSResponder))
+
+$(eval $(call gb_StaticLibrary_set_warnings_not_errors,mDNSResponder))
+
+$(eval $(call gb_StaticLibrary_use_unpacked,mDNSResponder,mDNSResponder))
+
+$(eval $(call gb_StaticLibrary_set_include,mDNSResponder,\
+ -I$(call gb_UnpackedTarball_get_dir,mDNSResponder)/mDNSShared \
+ $$(INCLUDE) \
+))
+
+$(eval $(call gb_StaticLibrary_add_defs,mDNSResponder,\
+ -DWIN32_LEAN_AND_MEAN \
+ -D_WINSOCK_DEPRECATED_NO_WARNINGS \
+ -DUSE_TCP_LOOPBACK \
+ -DNOT_HAVE_SA_LEN \
+))
+
+$(eval $(call gb_StaticLibrary_add_generated_cobjects,mDNSResponder,\
+ UnpackedTarball/mDNSResponder/mDNSShared/DebugServices \
+ UnpackedTarball/mDNSResponder/mDNSShared/GenLinkedList \
+ UnpackedTarball/mDNSResponder/mDNSShared/dnssd_clientlib \
+ UnpackedTarball/mDNSResponder/mDNSShared/dnssd_clientstub \
+ UnpackedTarball/mDNSResponder/mDNSShared/dnssd_ipc \
+ UnpackedTarball/mDNSResponder/mDNSWindows/DLL/dllmain \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/external/mdnsresponder/UnpackedTarball_mDNSResponder.mk b/external/mdnsresponder/UnpackedTarball_mDNSResponder.mk
new file mode 100644
index 000000000000..9b436b2f077c
--- /dev/null
+++ b/external/mdnsresponder/UnpackedTarball_mDNSResponder.mk
@@ -0,0 +1,14 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_UnpackedTarball_UnpackedTarball,mDNSResponder))
+
+$(eval $(call gb_UnpackedTarball_set_tarball,mDNSResponder,$(MDNSRESPONDER_TARBALL)))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sd/CppunitTest_sd_uimpress.mk b/sd/CppunitTest_sd_uimpress.mk
index a94b131abd0e..78e9f908a7cf 100644
--- a/sd/CppunitTest_sd_uimpress.mk
+++ b/sd/CppunitTest_sd_uimpress.mk
@@ -79,6 +79,7 @@ $(eval $(call gb_CppunitTest_use_externals,sd_uimpress,\
$(if $(ENABLE_AVAHI), \
avahi \
) \
+ $(if $(filter WNT,$(OS)),mDNSResponder) \
libxml2 \
))
diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index b86c51c02662..66dca4396955 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -529,14 +529,7 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
sd/source/ui/remotecontrol/WINNetworkService \
))
-$(eval $(call gb_Library_add_cobjects,sd,\
- sd/source/ui/remotecontrol/mDNSResponder/DebugServices \
- sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientlib \
- sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientstub \
- sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc \
- sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList \
- sd/source/ui/remotecontrol/mDNSResponder/dllmain \
-))
+$(eval $(call gb_Library_use_external,sd,mDNSResponder))
endif # OS=WNT
diff --git a/sd/source/ui/remotecontrol/WINNetworkService.cxx b/sd/source/ui/remotecontrol/WINNetworkService.cxx
index 3643e1d2fd26..faedcf4efd9e 100644
--- a/sd/source/ui/remotecontrol/WINNetworkService.cxx
+++ b/sd/source/ui/remotecontrol/WINNetworkService.cxx
@@ -1,7 +1,6 @@
#include <string>
#include <iostream>
#include "WINNetworkService.hxx"
-#include "mDNSResponder/dns_sd.h"
#include <sal/log.hxx>
void sd::WINNetworkService::setup()
diff --git a/sd/source/ui/remotecontrol/WINNetworkService.hxx b/sd/source/ui/remotecontrol/WINNetworkService.hxx
index 0ca284feea0c..1e3227414bfa 100644
--- a/sd/source/ui/remotecontrol/WINNetworkService.hxx
+++ b/sd/source/ui/remotecontrol/WINNetworkService.hxx
@@ -4,7 +4,7 @@
#include <string>
#undef WB_LEFT
#undef WB_RIGHT
-#include "mDNSResponder/dns_sd.h"
+#include <dns_sd.h>
#include "ZeroconfService.hxx"
namespace sd{
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/CommonServices.h b/sd/source/ui/remotecontrol/mDNSResponder/CommonServices.h
deleted file mode 100644
index 1c1ae684846e..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/CommonServices.h
+++ /dev/null
@@ -1,1213 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/*! @header CommonServices
-
- Common Services for Mac OS X, Linux, Palm, VxWorks, Windows, and Windows CE.
- */
-
-#ifndef __COMMON_SERVICES__
-#define __COMMON_SERVICES__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if 0
-#pragma mark == Target ==
-#endif
-
-
-// Target
-// Macintosh
-#if ( !defined( TARGET_OS_MAC ) )
- #if ( ( macintosh || __MACH__ ) && !KERNEL )
- // ConditionalMacros.h in CoreServices will define this TARGET_* flag.
- #else
- #define TARGET_OS_MAC 0
- #endif
-#endif
-
-#if ( !defined( TARGET_API_MAC_OSX_KERNEL ) )
- #if ( __MACH__ && KERNEL )
- #define TARGET_API_MAC_OSX_KERNEL 1
- #else
- #define TARGET_API_MAC_OSX_KERNEL 0
- #endif
-#endif
-
-// FreeBSD
-#if ( !defined( TARGET_OS_FREEBSD ) )
- #if ( defined( __FreeBSD__ ) )
- #define TARGET_OS_FREEBSD 1
- #else
- #define TARGET_OS_FREEBSD 0
- #endif
-#endif
-
-// Linux
-#if ( !defined( TARGET_OS_LINUX ) )
- #if ( defined( __linux__ ) )
- #define TARGET_OS_LINUX 1
- #else
- #define TARGET_OS_LINUX 0
- #endif
-#endif
-
-// Solaris
-#if ( !defined( TARGET_OS_SOLARIS ) )
- #if ( defined(solaris) || (defined(__SVR4) && defined(sun)) )
- #define TARGET_OS_SOLARIS 1
- #else
- #define TARGET_OS_SOLARIS 0
- #endif
-#endif
-
-// Palm
-#if ( !defined( TARGET_OS_PALM ) )
- #if ( defined( __PALMOS_TRAPS__ ) || defined( __PALMOS_ARMLET__ ) )
- #define TARGET_OS_PALM 1
- #else
- #define TARGET_OS_PALM 0
- #endif
-#endif
-
-// VxWorks
-#if ( !defined( TARGET_OS_VXWORKS ) )
-
-// No predefined macro for VxWorks so just assume VxWorks if nothing else is set.
-
- #if ( !macintosh && !__MACH__ && !defined( __FreeBSD__ ) && !defined( __linux__ ) && !defined ( __SVR4 ) && !defined ( __sun ) && !defined( __PALMOS_TRAPS__ ) && !defined( __PALMOS_ARMLET__ ) && !defined( _WIN32 ) )
- #define TARGET_OS_VXWORKS 1
- #else
- #define TARGET_OS_VXWORKS 0
- #endif
-#endif
-
-// Windows
-#if ( !defined( TARGET_OS_WIN32 ) )
- #if ( macintosh || __MACH__ )
-// ConditionalMacros.h in CoreServices will define this TARGET_* flag.
- #else
- #if ( defined( _WIN32 ) )
- #define TARGET_OS_WIN32 1
- #else
- #define TARGET_OS_WIN32 0
- #endif
- #endif
-#endif
-
-// Windows CE
-#if ( !defined( TARGET_OS_WINDOWS_CE ) )
- #if ( defined( _WIN32_WCE ) )
- #define TARGET_OS_WINDOWS_CE 1
- #else
- #define TARGET_OS_WINDOWS_CE 0
- #endif
-#endif
-
-#if 0
-#pragma mark == Includes ==
-#endif
-
-
-// Includes
-#if ( !KERNEL )
- #if defined(WIN32) && !defined(_WSPIAPI_COUNTOF)
- #define _WSPIAPI_COUNTOF(_Array) (sizeof(_Array) / sizeof(_Array[0]))
- #endif
- #include <stddef.h>
-#endif
-
-#if ( ( macintosh || __MACH__ ) && !KERNEL )
-
- #if ( defined( __MWERKS__ ) )
- #if ( __option( c9x ) )
- #include <stdbool.h>
- #endif
- #else
- #include <stdbool.h>
- #endif
-
- #include <stdint.h>
-
- #if ( __MACH__ )
-
-// Mac OS X
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <fcntl.h>
- #include <pthread.h>
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <unistd.h>
-
- #else
-
-// Classic Mac OS
- #include <ConditionalMacros.h>
- #include <MacTypes.h>
-
- #endif
-
-#elif ( KERNEL )
-
-// Mac OS X Kernel
- #include <stdint.h>
-
- #include <libkern/OSTypes.h>
- #include <sys/types.h>
-
-#elif ( TARGET_OS_FREEBSD )
-
-// FreeBSD
- #include <stdint.h>
- #include <pthread.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <sys/socket.h>
-
-#elif ( TARGET_OS_LINUX )
-
-// Linux
- #include <stdint.h>
- #include <arpa/inet.h>
-
-#elif ( TARGET_OS_SOLARIS )
-
-// Solaris
- #include <stdint.h>
-
- #include <arpa/inet.h>
- #include <arpa/nameser.h>
-
- #if ( defined( BYTE_ORDER ) && defined( LITTLE_ENDIAN ) && ( BYTE_ORDER == LITTLE_ENDIAN ) )
- #define TARGET_RT_LITTLE_ENDIAN 1
- #endif
- #if ( defined( BYTE_ORDER ) && defined( BIG_ENDIAN ) && ( BYTE_ORDER == BIG_ENDIAN ) )
- #define TARGET_RT_BIG_ENDIAN 1
- #endif
-
-#elif ( TARGET_OS_PALM )
-
-// Palm (no special includes yet).
-
-#elif ( TARGET_OS_VXWORKS )
-
-// VxWorks
- #include "vxWorks.h"
-
-#elif ( TARGET_OS_WIN32 )
-
-// Windows
- #if ( !defined( WIN32_WINDOWS ) )
- #define WIN32_WINDOWS 0x0401
- #endif
-
- #if ( !defined( _WIN32_WINDOWS ) )
- #define _WIN32_WINDOWS 0x0401
- #endif
-
- #if ( !defined( WIN32_LEAN_AND_MEAN ) )
- #define WIN32_LEAN_AND_MEAN // Needed to avoid redefinitions by Windows interfaces.
- #endif
-
- #if ( defined( __MWERKS__ ) )
-
- #if ( __option( c9x ) )
- #include <stdbool.h>
- #endif
-
- #include <stdint.h>
-
- #elif ( defined( _MSC_VER ) )
-
- #pragma warning( disable:4127 ) // Disable "conditional expression is constant" warning for debug macros.
-
- #endif
-
- #include <windows.h>
- #include <winsock2.h>
- #include <ws2tcpip.h>
-
-#else
- #error unknown OS - update this file to support your OS
-#endif
-
-#if ( !defined( TARGET_BUILD_MAIN ) )
- #if ( !TARGET_OS_VXWORKS )
- #define TARGET_BUILD_MAIN 1
- #endif
-#endif
-
-#if ( __GNUC__ || !TARGET_OS_VXWORKS )
- #define TARGET_LANGUAGE_C_LIKE 1
-#else
- #define TARGET_LANGUAGE_C_LIKE 0
-#endif
-
-#if 0
-#pragma mark == CPU ==
-#endif
-
-
-// CPU
-
-// PowerPC
-#if ( !defined( TARGET_CPU_PPC ) )
- #if ( defined( __ppc__ ) || defined( __PPC__ ) || defined( powerpc ) || defined( ppc ) || defined( _M_MPPC ) )
- #define TARGET_CPU_PPC 1
- #else
- #define TARGET_CPU_PPC 0
- #endif
-#endif
-
-// x86
-#if ( !defined( TARGET_CPU_X86 ) )
- #if ( __INTEL__ || defined( __i386__ ) || defined( i386 ) || defined( intel ) || defined( _M_IX86 ) )
- #define TARGET_CPU_X86 1
- #else
- #define TARGET_CPU_X86 0
- #endif
-#endif
-
-// MIPS
-#if ( !defined( TARGET_CPU_MIPS ) )
- #if ( __MIPS__ || defined( MIPS32 ) || defined( R3000 ) || defined( R4000 ) || defined( R4650 ) || defined( _M_MRX000 ) )
- #define TARGET_CPU_MIPS 1
- #else
- #define TARGET_CPU_MIPS 0
- #endif
-#endif
-
-#if ( !defined( TARGET_CPU_PPC ) && !defined( TARGET_CPU_X86 ) && !defined( TARGET_CPU_MIPS ) )
- #error unknown CPU - update this file to support your CPU
-#endif
-
-#if 0
-#pragma mark == Byte Order ==
-#endif
-
-
-// Byte Order
-
-// TARGET_RT_LITTLE_ENDIAN
-#if ( !defined( TARGET_RT_LITTLE_ENDIAN ) )
- #if ( MIPSEL || IL_LITTLE_ENDIAN || defined( __LITTLE_ENDIAN__ ) || \
- ( defined( BYTE_ORDER ) && defined( LITTLE_ENDIAN ) && ( BYTE_ORDER == LITTLE_ENDIAN ) ) || \
- ( defined( _BYTE_ORDER ) && defined( _LITTLE_ENDIAN ) && ( _BYTE_ORDER == _LITTLE_ENDIAN ) ) || \
- ( defined( __BYTE_ORDER ) && defined( __LITTLE_ENDIAN ) && ( __BYTE_ORDER == __LITTLE_ENDIAN ) ) || \
- TARGET_CPU_X86 || ( defined( TARGET_RT_BIG_ENDIAN ) && !TARGET_RT_BIG_ENDIAN ) )
- #define TARGET_RT_LITTLE_ENDIAN 1
- #else
- #define TARGET_RT_LITTLE_ENDIAN 0
- #endif
-#endif
-
-// TARGET_RT_BIG_ENDIAN
-#if ( !defined( TARGET_RT_BIG_ENDIAN ) )
- #if ( MIPSEB || IL_BIG_ENDIAN || defined( __BIG_ENDIAN__ ) || \
- ( defined( BYTE_ORDER ) && defined( BIG_ENDIAN ) && ( BYTE_ORDER == BIG_ENDIAN ) ) || \
- ( defined( _BYTE_ORDER ) && defined( _BIG_ENDIAN ) && ( _BYTE_ORDER == _BIG_ENDIAN ) ) || \
- ( defined( __BYTE_ORDER ) && defined( __BIG_ENDIAN ) && ( __BYTE_ORDER == __BIG_ENDIAN ) ) || \
- ( defined( TARGET_RT_LITTLE_ENDIAN ) && !TARGET_RT_LITTLE_ENDIAN ) )
- #define TARGET_RT_BIG_ENDIAN 1
- #else
- #define TARGET_RT_BIG_ENDIAN 0
- #endif
-#endif
-
-#if ( defined( TARGET_RT_LITTLE_ENDIAN ) && !defined( TARGET_RT_BIG_ENDIAN ) )
- #if ( TARGET_RT_LITTLE_ENDIAN )
- #define TARGET_RT_BIG_ENDIAN 0
- #else
- #define TARGET_RT_BIG_ENDIAN 1
- #endif
-#endif
-
-#if ( defined( TARGET_RT_BIG_ENDIAN ) && !defined( TARGET_RT_LITTLE_ENDIAN ) )
- #if ( TARGET_RT_BIG_ENDIAN )
- #define TARGET_RT_LITTLE_ENDIAN 0
- #else
- #define TARGET_RT_LITTLE_ENDIAN 1
- #endif
-#endif
-
-#if ( !defined( TARGET_RT_LITTLE_ENDIAN ) || !defined( TARGET_RT_BIG_ENDIAN ) )
- #error unknown byte order - update this file to support your byte order
-#endif
-
-// TARGET_RT_BYTE_ORDER
-#if ( !defined( TARGET_RT_BYTE_ORDER_BIG_ENDIAN ) )
- #define TARGET_RT_BYTE_ORDER_BIG_ENDIAN 1234
-#endif
-
-#if ( !defined( TARGET_RT_BYTE_ORDER_LITTLE_ENDIAN ) )
- #define TARGET_RT_BYTE_ORDER_LITTLE_ENDIAN 4321
-#endif
-
-#if ( !defined( TARGET_RT_BYTE_ORDER ) )
- #if ( TARGET_RT_LITTLE_ENDIAN )
- #define TARGET_RT_BYTE_ORDER TARGET_RT_BYTE_ORDER_LITTLE_ENDIAN
- #else
- #define TARGET_RT_BYTE_ORDER TARGET_RT_BYTE_ORDER_BIG_ENDIAN
- #endif
-#endif
-
-#if 0
-#pragma mark == Constants ==
-#endif
-
-
-// Constants
-#if ( !TARGET_OS_MAC )
- #define CR '\r'
-#endif
-
-#define LF '\n'
-#define CRLF "\r\n"
-
-#if 0
-#pragma mark == Compatibility ==
-#endif
-
-
-// Compatibility
-
-// Macros to allow the same code to work on Windows and other sockets API-compatible platforms.
-#if ( TARGET_OS_WIN32 )
- #define close_compat( X ) closesocket( X )
- #define errno_compat() (int) GetLastError()
- #define set_errno_compat( X ) SetLastError( X )
- #define EWOULDBLOCK_compat WSAEWOULDBLOCK
- #define ETIMEDOUT_compat WSAETIMEDOUT
- #define ENOTCONN_compat WSAENOTCONN
- #define IsValidSocket( X ) ( ( X ) != INVALID_SOCKET )
- #define kInvalidSocketRef INVALID_SOCKET
- #if ( TARGET_LANGUAGE_C_LIKE )
-typedef SOCKET SocketRef;
- #endif
-#else
- #define close_compat( X ) close( X )
- #define errno_compat() errno
- #define set_errno_compat( X ) do { errno = ( X ); } while( 0 )
- #define EWOULDBLOCK_compat EWOULDBLOCK
- #define ETIMEDOUT_compat ETIMEDOUT
- #define ENOTCONN_compat ENOTCONN
- #define IsValidSocket( X ) ( ( X ) >= 0 )
- #define kInvalidSocketRef -1
- #if ( TARGET_LANGUAGE_C_LIKE )
-typedef int SocketRef;
- #endif
-#endif
-
-// socklen_t is not defined on the following platforms so emulate it if not defined:
-
-// - Pre-Panther Mac OS X. Panther defines SO_NOADDRERR so trigger off that.
-// - Windows SDK prior to 2003. 2003+ SDK's define EAI_AGAIN so trigger off that.
-// - VxWorks
-
-#if ( TARGET_LANGUAGE_C_LIKE )
- #if ( ( TARGET_OS_MAC && !defined( SO_NOADDRERR ) ) || ( TARGET_OS_WIN32 && !defined( EAI_AGAIN ) ) || TARGET_OS_VXWORKS )
-typedef int socklen_t;
- #endif
-#endif
-
-// ssize_t is not defined on the following platforms so emulate it if not defined:
-
-// - Mac OS X when not building with BSD headers
-// - Windows
-
-#if ( TARGET_LANGUAGE_C_LIKE )
- #if ( !defined(_SSIZE_T) && ( TARGET_OS_WIN32 || !defined( _BSD_SSIZE_T_DEFINED_ ) ) && !TARGET_OS_FREEBSD && !TARGET_OS_LINUX && !TARGET_OS_VXWORKS && !TARGET_OS_MAC && !defined (__MINGW32__))
-typedef int ssize_t;
- #endif
-#endif
-
-// sockaddr_storage is not supported on non-IPv6 machines so alias it to an IPv4-compatible structure.
-
-#if ( TARGET_LANGUAGE_C_LIKE )
- #if ( !defined( AF_INET6 ) )
- #define sockaddr_storage sockaddr_in
- #define ss_family sin_family
- #endif
-#endif
-
-
-/*! @defined SOCKADDR_IS_IP_LOOPBACK
-
- @abstract Determines if a sockaddr is an IPv4 or IPv6 loopback address (if IPv6 is supported).
- */
-#if ( defined( AF_INET6 ) )
- #define SOCKADDR_IS_IP_LOOPBACK( SA ) \
- ( ( (const struct sockaddr *)( SA ) )->sa_family == AF_INET ) \
- ? ( ( (const struct sockaddr_in *)( SA ) )->sin_addr.s_addr == htonl( INADDR_LOOPBACK ) ) \
- : ( ( (const struct sockaddr *)( SA ) )->sa_family == AF_INET6 ) \
- ? IN6_IS_ADDR_LOOPBACK( &( (const struct sockaddr_in6 *)( SA ) )->sin6_addr ) \
- : 0
-#else
- #define SOCKADDR_IS_IP_LOOPBACK( SA ) \
- ( ( (const struct sockaddr *)( SA ) )->sa_family == AF_INET ) \
- ? ( ( (const struct sockaddr_in *)( SA ) )->sin_addr.s_addr == htonl( INADDR_LOOPBACK ) ) \
- : 0
-#endif
-
-
-/*! @defined SOCKADDR_IS_IP_LINK_LOCAL
-
- @abstract Determines if a sockaddr is an IPv4 or IPv6 link-local address (if IPv6 is supported).
- */
-#if ( defined( AF_INET6 ) )
- #define SOCKADDR_IS_IP_LINK_LOCAL( SA ) \
- ( ( ( (const struct sockaddr *)( SA ) )->sa_family == AF_INET ) \
- ? ( ( ( (uint8_t *)( &( (const struct sockaddr_in *)( SA ) )->sin_addr ) )[ 0 ] == 169 ) && \
- ( ( (uint8_t *)( &( (const struct sockaddr_in *)( SA ) )->sin_addr ) )[ 1 ] == 254 ) ) \
- : IN6_IS_ADDR_LOOPBACK( &( (const struct sockaddr_in6 *)( SA ) )->sin6_addr ) )
-#else
- #define SOCKADDR_IS_IP_LINK_LOCAL( SA ) \
- ( ( ( (const struct sockaddr *)( SA ) )->sa_family == AF_INET ) \
- ? ( ( ( (uint8_t *)( &( (const struct sockaddr_in *)( SA ) )->sin_addr ) )[ 0 ] == 169 ) && \
- ( ( (uint8_t *)( &( (const struct sockaddr_in *)( SA ) )->sin_addr ) )[ 1 ] == 254 ) ) \
- : 0 )
-#endif
-
-// _beginthreadex and _endthreadex are not supported on Windows CE 2.1 or later (the C runtime issues with leaking
-// resources have apparently been resolved and they seem to have just ripped out support for the API) so map it to
-// CreateThread on Windows CE.
-#if ( TARGET_OS_WINDOWS_CE )
- #define _beginthreadex_compat( SECURITY_PTR, STACK_SIZE, START_ADDRESS, ARG_LIST, FLAGS, THREAD_ID_PTR ) \
- (uintptr_t) CreateThread( SECURITY_PTR, STACK_SIZE, (LPTHREAD_START_ROUTINE) START_ADDRESS, ARG_LIST, FLAGS, \
- (LPDWORD) THREAD_ID_PTR )
-
- #define _endthreadex_compat( RESULT ) ExitThread( (DWORD) RESULT )
-#elif ( TARGET_OS_WIN32 )
- #define _beginthreadex_compat _beginthreadex
- #define _endthreadex_compat _endthreadex
-#endif
-
-// The C99 "inline" keyword is not supported by Microsoft compilers, but they do support __inline so map it when needed.
-
-#if ( defined( _MSC_VER ) )
- #define inline_compat __inline
-#else
- #define inline_compat inline
-#endif
-
-// Calling conventions
-
-#if ( !defined( CALLBACK_COMPAT ) )
- #if ( TARGET_OS_WIN32 || TARGET_OS_WINDOWS_CE )
- #define CALLBACK_COMPAT CALLBACK
- #else
- #define CALLBACK_COMPAT
- #endif
-#endif
-
-#if 0
-#pragma mark == Macros ==
-#endif
-
-
-/*! @defined kSizeCString
-
- @abstract A meta-value to pass to supported routines to indicate the size should be calculated with strlen.
- */
-
-#define kSizeCString ( (size_t) -1 )
-
-
-/*! @defined sizeof_array
-
- @abstract Determines the number of elements in an array.
- */
-
-#define sizeof_array( X ) ( sizeof( X ) / sizeof( X[ 0 ] ) )
-
-
-/*! @defined sizeof_element
-
- @abstract Determines the size of an array element.
- */
-
-#define sizeof_element( X ) sizeof( X[ 0 ] )
-
-
-/*! @defined sizeof_string
-
- @abstract Determines the size of a constant C string, excluding the null terminator.
- */
-
-#define sizeof_string( X ) ( sizeof( ( X ) ) - 1 )
-
-
-/*! @defined sizeof_field
-
- @abstract Determines the size of a field of a type.
- */
-
-#define sizeof_field( TYPE, FIELD ) sizeof( ( ( (TYPE *) 0 )->FIELD ) )
-
-
-/*! @function RoundUp
-
- @abstract Rounds X up to a multiple of Y.
- */
-
-#define RoundUp( X, Y ) ( ( X ) + ( ( Y ) -( ( X ) % ( Y ) ) ) )
-
-
-/*! @function IsAligned
-
- @abstract Returns non-zero if X is aligned to a Y byte boundary and 0 if not. Y must be a power of 2.
- */
-
-#define IsAligned( X, Y ) ( ( ( X ) &( ( Y ) -1 ) ) == 0 )
-
-
-/*! @function IsFieldAligned
-
- @abstract Returns non-zero if FIELD of type TYPE is aligned to a Y byte boundary and 0 if not. Y must be a power of 2.
- */
-
-#define IsFieldAligned( X, TYPE, FIELD, Y ) IsAligned( ( (uintptr_t)( X ) ) + offsetof( TYPE, FIELD ), ( Y ) )
-
-
-/*! @function AlignDown
-
- @abstract Aligns X down to a Y byte boundary. Y must be a power of 2.
- */
-
-#define AlignDown( X, Y ) ( ( X ) &~( ( Y ) -1 ) )
-
-
-/*! @function AlignUp
-
- @abstract Aligns X up to a Y byte boundary. Y must be a power of 2.
- */
-
-#define AlignUp( X, Y ) ( ( ( X ) + ( ( Y ) -1 ) ) & ~( ( Y ) -1 ) )
-
-
-/*! @function Min
-
- @abstract Returns the lesser of X and Y.
- */
-
-#if ( !defined( Min ) )
- #define Min( X, Y ) ( ( ( X ) < ( Y ) ) ? ( X ) : ( Y ) )
-#endif
-
-
-/*! @function Max
-
- @abstract Returns the greater of X and Y.
- */
-
-#if ( !defined( Max ) )
- #define Max( X, Y ) ( ( ( X ) > ( Y ) ) ? ( X ) : ( Y ) )
-#endif
-
-
-/*! @function InsertBits
-
- @abstract Inserts BITS (both 0 and 1 bits) into X, controlled by MASK and SHIFT, and returns the result.
-
- @discussion
-
- MASK is the bitmask of the bits in the final position.
- SHIFT is the number of bits to shift left for 1 to reach the first bit position of MASK.
-
- For example, if you wanted to insert 0x3 into the leftmost 4 bits of a 32-bit value:
-
- InsertBits( 0, 0x3, 0xF0000000U, 28 ) == 0x30000000
- */
-
-#define InsertBits( X, BITS, MASK, SHIFT ) ( ( ( X ) &~( MASK ) ) | ( ( ( BITS ) << ( SHIFT ) ) & ( MASK ) ) )
-
-
-/*! @function ExtractBits
-
- @abstract Extracts bits from X, controlled by MASK and SHIFT, and returns the result.
-
- @discussion
-
- MASK is the bitmask of the bits in the final position.
- SHIFT is the number of bits to shift right to right justify MASK.
-
- For example, if you had a 32-bit value (e.g. 0x30000000) wanted the left-most 4 bits (e.g. 3 in this example):
-
- ExtractBits( 0x30000000U, 0xF0000000U, 28 ) == 0x3
- */
-
-#define ExtractBits( X, MASK, SHIFT ) ( ( ( X ) >> ( SHIFT ) ) & ( ( MASK ) >> ( SHIFT ) ) )
-
-
-/*! @function Stringify
-
- @abstract Stringify's an expression.
-
- @discussion
-
- Stringify macros to process raw text passed via -D options to C string constants. The double-wrapping is necessary
- because the C preprocessor doesn't perform its normal argument expansion pre-scan with stringified macros so the
- -D macro needs to be expanded once via the wrapper macro then stringified so the raw text is stringified. Otherwise,
- the replacement value would be used instead of the symbolic name (only for preprocessor symbols like #defines).
-
- For example:
-
- #define kMyConstant 1
-
- printf( "%s", Stringify( kMyConstant ) ); // Prints "kMyConstant"
- printf( "%s", StringifyExpansion( kMyConstant ) ); // Prints "1"
-
- Non-preprocessor symbols do not have this issue. For example:
-
- enum
- {
- kMyConstant = 1
- };
-
- printf( "%s", Stringify( kMyConstant ) ); // Prints "kMyConstant"
- printf( "%s", StringifyExpansion( kMyConstant ) ); // Prints "kMyConstant"
-
- See <http://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html> for more info on C preprocessor pre-scanning.
- */
-
-#define Stringify( X ) # X
-#define StringifyExpansion( X ) Stringify( X )
-
-#if 0
-#pragma mark == Types ==
-#endif
-
-#if ( TARGET_LANGUAGE_C_LIKE )
-
-// Standard Types
-
-
-#if ( !defined( INT8_MIN ) )
-
- #define INT8_MIN SCHAR_MIN
-
- #if ( defined( _MSC_VER ) )
-
-// C99 stdint.h not supported in VC++/VS.NET yet.
-
-typedef INT8 int8_t;
-typedef UINT8 uint8_t;
-typedef INT16 int16_t;
-typedef UINT16 uint16_t;
-typedef INT32 int32_t;
-typedef UINT32 uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
- #elif defined (__MINGW32__)
- # include <stdint.h>
- #elif ( TARGET_OS_VXWORKS && ( TORNADO_VERSION < 220 ) )
-typedef long long int64_t;
-typedef unsigned long long uint64_t;
- #endif
-
-typedef int32_t int_least32_t;
-
-
-
-
- #if ( !defined( _WIN32 ) || TARGET_OS_WINDOWS_CE )
-typedef long int intptr_t;
-typedef unsigned long int uintptr_t;
- #endif
-
-#endif
-
-// Macros for minimum-width integer constants
-
-#if ( !defined( INT8_C ) )
- #define INT8_C( value ) value
-#endif
-
-#if ( !defined( INT16_C ) )
- #define INT16_C( value ) value
-#endif
-
-#if ( !defined( INT32_C ) )
- #define INT32_C( value ) value ## L
-#endif
-
-#if ( !defined( INT64_C ) )
- #if ( defined( _MSC_VER ) )
- #define INT64_C( value ) value ## i64
- #else
- #define INT64_C( value ) value ## LL
- #endif
-#endif
-
-#if ( !defined( UINT8_C ) )
- #define UINT8_C( value ) value ## U
-#endif
-
-#if ( !defined( UINT16_C ) )
- #define UINT16_C( value ) value ## U
-#endif
-
-#if ( !defined( UINT32_C ) )
- #define UINT32_C( value ) value ## UL
-#endif
-
-#if ( !defined( UINT64_C ) )
- #if ( defined( _MSC_VER ) )
- #define UINT64_C( value ) value ## UI64
- #else
- #define UINT64_C( value ) value ## ULL
- #endif
-#endif
-
-#if 0
-#pragma mark == bool ==
-#endif
-
-
-// Boolean Constants and Types
-
-
-// C++ defines bool, true, and false. Metrowerks allows this to be controlled by the "bool" option though.
-// C99 defines __bool_true_false_are_defined when bool, true, and false are defined.
-// MacTypes.h defines true and false (Mac builds only).
-
-// Note: The Metrowerks has to be in its own block because Microsoft Visual Studio .NET does not completely
-// short-circuit and gets confused by the option( bool ) portion of the conditional.
-
-#if ( defined( __MWERKS__ ) )
-
-// Note: The following test is done on separate lines because CodeWarrior doesn't like it all on one line.
-
- #if ( !__bool_true_false_are_defined && ( !defined( __cplusplus ) || !__option( bool ) ) )
- #define COMMON_SERVICES_NEEDS_BOOL 1
- #else
- #define COMMON_SERVICES_NEEDS_BOOL 0
- #endif
-
-// Workaround when building with CodeWarrior, but using the Apple stdbool.h header, which uses _Bool.
-
- #if ( __bool_true_false_are_defined && !defined( __cplusplus ) && !__option( c9x ) )
- #define _Bool int
- #endif
-
-// Workaround when building with CodeWarrior for C++ with bool disabled and using the Apple stdbool.h header,
-// which defines true and false to map to C++ true and false (which are not enabled). Serenity Now!
-
- #if ( __bool_true_false_are_defined && defined( __cplusplus ) && !__option( bool ) )
- #define true 1
- #define false 0
- #endif
-#else
- #define COMMON_SERVICES_NEEDS_BOOL ( !defined( __cplusplus ) && !__bool_true_false_are_defined )
-#endif
-
-#if ( COMMON_SERVICES_NEEDS_BOOL )
-
-typedef int bool;
-
- #define bool bool
-
- #if ( !defined( __MACTYPES__ ) && !defined( true ) && !defined( false ) )
- #define true 1
- #define false 0
- #endif
-
- #define __bool_true_false_are_defined 1
-#endif
-
-// IOKit IOTypes.h typedef's bool if TYPE_BOOL is not defined so define it here to prevent redefinition by IOTypes.h.
-
-#if ( TARGET_API_MAC_OSX_KERNEL )
- #define TYPE_BOOL 1
-#endif
-
-
-/*! @typedef CStr255
-
- @abstract 255 character null-terminated (C-style) string.
- */
-
-#if ( TARGET_LANGUAGE_C_LIKE )
-typedef char CStr255[ 256 ];
-#endif
-
-#endif // TARGET_LANGUAGE_C_LIKE
-
-
-/*! @defined TYPE_LONGLONG_NATIVE
-
- @abstract Defines whether long long (or its equivalent) is natively supported or requires special libraries.
- */
-
-#if ( !defined( TYPE_LONGLONG_NATIVE ) )
- #if ( !TARGET_OS_VXWORKS )
- #define TYPE_LONGLONG_NATIVE 1
- #else
- #define TYPE_LONGLONG_NATIVE 0
- #endif
-#endif
-
-
-/*! @defined long_long_compat
-
- @abstract Compatibility type to map to the closest thing to long long and unsigned long long.
-
- @discussion
-
- Neither long long nor unsigned long long are supported by Microsoft compilers, but they do support proprietary
- "__int64" and "unsigned __int64" equivalents so map to those types if the real long long is not supported.
- */
-
-#if ( TARGET_LANGUAGE_C_LIKE )
- #if ( TARGET_OS_WIN32 )
-typedef __int64 long_long_compat;
-typedef unsigned __int64 unsigned_long_long_compat;
- #else
-typedef signed long long long_long_compat;
-typedef unsigned long long unsigned_long_long_compat;
- #endif
-#endif
-
-#if 0
-#pragma mark == Errors ==
-#endif
-
-
-/*! @enum OSStatus
-
- @abstract Status Code
-
- @constant kNoErr 0 No error occurred.
- @constant kInProgressErr 1 Operation in progress.
- @constant kUnknownErr -6700 Unknown error occurred.
- @constant kOptionErr -6701 Option was not acceptable.
- @constant kSelectorErr -6702 Selector passed in is invalid or unknown.
- @constant kExecutionStateErr -6703 Call made in the wrong execution state (e.g. called at interrupt time).
- @constant kPathErr -6704 Path is invalid, too long, or otherwise not usable.
- @constant kParamErr -6705 Parameter is incorrect, missing, or not appropriate.
- @constant kParamCountErr -6706 Incorrect or unsupported number of parameters.
- @constant kCommandErr -6707 Command invalid or not supported.
- @constant kIDErr -6708 Unknown, invalid, or inappropriate identifier.
- @constant kStateErr -6709 Not in appropriate state to perform operation.
- @constant kRangeErr -6710 Index is out of range or not valid.
- @constant kRequestErr -6711 Request was improperly formed or not appropriate.
- @constant kResponseErr -6712 Response was incorrect or out of sequence.
- @constant kChecksumErr -6713 Checksum does not match the actual data.
- @constant kNotHandledErr -6714 Operation was not handled (or not handled completely).
- @constant kVersionErr -6715 Version is not incorrect or not compatibile.
- @constant kSignatureErr -6716 Signature did not match what was expected.
- @constant kFormatErr -6717 Unknown, invalid, or inappropriate file/data format.
- @constant kNotInitializedErr -6718 Action request before needed services were initialized.
- @constant kAlreadyInitializedErr -6719 Attempt made to initialize when already initialized.
- @constant kNotInUseErr -6720 Object not in use (e.g. cannot abort if not already in use).
- @constant kInUseErr -6721 Object is in use (e.g. cannot reuse active param blocks).
- @constant kTimeoutErr -6722 Timeout occurred.
- @constant kCanceledErr -6723 Operation canceled (successful cancel).
- @constant kAlreadyCanceledErr -6724 Operation has already been canceled.
- @constant kCannotCancelErr -6725 Operation could not be canceled (maybe already done or invalid).
- @constant kDeletedErr -6726 Object has already been deleted.
- @constant kNotFoundErr -6727 Something was not found.
- @constant kNoMemoryErr -6728 Not enough memory was available to perform the operation.
- @constant kNoResourcesErr -6729 Resources unavailable to perform the operation.
- @constant kDuplicateErr -6730 Duplicate found or something is a duplicate.
- @constant kImmutableErr -6731 Entity is not changeable.
- @constant kUnsupportedDataErr -6732 Data is unknown or not supported.
- @constant kIntegrityErr -6733 Data is corrupt.
- @constant kIncompatibleErr -6734 Data is not compatible or it is in an incompatible format.
- @constant kUnsupportedErr -6735 Feature or option is not supported.
- @constant kUnexpectedErr -6736 Error occurred that was not expected.
- @constant kValueErr -6737 Value is not appropriate.
- @constant kNotReadableErr -6738 Could not read or reading is not allowed.
- @constant kNotWritableErr -6739 Could not write or writing is not allowed.
- @constant kBadReferenceErr -6740 An invalid or inappropriate reference was specified.
- @constant kFlagErr -6741 An invalid, inappropriate, or unsupported flag was specified.
- @constant kMalformedErr -6742 Something was not formed correctly.
- @constant kSizeErr -6743 Size was too big, too small, or not appropriate.
- @constant kNameErr -6744 Name was not correct, allowed, or appropriate.
- @constant kNotReadyErr -6745 Device or service is not ready.
- @constant kReadErr -6746 Could not read.
- @constant kWriteErr -6747 Could not write.
- @constant kMismatchErr -6748 Something does not match.
- @constant kDateErr -6749 Date is invalid or out-of-range.
- @constant kUnderrunErr -6750 Less data than expected.
- @constant kOverrunErr -6751 More data than expected.
- @constant kEndingErr -6752 Connection, session, or something is ending.
- @constant kConnectionErr -6753 Connection failed or could not be established.
- @constant kAuthenticationErr -6754 Authentication failed or is not supported.
- @constant kOpenErr -6755 Could not open file, pipe, device, etc.
- @constant kTypeErr -6756 Incorrect or incompatible type (e.g. file, data, etc.).
- @constant kSkipErr -6757 Items should be or was skipped.
- @constant kNoAckErr -6758 No acknowledge.
- @constant kCollisionErr -6759 Collision occurred (e.g. two on bus at same time).
- @constant kBackoffErr -6760 Backoff in progress and operation intentionally failed.
- @constant kNoAddressAckErr -6761 No acknowledge of address.
- @constant kBusyErr -6762 Cannot perform because something is busy.
- @constant kNoSpaceErr -6763 Not enough space to perform operation.
- */
-
-#if ( TARGET_LANGUAGE_C_LIKE )
- #if ( !TARGET_OS_MAC && !TARGET_API_MAC_OSX_KERNEL )
-typedef int32_t OSStatus;
- #endif
-#endif
-
-#define kNoErr 0
-#define kInProgressErr 1
-
-// Generic error codes are in the range -6700 to -6779.
-
-#define kGenericErrorBase -6700 // Starting error code for all generic errors.
-
-#define kUnknownErr -6700
-#define kOptionErr -6701
-#define kSelectorErr -6702
-#define kExecutionStateErr -6703
-#define kPathErr -6704
-#define kParamErr -6705
-#define kParamCountErr -6706
-#define kCommandErr -6707
-#define kIDErr -6708
-#define kStateErr -6709
-#define kRangeErr -6710
-#define kRequestErr -6711
-#define kResponseErr -6712
-#define kChecksumErr -6713
-#define kNotHandledErr -6714
-#define kVersionErr -6715
-#define kSignatureErr -6716
-#define kFormatErr -6717
-#define kNotInitializedErr -6718
-#define kAlreadyInitializedErr -6719
-#define kNotInUseErr -6720
-#define kInUseErr -6721
-#define kTimeoutErr -6722
-#define kCanceledErr -6723
-#define kAlreadyCanceledErr -6724
-#define kCannotCancelErr -6725
-#define kDeletedErr -6726
-#define kNotFoundErr -6727
-#define kNoMemoryErr -6728
-#define kNoResourcesErr -6729
-#define kDuplicateErr -6730
-#define kImmutableErr -6731
-#define kUnsupportedDataErr -6732
-#define kIntegrityErr -6733
-#define kIncompatibleErr -6734
-#define kUnsupportedErr -6735
-#define kUnexpectedErr -6736
-#define kValueErr -6737
-#define kNotReadableErr -6738
-#define kNotWritableErr -6739
-#define kBadReferenceErr -6740
-#define kFlagErr -6741
-#define kMalformedErr -6742
-#define kSizeErr -6743
-#define kNameErr -6744
-#define kNotReadyErr -6745
-#define kReadErr -6746
-#define kWriteErr -6747
-#define kMismatchErr -6748
-#define kDateErr -6749
-#define kUnderrunErr -6750
-#define kOverrunErr -6751
-#define kEndingErr -6752
-#define kConnectionErr -6753
-#define kAuthenticationErr -6754
-#define kOpenErr -6755
-#define kTypeErr -6756
-#define kSkipErr -6757
-#define kNoAckErr -6758
-#define kCollisionErr -6759
-#define kBackoffErr -6760
-#define kNoAddressAckErr -6761
-#define kBusyErr -6762
-#define kNoSpaceErr -6763
-
-#define kGenericErrorEnd -6779 // Last generic error code (inclusive)
-
-#if 0
-#pragma mark == Mac Compatibility ==
-#endif
-
-
-// Mac Compatibility
-
-
-
-/*! @enum Duration
-
- @abstract Type used to specify a duration of time.
-
- @constant kDurationImmediate Indicates no delay/wait time.
- @constant kDurationMicrosecond Microsecond units.
- @constant kDurationMillisecond Millisecond units.
- @constant kDurationSecond Second units.
- @constant kDurationMinute Minute units.
- @constant kDurationHour Hour units.
- @constant kDurationDay Day units.
- @constant kDurationForever Infinite period of time (no timeout).
-
- @discussion
-
- Duration values are intended to be multiplied by the specific interval to achieve an actual duration. For example,
- to wait for 5 seconds you would use "5 * kDurationSecond".
- */
-
-#if ( TARGET_LANGUAGE_C_LIKE )
- #if ( !TARGET_OS_MAC )
-typedef int32_t Duration;
- #endif
-#endif
-
-#define kDurationImmediate 0L
-#define kDurationMicrosecond -1L
-#define kDurationMillisecond 1L
-#define kDurationSecond ( 1000L * kDurationMillisecond )
-#define kDurationMinute ( 60L * kDurationSecond )
-#define kDurationHour ( 60L * kDurationMinute )
-#define kDurationDay ( 24L * kDurationHour )
-#define kDurationForever 0x7FFFFFFFL
-
-// Seconds <-> Minutes <-> Hours <-> Days <-> Weeks <-> Months <-> Years conversions
-
-#define kSecondsPerHour ( 60 * 60 ) // 3600
-#define kSecondsPerDay ( 60 * 60 * 24 ) // 86400
-#define kSecondsPerWeek ( 60 * 60 * 24 * 7 ) // 604800
-#define kMinutesPerDay ( 60 * 24 ) // 1440
-
-
-/*! @defined VersionStages
-
- @abstract NumVersion-style version stages.
- */
-
-#define kVersionStageDevelopment 0x20
-#define kVersionStageAlpha 0x40
-#define kVersionStageBeta 0x60
-#define kVersionStageFinal 0x80
-
-
-/*! @function NumVersionBuild
-
- @abstract Builds a 32-bit Mac-style NumVersion value (e.g. NumVersionBuild( 1, 2, 3, kVersionStageBeta, 4 ) -> 1.2.3b4).
- */
-
-#define NumVersionBuild( MAJOR, MINOR, BUGFIX, STAGE, REV ) \
- ( ( ( ( MAJOR ) & 0xFF ) << 24 ) | \
- ( ( ( MINOR ) & 0x0F ) << 20 ) | \
- ( ( ( BUGFIX ) & 0x0F ) << 16 ) | \
- ( ( ( STAGE ) & 0xFF ) << 8 ) | \
- ( ( ( REV ) & 0xFF ) ) )
-
-#define NumVersionExtractMajor( VERSION ) ( (uint8_t)( ( ( VERSION ) >> 24 ) & 0xFF ) )
-#define NumVersionExtractMinorAndBugFix( VERSION ) ( (uint8_t)( ( ( VERSION ) >> 16 ) & 0xFF ) )
-#define NumVersionExtractMinor( VERSION ) ( (uint8_t)( ( ( VERSION ) >> 20 ) & 0x0F ) )
-#define NumVersionExtractBugFix( VERSION ) ( (uint8_t)( ( ( VERSION ) >> 16 ) & 0x0F ) )
-#define NumVersionExtractStage( VERSION ) ( (uint8_t)( ( ( VERSION ) >> 8 ) & 0xFF ) )
-#define NumVersionExtractRevision( VERSION ) ( (uint8_t)( ( VERSION ) & 0xFF ) )
-
-
-/*! @function NumVersionCompare
-
- @abstract Compares two NumVersion values and returns the following values:
-
- left < right -> -1
- left > right -> 1
- left = right -> 0
- */
-
-#if ( TARGET_LANGUAGE_C_LIKE )
-int NumVersionCompare( uint32_t inLeft, uint32_t inRight );
-#endif
-
-#if 0
-#pragma mark == Binary Constants ==
-#endif
-
-
-/*! @defined binary_4
-
- @abstract Macro to generate an 4-bit constant using binary notation (e.g. binary_4( 1010 ) == 0xA).
- */
-
-#define binary_4( a ) binary_4_hex_wrap( hex_digit4( a ) )
-#define binary_4_hex_wrap( a ) binary_4_hex( a )
-#define binary_4_hex( a ) ( 0x ## a )
-
-
-/*! @defined binary_8
-
- @abstract Macro to generate an 8-bit constant using binary notation (e.g. binary_8( 01111011 ) == 0x7B).
- */
-
-#define binary_8( a ) binary_8_hex_wrap( hex_digit8( a ) )
-#define binary_8_hex_wrap( a ) binary_8_hex( a )
-#define binary_8_hex( a ) ( 0x ## a )
-
-
-/*! @defined binary_16
-
- @abstract Macro to generate an 16-bit constant using binary notation (e.g. binary_16( 01111011, 01111011 ) == 0x7B7B).
- */
-
-#define binary_16( a, b ) binary_16_hex_wrap( hex_digit8( a ), hex_digit8( b ) )
-#define binary_16_hex_wrap( a, b ) binary_16_hex( a, b )
-#define binary_16_hex( a, b ) ( 0x ## a ## b )
-
-
-/*! @defined binary_32
-
- @abstract Macro to generate an 32-bit constant using binary notation
- (e.g. binary_32( 01111011, 01111011, 01111011, 01111011 ) == 0x7B7B7B7B).
- */
-
-#define binary_32( a, b, c, d ) binary_32_hex_wrap( hex_digit8( a ), hex_digit8( b ), hex_digit8( c ), hex_digit8( d ) )
-#define binary_32_hex_wrap( a, b, c, d ) binary_32_hex( a, b, c, d )
-#define binary_32_hex( a, b, c, d ) ( 0x ## a ## b ## c ## d )
-
-// Binary Constant Helpers
-
-#define hex_digit8( a ) HEX_DIGIT_ ## a
-#define hex_digit4( a ) HEX_DIGIT_ ## 0000 ## a
-
-
-#if 0
-#pragma mark == Debugging ==
-#endif
-
-
-/*! @function CommonServicesTest
-
- @abstract Unit test.
- */
-
-#if ( DEBUG )
- #if ( TARGET_LANGUAGE_C_LIKE )
-OSStatus CommonServicesTest( void );
- #endif
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __COMMON_SERVICES__
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/DebugServices.c b/sd/source/ui/remotecontrol/mDNSResponder/DebugServices.c
deleted file mode 100644
index 7f57d88705aa..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/DebugServices.c
+++ /dev/null
@@ -1,2978 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-
- To Do:
-
- - Use StackWalk on Windows to optionally print stack frames.
- */
-
-#if 0
-#pragma mark == Includes ==
-#endif
-
-
-// Includes
-#if ( !KERNEL )
- #include <ctype.h>
- #include <stdio.h>
- #include <string.h>
-#endif
-
-#include "CommonServices.h"
-
-#include "DebugServices.h"
-
-#if ( DEBUG )
-
-#if ( TARGET_OS_VXWORKS )
- #include "intLib.h"
-#endif
-
-#if ( TARGET_OS_WIN32 )
- #include <time.h>
-
- #if ( !TARGET_OS_WINDOWS_CE )
- #include <fcntl.h>
- #include <io.h>
- #endif
-#endif
-
-#if ( DEBUG_IDEBUG_ENABLED && TARGET_API_MAC_OSX_KERNEL )
- #include <IOKit/IOLib.h>
-#endif
-
-// If MDNS_DEBUGMSGS is defined (even if defined 0), it is aware of mDNS and it is probably safe to include mDNSEmbeddedAPI.h.
-#if ( defined( MDNS_DEBUGMSGS ) )
- #include "mDNSEmbeddedAPI.h"
-#endif
-
-#if 0
-#pragma mark == Macros ==
-#endif
-
-
-// Macros
-#define DebugIsPrint( C ) ( ( ( C ) >= 0x20 ) && ( ( C ) <= 0x7E ) )
-
-#if 0
-#pragma mark == Prototypes ==
-#endif
-
-
-// Prototypes
-static OSStatus DebugPrint( DebugLevel inLevel, char *inData, size_t inSize );
-
-// fprintf
-#if ( DEBUG_FPRINTF_ENABLED )
-static OSStatus DebugFPrintFInit( DebugOutputTypeFlags inFlags, const char *inFilename );
-static void DebugFPrintFPrint( char *inData, size_t inSize );
-#endif
-
-// iDebug (Mac OS X user and kernel)
-#if ( DEBUG_IDEBUG_ENABLED )
-static OSStatus DebugiDebugInit( void );
-static void DebugiDebugPrint( char *inData, size_t inSize );
-#endif
-
-// kprintf (Mac OS X Kernel)
-#if ( DEBUG_KPRINTF_ENABLED )
-static void DebugKPrintFPrint( char *inData, size_t inSize );
-#endif
-
-// Mac OS X IOLog (Mac OS X Kernel)
-#if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
-static void DebugMacOSXIOLogPrint( char *inData, size_t inSize );
-#endif
-
-// Mac OS X Log
-#if ( TARGET_OS_MAC )
-static OSStatus DebugMacOSXLogInit( void );
-static void DebugMacOSXLogPrint( char *inData, size_t inSize );
-#endif
-
-// Windows Debugger
-#if ( TARGET_OS_WIN32 )
-static void DebugWindowsDebuggerPrint( char *inData, size_t inSize );
-#endif
-
-// Windows Event Log
-#if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
-static OSStatus DebugWindowsEventLogInit( const char *inName, HMODULE inModule );
-static void DebugWindowsEventLogPrint( DebugLevel inLevel, char *inData, size_t inSize );
-#endif
-
-// DebugLib support
-#if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
-static pascal void
-DebugAssertOutputHandler(
- OSType inComponentSignature,
- UInt32 inOptions,
- const char * inAssertionString,
- const char * inExceptionString,
- const char * inErrorString,
- const char * inFileName,
- long inLineNumber,
- void * inValue,
- ConstStr255Param inOutputMsg );
-#endif
-
-// Utilities
-static char * DebugNumVersionToString( uint32_t inVersion, char *inString );
-
-#if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
-static void DebugWinEnableConsole( void );
-#endif
-
-#if ( TARGET_OS_WIN32 )
-static TCHAR *
-DebugWinCharToTCharString(
- const char * inCharString,
- size_t inCharCount,
- TCHAR * outTCharString,
- size_t inTCharCountMax,
- size_t * outTCharCount );
-#endif
-
-#if 0
-#pragma mark == Globals ==
-#endif
-
-
-// Private Globals
-#if ( TARGET_OS_VXWORKS )
-// TCP States for inetstatShow.
-
-extern char ** pTcpstates; // defined in tcpLib.c
-
-const char * kDebugTCPStates[] =
-{
- "(0) TCPS_CLOSED",
- "(1) TCPS_LISTEN",
- "(2) TCPS_SYN_SENT",
- "(3) TCPS_SYN_RECEIVED",
- "(4) TCPS_ESTABLISHED",
- "(5) TCPS_CLOSE_WAIT",
- "(6) TCPS_FIN_WAIT_1",
- "(7) TCPS_CLOSING",
- "(8) TCPS_LAST_ACK",
- "(9) TCPS_FIN_WAIT_2",
- "(10) TCPS_TIME_WAIT",
-};
-#endif
-
-// General
-static bool gDebugInitialized = false;
-static DebugOutputType gDebugOutputType = kDebugOutputTypeNone;
-static DebugLevel gDebugPrintLevelMin = kDebugLevelInfo;
-static DebugLevel gDebugPrintLevelMax = kDebugLevelMax;
-static DebugLevel gDebugBreakLevel = kDebugLevelAssert;
-#if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
-static DebugAssertOutputHandlerUPP gDebugAssertOutputHandlerUPP = NULL;
-#endif
-
-// Custom
-static DebugOutputFunctionPtr gDebugCustomOutputFunction = NULL;
-static void * gDebugCustomOutputContext = NULL;
-
-// fprintf
-
-#if ( DEBUG_FPRINTF_ENABLED )
-static FILE * gDebugFPrintFFile = NULL;
-#endif
-
-// MacOSXLog
-#if ( TARGET_OS_MAC )
-typedef int ( *DebugMacOSXLogFunctionPtr )( const char *inFormat, ... );
-
-static DebugMacOSXLogFunctionPtr gDebugMacOSXLogFunction = NULL;
-#endif
-
-// WindowsEventLog
-#if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
-static HANDLE gDebugWindowsEventLogEventSource = NULL;
-#endif
-
-#if 0
-#pragma mark -
-#pragma mark == General ==
-#endif
-
-
-// DebugInitialize
-DEBUG_EXPORT OSStatus DebugInitialize( DebugOutputType inType, ... )
-{
- OSStatus err;
- DebugOutputType type;
- va_list args;
-
- va_start( args, inType );
-
-#if ( TARGET_OS_VXWORKS )
- // Set up the TCP state strings if they are not already set up by VxWorks (normally not set up for some reason).
-
- if( !pTcpstates )
- {
- pTcpstates = (char **) kDebugTCPStates;
- }
-#endif
-
- // Set up DebugLib stuff (if building with Debugging.h).
-
-#if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
- if( !gDebugAssertOutputHandlerUPP )
- {
- gDebugAssertOutputHandlerUPP = NewDebugAssertOutputHandlerUPP( DebugAssertOutputHandler );
- check( gDebugAssertOutputHandlerUPP );
- if( gDebugAssertOutputHandlerUPP )
- {
- InstallDebugAssertOutputHandler( gDebugAssertOutputHandlerUPP );
- }
- }
-#endif
-
- // Pre-process meta-output kind to pick an appropriate output kind for the platform.
-
- type = inType;
- if( type == kDebugOutputTypeMetaConsole )
- {
- #if ( TARGET_OS_MAC )
- type = kDebugOutputTypeMacOSXLog;
- #elif ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
- #if ( DEBUG_FPRINTF_ENABLED )
- type = kDebugOutputTypeFPrintF;
- #else
- type = kDebugOutputTypeWindowsDebugger;
- #endif
- #elif ( TARGET_API_MAC_OSX_KERNEL )
- #if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
- type = kDebugOutputTypeMacOSXIOLog;
- #elif ( DEBUG_IDEBUG_ENABLED )
- type = kDebugOutputTypeiDebug;
- #elif ( DEBUG_KPRINTF_ENABLED )
- type = kDebugOutputTypeKPrintF;
- #endif
- #elif ( TARGET_OS_VXWORKS )
- #if ( DEBUG_FPRINTF_ENABLED )
- type = kDebugOutputTypeFPrintF;
- #else
- #error target is VxWorks, but fprintf output is disabled
- #endif
- #else
- #if ( DEBUG_FPRINTF_ENABLED )
- type = kDebugOutputTypeFPrintF;
- #endif
- #endif
- }
-
- // Process output kind
- gDebugOutputType = type;
- switch( type )
- {
- case kDebugOutputTypeNone:
- err = kNoErr;
- break;
-
- case kDebugOutputTypeCustom:
- gDebugCustomOutputFunction = va_arg( args, DebugOutputFunctionPtr );
- gDebugCustomOutputContext = va_arg( args, void * );
- err = kNoErr;
- break;
-
-#if ( DEBUG_FPRINTF_ENABLED )
- case kDebugOutputTypeFPrintF:
- if( inType == kDebugOutputTypeMetaConsole )
- {
- err = DebugFPrintFInit( kDebugOutputTypeFlagsStdErr, NULL );
- }
- else
- {
- DebugOutputTypeFlags flags;
- const char * filename;
-
- flags = (DebugOutputTypeFlags) va_arg( args, unsigned int );
- if( ( flags & kDebugOutputTypeFlagsTypeMask ) == kDebugOutputTypeFlagsFile )
- {
- filename = va_arg( args, const char * );
- }
- else
- {
- filename = NULL;
- }
- err = DebugFPrintFInit( flags, filename );
- }
- break;
-#endif
-
-#if ( DEBUG_IDEBUG_ENABLED )
- case kDebugOutputTypeiDebug:
- err = DebugiDebugInit();
- break;
-#endif
-
-#if ( DEBUG_KPRINTF_ENABLED )
- case kDebugOutputTypeKPrintF:
- err = kNoErr;
- break;
-#endif
-
-#if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
- case kDebugOutputTypeMacOSXIOLog:
- err = kNoErr;
- break;
-#endif
-
-#if ( TARGET_OS_MAC )
- case kDebugOutputTypeMacOSXLog:
- err = DebugMacOSXLogInit();
- break;
-#endif
-
-#if ( TARGET_OS_WIN32 )
- case kDebugOutputTypeWindowsDebugger:
- err = kNoErr;
- break;
-#endif
-
-#if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
- case kDebugOutputTypeWindowsEventLog:
- {
- const char * name;
- HMODULE module;
-
- name = va_arg( args, const char * );
- module = va_arg( args, HMODULE );
- err = DebugWindowsEventLogInit( name, module );
- }
- break;
-#endif
-
- default:
- err = kParamErr;
- goto exit;
- }
- gDebugInitialized = true;
-
-exit:
- va_end( args );
- return err;
-}
-
-
-// DebugFinalize
-DEBUG_EXPORT void DebugFinalize( void )
-{
-#if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
- check( gDebugAssertOutputHandlerUPP );
- if( gDebugAssertOutputHandlerUPP )
- {
- InstallDebugAssertOutputHandler( NULL );
- DisposeDebugAssertOutputHandlerUPP( gDebugAssertOutputHandlerUPP );
- gDebugAssertOutputHandlerUPP = NULL;
- }
-#endif
-}
-
-
-// DebugGetProperty
-DEBUG_EXPORT OSStatus DebugGetProperty( DebugPropertyTag inTag, ... )
-{
- OSStatus err;
- va_list args;
- DebugLevel * level;
-
- va_start( args, inTag );
- switch( inTag )
- {
- case kDebugPropertyTagPrintLevelMin:
- level = va_arg( args, DebugLevel * );
- *level = gDebugPrintLevelMin;
- err = kNoErr;
- break;
-
- case kDebugPropertyTagPrintLevelMax:
- level = va_arg( args, DebugLevel * );
- *level = gDebugPrintLevelMax;
- err = kNoErr;
- break;
-
- case kDebugPropertyTagBreakLevel:
- level = va_arg( args, DebugLevel * );
- *level = gDebugBreakLevel;
- err = kNoErr;
- break;
-
- default:
- err = kUnsupportedErr;
- break;
- }
- va_end( args );
- return err;
-}
-
-
-// DebugSetProperty
-DEBUG_EXPORT OSStatus DebugSetProperty( DebugPropertyTag inTag, ... )
-{
- OSStatus err;
- va_list args;
- DebugLevel level;
-
- va_start( args, inTag );
- switch( inTag )
- {
- case kDebugPropertyTagPrintLevelMin:
- level = va_arg( args, DebugLevel );
- gDebugPrintLevelMin = level;
- err = kNoErr;
- break;
-
- case kDebugPropertyTagPrintLevelMax:
- level = va_arg( args, DebugLevel );
- gDebugPrintLevelMax = level;
- err = kNoErr;
- break;
-
- case kDebugPropertyTagBreakLevel:
- level = va_arg( args, DebugLevel );
- gDebugBreakLevel = level;
- err = kNoErr;
- break;
-
- default:
- err = kUnsupportedErr;
- break;
- }
- va_end( args );
- return err;
-}
-
-#if 0
-#pragma mark -
-#pragma mark == Output ==
-#endif
-
-
-// DebugPrintF
-DEBUG_EXPORT size_t DebugPrintF( DebugLevel inLevel, const char *inFormat, ... )
-{
- va_list args;
- size_t n;
-
- // Skip if the level is not in the enabled range..
-
- if( ( inLevel < gDebugPrintLevelMin ) || ( inLevel > gDebugPrintLevelMax ) )
- {
- n = 0;
- goto exit;
- }
-
- va_start( args, inFormat );
- n = DebugPrintFVAList( inLevel, inFormat, args );
- va_end( args );
-
-exit:
- return n;
-}
-
-
-// DebugPrintFVAList
-DEBUG_EXPORT size_t DebugPrintFVAList( DebugLevel inLevel, const char *inFormat, va_list inArgs )
-{
- size_t n;
- char buffer[ 512 ];
-
- // Skip if the level is not in the enabled range..
-
- if( ( inLevel < gDebugPrintLevelMin ) || ( inLevel > gDebugPrintLevelMax ) )
- {
- n = 0;
- goto exit;
- }
-
- n = DebugSNPrintFVAList( buffer, sizeof( buffer ), inFormat, inArgs );
- DebugPrint( inLevel, buffer, (size_t) n );
-
-exit:
- return n;
-}
-
-
-// DebugPrint
-static OSStatus DebugPrint( DebugLevel inLevel, char *inData, size_t inSize )
-{
- OSStatus err;
-
- // Skip if the level is not in the enabled range..
-
- if( ( inLevel < gDebugPrintLevelMin ) || ( inLevel > gDebugPrintLevelMax ) )
- {
- err = kRangeErr;
- goto exit;
- }
-
- // Printing is not safe at interrupt time so check for this and warn with an interrupt safe mechanism (if available).
-
- if( DebugTaskLevel() & kDebugInterruptLevelMask )
- {
- #if ( TARGET_OS_VXWORKS )
- logMsg( "\ncannot print at interrupt time\n\n", 1, 2, 3, 4, 5, 6 );
- #endif
-
- err = kExecutionStateErr;
- goto exit;
- }
-
- // Initialize the debugging library if it hasn't already been initialized (allows for zero-config usage).
-
- if( !gDebugInitialized )
- {
- debug_initialize( kDebugOutputTypeMetaConsole );
- }
-
- // Print based on the current output type.
-
- switch( gDebugOutputType )
- {
- case kDebugOutputTypeNone:
- break;
-
- case kDebugOutputTypeCustom:
- if( gDebugCustomOutputFunction )
- {
- gDebugCustomOutputFunction( inData, inSize, gDebugCustomOutputContext );
- }
- break;
-
-#if ( DEBUG_FPRINTF_ENABLED )
- case kDebugOutputTypeFPrintF:
- DebugFPrintFPrint( inData, inSize );
- break;
-#endif
-
-#if ( DEBUG_IDEBUG_ENABLED )
- case kDebugOutputTypeiDebug:
- DebugiDebugPrint( inData, inSize );
- break;
-#endif
-
-#if ( DEBUG_KPRINTF_ENABLED )
- case kDebugOutputTypeKPrintF:
- DebugKPrintFPrint( inData, inSize );
- break;
-#endif
-
-#if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
- case kDebugOutputTypeMacOSXIOLog:
- DebugMacOSXIOLogPrint( inData, inSize );
- break;
-#endif
-
-#if ( TARGET_OS_MAC )
- case kDebugOutputTypeMacOSXLog:
- DebugMacOSXLogPrint( inData, inSize );
- break;
-#endif
-
-#if ( TARGET_OS_WIN32 )
- case kDebugOutputTypeWindowsDebugger:
- DebugWindowsDebuggerPrint( inData, inSize );
- break;
-#endif
-
-#if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
- case kDebugOutputTypeWindowsEventLog:
- DebugWindowsEventLogPrint( inLevel, inData, inSize );
- break;
-#endif
-
- default:
- break;
- }
- err = kNoErr;
-
-exit:
- return err;
-}
-
-
-// DebugPrintAssert
-
-// Warning: This routine relies on several of the strings being string constants that will exist forever because the
-// underlying logMsg API that does the printing is asynchronous so it cannot use temporary/stack-based
-// pointer variables (e.g. local strings). The debug macros that invoke this function only use constant
-// constant strings, but if this function is invoked directly from other places, it must use constant strings.
-DEBUG_EXPORT void
-DebugPrintAssert(
- int_least32_t inErrorCode,
- const char * inAssertString,
- const char * inMessage,
- const char * inFilename,
- int_least32_t inLineNumber,
- const char * inFunction )
-{
- // Skip if the level is not in the enabled range..
- if( ( kDebugLevelAssert < gDebugPrintLevelMin ) || ( kDebugLevelAssert > gDebugPrintLevelMax ) )
- {
- return;
- }
-
- if( inErrorCode != 0 )
- {
- DebugPrintF(
- kDebugLevelAssert,
- "\n"
- "[ASSERT] error: %ld (%m)\n"
- "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
- "\n",
- inErrorCode, inErrorCode,
- inFilename ? inFilename : "",
- inLineNumber,
- inFunction ? inFunction : "" );
- }
- else
- {
- DebugPrintF(
- kDebugLevelAssert,
- "\n"
- "[ASSERT] assert: \"%s\" %s\n"
- "[ASSERT] where: \"%s\", line %ld, \"%s\"\n"
- "\n",
- inAssertString ? inAssertString : "",
- inMessage ? inMessage : "",
- inFilename ? inFilename : "",
- inLineNumber,
- inFunction ? inFunction : "" );
- }
-
- // Break into the debugger if enabled
- #if ( TARGET_OS_WIN32 )
- if( gDebugBreakLevel <= kDebugLevelAssert )
- {
- if( IsDebuggerPresent() )
- {
- DebugBreak();
- }
- }
- #endif
-}
-
-#if 0
-#pragma mark -
-#endif
-
-#if ( DEBUG_FPRINTF_ENABLED )
-
-// DebugFPrintFInit
-static OSStatus DebugFPrintFInit( DebugOutputTypeFlags inFlags, const char *inFilename )
-{
- OSStatus err;
- DebugOutputTypeFlags typeFlags;
-
- typeFlags = inFlags & kDebugOutputTypeFlagsTypeMask;
- if( typeFlags == kDebugOutputTypeFlagsStdOut )
- {
- #if ( TARGET_OS_WIN32 )
- DebugWinEnableConsole();
- #endif
-
- gDebugFPrintFFile = stdout;
- }
- else if( typeFlags == kDebugOutputTypeFlagsStdErr )
- {
- #if ( TARGET_OS_WIN32 )
- DebugWinEnableConsole();
- #endif
-
- gDebugFPrintFFile = stdout;
- }
- else if( typeFlags == kDebugOutputTypeFlagsFile )
- {
- require_action_quiet( inFilename && ( *inFilename != '\0' ), exit, err = kOpenErr );
-
- gDebugFPrintFFile = fopen( inFilename, "a" );
- require_action_quiet( gDebugFPrintFFile, exit, err = kOpenErr );
- }
- else
- {
- err = kParamErr;
- goto exit;
- }
- err = kNoErr;
-
-exit:
- return err;
-}
-
-
-// DebugFPrintFPrint
-static void DebugFPrintFPrint( char *inData, size_t inSize )
-{
- char * p;
- char * q;
-
- // Convert \r to \n. fprintf will interpret \n and convert to whatever is appropriate for the platform.
- p = inData;
- q = p + inSize;
- while( p < q )
- {
- if( *p == '\r' )
- {
- *p = '\n';
- }
- ++p;
- }
-
- // Write the data and flush.
- if( gDebugFPrintFFile )
- {
- fprintf( gDebugFPrintFFile, "%.*s", (int) inSize, inData );
- fflush( gDebugFPrintFFile );
- }
-}
-#endif // DEBUG_FPRINTF_ENABLED
-
-#if ( DEBUG_IDEBUG_ENABLED )
-
-// DebugiDebugInit
-static OSStatus DebugiDebugInit( void )
-{
- OSStatus err;
-
- #if ( TARGET_API_MAC_OSX_KERNEL )
-
- extern uint32_t * _giDebugReserved1;
-
- // Emulate the iDebugSetOutputType macro in iDebugServices.h.
- // Note: This is not thread safe, but neither is iDebugServices.h nor iDebugKext.
- if( !_giDebugReserved1 )
- {
- _giDebugReserved1 = (uint32_t *) IOMalloc( sizeof( uint32_t ) );
- require_action_quiet( _giDebugReserved1, exit, err = kNoMemoryErr );
- }
- *_giDebugReserved1 = 0x00010000U;
- err = kNoErr;
-exit:
- #else
-
- __private_extern__ void iDebugSetOutputTypeInternal( uint32_t inType );
-
- iDebugSetOutputTypeInternal( 0x00010000U );
- err = kNoErr;
-
- #endif
-
- return err;
-}
-
-
-// DebugiDebugPrint
-static void DebugiDebugPrint( char *inData, size_t inSize )
-{
- #if ( TARGET_API_MAC_OSX_KERNEL )
-
- // Locally declared here so we do not need to include iDebugKext.h.
- // Note: IOKit uses a global namespace for all code and only a partial link occurs at build time. When the
- // KEXT is loaded, the runtime linker will link in this extern'd symbol (assuming iDebug is present).
- // _giDebugLogInternal is actually part of IOKit proper so this should link even if iDebug is not present.
-
- typedef void ( *iDebugLogFunctionPtr )( uint32_t inLevel, uint32_t inTag, const char *inFormat, ... );
-
- extern iDebugLogFunctionPtr _giDebugLogInternal;
-
- if( _giDebugLogInternal )
- {
- _giDebugLogInternal( 0, 0, "%.*s", (int) inSize, inData );
- }
-
- #else
-
- __private_extern__ void iDebugLogInternal( uint32_t inLevel, uint32_t inTag, const char *inFormat, ... );
-
- iDebugLogInternal( 0, 0, "%.*s", (int) inSize, inData );
-
- #endif
-}
-#endif
-
-#if ( DEBUG_KPRINTF_ENABLED )
-
-// DebugKPrintFPrint
-static void DebugKPrintFPrint( char *inData, size_t inSize )
-{
- extern void kprintf( const char *inFormat, ... );
-
- kprintf( "%.*s", (int) inSize, inData );
-}
-#endif
-
-#if ( DEBUG_MAC_OS_X_IOLOG_ENABLED )
-
-// DebugMacOSXIOLogPrint
-static void DebugMacOSXIOLogPrint( char *inData, size_t inSize )
-{
- extern void IOLog( const char *inFormat, ... );
-
- IOLog( "%.*s", (int) inSize, inData );
-}
-#endif
-
-#if ( TARGET_OS_MAC )
-
-// DebugMacOSXLogInit
-static OSStatus DebugMacOSXLogInit( void )
-{
- OSStatus err;
- CFStringRef path;
- CFURLRef url;
- CFBundleRef bundle;
- CFStringRef functionName;
- void * functionPtr;
-
- bundle = NULL;
-
- // Create a bundle reference for System.framework.
-
- path = CFSTR( "/System/Library/Frameworks/System.framework" );
- url = CFURLCreateWithFileSystemPath( NULL, path, kCFURLPOSIXPathStyle, true );
- require_action_quiet( url, exit, err = memFullErr );
-
- bundle = CFBundleCreate( NULL, url );
- CFRelease( url );
- require_action_quiet( bundle, exit, err = memFullErr );
-
- // Get a ptr to the system's "printf" function from System.framework.
-
- functionName = CFSTR( "printf" );
- functionPtr = CFBundleGetFunctionPointerForName( bundle, functionName );
- require_action_quiet( functionPtr, exit, err = memFullErr );
-
- // Success! Note: The bundle cannot be released because it would invalidate the function ptr.
-
- gDebugMacOSXLogFunction = (DebugMacOSXLogFunctionPtr) functionPtr;
- bundle = NULL;
- err = noErr;
-
-exit:
- if( bundle )
- {
- CFRelease( bundle );
- }
- return err;
-}
-
-// DebugMacOSXLogPrint
-static void DebugMacOSXLogPrint( char *inData, size_t inSize )
-{
- if( gDebugMacOSXLogFunction )
- {
- gDebugMacOSXLogFunction( "%.*s", (int) inSize, inData );
- }
-}
-#endif
-
-#if ( TARGET_OS_WIN32 )
-
-// DebugWindowsDebuggerPrint
-void DebugWindowsDebuggerPrint( char *inData, size_t inSize )
-{
- TCHAR buffer[ 512 ];
- const char * src;
- const char * end;
- TCHAR * dst;
- char c;
-
- // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
- // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
- src = inData;
- if( inSize >= sizeof_array( buffer ) )
- {
- inSize = sizeof_array( buffer ) - 1;
- }
- end = src + inSize;
- dst = buffer;
- while( src < end )
- {
- c = *src++;
- if( c == '\r' )
- {
- c = '\n';
- }
- *dst++ = (TCHAR) c;
- }
- *dst = 0;
-
- // Print out the string to the debugger.
- OutputDebugString( buffer );
-}
-#endif
-
-#if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
-
-// DebugWindowsEventLogInit
-static OSStatus DebugWindowsEventLogInit( const char *inName, HMODULE inModule )
-{
- OSStatus err;
- HKEY key;
- TCHAR name[ 128 ];
- const char * src;
- TCHAR path[ MAX_PATH ];
- size_t size;
- DWORD typesSupported;
- DWORD n;
-
- key = NULL;
-
- // Use a default name if needed then convert the name to TCHARs so it works on ANSI or Unicode builds.
- if( !inName || ( *inName == '\0' ) )
- {
- inName = "DefaultApp";
- }
- DebugWinCharToTCharString( inName, kSizeCString, name, sizeof( name ), NULL );
-
- // Build the path string using the fixed registry path and app name.
- src = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
- DebugWinCharToTCharString( src, kSizeCString, path, sizeof_array( path ), &size );
- DebugWinCharToTCharString( inName, kSizeCString, path + size, sizeof_array( path ) - size, NULL );
-
- // Add/Open the source name as a sub-key under the Application key in the EventLog registry key.
- err = RegCreateKeyEx( HKEY_LOCAL_MACHINE, path, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &key, NULL );
- require_noerr_quiet( err, exit );
-
- // Set the path in the EventMessageFile subkey. Add 1 to the TCHAR count to include the null terminator.
- n = GetModuleFileName( inModule, path, sizeof_array( path ) );
- err = translate_errno( n > 0, (OSStatus) GetLastError(), kParamErr );
- require_noerr_quiet( err, exit );
- n += 1;
- n *= sizeof( TCHAR );
-
- err = RegSetValueEx( key, TEXT( "EventMessageFile" ), 0, REG_EXPAND_SZ, (const LPBYTE) path, n );
- require_noerr_quiet( err, exit );
-
- // Set the supported event types in the TypesSupported subkey.
- typesSupported = EVENTLOG_SUCCESS | EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE |
- EVENTLOG_AUDIT_SUCCESS | EVENTLOG_AUDIT_FAILURE;
- err = RegSetValueEx( key, TEXT( "TypesSupported" ), 0, REG_DWORD, (const LPBYTE) &typesSupported, sizeof( DWORD ) );
- require_noerr_quiet( err, exit );
-
- // Set up the event source.
- gDebugWindowsEventLogEventSource = RegisterEventSource( NULL, name );
- err = translate_errno( gDebugWindowsEventLogEventSource, (OSStatus) GetLastError(), kParamErr );
- require_noerr_quiet( err, exit );
-
-exit:
- if( key )
- {
- RegCloseKey( key );
- }
- return err;
-}
-
-
-// DebugWindowsEventLogPrint
-static void DebugWindowsEventLogPrint( DebugLevel inLevel, char *inData, size_t inSize )
-{
- WORD type;
- TCHAR buffer[ 512 ];
- const char * src;
- const char * end;
- TCHAR * dst;
- char c;
- const TCHAR * array[ 1 ];
-
- // Map the debug level to a Windows EventLog type
- if( inLevel <= kDebugLevelNotice )
- {
- type = EVENTLOG_INFORMATION_TYPE;
- }
- else if( inLevel <= kDebugLevelWarning )
- {
- type = EVENTLOG_WARNING_TYPE;
- }
- else
- {
- type = EVENTLOG_ERROR_TYPE;
- }
-
- // Copy locally and null terminate the string. This also converts from char to TCHAR in case we are
- // building with UNICODE enabled since the input is always char. Also convert \r to \n in the process.
- src = inData;
- if( inSize >= sizeof_array( buffer ) )
- {
- inSize = sizeof_array( buffer ) - 1;
- }
- end = src + inSize;
- dst = buffer;
- while( src < end )
- {
- c = *src++;
- if( c == '\r' )
- {
- c = '\n';
- }
- *dst++ = (TCHAR) c;
- }
- *dst = 0;
-
- // Add the string to the event log.
- array[ 0 ] = buffer;
- if( gDebugWindowsEventLogEventSource )
- {
- ReportEvent( gDebugWindowsEventLogEventSource, type, 0, 0x20000001L, NULL, 1, 0, array, NULL );
- }
-}
-#endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
-
-#if ( DEBUG_CORE_SERVICE_ASSERTS_ENABLED )
-
-// DebugAssertOutputHandler
-static pascal void
-DebugAssertOutputHandler(
- OSType inComponentSignature,
- UInt32 inOptions,
- const char * inAssertString,
- const char * inExceptionString,
- const char * inErrorString,
- const char * inFileName,
- long inLineNumber,
- void * inValue,
- ConstStr255Param inOutputMsg )
-{
- DEBUG_UNUSED( inComponentSignature );
- DEBUG_UNUSED( inOptions );
- DEBUG_UNUSED( inExceptionString );
- DEBUG_UNUSED( inValue );
- DEBUG_UNUSED( inOutputMsg );
-
- DebugPrintAssert( 0, inAssertString, inErrorString, inFileName, (int_least32_t) inLineNumber, "" );
-}
-#endif
-
-#if 0
-#pragma mark -
-#pragma mark == Utilities ==
-#endif
-
-
-// DebugSNPrintF
-
-// Stolen from mDNS.c's mDNS_snprintf/mDNS_vsnprintf with the following changes:
-
-// Changed names to avoid name collisions with the mDNS versions.
-// Changed types to standard C types since mDNSEmbeddedAPI.h may not be available.
-// Conditionalized mDNS stuff so it can be used with or with mDNSEmbeddedAPI.h.
-// Added 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
-// Added %@ - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
-// Added %.8a - FIbre Channel address. Arg=ptr to address.
-// Added %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
-// Added %b - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
-// Added %C - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
-// Added %H - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
-// Added %#H - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
-// Added %m - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code args are the same as %d, %x, etc.
-// Added %S - UTF-16 string. Host order if no BOM. Precision is UTF-16 char count. BOM counts in any precision. Arg=ptr.
-// Added %#S - Big Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
-// Added %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise the same as %S.
-// Added %U - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
-
-
-DEBUG_EXPORT size_t DebugSNPrintF(char *sbuffer, size_t buflen, const char *fmt, ...)
-{
- size_t length;
-
- va_list ptr;
- va_start(ptr,fmt);
- length = DebugSNPrintFVAList(sbuffer, buflen, fmt, ptr);
- va_end(ptr);
-
- return length;
-}
-
-
-// DebugSNPrintFVAList - va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
-DEBUG_EXPORT size_t DebugSNPrintFVAList(char *sbuffer, size_t buflen, const char *fmt, va_list arg)
-{
- static const struct DebugSNPrintF_format
- {
- unsigned leftJustify : 1;
- unsigned forceSign : 1;
- unsigned zeroPad : 1;
- unsigned havePrecision : 1;
- unsigned hSize : 1;
- char lSize;
- char altForm;
- char sign; // +, - or space
- unsigned int fieldWidth;
- unsigned int precision;
- } DebugSNPrintF_format_default = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
- size_t nwritten = 0;
- int c;
- if (buflen == 0) return 0;
- buflen--; // Pre-reserve one space in the buffer for the terminating nul
- if (buflen == 0) goto exit;
-
- for (c = *fmt; c != 0; c = *++fmt)
- {
- if (c != '%')
- {
- *sbuffer++ = (char)c;
- if (++nwritten >= buflen) goto exit;
- }
- else
- {
- size_t i=0, j;
- // The mDNS Vsprintf Argument Conversion Buffer is used as a temporary holding area for
- // generating decimal numbers, hexdecimal numbers, IP addresses, domain name strings, etc.
- // The size needs to be enough for a 256-byte domain name plus some error text.
- #define mDNS_VACB_Size 300
- char mDNS_VACB[mDNS_VACB_Size];
- #define mDNS_VACB_Lim (&mDNS_VACB[mDNS_VACB_Size])
- #define mDNS_VACB_Remain(s) ((size_t)(mDNS_VACB_Lim - s))
- char *s = mDNS_VACB_Lim;
- const char *digits = "0123456789ABCDEF";
- struct DebugSNPrintF_format F = DebugSNPrintF_format_default;
-
- for(;;) // decode flags
- {
- c = *++fmt;
- if (c == '-') F.leftJustify = 1;
- else if (c == '+') F.forceSign = 1;
- else if (c == ' ') F.sign = ' ';
- else if (c == '#') F.altForm++;
- else if (c == '0') F.zeroPad = 1;
- else break;
- }
-
- if (c == '*') // decode field width
- {
- int f = va_arg(arg, int);
- if (f < 0) { f = -f; F.leftJustify = 1; }
- F.fieldWidth = (unsigned int)f;
- c = *++fmt;
- }
- else
- {
- for (; c >= '0' && c <= '9'; c = *++fmt)
- F.fieldWidth = (10 * F.fieldWidth) + (c - '0');
- }
-
- if (c == '.') // decode precision
- {
- if ((c = *++fmt) == '*')
- { F.precision = va_arg(arg, unsigned int); c = *++fmt; }
- else for (; c >= '0' && c <= '9'; c = *++fmt)
- F.precision = (10 * F.precision) + (c - '0');
- F.havePrecision = 1;
- }
-
- if (F.leftJustify) F.zeroPad = 0;
-
-conv:
- switch (c) // perform appropriate conversion
- {
- #if TYPE_LONGLONG_NATIVE
- unsigned_long_long_compat n;
- unsigned_long_long_compat base;
- #else
- unsigned long n;
- unsigned long base;
- #endif
- case 'h': F.hSize = 1; c = *++fmt; goto conv;
- case 'l': // fall through
- case 'L': F.lSize++; c = *++fmt; goto conv;
- case 'd':
- case 'i': base = 10;
- goto canBeSigned;
- case 'u': base = 10;
- goto notSigned;
- case 'o': base = 8;
- goto notSigned;
- case 'b': base = 2;
- goto notSigned;
- case 'p': n = va_arg(arg, uintptr_t);
- F.havePrecision = 1;
- F.precision = (sizeof(uintptr_t) == 4) ? 8 : 16;
- F.sign = 0;
- base = 16;
- c = 'x';
- goto number;
- case 'x': digits = "0123456789abcdef";
- case 'X': base = 16;
- goto notSigned;
-canBeSigned:
- #if TYPE_LONGLONG_NATIVE
- if (F.lSize == 1) n = (unsigned_long_long_compat)va_arg(arg, long);
- else if (F.lSize == 2) n = (unsigned_long_long_compat)va_arg(arg, long_long_compat);
- else n = (unsigned_long_long_compat)va_arg(arg, int);
- #else
- if (F.lSize == 1) n = (unsigned long)va_arg(arg, long);
- else if (F.lSize == 2) goto exit;
- else n = (unsigned long)va_arg(arg, int);
- #endif
- if (F.hSize) n = (short) n;
- #if TYPE_LONGLONG_NATIVE
- if ((long_long_compat) n < 0) { n = (unsigned_long_long_compat)-(long_long_compat)n; F.sign = '-'; }
- #else
- if ((long) n < 0) { n = (unsigned long)-(long)n; F.sign = '-'; }
- #endif
- else if (F.forceSign) F.sign = '+';
- goto number;
-
-notSigned: if (F.lSize == 1) n = va_arg(arg, unsigned long);
- else if (F.lSize == 2)
- {
- #if TYPE_LONGLONG_NATIVE
- n = va_arg(arg, unsigned_long_long_compat);
- #else
- goto exit;
- #endif
- }
- else n = va_arg(arg, unsigned int);
- if (F.hSize) n = (unsigned short) n;
- F.sign = 0;
- goto number;
-
-number: if (!F.havePrecision)
- {
- if (F.zeroPad)
- {
- F.precision = F.fieldWidth;
- if (F.altForm) F.precision -= 2;
- if (F.sign) --F.precision;
- }
- if (F.precision < 1) F.precision = 1;
- }
- if (F.precision > mDNS_VACB_Size - 1)
- F.precision = mDNS_VACB_Size - 1;
- for (i = 0; n; n /= base, i++) *--s = (char)(digits[n % base]);
- for (; i < F.precision; i++) *--s = '0';
- if (F.altForm) { *--s = (char)c; *--s = '0'; i += 2; }
- if (F.sign) { *--s = F.sign; i++; }
- break;
-
- case 'a': {
- unsigned char *a = va_arg(arg, unsigned char *);
- char pre[4] = "";
- char post[32] = "";
- if (!a) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
- else
- {
- s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
- if (F.altForm == 1)
- {
- #if (defined(MDNS_DEBUGMSGS))
- mDNSAddr *ip = (mDNSAddr*)a;
- switch (ip->type)
- {
- case mDNSAddrType_IPv4: F.precision = 4; a = (unsigned char *)&ip->ip.v4; break;
- case mDNSAddrType_IPv6: F.precision = 16; a = (unsigned char *)&ip->ip.v6; break;
- default: F.precision = 0; break;
- }
- #else
- F.precision = 0; // mDNSEmbeddedAPI.h not included so no mDNSAddr support
- #endif
- }
- else if (F.altForm == 2)
- {
- #ifdef AF_INET
- const struct sockaddr *sa;
- unsigned char *port;
- sa = (const struct sockaddr*)a;
- switch (sa->sa_family)
- {
- case AF_INET: F.precision = 4; a = (unsigned char*)&((const struct sockaddr_in *)a)->sin_addr;
- port = (unsigned char*)&((const struct sockaddr_in *)sa)->sin_port;
- DebugSNPrintF(post, sizeof(post), ":%d", (port[0] << 8) | port[1]); break;
- #ifdef AF_INET6
- case AF_INET6: F.precision = 16; a = (unsigned char*)&((const struct sockaddr_in6 *)a)->sin6_addr;
- pre[0] = '['; pre[1] = '\0';
- port = (unsigned char*)&((const struct sockaddr_in6 *)sa)->sin6_port;
- DebugSNPrintF(post, sizeof(post), "%%%d]:%d",
- (int)((const struct sockaddr_in6 *)sa)->sin6_scope_id,
- (port[0] << 8) | port[1]); break;
- #endif
- default: F.precision = 0; break;
- }
- #else
- F.precision = 0; // socket interfaces not included so no sockaddr support
- #endif
- }
- switch (F.precision)
- {
- case 4: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%d.%d.%d.%d%s",
- a[0], a[1], a[2], a[3], post); break;
- case 6: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%02X:%02X:%02X:%02X:%02X:%02X",
- a[0], a[1], a[2], a[3], a[4], a[5]); break;
- case 8: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X",
- a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); break;
- case 16: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB),
- "%s%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X%s",
- pre, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8],
- a[9], a[10], a[11], a[12], a[13], a[14], a[15], post); break;
- default: i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%s", "<< ERROR: Must specify address size "
- "(i.e. %.4a=IPv4, %.6a=Ethernet, %.8a=Fibre Channel %.16a=IPv6) >>"); break;
- }
- }
- }
- break;
-
- case 'U': {
- unsigned char *a = va_arg(arg, unsigned char *);
- if (!a) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
- else
- {
- s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
- i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
- *((uint32_t*) &a[0]), *((uint16_t*) &a[4]), *((uint16_t*) &a[6]),
- a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); break;
- }
- }
- break;
-
- case 'c': *--s = (char)va_arg(arg, int); i = 1; break;
-
- case 'C': if (F.lSize) n = va_arg(arg, unsigned long);
- else n = va_arg(arg, unsigned int);
- if (F.hSize) n = (unsigned short) n;
- c = (int)( n & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
- c = (int)((n >> 8) & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
- c = (int)((n >> 16) & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
- c = (int)((n >> 24) & 0xFF); *--s = (char)(DebugIsPrint(c) ? c : '^');
- i = 4;
- break;
-
- case 's': s = va_arg(arg, char *);
- if (!s) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
- else switch (F.altForm)
- {
- case 0: i=0;
- if (F.havePrecision) // C string
- {
- while((i < F.precision) && s[i]) i++;
- // Make sure we don't truncate in the middle of a UTF-8 character.
- // If the last character is part of a multi-byte UTF-8 character, back up to the start of it.
- j=0;
- while((i > 0) && ((c = s[i-1]) & 0x80)) { j++; i--; if((c & 0xC0) != 0x80) break;}
- // If the actual count of UTF-8 characters matches the encoded UTF-8 count, add it back.
- if((j > 1) && (j <= 6))
- {
- int test = (0xFF << (8-j)) & 0xFF;
- int mask = test | (1 << ((8-j)-1));
- if((c & mask) == test) i += j;
- }
- }
- else
- while(s[i]) i++;
- break;
- case 1: i = (unsigned char) *s++; break; // Pascal string
- case 2: { // DNS label-sequence name
- unsigned char *a = (unsigned char *)s;
- s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
- if (*a == 0) *s++ = '.'; // Special case for root DNS name
- while (*a)
- {
- if (*a > 63) { s += DebugSNPrintF(s, mDNS_VACB_Remain(s), "<<INVALID LABEL LENGTH %u>>", *a); break; }
- if (s + *a >= &mDNS_VACB[254]) { s += DebugSNPrintF(s, mDNS_VACB_Remain(s), "<<NAME TOO LONG>>"); break; }
- s += DebugSNPrintF(s, mDNS_VACB_Remain(s), "%#s.", a);
- a += 1 + *a;
- }
- i = (size_t)(s - mDNS_VACB);
- s = mDNS_VACB; // Reset s back to the start of the buffer
- break;
- }
- }
- if (F.havePrecision && i > F.precision) // Make sure we don't truncate in the middle of a UTF-8 character
- { i = F.precision; while (i>0 && (s[i] & 0xC0) == 0x80) i--;}
- break;
-
- case 'S': { // UTF-16 string
- unsigned char *a = va_arg(arg, unsigned char *);
- uint16_t *u = (uint16_t*)a;
- if (!u) { static char emsg[] = "<<NULL>>"; s = emsg; i = sizeof(emsg)-1; }
- if ((!F.havePrecision || F.precision))
- {
- if ((a[0] == 0xFE) && (a[1] == 0xFF)) { F.altForm = 1; u += 1; a += 2; F.precision--; } // Big Endian
- else if ((a[0] == 0xFF) && (a[1] == 0xFE)) { F.altForm = 2; u += 1; a += 2; F.precision--; } // Little Endian
- }
- s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
- switch (F.altForm)
- {
- case 0: while ((!F.havePrecision || (i < F.precision)) && u[i] && mDNS_VACB_Remain(s)) // Host Endian
- { c = u[i]; *s++ = (char)(DebugIsPrint(c) ? c : '^'); i++; }
- break;
- case 1: while ((!F.havePrecision || (i < F.precision)) && u[i] && mDNS_VACB_Remain(s)) // Big Endian
- { c = ((a[0] << 8) | a[1]) & 0xFF; *s++ = (char)(DebugIsPrint(c) ? c : '^'); i++; a += 2; }
- break;
- case 2: while ((!F.havePrecision || (i < F.precision)) && u[i] && mDNS_VACB_Remain(s)) // Little Endian
- { c = ((a[1] << 8) | a[0]) & 0xFF; *s++ = (char)(DebugIsPrint(c) ? c : '^'); i++; a += 2; }
- break;
- }
- }
- s = mDNS_VACB; // Reset s back to the start of the buffer
- break;
-
- #if TARGET_OS_MAC
- case '@': { // Cocoa/CoreFoundation object
- CFTypeRef cfObj;
- CFStringRef cfStr;
- cfObj = (CFTypeRef) va_arg(arg, void *);
- cfStr = (CFGetTypeID(cfObj) == CFStringGetTypeID()) ? (CFStringRef)CFRetain(cfObj) : CFCopyDescription(cfObj);
- s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
- if (cfStr)
- {
- CFRange range;
- CFIndex m;
- range = CFRangeMake(0, CFStringGetLength(cfStr));
- m = 0;
- CFStringGetBytes(cfStr, range, kCFStringEncodingUTF8, '^', false, (UInt8*)mDNS_VACB, (CFIndex)sizeof(mDNS_VACB), &m);
- CFRelease(cfStr);
- i = (size_t) m;
- }
- else
- {
- i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "%s", "ERROR: <invalid CF object>" );
- }
- }
- if (F.havePrecision && i > F.precision) // Make sure we don't truncate in the middle of a UTF-8 character
- { i = F.precision; while (i>0 && (s[i] & 0xC0) == 0x80) i--;}
- break;
- #endif
-
- case 'm': { // Error Message
- long err;
- if (F.lSize) err = va_arg(arg, long);
- else err = va_arg(arg, int);
- if (F.hSize) err = (short)err;
- DebugGetErrorString(err, mDNS_VACB, sizeof(mDNS_VACB));
- s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
- for(i=0; s[i]; i++) {}
- }
- break;
-
- case 'H': { // Hex Dump
- void *a = va_arg(arg, void *);
- size_t size = (size_t)va_arg(arg, int);
- size_t max = (size_t)va_arg(arg, int);
- DebugFlags flags =
- kDebugFlagsNoAddress | kDebugFlagsNoOffset | kDebugFlagsNoNewLine |
- kDebugFlags8BitSeparator | kDebugFlagsNo32BitSeparator |
- kDebugFlagsNo16ByteHexPad | kDebugFlagsNoByteCount;
- if (F.altForm == 0) flags |= kDebugFlagsNoASCII;
- size = (max < size) ? max : size;
- s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
- i = DebugHexDump(kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, a, a, size, flags, mDNS_VACB, sizeof(mDNS_VACB));
- }
- break;
-
- case 'v': { // Version
- uint32_t version;
- version = va_arg(arg, unsigned int);
- DebugNumVersionToString(version, mDNS_VACB);
- s = mDNS_VACB; // Adjust s to point to the start of the buffer, not the end
- for(i=0; s[i]; i++) {}
- }
- break;
-
- case 'n': s = va_arg(arg, char *);
- if (F.hSize) *(short *) s = (short)nwritten;
- else if (F.lSize) *(long *) s = (long)nwritten;
- else *(int *) s = (int)nwritten;
- continue;
-
- default: s = mDNS_VACB;
- i = DebugSNPrintF(mDNS_VACB, sizeof(mDNS_VACB), "<<UNKNOWN FORMAT CONVERSION CODE %%%c>>", c);
-
- case '%': *sbuffer++ = (char)c;
- if (++nwritten >= buflen) goto exit;
- break;
- }
-
- if (i < F.fieldWidth && !F.leftJustify) // Pad on the left
- do {
- *sbuffer++ = ' ';
- if (++nwritten >= buflen) goto exit;
- } while (i < --F.fieldWidth);
-
- if (i > buflen - nwritten) // Make sure we don't truncate in the middle of a UTF-8 character
- { i = buflen - nwritten; while (i>0 && (s[i] & 0xC0) == 0x80) i--;}
- for (j=0; j<i; j++) *sbuffer++ = *s++; // Write the converted result
- nwritten += i;
- if (nwritten >= buflen) goto exit;
-
- for (; i < F.fieldWidth; i++) // Pad on the right
- {
- *sbuffer++ = ' ';
- if (++nwritten >= buflen) goto exit;
- }
- }
- }
-exit:
- *sbuffer++ = 0;
- return nwritten;
-}
-
-
-// DebugGetErrorString
-DEBUG_EXPORT const char * DebugGetErrorString( int_least32_t inErrorCode, char *inBuffer, size_t inBufferSize )
-{
- const char * s;
- char * dst;
- char * end;
-#if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
- char buffer[ 256 ];
-#endif
-
- switch( inErrorCode )
- {
- #define CaseErrorString( X, STR ) case X: s = STR; break
- #define CaseErrorStringify( X ) case X: s = # X; break
- #define CaseErrorStringifyHardCode( VALUE, X ) case VALUE: s = # X; break
-
- // General Errors
-
- CaseErrorString( 0, "no error" );
- CaseErrorString( 1, "in-progress/waiting" );
- CaseErrorString( -1, "catch-all unknown error" );
-
- // ACP Errors
-
- CaseErrorStringifyHardCode( -2, kACPBadRequestErr );
- CaseErrorStringifyHardCode( -3, kACPNoMemoryErr );
- CaseErrorStringifyHardCode( -4, kACPBadParamErr );
- CaseErrorStringifyHardCode( -5, kACPNotFoundErr );
- CaseErrorStringifyHardCode( -6, kACPBadChecksumErr );
- CaseErrorStringifyHardCode( -7, kACPCommandNotHandledErr );
- CaseErrorStringifyHardCode( -8, kACPNetworkErr );
- CaseErrorStringifyHardCode( -9, kACPDuplicateCommandHandlerErr );
- CaseErrorStringifyHardCode( -10, kACPUnknownPropertyErr );
- CaseErrorStringifyHardCode( -11, kACPImmutablePropertyErr );
- CaseErrorStringifyHardCode( -12, kACPBadPropertyValueErr );
- CaseErrorStringifyHardCode( -13, kACPNoResourcesErr );
- CaseErrorStringifyHardCode( -14, kACPBadOptionErr );
- CaseErrorStringifyHardCode( -15, kACPBadSizeErr );
- CaseErrorStringifyHardCode( -16, kACPBadPasswordErr );
- CaseErrorStringifyHardCode( -17, kACPNotInitializedErr );
- CaseErrorStringifyHardCode( -18, kACPNonReadablePropertyErr );
- CaseErrorStringifyHardCode( -19, kACPBadVersionErr );
- CaseErrorStringifyHardCode( -20, kACPBadSignatureErr );
- CaseErrorStringifyHardCode( -21, kACPBadIndexErr );
- CaseErrorStringifyHardCode( -22, kACPUnsupportedErr );
- CaseErrorStringifyHardCode( -23, kACPInUseErr );
- CaseErrorStringifyHardCode( -24, kACPParamCountErr );
- CaseErrorStringifyHardCode( -25, kACPIDErr );
- CaseErrorStringifyHardCode( -26, kACPFormatErr );
- CaseErrorStringifyHardCode( -27, kACPUnknownUserErr );
- CaseErrorStringifyHardCode( -28, kACPAccessDeniedErr );
- CaseErrorStringifyHardCode( -29, kACPIncorrectFWErr );
-
- // Common Services Errors
-
- CaseErrorStringify( kUnknownErr );
- CaseErrorStringify( kOptionErr );
- CaseErrorStringify( kSelectorErr );
- CaseErrorStringify( kExecutionStateErr );
- CaseErrorStringify( kPathErr );
- CaseErrorStringify( kParamErr );
- CaseErrorStringify( kParamCountErr );
- CaseErrorStringify( kCommandErr );
- CaseErrorStringify( kIDErr );
- CaseErrorStringify( kStateErr );
- CaseErrorStringify( kRangeErr );
- CaseErrorStringify( kRequestErr );
- CaseErrorStringify( kResponseErr );
- CaseErrorStringify( kChecksumErr );
- CaseErrorStringify( kNotHandledErr );
- CaseErrorStringify( kVersionErr );
- CaseErrorStringify( kSignatureErr );
- CaseErrorStringify( kFormatErr );
- CaseErrorStringify( kNotInitializedErr );
- CaseErrorStringify( kAlreadyInitializedErr );
- CaseErrorStringify( kNotInUseErr );
- CaseErrorStringify( kInUseErr );
- CaseErrorStringify( kTimeoutErr );
- CaseErrorStringify( kCanceledErr );
- CaseErrorStringify( kAlreadyCanceledErr );
- CaseErrorStringify( kCannotCancelErr );
- CaseErrorStringify( kDeletedErr );
- CaseErrorStringify( kNotFoundErr );
- CaseErrorStringify( kNoMemoryErr );
- CaseErrorStringify( kNoResourcesErr );
- CaseErrorStringify( kDuplicateErr );
- CaseErrorStringify( kImmutableErr );
- CaseErrorStringify( kUnsupportedDataErr );
- CaseErrorStringify( kIntegrityErr );
- CaseErrorStringify( kIncompatibleErr );
- CaseErrorStringify( kUnsupportedErr );
- CaseErrorStringify( kUnexpectedErr );
- CaseErrorStringify( kValueErr );
- CaseErrorStringify( kNotReadableErr );
- CaseErrorStringify( kNotWritableErr );
- CaseErrorStringify( kBadReferenceErr );
- CaseErrorStringify( kFlagErr );
- CaseErrorStringify( kMalformedErr );
- CaseErrorStringify( kSizeErr );
- CaseErrorStringify( kNameErr );
- CaseErrorStringify( kNotReadyErr );
- CaseErrorStringify( kReadErr );
- CaseErrorStringify( kWriteErr );
- CaseErrorStringify( kMismatchErr );
- CaseErrorStringify( kDateErr );
- CaseErrorStringify( kUnderrunErr );
- CaseErrorStringify( kOverrunErr );
- CaseErrorStringify( kEndingErr );
- CaseErrorStringify( kConnectionErr );
- CaseErrorStringify( kAuthenticationErr );
- CaseErrorStringify( kOpenErr );
- CaseErrorStringify( kTypeErr );
- CaseErrorStringify( kSkipErr );
- CaseErrorStringify( kNoAckErr );
- CaseErrorStringify( kCollisionErr );
- CaseErrorStringify( kBackoffErr );
- CaseErrorStringify( kNoAddressAckErr );
- CaseErrorStringify( kBusyErr );
- CaseErrorStringify( kNoSpaceErr );
-
- // mDNS/DNS-SD Errors
-
- CaseErrorStringifyHardCode( -65537, mStatus_UnknownErr );
- CaseErrorStringifyHardCode( -65538, mStatus_NoSuchNameErr );
- CaseErrorStringifyHardCode( -65539, mStatus_NoMemoryErr );
- CaseErrorStringifyHardCode( -65540, mStatus_BadParamErr );
- CaseErrorStringifyHardCode( -65541, mStatus_BadReferenceErr );
- CaseErrorStringifyHardCode( -65542, mStatus_BadStateErr );
- CaseErrorStringifyHardCode( -65543, mStatus_BadFlagsErr );
- CaseErrorStringifyHardCode( -65544, mStatus_UnsupportedErr );
- CaseErrorStringifyHardCode( -65545, mStatus_NotInitializedErr );
- CaseErrorStringifyHardCode( -65546, mStatus_NoCache );
- CaseErrorStringifyHardCode( -65547, mStatus_AlreadyRegistered );
- CaseErrorStringifyHardCode( -65548, mStatus_NameConflict );
- CaseErrorStringifyHardCode( -65549, mStatus_Invalid );
- CaseErrorStringifyHardCode( -65550, mStatus_GrowCache );
- CaseErrorStringifyHardCode( -65551, mStatus_BadInterfaceErr );
- CaseErrorStringifyHardCode( -65552, mStatus_Incompatible );
- CaseErrorStringifyHardCode( -65791, mStatus_ConfigChanged );
- CaseErrorStringifyHardCode( -65792, mStatus_MemFree );
-
- // RSP Errors
-
- CaseErrorStringifyHardCode( -400000, kRSPUnknownErr );
- CaseErrorStringifyHardCode( -400050, kRSPParamErr );
- CaseErrorStringifyHardCode( -400108, kRSPNoMemoryErr );
- CaseErrorStringifyHardCode( -405246, kRSPRangeErr );
- CaseErrorStringifyHardCode( -409057, kRSPSizeErr );
- CaseErrorStringifyHardCode( -400200, kRSPHardwareErr );
- CaseErrorStringifyHardCode( -401712, kRSPTimeoutErr );
- CaseErrorStringifyHardCode( -402053, kRSPUnsupportedErr );
- CaseErrorStringifyHardCode( -402419, kRSPIDErr );
- CaseErrorStringifyHardCode( -403165, kRSPFlagErr );
- CaseErrorString( -200000, "kRSPControllerStatusBase - 0x50" );
- CaseErrorString( -200080, "kRSPCommandSucceededErr - 0x50" );
- CaseErrorString( -200001, "kRSPCommandFailedErr - 0x01" );
- CaseErrorString( -200051, "kRSPChecksumErr - 0x33" );
- CaseErrorString( -200132, "kRSPCommandTimeoutErr - 0x84" );
- CaseErrorString( -200034, "kRSPPasswordRequiredErr - 0x22 OBSOLETE" );
- CaseErrorString( -200128, "kRSPCanceledErr - 0x02 Async" );
-
- // XML Errors
-
- CaseErrorStringifyHardCode( -100043, kXMLNotFoundErr );
- CaseErrorStringifyHardCode( -100050, kXMLParamErr );
- CaseErrorStringifyHardCode( -100108, kXMLNoMemoryErr );
- CaseErrorStringifyHardCode( -100206, kXMLFormatErr );
- CaseErrorStringifyHardCode( -100586, kXMLNoRootElementErr );
- CaseErrorStringifyHardCode( -101703, kXMLWrongDataTypeErr );
- CaseErrorStringifyHardCode( -101726, kXMLKeyErr );
- CaseErrorStringifyHardCode( -102053, kXMLUnsupportedErr );
- CaseErrorStringifyHardCode( -102063, kXMLMissingElementErr );
- CaseErrorStringifyHardCode( -103026, kXMLParseErr );
- CaseErrorStringifyHardCode( -103159, kXMLBadDataErr );
- CaseErrorStringifyHardCode( -103170, kXMLBadNameErr );
- CaseErrorStringifyHardCode( -105246, kXMLRangeErr );
- CaseErrorStringifyHardCode( -105251, kXMLUnknownElementErr );
- CaseErrorStringifyHardCode( -108739, kXMLMalformedInputErr );
- CaseErrorStringifyHardCode( -109057, kXMLBadSizeErr );
- CaseErrorStringifyHardCode( -101730, kXMLMissingChildElementErr );
- CaseErrorStringifyHardCode( -102107, kXMLMissingParentElementErr );
- CaseErrorStringifyHardCode( -130587, kXMLNonRootElementErr );
- CaseErrorStringifyHardCode( -102015, kXMLDateErr );
-
- #if ( __MACH__ )
-
- // Mach Errors
-
- CaseErrorStringifyHardCode( 0x00002000, MACH_MSG_IPC_SPACE );
- CaseErrorStringifyHardCode( 0x00001000, MACH_MSG_VM_SPACE );
- CaseErrorStringifyHardCode( 0x00000800, MACH_MSG_IPC_KERNEL );
- CaseErrorStringifyHardCode( 0x00000400, MACH_MSG_VM_KERNEL );
- CaseErrorStringifyHardCode( 0x10000001, MACH_SEND_IN_PROGRESS );
- CaseErrorStringifyHardCode( 0x10000002, MACH_SEND_INVALID_DATA );
- CaseErrorStringifyHardCode( 0x10000003, MACH_SEND_INVALID_DEST );
- CaseErrorStringifyHardCode( 0x10000004, MACH_SEND_TIMED_OUT );
- CaseErrorStringifyHardCode( 0x10000007, MACH_SEND_INTERRUPTED );
- CaseErrorStringifyHardCode( 0x10000008, MACH_SEND_MSG_TOO_SMALL );
- CaseErrorStringifyHardCode( 0x10000009, MACH_SEND_INVALID_REPLY );
- CaseErrorStringifyHardCode( 0x1000000A, MACH_SEND_INVALID_RIGHT );
- CaseErrorStringifyHardCode( 0x1000000B, MACH_SEND_INVALID_NOTIFY );
- CaseErrorStringifyHardCode( 0x1000000C, MACH_SEND_INVALID_MEMORY );
- CaseErrorStringifyHardCode( 0x1000000D, MACH_SEND_NO_BUFFER );
- CaseErrorStringifyHardCode( 0x1000000E, MACH_SEND_TOO_LARGE );
- CaseErrorStringifyHardCode( 0x1000000F, MACH_SEND_INVALID_TYPE );
- CaseErrorStringifyHardCode( 0x10000010, MACH_SEND_INVALID_HEADER );
- CaseErrorStringifyHardCode( 0x10000011, MACH_SEND_INVALID_TRAILER );
- CaseErrorStringifyHardCode( 0x10000015, MACH_SEND_INVALID_RT_OOL_SIZE );
- CaseErrorStringifyHardCode( 0x10004001, MACH_RCV_IN_PROGRESS );
- CaseErrorStringifyHardCode( 0x10004002, MACH_RCV_INVALID_NAME );
- CaseErrorStringifyHardCode( 0x10004003, MACH_RCV_TIMED_OUT );
- CaseErrorStringifyHardCode( 0x10004004, MACH_RCV_TOO_LARGE );
- CaseErrorStringifyHardCode( 0x10004005, MACH_RCV_INTERRUPTED );
- CaseErrorStringifyHardCode( 0x10004006, MACH_RCV_PORT_CHANGED );
- CaseErrorStringifyHardCode( 0x10004007, MACH_RCV_INVALID_NOTIFY );
- CaseErrorStringifyHardCode( 0x10004008, MACH_RCV_INVALID_DATA );
- CaseErrorStringifyHardCode( 0x10004009, MACH_RCV_PORT_DIED );
- CaseErrorStringifyHardCode( 0x1000400A, MACH_RCV_IN_SET );
- CaseErrorStringifyHardCode( 0x1000400B, MACH_RCV_HEADER_ERROR );
- CaseErrorStringifyHardCode( 0x1000400C, MACH_RCV_BODY_ERROR );
- CaseErrorStringifyHardCode( 0x1000400D, MACH_RCV_INVALID_TYPE );
- CaseErrorStringifyHardCode( 0x1000400E, MACH_RCV_SCATTER_SMALL );
- CaseErrorStringifyHardCode( 0x1000400F, MACH_RCV_INVALID_TRAILER );
- CaseErrorStringifyHardCode( 0x10004011, MACH_RCV_IN_PROGRESS_TIMED );
-
- // Mach OSReturn Errors
-
- CaseErrorStringifyHardCode( 0xDC000001, kOSReturnError );
- CaseErrorStringifyHardCode( 0xDC004001, kOSMetaClassInternal );
- CaseErrorStringifyHardCode( 0xDC004002, kOSMetaClassHasInstances );
- CaseErrorStringifyHardCode( 0xDC004003, kOSMetaClassNoInit );
- CaseErrorStringifyHardCode( 0xDC004004, kOSMetaClassNoTempData );
- CaseErrorStringifyHardCode( 0xDC004005, kOSMetaClassNoDicts );
- CaseErrorStringifyHardCode( 0xDC004006, kOSMetaClassNoKModSet );
- CaseErrorStringifyHardCode( 0xDC004007, kOSMetaClassNoInsKModSet );
- CaseErrorStringifyHardCode( 0xDC004008, kOSMetaClassNoSuper );
- CaseErrorStringifyHardCode( 0xDC004009, kOSMetaClassInstNoSuper );
- CaseErrorStringifyHardCode( 0xDC00400A, kOSMetaClassDuplicateClass );
-
- // IOKit Errors
-
- CaseErrorStringifyHardCode( 0xE00002BC, kIOReturnError );
- CaseErrorStringifyHardCode( 0xE00002BD, kIOReturnNoMemory );
- CaseErrorStringifyHardCode( 0xE00002BE, kIOReturnNoResources );
- CaseErrorStringifyHardCode( 0xE00002BF, kIOReturnIPCError );
- CaseErrorStringifyHardCode( 0xE00002C0, kIOReturnNoDevice );
- CaseErrorStringifyHardCode( 0xE00002C1, kIOReturnNotPrivileged );
- CaseErrorStringifyHardCode( 0xE00002C2, kIOReturnBadArgument );
- CaseErrorStringifyHardCode( 0xE00002C3, kIOReturnLockedRead );
- CaseErrorStringifyHardCode( 0xE00002C4, kIOReturnLockedWrite );
- CaseErrorStringifyHardCode( 0xE00002C5, kIOReturnExclusiveAccess );
- CaseErrorStringifyHardCode( 0xE00002C6, kIOReturnBadMessageID );
- CaseErrorStringifyHardCode( 0xE00002C7, kIOReturnUnsupported );
- CaseErrorStringifyHardCode( 0xE00002C8, kIOReturnVMError );
- CaseErrorStringifyHardCode( 0xE00002C9, kIOReturnInternalError );
- CaseErrorStringifyHardCode( 0xE00002CA, kIOReturnIOError );
- CaseErrorStringifyHardCode( 0xE00002CC, kIOReturnCannotLock );
- CaseErrorStringifyHardCode( 0xE00002CD, kIOReturnNotOpen );
- CaseErrorStringifyHardCode( 0xE00002CE, kIOReturnNotReadable );
- CaseErrorStringifyHardCode( 0xE00002CF, kIOReturnNotWritable );
- CaseErrorStringifyHardCode( 0xE00002D0, kIOReturnNotAligned );
- CaseErrorStringifyHardCode( 0xE00002D1, kIOReturnBadMedia );
- CaseErrorStringifyHardCode( 0xE00002D2, kIOReturnStillOpen );
- CaseErrorStringifyHardCode( 0xE00002D3, kIOReturnRLDError );
- CaseErrorStringifyHardCode( 0xE00002D4, kIOReturnDMAError );
- CaseErrorStringifyHardCode( 0xE00002D5, kIOReturnBusy );
- CaseErrorStringifyHardCode( 0xE00002D6, kIOReturnTimeout );
- CaseErrorStringifyHardCode( 0xE00002D7, kIOReturnOffline );
- CaseErrorStringifyHardCode( 0xE00002D8, kIOReturnNotReady );
- CaseErrorStringifyHardCode( 0xE00002D9, kIOReturnNotAttached );
- CaseErrorStringifyHardCode( 0xE00002DA, kIOReturnNoChannels );
- CaseErrorStringifyHardCode( 0xE00002DB, kIOReturnNoSpace );
- CaseErrorStringifyHardCode( 0xE00002DD, kIOReturnPortExists );
- CaseErrorStringifyHardCode( 0xE00002DE, kIOReturnCannotWire );
- CaseErrorStringifyHardCode( 0xE00002DF, kIOReturnNoInterrupt );
- CaseErrorStringifyHardCode( 0xE00002E0, kIOReturnNoFrames );
- CaseErrorStringifyHardCode( 0xE00002E1, kIOReturnMessageTooLarge );
- CaseErrorStringifyHardCode( 0xE00002E2, kIOReturnNotPermitted );
- CaseErrorStringifyHardCode( 0xE00002E3, kIOReturnNoPower );
- CaseErrorStringifyHardCode( 0xE00002E4, kIOReturnNoMedia );
- CaseErrorStringifyHardCode( 0xE00002E5, kIOReturnUnformattedMedia );
- CaseErrorStringifyHardCode( 0xE00002E6, kIOReturnUnsupportedMode );
- CaseErrorStringifyHardCode( 0xE00002E7, kIOReturnUnderrun );
- CaseErrorStringifyHardCode( 0xE00002E8, kIOReturnOverrun );
- CaseErrorStringifyHardCode( 0xE00002E9, kIOReturnDeviceError );
- CaseErrorStringifyHardCode( 0xE00002EA, kIOReturnNoCompletion );
- CaseErrorStringifyHardCode( 0xE00002EB, kIOReturnAborted );
- CaseErrorStringifyHardCode( 0xE00002EC, kIOReturnNoBandwidth );
- CaseErrorStringifyHardCode( 0xE00002ED, kIOReturnNotResponding );
- CaseErrorStringifyHardCode( 0xE00002EE, kIOReturnIsoTooOld );
- CaseErrorStringifyHardCode( 0xE00002EF, kIOReturnIsoTooNew );
- CaseErrorStringifyHardCode( 0xE00002F0, kIOReturnNotFound );
- CaseErrorStringifyHardCode( 0xE0000001, kIOReturnInvalid );
-
- // IOKit FireWire Errors
-
- CaseErrorStringifyHardCode( 0xE0008010, kIOFireWireResponseBase );
- CaseErrorStringifyHardCode( 0xE0008020, kIOFireWireBusReset );
- CaseErrorStringifyHardCode( 0xE0008001, kIOConfigNoEntry );
- CaseErrorStringifyHardCode( 0xE0008002, kIOFireWirePending );
- CaseErrorStringifyHardCode( 0xE0008003, kIOFireWireLastDCLToken );
- CaseErrorStringifyHardCode( 0xE0008004, kIOFireWireConfigROMInvalid );
- CaseErrorStringifyHardCode( 0xE0008005, kIOFireWireAlreadyRegistered );
- CaseErrorStringifyHardCode( 0xE0008006, kIOFireWireMultipleTalkers );
- CaseErrorStringifyHardCode( 0xE0008007, kIOFireWireChannelActive );
- CaseErrorStringifyHardCode( 0xE0008008, kIOFireWireNoListenerOrTalker );
- CaseErrorStringifyHardCode( 0xE0008009, kIOFireWireNoChannels );
- CaseErrorStringifyHardCode( 0xE000800A, kIOFireWireChannelNotAvailable );
- CaseErrorStringifyHardCode( 0xE000800B, kIOFireWireSeparateBus );
- CaseErrorStringifyHardCode( 0xE000800C, kIOFireWireBadSelfIDs );
- CaseErrorStringifyHardCode( 0xE000800D, kIOFireWireLowCableVoltage );
- CaseErrorStringifyHardCode( 0xE000800E, kIOFireWireInsufficientPower );
- CaseErrorStringifyHardCode( 0xE000800F, kIOFireWireOutOfTLabels );
- CaseErrorStringifyHardCode( 0xE0008101, kIOFireWireBogusDCLProgram );
- CaseErrorStringifyHardCode( 0xE0008102, kIOFireWireTalkingAndListening );
- CaseErrorStringifyHardCode( 0xE0008103, kIOFireWireHardwareSlept );
- CaseErrorStringifyHardCode( 0xE00087D0, kIOFWMessageServiceIsRequestingClose );
- CaseErrorStringifyHardCode( 0xE00087D1, kIOFWMessagePowerStateChanged );
- CaseErrorStringifyHardCode( 0xE00087D2, kIOFWMessageTopologyChanged );
-
- // IOKit USB Errors
-
- CaseErrorStringifyHardCode( 0xE0004061, kIOUSBUnknownPipeErr );
- CaseErrorStringifyHardCode( 0xE0004060, kIOUSBTooManyPipesErr );
- CaseErrorStringifyHardCode( 0xE000405F, kIOUSBNoAsyncPortErr );
- CaseErrorStringifyHardCode( 0xE000405E, kIOUSBNotEnoughPipesErr );
- CaseErrorStringifyHardCode( 0xE000405D, kIOUSBNotEnoughPowerErr );
- CaseErrorStringifyHardCode( 0xE0004057, kIOUSBEndpointNotFound );
- CaseErrorStringifyHardCode( 0xE0004056, kIOUSBConfigNotFound );
- CaseErrorStringifyHardCode( 0xE0004051, kIOUSBTransactionTimeout );
- CaseErrorStringifyHardCode( 0xE0004050, kIOUSBTransactionReturned );
- CaseErrorStringifyHardCode( 0xE000404F, kIOUSBPipeStalled );
- CaseErrorStringifyHardCode( 0xE000404E, kIOUSBInterfaceNotFound );
- CaseErrorStringifyHardCode( 0xE000404D, kIOUSBLowLatencyBufferNotPreviouslyAllocated );
- CaseErrorStringifyHardCode( 0xE000404C, kIOUSBLowLatencyFrameListNotPreviouslyAllocated );
- CaseErrorStringifyHardCode( 0xE000404B, kIOUSBHighSpeedSplitError );
- CaseErrorStringifyHardCode( 0xE0004010, kIOUSBLinkErr );
- CaseErrorStringifyHardCode( 0xE000400F, kIOUSBNotSent2Err );
- CaseErrorStringifyHardCode( 0xE000400E, kIOUSBNotSent1Err );
- CaseErrorStringifyHardCode( 0xE000400D, kIOUSBBufferUnderrunErr );
- CaseErrorStringifyHardCode( 0xE000400C, kIOUSBBufferOverrunErr );
- CaseErrorStringifyHardCode( 0xE000400B, kIOUSBReserved2Err );
- CaseErrorStringifyHardCode( 0xE000400A, kIOUSBReserved1Err );
- CaseErrorStringifyHardCode( 0xE0004007, kIOUSBWrongPIDErr );
- CaseErrorStringifyHardCode( 0xE0004006, kIOUSBPIDCheckErr );
- CaseErrorStringifyHardCode( 0xE0004003, kIOUSBDataToggleErr );
- CaseErrorStringifyHardCode( 0xE0004002, kIOUSBBitstufErr );
- CaseErrorStringifyHardCode( 0xE0004001, kIOUSBCRCErr );
-
- #endif // __MACH__
-
- // Other Errors
-
- default:
- s = NULL;
- #if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
- if( inBuffer && ( inBufferSize > 0 ) )
- {
- DWORD n;
-
- n = FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, (DWORD) inErrorCode,
- MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), buffer, sizeof( buffer ), NULL );
- if( n > 0 )
- {
- // Remove any trailing CR's or LF's since some messages have them.
-
- while( ( n > 0 ) && isspace( ( (unsigned char *) buffer )[ n - 1 ] ) )
- {
- buffer[ --n ] = '\0';
- }
- s = buffer;
- }
- }
- #endif
-
- if( !s )
- {
- #if ( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
- s = strerror( inErrorCode );
- #endif
- if( !s )
- {
- s = "<unknown error code>";
- }
- }
- break;
- }
-
- // Copy the string to the output buffer. If no buffer is supplied or it is empty, return an empty string.
-
- if( inBuffer && ( inBufferSize > 0 ) )
- {
- dst = inBuffer;
- end = dst + ( inBufferSize - 1 );
- while( ( ( end - dst ) > 0 ) && ( *s != '\0' ) )
- {
- *dst++ = *s++;
- }
- *dst = '\0';
- s = inBuffer;
- }
- return s;
-}
-
-
-// DebugHexDump
-DEBUG_EXPORT size_t
-DebugHexDump(
- DebugLevel inLevel,
- int inIndent,
- const char * inLabel,
- size_t inLabelSize,
- int inLabelMinWidth,
- const char * inType,
- size_t inTypeSize,
- const void * inDataStart,
- const void * inData,
- size_t inDataSize,
- DebugFlags inFlags,
- char * outBuffer,
- size_t inBufferSize )
-{
- static const char kHexChars[] = "0123456789ABCDEF";
- const uint8_t * start;
- const uint8_t * src;
- char * dst;
- char * end;
- size_t n;
- int offset;
- int width;
- const char * newline;
- char separator[ 8 ];
- char * s;
-
- DEBUG_UNUSED( inType );
- DEBUG_UNUSED( inTypeSize );
-
- // Set up the function-wide variables.
-
- if( inLabelSize == kSizeCString )
- {
- inLabelSize = strlen( inLabel );
- }
- start = (const uint8_t *) inData;
- src = start;
- dst = outBuffer;
- end = dst + inBufferSize;
- offset = (int)( (intptr_t) inData - (intptr_t) inDataStart );
- width = ( (int) inLabelSize > inLabelMinWidth ) ? (int) inLabelSize : inLabelMinWidth;
- newline = ( inFlags & kDebugFlagsNoNewLine ) ? "" : "\n";
-
- // Set up the separator string. This is used to insert spaces on subsequent "lines" when not using newlines.
-
- s = separator;
- if( inFlags & kDebugFlagsNoNewLine )
- {
- if( inFlags & kDebugFlags8BitSeparator )
- {
- *s++ = ' ';
- }
- if( inFlags & kDebugFlags16BitSeparator )
- {
- *s++ = ' ';
- }
- if( !( inFlags & kDebugFlagsNo32BitSeparator ) )
- {
- *s++ = ' ';
- }
- check( ( (size_t)( s - separator ) ) < sizeof( separator ) );
- }
- *s = '\0';
-
- for( ;; )
- {
- char prefixString[ 32 ];
- char hexString[ 64 ];
- char asciiString[ 32 ];
- char byteCountString[ 32 ];
- int c;
- size_t chunkSize;
- size_t i;
-
- // If this is a label-only item (i.e. no data), print the label (accounting for prefix string spacing) and exit.
-
- if( inDataSize == 0 )
- {
- if( inLabel && ( inLabelSize > 0 ) )
- {
- width = 0;
- if( !( inFlags & kDebugFlagsNoAddress ) )
- {
- width += 8; // "00000000"
- if( !( inFlags & kDebugFlagsNoOffset ) )
- {
- width += 1; // "+"
- }
- }
- if( inFlags & kDebugFlags32BitOffset )
- {
- width += 8; // "00000000"
- }
- else if( !( inFlags & kDebugFlagsNoOffset ) )
- {
- width += 4; // "0000"
- }
-
- if( outBuffer )
- {
- dst += DebugSNPrintF( dst, (size_t)( end - dst ), "%*s" "%-*.*s" "%.*s" "%s",
- width, "",
- ( width > 0 ) ? ": " : "",
- width, (int) inLabelSize, inLabel,
- newline );
- }
- else
- {
- dst += DebugPrintF( inLevel, "%*s" "%-*.*s" "%.*s" "%s",
- width, "",
- ( width > 0 ) ? ": " : "",
- width, (int) inLabelSize, inLabel,
- newline );
- }
- }
- break;
- }
-
- // Build the prefix string. It will be in one of the following formats:
-
- // 1) "00000000+0000[0000]" (address and offset)
- // 2) "00000000" (address only)
- // 3) "0000[0000]" (offset only)
- // 4) "" (no address or offset)
-
- // Note: If we're printing multiple "lines", but not printing newlines, a space is used to separate.
-
- s = prefixString;
- if( !( inFlags & kDebugFlagsNoAddress ) )
- {
- *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 28 ) & 0xF ];
- *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 24 ) & 0xF ];
- *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 20 ) & 0xF ];
- *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 16 ) & 0xF ];
- *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 12 ) & 0xF ];
- *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 8 ) & 0xF ];
- *s++ = kHexChars[ ( ( (uintptr_t) src ) >> 4 ) & 0xF ];
- *s++ = kHexChars[ ( (uintptr_t) src ) & 0xF ];
-
- if( !( inFlags & kDebugFlagsNoOffset ) )
- {
- *s++ = '+';
- }
- }
- if( !( inFlags & kDebugFlagsNoOffset ) )
- {
- if( inFlags & kDebugFlags32BitOffset )
- {
- *s++ = kHexChars[ ( offset >> 28 ) & 0xF ];
- *s++ = kHexChars[ ( offset >> 24 ) & 0xF ];
- *s++ = kHexChars[ ( offset >> 20 ) & 0xF ];
- *s++ = kHexChars[ ( offset >> 16 ) & 0xF ];
- }
- *s++ = kHexChars[ ( offset >> 12 ) & 0xF ];
- *s++ = kHexChars[ ( offset >> 8 ) & 0xF ];
- *s++ = kHexChars[ ( offset >> 4 ) & 0xF ];
- *s++ = kHexChars[ offset & 0xF ];
- }
- if( s != prefixString )
- {
- *s++ = ':';
- *s++ = ' ';
- }
- check( ( (size_t)( s - prefixString ) ) < sizeof( prefixString ) );
- *s = '\0';
-
- // Build a hex string with a optional spaces after every 1, 2, and/or 4 bytes to make it easier to read.
- // Optionally pads the hex string with space to fill the full 16 byte range (so it lines up).
-
- s = hexString;
- chunkSize = ( inDataSize < 16 ) ? inDataSize : 16;
- n = ( inFlags & kDebugFlagsNo16ByteHexPad ) ? chunkSize : 16;
- for( i = 0; i < n; ++i )
- {
- if( ( inFlags & kDebugFlags8BitSeparator ) && ( i > 0 ) )
- {
- *s++ = ' ';
- }
- if( ( inFlags & kDebugFlags16BitSeparator ) && ( i > 0 ) && ( ( i % 2 ) == 0 ) )
- {
- *s++ = ' ';
- }
- if( !( inFlags & kDebugFlagsNo32BitSeparator ) && ( i > 0 ) && ( ( i % 4 ) == 0 ) )
- {
- *s++ = ' ';
- }
- if( i < chunkSize )
- {
- *s++ = kHexChars[ src[ i ] >> 4 ];
- *s++ = kHexChars[ src[ i ] & 0xF ];
- }
- else
- {
- *s++ = ' ';
- *s++ = ' ';
- }
- }
- check( ( (size_t)( s - hexString ) ) < sizeof( hexString ) );
- *s = '\0';
-
- // Build a string with the ASCII version of the data (replaces non-printable characters with '^').
- // Optionally pads the string with '`' to fill the full 16 byte range (so it lines up).
-
- s = asciiString;
- if( !( inFlags & kDebugFlagsNoASCII ) )
- {
- *s++ = ' ';
- *s++ = '|';
- for( i = 0; i < n; ++i )
- {
- if( i < chunkSize )
- {
- c = src[ i ];
- if( !DebugIsPrint( c ) )
- {
- c = '^';
- }
- }
- else
- {
- c = '`';
- }
- *s++ = (char) c;
- }
- *s++ = '|';
- check( ( (size_t)( s - asciiString ) ) < sizeof( asciiString ) );
- }
- *s = '\0';
-
- // Build a string indicating how bytes are in the hex dump. Only printed on the first line.
-
- s = byteCountString;
- if( !( inFlags & kDebugFlagsNoByteCount ) )
- {
- if( src == start )
- {
- s += DebugSNPrintF( s, sizeof( byteCountString ), " (%d bytes)", (int) inDataSize );
- }
- }
- check( ( (size_t)( s - byteCountString ) ) < sizeof( byteCountString ) );
- *s = '\0';
-
- // Build the entire line from all the pieces we've previously built.
-
- if( outBuffer )
- {
- if( src == start )
- {
- dst += DebugSNPrintF( dst, (size_t)( end - dst ),
- "%*s" // Indention
- "%s" // Separator (only if needed)
- "%s" // Prefix
- "%-*.*s" // Label
- "%s" // Separator
- "%s" // Hex
- "%s" // ASCII
- "%s" // Byte Count
- "%s", // Newline
- inIndent, "",
- ( src != start ) ? separator : "",
- prefixString,
- width, (int) inLabelSize, inLabel ? inLabel : "",
- ( width > 0 ) ? " " : "",
- hexString,
- asciiString,
- byteCountString,
- newline );
- }
- else
- {
- dst += DebugSNPrintF( dst, (size_t)( end - dst ),
- "%*s" // Indention
- "%s" // Separator (only if needed)
- "%s" // Prefix
- "%*s" // Label Spacing
- "%s" // Separator
- "%s" // Hex
- "%s" // ASCII
- "%s" // Byte Count
- "%s", // Newline
- inIndent, "",
- ( src != start ) ? separator : "",
- prefixString,
- width, "",
- ( width > 0 ) ? " " : "",
- hexString,
- asciiString,
- byteCountString,
- newline );
- }
- }
- else
- {
- if( src == start )
- {
- dst += DebugPrintF( inLevel,
- "%*s" // Indention
- "%s" // Separator (only if needed)
- "%s" // Prefix
- "%-*.*s" // Label
- "%s" // Separator
- "%s" // Hex
- "%s" // ASCII
- "%s" // Byte Count
- "%s", // Newline
- inIndent, "",
- ( src != start ) ? separator : "",
- prefixString,
- width, (int) inLabelSize, inLabel,
- ( width > 0 ) ? " " : "",
- hexString,
- asciiString,
- byteCountString,
- newline );
- }
- else
- {
- dst += DebugPrintF( inLevel,
- "%*s" // Indention
- "%s" // Separator (only if needed)
- "%s" // Prefix
- "%*s" // Label Spacing
- "%s" // Separator
- "%s" // Hex
- "%s" // ASCII
- "%s" // Byte Count
- "%s", // Newline
- inIndent, "",
- ( src != start ) ? separator : "",
- prefixString,
- width, "",
- ( width > 0 ) ? " " : "",
- hexString,
- asciiString,
- byteCountString,
- newline );
- }
- }
-
- // Move to the next chunk. Exit if there is no more data.
-
- offset += (int) chunkSize;
- src += chunkSize;
- inDataSize -= chunkSize;
- if( inDataSize == 0 )
- {
- break;
- }
- }
-
- // Note: The "dst - outBuffer" size calculation works even if "outBuffer" is NULL because it's all relative.
-
- return (size_t)( dst - outBuffer );
-}
-
-
-// DebugNumVersionToString
-static char * DebugNumVersionToString( uint32_t inVersion, char *inString )
-{
- char * s;
- uint8_t majorRev;
- uint8_t minor;
- uint8_t bugFix;
- uint8_t stage;
- uint8_t revision;
-
- check( inString );
-
- majorRev = (uint8_t)( ( inVersion >> 24 ) & 0xFF );
- minor = (uint8_t)( ( inVersion >> 20 ) & 0x0F );
- bugFix = (uint8_t)( ( inVersion >> 16 ) & 0x0F );
- stage = (uint8_t)( ( inVersion >> 8 ) & 0xFF );
- revision = (uint8_t)( inVersion & 0xFF );
-
- // Convert the major, minor, and bugfix numbers.
-
- s = inString;
- s += sprintf( s, "%u", majorRev );
- s += sprintf( s, ".%u", minor );
- if( bugFix != 0 )
- {
- s += sprintf( s, ".%u", bugFix );
- }
-
- // Convert the version stage and non-release revision number.
-
- switch( stage )
- {
- case kVersionStageDevelopment:
- s += sprintf( s, "d%u", revision );
- break;
-
- case kVersionStageAlpha:
- s += sprintf( s, "a%u", revision );
- break;
-
- case kVersionStageBeta:
- s += sprintf( s, "b%u", revision );
- break;
-
- case kVersionStageFinal:
-
- // A non-release revision of zero is a special case indicating the software is GM (at the golden master
- // stage) and therefore, the non-release revision should not be added to the string.
-
- if( revision != 0 )
- {
- s += sprintf( s, "f%u", revision );
- }
- break;
-
- default:
- dlog( kDebugLevelError, "invalid NumVersion stage (0x%02X)\n", stage );
- break;
- }
- return inString;
-}
-
-
-// DebugTaskLevel
-DEBUG_EXPORT uint32_t DebugTaskLevel( void )
-{
- uint32_t level;
-
- level = 0;
-
-#if ( TARGET_OS_VXWORKS )
- if( intContext() )
- {
- level |= ( ( 1 << kDebugInterruptLevelShift ) & kDebugInterruptLevelMask );
- }
-#endif
-
- return level;
-}
-
-#if ( TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE )
-
-// DebugWinEnableConsole
-#pragma warning( disable:4311 )
-
-static void DebugWinEnableConsole( void )
-{
- static bool sConsoleEnabled = false;
- BOOL result;
- int fileHandle;
- FILE * file;
- int err;
-
- if( sConsoleEnabled )
- {
- goto exit;
- }
-
- // Create console window.
-
- result = AllocConsole();
- require_quiet( result, exit );
-
- // Redirect stdin to the console stdin.
-
- fileHandle = _open_osfhandle( (long) GetStdHandle( STD_INPUT_HANDLE ), _O_TEXT );
-
- #if ( defined( __MWERKS__ ) )
- file = __handle_reopen( (unsigned long) fileHandle, "r", stdin );
- require_quiet( file, exit );
- #else
- file = _fdopen( fileHandle, "r" );
- require_quiet( file, exit );
-
- *stdin = *file;
- #endif
-
- err = setvbuf( stdin, NULL, _IONBF, 0 );
- require_noerr_quiet( err, exit );
-
- // Redirect stdout to the console stdout.
-
- fileHandle = _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE ), _O_TEXT );
-
- #if ( defined( __MWERKS__ ) )
- file = __handle_reopen( (unsigned long) fileHandle, "w", stdout );
- require_quiet( file, exit );
- #else
- file = _fdopen( fileHandle, "w" );
- require_quiet( file, exit );
-
- *stdout = *file;
- #endif
-
- err = setvbuf( stdout, NULL, _IONBF, 0 );
- require_noerr_quiet( err, exit );
-
- // Redirect stderr to the console stdout.
-
- fileHandle = _open_osfhandle( (long) GetStdHandle( STD_OUTPUT_HANDLE ), _O_TEXT );
-
- #if ( defined( __MWERKS__ ) )
- file = __handle_reopen( (unsigned long) fileHandle, "w", stderr );
- require_quiet( file, exit );
- #else
- file = _fdopen( fileHandle, "w" );
- require_quiet( file, exit );
-
- *stderr = *file;
- #endif
-
- err = setvbuf( stderr, NULL, _IONBF, 0 );
- require_noerr_quiet( err, exit );
-
- sConsoleEnabled = true;
-
-exit:
- return;
-}
-
-#pragma warning( default:4311 )
-
-#endif // TARGET_OS_WIN32 && !TARGET_OS_WINDOWS_CE
-
-#if ( TARGET_OS_WIN32 )
-
-// DebugWinCharToTCharString
-static TCHAR *
-DebugWinCharToTCharString(
- const char * inCharString,
- size_t inCharCount,
- TCHAR * outTCharString,
- size_t inTCharCountMax,
- size_t * outTCharCount )
-{
- const char * src;
- TCHAR * dst;
- TCHAR * end;
-
- if( inCharCount == kSizeCString )
- {
- inCharCount = strlen( inCharString );
- }
- src = inCharString;
- dst = outTCharString;
- if( inTCharCountMax > 0 )
- {
- inTCharCountMax -= 1;
- if( inTCharCountMax > inCharCount )
- {
- inTCharCountMax = inCharCount;
- }
-
- end = dst + inTCharCountMax;
- while( dst < end )
- {
- *dst++ = (TCHAR) *src++;
- }
- *dst = 0;
- }
- if( outTCharCount )
- {
- *outTCharCount = (size_t)( dst - outTCharString );
- }
- return outTCharString;
-}
-#endif
-
-#if 0
-#pragma mark -
-#pragma mark == Debugging ==
-#endif
-
-
-// DebugServicesTest
-DEBUG_EXPORT OSStatus DebugServicesTest( void )
-{
- OSStatus err;
- char s[ 512 ];
- uint8_t * p;
- uint8_t data[] =
- {
- 0x11, 0x22, 0x33, 0x44,
- 0x55, 0x66,
- 0x77, 0x88, 0x99, 0xAA,
- 0xBB, 0xCC, 0xDD,
- 0xEE,
- 0xFF,
- 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
- 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90, 0xA0,
- 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x81, 0x91, 0xA1
- };
-
- debug_initialize( kDebugOutputTypeMetaConsole );
-
- // check's
-
- check( 0 && "SHOULD SEE: check" );
- check( 1 && "SHOULD *NOT* SEE: check (valid)" );
- check_string( 0, "SHOULD SEE: check_string" );
- check_string( 1, "SHOULD *NOT* SEE: check_string (valid)" );
- check_noerr( -123 );
- check_noerr( 10038 );
- check_noerr( 22 );
- check_noerr( 0 );
- check_noerr_string( -6712, "SHOULD SEE: check_noerr_string" );
- check_noerr_string( 0, "SHOULD *NOT* SEE: check_noerr_string (valid)" );
- check_translated_errno( 0 >= 0 && "SHOULD *NOT* SEE", -384, -999 );
- check_translated_errno( -1 >= 0 && "SHOULD SEE", -384, -999 );
- check_translated_errno( -1 >= 0 && "SHOULD SEE", 0, -999 );
- check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 22, 10 );
- check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 5, 10 );
- check_ptr_overlap( "SHOULD SEE" ? 10 : 0, 10, 12, 6 );
- check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 6, 10, 10 );
- check_ptr_overlap( "SHOULD SEE" ? 12 : 0, 10, 10, 10 );
- check_ptr_overlap( "SHOULD *NOT* SEE" ? 22 : 0, 10, 10, 10 );
- check_ptr_overlap( "SHOULD *NOT* SEE" ? 10 : 0, 10, 20, 10 );
- check_ptr_overlap( "SHOULD *NOT* SEE" ? 20 : 0, 10, 10, 10 );
-
- // require's
-
- require( 0 && "SHOULD SEE", require1 );
- { err = kResponseErr; goto exit; }
-require1:
- require( 1 && "SHOULD *NOT* SEE", require2 );
- goto require2Good;
-require2:
- { err = kResponseErr; goto exit; }
-require2Good:
- require_string( 0 && "SHOULD SEE", require3, "SHOULD SEE: require_string" );
- { err = kResponseErr; goto exit; }
-require3:
- require_string( 1 && "SHOULD *NOT* SEE", require4, "SHOULD *NOT* SEE: require_string (valid)" );
- goto require4Good;
-require4:
- { err = kResponseErr; goto exit; }
-require4Good:
- require_quiet( 0 && "SHOULD SEE", require5 );
- { err = kResponseErr; goto exit; }
-require5:
- require_quiet( 1 && "SHOULD *NOT* SEE", require6 );
- goto require6Good;
-require6:
- { err = kResponseErr; goto exit; }
-require6Good:
- require_noerr( -1, require7 );
- { err = kResponseErr; goto exit; }
-require7:
- require_noerr( 0, require8 );
- goto require8Good;
-require8:
- { err = kResponseErr; goto exit; }
-require8Good:
- require_noerr_string( -2, require9, "SHOULD SEE: require_noerr_string");
- { err = kResponseErr; goto exit; }
-require9:
- require_noerr_string( 0, require10, "SHOULD *NOT* SEE: require_noerr_string (valid)" );
- goto require10Good;
-require10:
- { err = kResponseErr; goto exit; }
-require10Good:
- require_noerr_action_string( -3, require11, dlog( kDebugLevelMax, "action 1 (expected)\n" ), "require_noerr_action_string" );
- { err = kResponseErr; goto exit; }
-require11:
- require_noerr_action_string( 0, require12, dlog( kDebugLevelMax, "action 2\n" ), "require_noerr_action_string (valid)" );
- goto require12Good;
-require12:
- { err = kResponseErr; goto exit; }
-require12Good:
- require_noerr_quiet( -4, require13 );
- { err = kResponseErr; goto exit; }
-require13:
- require_noerr_quiet( 0, require14 );
- goto require14Good;
-require14:
- { err = kResponseErr; goto exit; }
-require14Good:
- require_noerr_action( -5, require15, dlog( kDebugLevelMax, "SHOULD SEE: action 3 (expected)\n" ) );
- { err = kResponseErr; goto exit; }
-require15:
- require_noerr_action( 0, require16, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 4\n" ) );
- goto require16Good;
-require16:
- { err = kResponseErr; goto exit; }
-require16Good:
- require_noerr_action_quiet( -4, require17, dlog( kDebugLevelMax, "SHOULD SEE: action 5 (expected)\n" ) );
- { err = kResponseErr; goto exit; }
-require17:
- require_noerr_action_quiet( 0, require18, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 6\n" ) );
- goto require18Good;
-require18:
- { err = kResponseErr; goto exit; }
-require18Good:
- require_action( 0 && "SHOULD SEE", require19, dlog( kDebugLevelMax, "SHOULD SEE: action 7 (expected)\n" ) );
- { err = kResponseErr; goto exit; }
-require19:
- require_action( 1 && "SHOULD *NOT* SEE", require20, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 8\n" ) );
- goto require20Good;
-require20:
- { err = kResponseErr; goto exit; }
-require20Good:
- require_action_quiet( 0, require21, dlog( kDebugLevelMax, "SHOULD SEE: action 9 (expected)\n" ) );
- { err = kResponseErr; goto exit; }
-require21:
- require_action_quiet( 1, require22, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 10\n" ) );
- goto require22Good;
-require22:
- { err = kResponseErr; goto exit; }
-require22Good:
- require_action_string( 0, require23, dlog( kDebugLevelMax, "SHOULD SEE: action 11 (expected)\n" ), "SHOULD SEE: require_action_string" );
- { err = kResponseErr; goto exit; }
-require23:
- require_action_string( 1, require24, dlog( kDebugLevelMax, "SHOULD *NOT* SEE: action 12\n" ), "SHOULD *NOT* SEE: require_action_string" );
- goto require24Good;
-require24:
- { err = kResponseErr; goto exit; }
-require24Good:
-
-#if ( defined( __MWERKS__ ) )
- #if ( defined( __cplusplus ) && __option( exceptions ) )
- #define COMPILER_HAS_EXCEPTIONS 1
- #else
- #define COMPILER_HAS_EXCEPTIONS 0
- #endif
-#else
- #if ( defined( __cplusplus ) )
- #define COMPILER_HAS_EXCEPTIONS 1
- #else
- #define COMPILER_HAS_EXCEPTIONS 0
- #endif
-#endif
-
-#if ( COMPILER_HAS_EXCEPTIONS )
- try
- {
- require_throw( 1 && "SHOULD *NOT* SEE" );
- require_throw( 0 && "SHOULD SEE" );
- }
- catch(... )
- {
- goto require26Good;
- }
- { err = kResponseErr; goto exit; }
-require26Good:
-#endif
-
- // translate_errno
-
- err = translate_errno( 1 != -1, -123, -567 );
- require( ( err == 0 ) && "SHOULD *NOT* SEE", exit );
-
- err = translate_errno( -1 != -1, -123, -567 );
- require( ( err == -123 ) && "SHOULD *NOT* SEE", exit );
-
- err = translate_errno( -1 != -1, 0, -567 );
- require( ( err == -567 ) && "SHOULD *NOT* SEE", exit );
-
- // debug_string
-
- debug_string( "debug_string" );
-
- // DebugSNPrintF
-
- DebugSNPrintF( s, sizeof( s ), "%d", 1234 );
- require_action( strcmp( s, "1234" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%X", 0x2345 );
- require_action( strcmp( s, "2345" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%#s", "\05test" );
- require_action( strcmp( s, "test" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%##s", "\03www\05apple\03com" );
- require_action( strcmp( s, "www.apple.com." ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%ld", (long) INT32_C( 2147483647 ) );
- require_action( strcmp( s, "2147483647" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%lu", (unsigned long) UINT32_C( 4294967295 ) );
- require_action( strcmp( s, "4294967295" ) == 0, exit, err = -1 );
-
- #if ( TYPE_LONGLONG_NATIVE )
- DebugSNPrintF( s, sizeof( s ), "%lld", (long_long_compat) INT64_C( 9223372036854775807 ) );
- require_action( strcmp( s, "9223372036854775807" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%lld", (long_long_compat) INT64_C( -9223372036854775807 ) );
- require_action( strcmp( s, "-9223372036854775807" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%llu", (unsigned_long_long_compat) UINT64_C( 18446744073709551615 ) );
- require_action( strcmp( s, "18446744073709551615" ) == 0, exit, err = -1 );
- #endif
-
- DebugSNPrintF( s, sizeof( s ), "%lb", (unsigned long) binary_32( 01111011, 01111011, 01111011, 01111011 ) );
- require_action( strcmp( s, "1111011011110110111101101111011" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%C", 0x41624364 ); // 'AbCd'
- require_action( strcmp( s, "AbCd" ) == 0, exit, err = -1 );
-
- #if ( defined( MDNS_DEBUGMSGS ) )
- {
- mDNSAddr maddr;
-
- memset( &maddr, 0, sizeof( maddr ) );
- maddr.type = mDNSAddrType_IPv4;
- maddr.ip.v4.b[ 0 ] = 127;
- maddr.ip.v4.b[ 1 ] = 0;
- maddr.ip.v4.b[ 2 ] = 0;
- maddr.ip.v4.b[ 3 ] = 1;
- DebugSNPrintF( s, sizeof( s ), "%#a", &maddr );
- require_action( strcmp( s, "127.0.0.1" ) == 0, exit, err = -1 );
-
- memset( &maddr, 0, sizeof( maddr ) );
- maddr.type = mDNSAddrType_IPv6;
- maddr.ip.v6.b[ 0 ] = 0xFE;
- maddr.ip.v6.b[ 1 ] = 0x80;
- maddr.ip.v6.b[ 15 ] = 0x01;
- DebugSNPrintF( s, sizeof( s ), "%#a", &maddr );
- require_action( strcmp( s, "FE80:0000:0000:0000:0000:0000:0000:0001" ) == 0, exit, err = -1 );
- }
- #endif
-
- #if ( AF_INET )
- {
- struct sockaddr_in sa4;
-
- memset( &sa4, 0, sizeof( sa4 ) );
- sa4.sin_family = AF_INET;
- p = (uint8_t *) &sa4.sin_port;
- p[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
- p[ 1 ] = (uint8_t)( 80 & 0xFF );
- p = (uint8_t *) &sa4.sin_addr.s_addr;
- p[ 0 ] = (uint8_t)( ( INADDR_LOOPBACK >> 24 ) & 0xFF );
- p[ 1 ] = (uint8_t)( ( INADDR_LOOPBACK >> 16 ) & 0xFF );
- p[ 2 ] = (uint8_t)( ( INADDR_LOOPBACK >> 8 ) & 0xFF );
- p[ 3 ] = (uint8_t)( INADDR_LOOPBACK & 0xFF );
- DebugSNPrintF( s, sizeof( s ), "%##a", &sa4 );
- require_action( strcmp( s, "127.0.0.1:80" ) == 0, exit, err = -1 );
- }
- #endif
-
- #if ( AF_INET6 )
- {
- struct sockaddr_in6 sa6;
-
- memset( &sa6, 0, sizeof( sa6 ) );
- sa6.sin6_family = AF_INET6;
- p = (uint8_t *) &sa6.sin6_port;
- p[ 0 ] = (uint8_t)( ( 80 >> 8 ) & 0xFF );
- p[ 1 ] = (uint8_t)( 80 & 0xFF );
- sa6.sin6_addr.s6_addr[ 0 ] = 0xFE;
- sa6.sin6_addr.s6_addr[ 1 ] = 0x80;
- sa6.sin6_addr.s6_addr[ 15 ] = 0x01;
- sa6.sin6_scope_id = 2;
- DebugSNPrintF( s, sizeof( s ), "%##a", &sa6 );
- require_action( strcmp( s, "[FE80:0000:0000:0000:0000:0000:0000:0001%2]:80" ) == 0, exit, err = -1 );
- }
- #endif
-
- // Unicode
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 4, "tes" );
- require_action( strcmp( s, "tes" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 4, "test" );
- require_action( strcmp( s, "test" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 4, "testing" );
- require_action( strcmp( s, "test" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xC3\xA9" );
- require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xC3\xA9ing" );
- require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 4, "tes\xC3\xA9ing" );
- require_action( strcmp( s, "tes" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 4, "t\xed\x9f\xbf" );
- require_action( strcmp( s, "t\xed\x9f\xbf" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 4, "t\xed\x9f\xbfing" );
- require_action( strcmp( s, "t\xed\x9f\xbf" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xed\x9f\xbf" );
- require_action( strcmp( s, "te" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 4, "te\xed\x9f\xbfing" );
- require_action( strcmp( s, "te" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 7, "te\xC3\xA9\xed\x9f\xbfing" );
- require_action( strcmp( s, "te\xC3\xA9\xed\x9f\xbf" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 6, "te\xC3\xA9\xed\x9f\xbfing" );
- require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
-
- DebugSNPrintF(s, sizeof(s), "%.*s", 5, "te\xC3\xA9\xed\x9f\xbfing" );
- require_action( strcmp( s, "te\xC3\xA9" ) == 0, exit, err = kResponseErr );
-
- #if ( TARGET_RT_BIG_ENDIAN )
- DebugSNPrintF( s, sizeof( s ), "%S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" );
- require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
- #else
- DebugSNPrintF( s, sizeof( s ), "%S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" );
- require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
- #endif
-
- DebugSNPrintF( s, sizeof( s ), "%S",
- "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian BOM
- require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%S",
- "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian BOM
- require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%#S", "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" ); // Big Endian
- require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%##S", "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" "\x00" "\x00" ); // Little Endian
- require_action( strcmp( s, "abcd" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%.*S",
- 4, "\xFE\xFF" "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian BOM
- require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%.*S",
- 4, "\xFF\xFE" "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian BOM
- require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
-
- #if ( TARGET_RT_BIG_ENDIAN )
- DebugSNPrintF( s, sizeof( s ), "%.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" );
- require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
- #else
- DebugSNPrintF( s, sizeof( s ), "%.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" );
- require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
- #endif
-
- DebugSNPrintF( s, sizeof( s ), "%#.*S", 3, "\x00" "a" "\x00" "b" "\x00" "c" "\x00" "d" ); // Big Endian
- require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%##.*S", 3, "a" "\x00" "b" "\x00" "c" "\x00" "d" "\x00" ); // Little Endian
- require_action( strcmp( s, "abc" ) == 0, exit, err = -1 );
-
- // Misc
-
- DebugSNPrintF( s, sizeof( s ), "%U", "\x10\xb8\xa7\x6b" "\xad\x9d" "\xd1\x11" "\x80\xb4" "\x00\xc0\x4f\xd4\x30\xc8" );
- require_action( strcmp( s, "6ba7b810-9dad-11d1-80b4-00c04fd430c8" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%m", 0 );
- require_action( strcmp( s, "no error" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "%lm", (long) 0 );
- require_action( strcmp( s, "no error" ) == 0, exit, err = -1 );
-
- DebugSNPrintF( s, sizeof( s ), "\"%H\"", "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8", 16, 16 );
- DebugPrintF( kDebugLevelMax, "%s\n\n", s );
-
- DebugSNPrintF( s, sizeof( s ), "\"%H\"",
- "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8"
- "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8",
- 32, 32 );
- DebugPrintF( kDebugLevelMax, "%s\n\n", s );
-
- DebugSNPrintF( s, sizeof( s ), "\"%H\"", "\x6b\xa7", 2, 2 );
- DebugPrintF( kDebugLevelMax, "%s\n\n", s );
-
- // Hex Dumps
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 0, "My Label", kSizeCString, 0, NULL, 0, data, data, sizeof( data ),
- kDebugFlagsNone, s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
- kDebugFlagsNoAddress | kDebugFlagsNoOffset, s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 0, "My Label", kSizeCString, 0, NULL, 0, data, data, sizeof( data ),
- kDebugFlagsNoAddress | kDebugFlagsNoOffset, s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 0, "My Label", kSizeCString, 0, NULL, 0, data, data, sizeof( data ),
- kDebugFlagsNoAddress, s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
- kDebugFlagsNoOffset, s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
- kDebugFlagsNoAddress, s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
- kDebugFlagsNoOffset, s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
- kDebugFlagsNoByteCount, s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, "\x41\x62\x43\x64", "\x41\x62\x43\x64", 4, // 'AbCd'
- kDebugFlagsNoAddress | kDebugFlagsNoOffset | kDebugFlagsNoNewLine |
- kDebugFlagsNo32BitSeparator | kDebugFlagsNo16ByteHexPad | kDebugFlagsNoByteCount,
- s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 0, NULL, 0, 0, NULL, 0, data, data, sizeof( data ),
- kDebugFlagsNoAddress | kDebugFlagsNoOffset | kDebugFlagsNoASCII | kDebugFlagsNoNewLine |
- kDebugFlags16BitSeparator | kDebugFlagsNo32BitSeparator |
- kDebugFlagsNo16ByteHexPad | kDebugFlagsNoByteCount, s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- s[ 0 ] = '\0';
- DebugHexDump( kDebugLevelMax, 8, NULL, 0, 0, NULL, 0, data, data, sizeof( data ), kDebugFlagsNone, s, sizeof( s ) );
- DebugPrintF( kDebugLevelMax, "%s\n", s );
-
- // dlog's
-
- dlog( kDebugLevelNotice, "dlog\n" );
- dlog( kDebugLevelNotice, "dlog integer: %d\n", 123 );
- dlog( kDebugLevelNotice, "dlog string: \"%s\"\n", "test string" );
- dlogmem( kDebugLevelNotice, data, sizeof( data ) );
-
- // Done
-
- DebugPrintF( kDebugLevelMax, "\n\nALL TESTS DONE\n\n" );
- err = kNoErr;
-
-exit:
- if( err )
- {
- DebugPrintF( kDebugLevelMax, "\n\n### TEST FAILED ###\n\n" );
- }
- return err;
-}
-
-#endif // DEBUG
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/DebugServices.h b/sd/source/ui/remotecontrol/mDNSResponder/DebugServices.h
deleted file mode 100644
index b8411e57ad56..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/DebugServices.h
+++ /dev/null
@@ -1,1576 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 1997-2004 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/*! @header DebugServices
-
- Debugging Library
- */
-
-#ifndef __DEBUG_SERVICES__
-#define __DEBUG_SERVICES__
-
-#include <stdarg.h>
-
-#include "CommonServices.h"
-
-#if ( TARGET_OS_VXWORKS )
- #include "logLib.h"
-#endif
-
-#if 0
-#pragma mark == Settings ==
-#endif
-
-
-// Settings
-
-
-// General
-
-#if ( !defined( DEBUG ) )
- #define DEBUG 0
-#endif
-
-#if ( defined( NDEBUG ) && DEBUG )
- #error NDEBUG defined and DEBUG is also enabled...they need to be in-sync
-#endif
-
-// AssertMacros.h/Debugging.h overrides.
-
-#if ( !defined( DEBUG_OVERRIDE_APPLE_MACROS ) )
- #define DEBUG_OVERRIDE_APPLE_MACROS 1
-#endif
-
-// Routine name. Uses ISO __func__ where possible. Otherwise, uses the best thing that is available (if anything).
-
-#if ( defined( __MWERKS__ ) || ( __GNUC__ > 2 ) || ( ( __GNUC__ == 2 ) && ( __GNUC_MINOR__ >= 9 ) ) )
- #define __ROUTINE__ __func__
-#elif ( defined( __GNUC__ ) )
- #define __ROUTINE__ __PRETTY_FUNCTION__
-#elif ( defined( _MSC_VER ) && !defined( _WIN32_WCE ) )
- #define __ROUTINE__ __FUNCTION__
-#else
- #define __ROUTINE__ ""
-#endif
-
-// Variable argument macro support. Use ANSI C99 __VA_ARGS__ where possible. Otherwise, use the next best thing.
-
-#if ( defined( __GNUC__ ) )
- #if ( ( __GNUC__ > 3 ) || ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 3) ) )
- #define DEBUG_C99_VA_ARGS 1
- #define DEBUG_GNU_VA_ARGS 0
- #else
- #define DEBUG_C99_VA_ARGS 0
- #define DEBUG_GNU_VA_ARGS 1
- #endif
-#elif ( defined( __MWERKS__ ) )
- #define DEBUG_C99_VA_ARGS 1
- #define DEBUG_GNU_VA_ARGS 0
-#else
- #define DEBUG_C99_VA_ARGS 0
- #define DEBUG_GNU_VA_ARGS 0
-#endif
-
-#if 0
-#pragma mark == Output ==
-#endif
-
-
-/*! @defined DEBUG_FPRINTF_ENABLED
-
- @abstract Enables ANSI C fprintf output.
- */
-
-#if ( !defined( DEBUG_FPRINTF_ENABLED ) )
- #if ( !TARGET_API_MAC_OSX_KERNEL && !TARGET_OS_WINDOWS_CE )
- #define DEBUG_FPRINTF_ENABLED 1
- #else
- #define DEBUG_FPRINTF_ENABLED 0
- #endif
-#else
- #if ( TARGET_API_MAC_OSX_KERNEL || TARGET_OS_WINDOWS_CE )
- #error fprintf enabled, but not supported on Mac OS X kernel or Windows CE
- #endif
-#endif
-
-
-/*! @defined DEBUG_MAC_OS_X_IOLOG_ENABLED
-
- @abstract Enables IOLog (Mac OS X Kernel) output.
- */
-
-#if ( !defined( DEBUG_MAC_OS_X_IOLOG_ENABLED ) )
- #define DEBUG_MAC_OS_X_IOLOG_ENABLED TARGET_API_MAC_OSX_KERNEL
-#endif
-
-
-/*! @defined DEBUG_KPRINTF_ENABLED
-
- @abstract Enables kprintf (Mac OS X Kernel) output.
- */
-
-#if ( !defined( DEBUG_KPRINTF_ENABLED ) )
- #define DEBUG_KPRINTF_ENABLED TARGET_API_MAC_OSX_KERNEL
-#endif
-
-
-/*! @defined DEBUG_IDEBUG_ENABLED
-
- @abstract Enables iDebug (Mac OS X user and Kernel) output.
-
- @discussion
-
- For Mac OS X kernel development, iDebug is enabled by default because we can dynamically check for the presence
- of iDebug via some exported IOKit symbols. Mac OS X app usage doesn't allow dynamic detection because it relies
- on statically linking to the iDebugServices.cp file so for Mac OS X app usage, you have to manually enable iDebug.
- */
-
-#if ( !defined( DEBUG_IDEBUG_ENABLED ) )
- #define DEBUG_IDEBUG_ENABLED TARGET_API_MAC_OSX_KERNEL
-#endif
-
-
-/*! @defined DEBUG_CORE_SERVICE_ASSERTS_ENABLED
-
- @abstract Controls whether Core Services assert handling is enabled. Enabling requires CoreServices framework.
- */
-
-#if ( !defined( DEBUG_CORE_SERVICE_ASSERTS_ENABLED ) )
- #if ( defined( __DEBUGGING__ ) )
- #define DEBUG_CORE_SERVICE_ASSERTS_ENABLED 1
- #else
- #define DEBUG_CORE_SERVICE_ASSERTS_ENABLED 0
- #endif
-#endif
-
-
-/*! @typedef DebugOutputType
-
- @abstract Type of debug output (i.e. where the output goes).
- */
-
-typedef uint32_t DebugOutputType;
-
-#define kDebugOutputTypeNone 0x6E6F6E65U // 'none' - no params
-#define kDebugOutputTypeCustom 0x63757374U // 'cust' - 1st param = function ptr, 2nd param = context
-#define kDebugOutputTypeFPrintF 0x66707269U // 'fpri' - 1st param = DebugOutputTypeFlags [, 2nd param = filename]
-#define kDebugOutputTypeiDebug 0x69646267U // 'idbg' - no params
-#define kDebugOutputTypeKPrintF 0x6B707266U // 'kprf' - no params
-#define kDebugOutputTypeMacOSXIOLog 0x696C6F67U // 'ilog' - no params
-#define kDebugOutputTypeMacOSXLog 0x786C6F67U // 'xlog' - no params
-#define kDebugOutputTypeWindowsDebugger 0x77696E64U // 'wind' - no params
-#define kDebugOutputTypeWindowsEventLog 0x7765766CU // 'wevl' - 1st param = C-string name, 2nd param = HMODULE or NULL.
-
-// Console meta output kind - Any kind of Console output (in horizontal order of preference):
-
-// Mac OS X = ANSI printf (viewable in Console.app)
-// Mac OS X Kernel = IOLog (/var/log/system.log) or kprintf (serial).
-// Windows = ANSI printf (Console window) or OutputDebugString (debugger).
-// Other = ANSI printf (viewer varies).
-
-#define kDebugOutputTypeMetaConsole 0x434F4E53U // 'CONS' - no params
-
-
-/*! @typedef DebugOutputTypeFlags
-
- @abstract Flags controlling how the output type is configured.
-
- @constant kDebugOutputTypeFlagsTypeMask Bit mask for the output type (e.g. stdout, stderr, file, etc.).
- @constant kDebugOutputTypeFlagsStdOut fprintf should go to stdout.
- @constant kDebugOutputTypeFlagsStdErr fprintf should go to stderr.
- @constant kDebugOutputTypeFlagsFile fprintf should go to a specific file (filename passed as va_arg).
- */
-
-typedef unsigned int DebugOutputTypeFlags;
-
-#define kDebugOutputTypeFlagsTypeMask 0xF
-#define kDebugOutputTypeFlagsStdOut 1
-#define kDebugOutputTypeFlagsStdErr 2
-#define kDebugOutputTypeFlagsFile 10
-
-
-/*! @typedef DebugOutputFunctionPtr
-
- @abstract Function ptr for a custom callback to print debug output.
- */
-
-typedef void ( *DebugOutputFunctionPtr )( char *inData, size_t inSize, void *inContext );
-
-
-// Constants
-
-
-#if 0
-#pragma mark == Flags ==
-#endif
-
-
-/*! @typedef DebugFlags
-
- @abstract Flags controlling how output is printed.
- */
-
-typedef uint32_t DebugFlags;
-
-#define kDebugFlagsNone 0
-#define kDebugFlagsNoAddress ( 1 << 0 )
-#define kDebugFlagsNoOffset ( 1 << 1 )
-#define kDebugFlags32BitOffset ( 1 << 2 )
-#define kDebugFlagsNoASCII ( 1 << 3 )
-#define kDebugFlagsNoNewLine ( 1 << 4 )
-#define kDebugFlags8BitSeparator ( 1 << 5 )
-#define kDebugFlags16BitSeparator ( 1 << 6 )
-#define kDebugFlagsNo32BitSeparator ( 1 << 7 )
-#define kDebugFlagsNo16ByteHexPad ( 1 << 8 )
-#define kDebugFlagsNoByteCount ( 1 << 9 )
-
-
-/*! @enum DebugTaskLevelFlags
-
- @abstract Flags indicating the task level.
- */
-
-enum
-{
- kDebugInterruptLevelShift = 0,
- kDebugInterruptLevelMask = 0x00000007,
- kDebugInVBLTaskMask = 0x00000010,
- kDebugInDeferredTaskMask = 0x00000020,
- kDebugInSecondaryInterruptHandlerMask = 0x00000040,
- kDebugPageFaultFatalMask = 0x00000100, // There should be a "kPageFaultFatalMask" in Debugging.h.
- kDebugMPTaskLevelMask = 0x00000200, // There should be a "kMPTaskLevelMask" in Debugging.h.
- kDebugInterruptDepthShift = 16,
- kDebugInterruptDepthMask = 0x00FF0000
-};
-
-#define DebugExtractTaskLevelInterruptDepth( LEVEL ) \
- ( ( ( LEVEL ) &kDebugInterruptDepthMask ) >> kDebugInterruptDepthShift )
-
-#if 0
-#pragma mark == Levels ==
-#endif
-
-
-// Constants & Types - Levels
-
-
-
-/*! @typedef DebugLevel
-
- @abstract Level used to control debug logging.
- */
-
-typedef int32_t DebugLevel;
-
-// Levels
-
-#define kDebugLevelInfo 1000
-#define kDebugLevelNotice 3000
-#define kDebugLevelWarning 5000
-#define kDebugLevelAssert 6000
-#define kDebugLevelError 8000
-#define kDebugLevelMax 0x0000FFFF
-
-// Level Flags
-
-
-
-/*! @typedef LogLevel
-
- @abstract Level used to control which events are logged.
- */
-
-typedef int32_t LogLevel;
-
-#define kLogLevelUninitialized -1L
-
-#if 0
-#pragma mark == Properties ==
-#endif
-
-
-/*! @typedef DebugPropertyTag
-
- @abstract Tag for properties.
- */
-
-typedef uint32_t DebugPropertyTag;
-
-#define kDebugPropertyTagPrintLevelMin 0x6D696E70U // 'minp' Get: 1st param = DebugLevel *
- // Set: 1st param = DebugLevel
-
-
-#define kDebugPropertyTagPrintLevelMax 0x706D786CU // 'maxp' Get: 1st param = DebugLevel *
- // Set: 1st param = DebugLevel
-
-#define kDebugPropertyTagBreakLevel 0x62726B6CU // 'brkl' Get: 1st param = DebugLevel *
- // Set: 1st param = DebugLevel
-#if 0
-#pragma mark == General macros ==
-#endif
-
-
-/*! @defined DEBUG_UNUSED
-
- @abstract Macro to mark a parameter as unused to avoid unused parameter warnings.
-
- @discussion
-
- There is no universally supported pragma/attribute for indicating a variable is unused. DEBUG_UNUSED lets us
- indicate a variable is unused in a manner that is supported by most compilers.
- */
-
-#define DEBUG_UNUSED( X ) (void)( X )
-
-
-/*! @defined DEBUG_USE_ONLY
-
- @abstract Macro to mark a variable as used only when debugging is enabled.
-
- @discussion
-
- Variables are sometimes needed only for debugging. When debugging is turned off, these debug-only variables generate
- compiler warnings about unused variables. To eliminate these warnings, use these macros to indicate variables that
- are only used for debugging.
- */
-
-#if ( DEBUG )
- #define DEBUG_USE_ONLY( X )
-#else
- #define DEBUG_USE_ONLY( X ) (void)( X )
-#endif
-
-
-/*! @defined DEBUG_LOCAL
-
- @abstract Macros to make variables and functions static when debugging is off, but extern when debugging is on.
-
- @discussion
-
- Rather than using "static" directly, using this macros allows you to access these variables external while
- debugging without being penalized for production builds.
- */
-
-#if ( DEBUG )
- #define DEBUG_LOCAL
-#else
- #define DEBUG_LOCAL static
-#endif
-
-
-/*! @defined DEBUG_STATIC
-
- @abstract Macros to make variables and functions static when debugging is off, but extern when debugging is on.
-
- @discussion
-
- Rather than using "static" directly, using this macros allows you to access these variables external while
- debugging without being penalized for production builds.
- */
-
-#if ( DEBUG )
- #define DEBUG_STATIC
-#else
- #define DEBUG_STATIC static
-#endif
-
-
-/*! @defined DEBUG_EXPORT
-
- @abstract Macros to export variables.
-
- @discussion
-
- "__private_extern__" is a hack for IOKit to allow symbols to be exported from compilation units, but
- // not exported outside a driver (IOKit uses a lame global namespace for symbols). This still does not
- // solve the problem of multiple drivers in the same dependency chain since they share symbols.
- */
-
-#if ( TARGET_API_MAC_OSX_KERNEL )
- #define DEBUG_EXPORT __private_extern__
-#else
- #define DEBUG_EXPORT extern
-#endif
-
-
-/*! @defined debug_add
-
- @abstract Macro to add (or subtract if negative) a value when debugging is on. Does nothing if debugging is off.
- */
-
-#if ( DEBUG )
- #define debug_add( A, B ) ( A ) += ( B )
-#else
- #define debug_add( A, B )
-#endif
-
-
-/*! @defined debug_perform
-
- @abstract Macro to perform something in debug-only builds.
- */
-
-#if ( DEBUG )
- #define debug_perform( X ) do { X; } while( 0 )
-#else
- #define debug_perform( X )
-#endif
-
-
-/*! @function translate_errno
-
- @abstract Returns 0 if the test success. If the test fails, returns errno if non-zero and othewise the alternate error.
- */
-
-#define translate_errno( TEST, ERRNO, ALTERNATE_ERROR ) ( ( TEST ) ? 0 : ( ERRNO ) ? ( ERRNO ) : ( ALTERNATE_ERROR ) )
-
-#if 0
-#pragma mark == Compile Time macros ==
-#endif
-
-
-/*! @defined check_compile_time
-
- @abstract Performs a compile-time check of something such as the size of an int.
-
- @discussion
-
- This declares an array with a size that is determined by a compile-time expression. If the expression evaluates
- to 0, the array has a size of -1, which is illegal and generates a compile-time error.
-
- For example:
-
- check_compile_time( sizeof( int ) == 4 );
-
- Note: This only works with compile-time expressions.
- Note: This only works in places where extern declarations are allowed (e.g. global scope).
-
- References:
-
- <http://www.jaggersoft.com/pubs/CVu11_3.html>
- <http://www.jaggersoft.com/pubs/CVu11_5.html>
-
- Note: The following macros differ from the macros on the www.jaggersoft.com web site because those versions do not
- work with GCC due to GCC allow a zero-length array. Using a -1 condition turned out to be more portable.
- */
-
-#define check_compile_time( X ) extern int debug_compile_time_name[ ( X ) ? 1 : -1 ]
-
-
-/*! @defined check_compile_time_code
-
- @abstract Perform a compile-time check, suitable for placement in code, of something such as the size of an int.
-
- @discussion
-
- This creates a switch statement with an existing case for 0 and an additional case using the result of a
- compile-time expression. A switch statement cannot have two case labels with the same constant so if the
- compile-time expression evaluates to 0, it is illegal and generates a compile-time error. If the compile-time
- expression does not evaluate to 0, the resulting value is used as the case label and it compiles without error.
-
- For example:
-
- check_compile_time_code( sizeof( int ) == 4 );
-
- Note: This only works with compile-time expressions.
- Note: This does not work in a global scope so it must be inside a function.
-
- References:
-
- <http://www.jaggersoft.com/pubs/CVu11_3.html>
- <http://www.jaggersoft.com/pubs/CVu11_5.html>
- */
-
-#define check_compile_time_code( X ) switch( 0 ) { case 0: case X:; }
-
-#if 0
-#pragma mark == check macros ==
-#endif
-
-
-/*! @defined check
-
- @abstract Check that an expression is true (non-zero).
-
- @discussion
-
- If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
- function name, etc.) using the default debugging output method.
-
- Code inside check() statements is not compiled into production builds.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef check
-#endif
-#if ( !defined( check ) )
- #if ( DEBUG )
- #define check( X ) \
- do \
- { \
- if( !( X ) ) \
- { \
- debug_print_assert( 0, # X, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
- } \
- } while( 0 )
- #else
- #define check( X )
- #endif
-#endif
-
-
-/*! @defined check_string
-
- @abstract Check that an expression is true (non-zero) with an explanation.
-
- @discussion
-
- If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
- function name, etc.) and a custom explanation string using the default debugging output method.
-
- Code inside check_string() statements is not compiled into production builds.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef check_string
-#endif
-#if ( !defined( check_string ) )
- #if ( DEBUG )
- #define check_string( X, STR ) \
- do \
- { \
- if( !( X ) ) \
- { \
- debug_print_assert( 0, # X, STR, __FILE__, __LINE__, __ROUTINE__ ); \
- } \
- \
- } while( 0 )
- #else
- #define check_string( X, STR )
- #endif
-#endif
-
-
-/*! @defined check_noerr
-
- @abstract Check that an error code is noErr (0).
-
- @discussion
-
- If the error code is non-0, this prints debugging information (actual expression string, file, line number,
- function name, etc.) using the default debugging output method.
-
- Code inside check_noerr() statements is not compiled into production builds.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef check_noerr
-#endif
-#if ( !defined( check_noerr ) )
- #if ( DEBUG )
- #define check_noerr( ERR ) \
- do \
- { \
- int_least32_t localErr; \
- \
- localErr = (int_least32_t)( ERR ); \
- if( localErr != 0 ) \
- { \
- debug_print_assert( localErr, NULL, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
- } \
- \
- } while( 0 )
- #else
- #define check_noerr( ERR )
- #endif
-#endif
-
-
-/*! @defined check_noerr_string
-
- @abstract Check that an error code is noErr (0) with an explanation.
-
- @discussion
-
- If the error code is non-0, this prints debugging information (actual expression string, file, line number,
- function name, etc.) and a custom explanation string using the default debugging output method.
-
- Code inside check_noerr_string() statements is not compiled into production builds.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef check_noerr_string
-#endif
-#if ( !defined( check_noerr_string ) )
- #if ( DEBUG )
- #define check_noerr_string( ERR, STR ) \
- do \
- { \
- int_least32_t localErr; \
- \
- localErr = (int_least32_t)( ERR ); \
- if( localErr != 0 ) \
- { \
- debug_print_assert( localErr, NULL, STR, __FILE__, __LINE__, __ROUTINE__ ); \
- } \
- \
- } while( 0 )
- #else
- #define check_noerr_string( ERR, STR )
- #endif
-#endif
-
-
-/*! @defined check_translated_errno
-
- @abstract Check a condition and prints errno (if non-zero) to the log.
-
- @discussion
-
- Code inside check_translated_errno() statements is not compiled into production builds.
- */
-
-#if ( !defined( check_translated_errno ) )
- #if ( DEBUG )
- #define check_translated_errno( TEST, ERRNO, ALTERNATE_ERROR ) \
- do \
- { \
- if( !( TEST ) ) \
- { \
- int_least32_t localErr; \
- \
- localErr = (int_least32_t)( ERRNO ); \
- localErr = ( localErr != 0 ) ? localErr : (int_least32_t)( ALTERNATE_ERROR ); \
- debug_print_assert( localErr, # TEST, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
- } \
- \
- } while( 0 )
- #else
- #define check_translated_errno( TEST, ERRNO, ALTERNATE_ERROR )
- #endif
-#endif
-
-
-/*! @defined check_ptr_overlap
-
- @abstract Checks that two ptrs do not overlap.
- */
-
-#define check_ptr_overlap( P1, P1_SIZE, P2, P2_SIZE ) \
- do \
- { \
- check( !( ( (uintptr_t)( P1 ) >= (uintptr_t)( P2 ) ) && \
- ( (uintptr_t)( P1 ) < ( ( (uintptr_t)( P2 ) ) + ( P2_SIZE ) ) ) ) ); \
- check( !( ( (uintptr_t)( P2 ) >= (uintptr_t)( P1 ) ) && \
- ( (uintptr_t)( P2 ) < ( ( (uintptr_t)( P1 ) ) + ( P1_SIZE ) ) ) ) ); \
- \
- } while( 0 )
-
-#if 0
-#pragma mark == require macros ==
-#endif
-
-
-/*! @defined require
-
- @abstract Requires that an expression evaluate to true.
-
- @discussion
-
- If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
- function name, etc.) using the default debugging output method then jumps to a label.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require
-#endif
-#if ( !defined( require ) )
- #define require( X, LABEL ) \
- do \
- { \
- if( !( X ) ) \
- { \
- debug_print_assert( 0, # X, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_string
-
- @abstract Requires that an expression evaluate to true with an explanation.
-
- @discussion
-
- If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
- function name, etc.) and a custom explanation string using the default debugging output method then jumps to a label.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_string
-#endif
-#if ( !defined( require_string ) )
- #define require_string( X, LABEL, STR ) \
- do \
- { \
- if( !( X ) ) \
- { \
- debug_print_assert( 0, # X, STR, __FILE__, __LINE__, __ROUTINE__ ); \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_quiet
-
- @abstract Requires that an expression evaluate to true.
-
- @discussion
-
- If expression evalulates to false, this jumps to a label. No debugging information is printed.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_quiet
-#endif
-#if ( !defined( require_quiet ) )
- #define require_quiet( X, LABEL ) \
- do \
- { \
- if( !( X ) ) \
- { \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_noerr
-
- @abstract Require that an error code is noErr (0).
-
- @discussion
-
- If the error code is non-0, this prints debugging information (actual expression string, file, line number,
- function name, etc.) using the default debugging output method then jumps to a label.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_noerr
-#endif
-#if ( !defined( require_noerr ) )
- #define require_noerr( ERR, LABEL ) \
- do \
- { \
- int_least32_t localErr; \
- \
- localErr = (int_least32_t)( ERR ); \
- if( localErr != 0 ) \
- { \
- debug_print_assert( localErr, NULL, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_noerr_string
-
- @abstract Require that an error code is noErr (0).
-
- @discussion
-
- If the error code is non-0, this prints debugging information (actual expression string, file, line number,
- function name, etc.), and a custom explanation string using the default debugging output method using the
- default debugging output method then jumps to a label.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_noerr_string
-#endif
-#if ( !defined( require_noerr_string ) )
- #define require_noerr_string( ERR, LABEL, STR ) \
- do \
- { \
- int_least32_t localErr; \
- \
- localErr = (int_least32_t)( ERR ); \
- if( localErr != 0 ) \
- { \
- debug_print_assert( localErr, NULL, STR, __FILE__, __LINE__, __ROUTINE__ ); \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_noerr_action_string
-
- @abstract Require that an error code is noErr (0).
-
- @discussion
-
- If the error code is non-0, this prints debugging information (actual expression string, file, line number,
- function name, etc.), and a custom explanation string using the default debugging output method using the
- default debugging output method then executes an action and jumps to a label.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_noerr_action_string
-#endif
-#if ( !defined( require_noerr_action_string ) )
- #define require_noerr_action_string( ERR, LABEL, ACTION, STR ) \
- do \
- { \
- int_least32_t localErr; \
- \
- localErr = (int_least32_t)( ERR ); \
- if( localErr != 0 ) \
- { \
- debug_print_assert( localErr, NULL, STR, __FILE__, __LINE__, __ROUTINE__ ); \
- { ACTION; } \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_noerr_quiet
-
- @abstract Require that an error code is noErr (0).
-
- @discussion
-
- If the error code is non-0, this jumps to a label. No debugging information is printed.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_noerr_quiet
-#endif
-#if ( !defined( require_noerr_quiet ) )
- #define require_noerr_quiet( ERR, LABEL ) \
- do \
- { \
- if( ( ERR ) != 0 ) \
- { \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_noerr_action
-
- @abstract Require that an error code is noErr (0) with an action to execute otherwise.
-
- @discussion
-
- If the error code is non-0, this prints debugging information (actual expression string, file, line number,
- function name, etc.) using the default debugging output method then executes an action and jumps to a label.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_noerr_action
-#endif
-#if ( !defined( require_noerr_action ) )
- #define require_noerr_action( ERR, LABEL, ACTION ) \
- do \
- { \
- int_least32_t localErr; \
- \
- localErr = (int_least32_t)( ERR ); \
- if( localErr != 0 ) \
- { \
- debug_print_assert( localErr, NULL, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
- { ACTION; } \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_noerr_action_quiet
-
- @abstract Require that an error code is noErr (0) with an action to execute otherwise.
-
- @discussion
-
- If the error code is non-0, this executes an action and jumps to a label. No debugging information is printed.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_noerr_action_quiet
-#endif
-#if ( !defined( require_noerr_action_quiet ) )
- #define require_noerr_action_quiet( ERR, LABEL, ACTION ) \
- do \
- { \
- if( ( ERR ) != 0 ) \
- { \
- { ACTION; } \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_action
-
- @abstract Requires that an expression evaluate to true with an action to execute otherwise.
-
- @discussion
-
- If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
- function name, etc.) using the default debugging output method then executes an action and jumps to a label.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_action
-#endif
-#if ( !defined( require_action ) )
- #define require_action( X, LABEL, ACTION ) \
- do \
- { \
- if( !( X ) ) \
- { \
- debug_print_assert( 0, # X, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
- { ACTION; } \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_action_quiet
-
- @abstract Requires that an expression evaluate to true with an action to execute otherwise.
-
- @discussion
-
- If expression evalulates to false, this executes an action and jumps to a label. No debugging information is printed.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_action_quiet
-#endif
-#if ( !defined( require_action_quiet ) )
- #define require_action_quiet( X, LABEL, ACTION ) \
- do \
- { \
- if( !( X ) ) \
- { \
- { ACTION; } \
- goto LABEL; \
- } \
- \
- } while( 0 )
-#endif
-
-
-/*! @defined require_action_string
-
- @abstract Requires that an expression evaluate to true with an explanation and action to execute otherwise.
-
- @discussion
-
- If expression evalulates to false, this prints debugging information (actual expression string, file, line number,
- function name, etc.) and a custom explanation string using the default debugging output method then executes an
- action and jumps to a label.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef require_action_string
-#endif
-#if ( !defined( require_action_string ) )
- #define require_action_string( X, LABEL, ACTION, STR ) \
- do \
- { \
- if( !( X ) ) \
- { \
- debug_print_assert( 0, # X, STR, __FILE__, __LINE__, __ROUTINE__ ); \
- { ACTION; } \
- goto LABEL; \
- } \
- \
- } while( 0 )
-
-#endif
-
-
-/*! @defined require_throw
-
- @abstract Requires that an expression evaluates to true or an exception is thrown.
-
- @discussion
-
- If the expression evaluates to false, this prints debugging information (actual expression string, file,
- line number, function name, etc.) using the default debugging output method then throws an exception.
- */
-
-#if ( defined( __cplusplus ) )
- #define require_throw( X ) \
- do \
- { \
- if( !( X ) ) \
- { \
- debug_print_assert( 0, # X, NULL, __FILE__, __LINE__, __ROUTINE__ ); \
- throw kUnknownErr; \
- } \
- \
- } while( 0 )
-#endif
-
-#if 0
-#pragma mark == Design-By-Contract macros ==
-#endif
-
-
-// Design-By-Contract macros
-
-
-#define ensure( X ) check( X )
-#define ensure_string( X, STR ) check_string( X, STR )
-#define ensure_noerr( ERR ) check_noerr( ERR )
-#define ensure_noerr_string( ERR, STR ) check_noerr_string( ERR, STR )
-#define ensure_translated_errno( TEST, ERRNO, ALTERNATE_ERROR ) check_translated_errno( TEST, ERRNO, ALTERNATE_ERROR )
-
-// Note: Design-By-Contract "require" macros are already defined elsewhere.
-
-#if 0
-#pragma mark == Expect macros ==
-#endif
-
-
-// Expect macros
-
-
-// Expect macros allow code to include runtime checking of things that should not happen in shipping code (e.g. internal
-// programmer errors, such as a NULL parameter where it is not allowed). Once the code has been verified to work correctly
-// without asserting, the DEBUG_EXPECT_VERIFIED conditional can be set to eliminate the error checking entirely. It can
-// also be useful to measure the cost of error checking code by profiling with it enable and with it disabled.
-
-#if ( DEBUG_EXPECT_VERIFIED )
- #define require_expect
- #define require_string_expect
- #define require_quiet_expect
- #define require_noerr_expect
- #define require_noerr_string_expect
- #define require_noerr_action_string_expect
- #define require_noerr_quiet_expect
- #define require_noerr_action_expect
- #define require_noerr_action_quiet_expect
- #define require_action_expect
- #define require_action_quiet_expect
- #define require_action_string_expect
-#else
- #define require_expect require
- #define require_string_expect require_string
- #define require_quiet_expect require_quiet
- #define require_noerr_expect require_noerr
- #define require_noerr_string_expect require_noerr_string
- #define require_noerr_action_string_expect require_noerr_action_string
- #define require_noerr_quiet_expect require_noerr_quiet
- #define require_noerr_action_expect require_noerr_action
- #define require_noerr_action_quiet_expect require_noerr_action_quiet
- #define require_action_expect require_action
- #define require_action_quiet_expect require_action_quiet
- #define require_action_string_expect require_action_string
-#endif
-
-#if 0
-#pragma mark == Output macros ==
-#endif
-
-
-/*! @defined debug_string
-
- @abstract Prints a debugging C string.
- */
-
-#if ( DEBUG_OVERRIDE_APPLE_MACROS )
- #undef debug_string
-#endif
-#if ( !defined( debug_string ) )
- #if ( DEBUG )
- #define debug_string( STR ) \
- do \
- { \
- debug_print_assert( 0, NULL, STR, __FILE__, __LINE__, __ROUTINE__ ); \
- \
- } while( 0 )
- #else
- #define debug_string( STR )
- #endif
-#endif
-
-
-/*! @defined debug_print_assert
-
- @abstract Prints an assertion.
- */
-
-#if ( DEBUG )
- #define debug_print_assert( ERROR_CODE, ASSERT_STRING, MESSAGE, FILENAME, LINE_NUMBER, FUNCTION ) \
- DebugPrintAssert( ERROR_CODE, ASSERT_STRING, MESSAGE, FILENAME, LINE_NUMBER, FUNCTION )
-#else
- #define debug_print_assert( ERROR_CODE, ASSERT_STRING, MESSAGE, FILENAME, LINE_NUMBER, FUNCTION )
-#endif
-
-
-/*! @defined dlog
-
- @abstract Prints a debug-only message.
- */
-
-#if ( DEBUG )
- #if ( DEBUG_C99_VA_ARGS )
- #define dlog(... ) DebugPrintF( __VA_ARGS__ )
- #elif ( DEBUG_GNU_VA_ARGS )
- #define dlog( ARGS... ) DebugPrintF( ## ARGS )
- #else
- #define dlog DebugPrintF
- #endif
-#else
- #if ( DEBUG_C99_VA_ARGS )
- #define dlog(... )
- #elif ( DEBUG_GNU_VA_ARGS )
- #define dlog( ARGS... )
- #else
- #define dlog while( 0 )
- #endif
-#endif
-
-
-/*! @defined dlogv
-
- @abstract Prints a debug-only message.
- */
-
-#if ( DEBUG )
- #define dlogv( LEVEL, FORMAT, LIST ) DebugPrintFVAList( ( LEVEL ), ( FORMAT ), ( LIST ) )
-#else
- #define dlogv( LEVEL, FORMAT, LIST )
-#endif
-
-
-/*! @defined dlogmem
-
- @abstract Prints a debug-only dump of memory.
- */
-
-#if ( DEBUG )
- #define dlogmem( LEVEL, PTR, SIZE ) \
- DebugHexDump( ( LEVEL ), 0, NULL, 0, 0, NULL, 0, ( PTR ), ( PTR ), ( SIZE ), kDebugFlagsNone, NULL, 0 )
-#else
- #define dlogmem( LEVEL, PTR, SIZE )
-#endif
-
-
-/*! @defined DebugNSLog
-
- @abstract Debug-only macro for the Cocoa NSLog function.
- */
-
-#if ( DEBUG )
- #if ( DEBUG_C99_VA_ARGS )
- #define DebugNSLog(... ) NSLog( __VA_ARGS__ )
- #elif ( DEBUG_GNU_VA_ARGS )
- #define DebugNSLog( ARGS... ) NSLog( ## ARGS )
- #else
- #define DebugNSLog NSLog
- #endif
-#else
- #if ( DEBUG_C99_VA_ARGS )
- #define DebugNSLog(... )
- #elif ( DEBUG_GNU_VA_ARGS )
- #define DebugNSLog( ARGS... )
- #else
- #define DebugNSLog while( 0 )
- #endif
-#endif
-
-
-/*! @defined DebugLogMsg
-
- @abstract Debug-only macro for the VxWorks logMsg function.
- */
-
-#if ( TARGET_OS_VXWORKS )
- #if ( DEBUG )
- #define DebugLogMsg( LEVEL, FORMAT, P1, P2, P3, P4, P5, P6 ) \
- do \
- { \
- if( ( inLevel >= gDebugPrintLevelMin ) || ( inLevel <= gDebugPrintLevelMax ) ) \
- { \
- logMsg( ( FORMAT ), ( P1 ), ( P2 ), ( P3 ), ( P4 ), ( P5 ), ( P6 ) ); \
- } \
- \
- } while( 0 )
- #else
- #define DebugLogMsg( LEVEL, FORMAT, P1, P2, P3, P4, P5, P6 )
- #endif
-#else
- #define DebugLogMsg dlog
-#endif
-
-#if 0
-#pragma mark == Routines - General ==
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*! @function DebugInitialize
-
- @abstract Initializes the debugging library for a specific kind of output.
-
- @param inType
- @param varArg Variable number parameters, controlled by the "inType" parameter.
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT OSStatus DebugInitialize( DebugOutputType inType, ... );
-#endif
-
-#if ( DEBUG )
- #if ( DEBUG_C99_VA_ARGS )
- #define debug_initialize(... ) DebugInitialize( __VA_ARGS__ )
- #elif ( DEBUG_GNU_VA_ARGS )
- #define debug_initialize( ARGS... ) DebugInitialize( ## ARGS )
- #else
- #define debug_initialize DebugInitialize
- #endif
-#else
- #if ( DEBUG_C99_VA_ARGS )
- #define debug_initialize(... )
- #elif ( DEBUG_GNU_VA_ARGS )
- #define debug_initialize( ARGS... )
- #else
- #define debug_initialize while( 0 )
- #endif
-#endif
-
-
-/*! @function DebugFinalize
-
- @abstract Releases any resources used by the debugging library
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT void DebugFinalize( void );
-#endif
-
-#if ( DEBUG )
- #define debug_terminate() DebugFinalize()
-#else
- #define debug_terminate()
-#endif
-
-
-/*! @function DebugGetProperty
-
- @abstract Gets the specified property from the debugging library.
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT OSStatus DebugGetProperty( DebugPropertyTag inTag, ... );
-#endif
-
-#if ( DEBUG )
- #if ( DEBUG_C99_VA_ARGS )
- #define debug_get_property(... ) DebugGetProperty( __VA_ARGS__ )
- #elif ( DEBUG_GNU_VA_ARGS )
- #define debug_get_property( ARGS... ) DebugGetProperty( ## ARGS )
- #else
- #define debug_get_property DebugGetProperty
- #endif
-#else
- #if ( DEBUG_C99_VA_ARGS )
- #define debug_get_property(... )
- #elif ( DEBUG_GNU_VA_ARGS )
- #define debug_get_property( ARGS... )
- #else
- #define debug_get_property while( 0 )
- #endif
-#endif
-
-
-/*! @function DebugSetProperty
-
- @abstract Sets the specified property from the debugging library.
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT OSStatus DebugSetProperty( DebugPropertyTag inTag, ... );
-#endif
-
-#if ( DEBUG )
- #if ( DEBUG_C99_VA_ARGS )
- #define debug_set_property(... ) DebugSetProperty( __VA_ARGS__ )
- #elif ( DEBUG_GNU_VA_ARGS )
- #define debug_set_property( ARGS... ) DebugSetProperty( ## ARGS )
- #else
- #define debug_set_property DebugSetProperty
- #endif
-#else
- #if ( DEBUG_C99_VA_ARGS )
- #define debug_set_property(... )
- #elif ( DEBUG_GNU_VA_ARGS )
- #define debug_set_property( ARGS... )
- #else
- #define debug_set_property while( 0 )
- #endif
-#endif
-
-#if 0
-#pragma mark == Routines - Debugging Output ==
-#endif
-
-
-/*! @function DebugPrintF
-
- @abstract Prints a debug message with printf-style formatting.
-
- @param inLevel Error that generated this assert or noErr.
-
- @param inFormatString
- C string containing assertion text.
-
- @param VAR_ARG
- Variable number of arguments depending on the format string.
-
- @result Number of bytes printed or -1 on error.
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT size_t DebugPrintF( DebugLevel inLevel, const char *inFormat, ... );
-#endif
-
-
-/*! @function DebugPrintFVAList
-
- @abstract va_list version of DebugPrintF. See DebugPrintF for more info.
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT size_t DebugPrintFVAList( DebugLevel inLevel, const char *inFormat, va_list inArgs );
-#endif
-
-
-/*! @function DebugPrintAssert
-
- @abstract Prints a message describing the reason the (e.g. an assert failed), an optional error message,
- an optional source filename, an optional source line number.
-
- @param inErrorCode Error that generated this assert or noErr.
- @param inAssertString C string containing assertion text.
- @param inMessage C string containing a message about the assert.
- @param inFileName C string containing path of file where the error occurred.
- @param inLineNumber Line number in source file where the error occurred.
- @param inFunction C string containing name of function where assert occurred.
-
- @discussion
-
- Example output:
-
- [ASSERT] assert: "dataPtr != NULL" allocate memory for object failed
- [ASSERT] where: "MyFile.c", line 123, ("MyFunction")
-
- OR
-
- [ASSERT] error: -6728 (kNoMemoryErr)
- [ASSERT] where: "MyFile.c", line 123, ("MyFunction")
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT void
-DebugPrintAssert(
- int_least32_t inErrorCode,
- const char * inAssertString,
- const char * inMessage,
- const char * inFilename,
- int_least32_t inLineNumber,
- const char * inFunction );
-#endif
-
-#if 0
-#pragma mark == Routines - Utilities ==
-#endif
-
-
-/*! @function DebugSNPrintF
-
- @abstract Debugging versions of standard C snprintf with extra features.
-
- @param sbuffer Buffer to receive result. Null terminated unless the buffer size is 0.
- @param buflen Size of the buffer including space for the null terminator.
- @param fmt printf-style format string.
- @param VAR_ARG Variable number of arguments depending on the format string.
-
- @result Number of characters written (minus the null terminator).
-
- @discussion
-
- Extra features over the standard C snprintf:
- <pre>
- 64-bit support for %d (%lld), %i (%lli), %u (%llu), %o (%llo), %x (%llx), and %b (%llb).
- %@ - Cocoa/CoreFoundation object. Param is the object. Strings are used directly. Others use CFCopyDescription.
- %a - Network Address: %.4a=IPv4, %.6a=Ethernet, %.8a Fibre Channel, %.16a=IPv6. Arg=ptr to network address.
- %#a - IPv4 or IPv6 mDNSAddr. Arg=ptr to mDNSAddr.
- %##a - IPv4 (if AF_INET defined) or IPv6 (if AF_INET6 defined) sockaddr. Arg=ptr to sockaddr.
- %b - Binary representation of integer (e.g. 01101011). Modifiers and arg=the same as %d, %x, etc.
- %C - Mac-style FourCharCode (e.g. 'APPL'). Arg=32-bit value to print as a Mac-style FourCharCode.
- %H - Hex Dump (e.g. "\x6b\xa7" -> "6B A7"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
- %#H - Hex Dump & ASCII (e.g. "\x41\x62" -> "6B A7 'Ab'"). 1st arg=ptr, 2nd arg=size, 3rd arg=max size.
- %m - Error Message (e.g. 0 -> "kNoErr"). Modifiers and error code arg=the same as %d, %x, etc.
- %#s - Pascal-style length-prefixed string. Arg=ptr to string.
- %##s - DNS label-sequence name. Arg=ptr to name.
- %S - UTF-16 string, 0x0000 terminated. Host order if no BOM. Precision is UTF-16 count. Precision includes BOM.
- %#S - Big Endian UTF-16 string (unless BOM overrides). Otherwise, the same as %S.
- %##S - Little Endian UTF-16 string (unless BOM overrides). Otherwise, the same as %S.
- %U - Universally Unique Identifier (UUID) (e.g. 6ba7b810-9dad-11d1-80b4-00c04fd430c8). Arg=ptr to 16-byte UUID.
- </pre>
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT size_t DebugSNPrintF(char *sbuffer, size_t buflen, const char *fmt, ...);
-#endif
-
-
-/*! @function DebugSNPrintFVAList
-
- @abstract va_list version of DebugSNPrintF. See DebugSNPrintF for more info.
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT size_t DebugSNPrintFVAList(char *sbuffer, size_t buflen, const char *fmt, va_list arg);
-#endif
-
-
-/*! @function DebugGetErrorString
-
- @abstract Gets an error string from an error code.
-
- @param inStatus Error code to get the string for.
- @param inBuffer Optional buffer to copy the string to for non-static strings. May be null.
- @param inBufferSize Size of optional buffer. May be 0.
-
- @result C string containing error string for the error code. Guaranteed to be a valid, static string. If a
- buffer is supplied, the return value will always be a pointer to the supplied buffer, which will
- contain the best available description of the error code. If a buffer is not supplied, the return
- value will be the best available description of the error code that can be represented as a static
- string. This allows code that cannot use a temporary buffer to hold the result to still get a useful
- error string in most cases, but also allows code that can use a temporary buffer to get the best
- available description.
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT const char * DebugGetErrorString( int_least32_t inErrorCode, char *inBuffer, size_t inBufferSize );
-#endif
-
-
-/*! @function DebugHexDump
-
- @abstract Hex dumps data to a string or to the output device.
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT size_t
-DebugHexDump(
- DebugLevel inLevel,
- int inIndent,
- const char * inLabel,
- size_t inLabelSize,
- int inLabelMinWidth,
- const char * inType,
- size_t inTypeSize,
- const void * inDataStart,
- const void * inData,
- size_t inDataSize,
- DebugFlags inFlags,
- char * outBuffer,
- size_t inBufferSize );
-#endif
-
-#if ( DEBUG )
- #define dloghex( LEVEL, INDENT, LABEL, LABEL_SIZE, LABEL_MIN_SIZE, TYPE, TYPE_SIZE, DATA_START, DATA, DATA_SIZE, FLAGS, BUFFER, BUFFER_SIZE ) \
- DebugHexDump( ( LEVEL ), (INDENT), ( LABEL ), ( LABEL_SIZE ), ( LABEL_MIN_SIZE ), ( TYPE ), ( TYPE_SIZE ), \
- ( DATA_START ), ( DATA ), ( DATA_SIZE ), ( FLAGS ), ( BUFFER ), ( BUFFER_SIZE ) )
-#else
- #define dloghex( LEVEL, INDENT, LABEL, LABEL_SIZE, LABEL_MIN_SIZE, TYPE, TYPE_SIZE, DATA_START, DATA, DATA_SIZE, FLAGS, BUFFER, BUFFER_SIZE )
-#endif
-
-
-/*! @function DebugTaskLevel
-
- @abstract Returns the current task level.
-
- @result Current task level
-
- @discussion
-
- Bit masks to isolate portions of the result (note that some masks may also need bit shifts to right justify):
- <pre>
- kDebugInterruptLevelMask - Indicates the current interrupt level (> 0 means interrupt time).
- kDebugInVBLTaskMask - Indicates if a VBL task is currently being executed.
- kDebugInDeferredTaskMask - Indicates if a Deferred Task is currently being executed.
- kDebugInSecondaryInterruptHandlerMask - Indicates if a Secondary Interrupt Handler is currently being executed.
- kDebugPageFaultFatalMask - Indicates if it is unsafe to cause a page fault (worse than interrupt time).
- kDebugMPTaskLevelMask - Indicates if being called from an MP task.
- kDebugInterruptDepthMask - 0 means task level, 1 means in interrupt, > 1 means in nested interrupt.
- </pre>
-
- Helpers:
- <pre>
- DebugExtractTaskLevelInterruptDepth() - Macro to extract interrupt depth from task level value.
- </pre>
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT uint32_t DebugTaskLevel( void );
-#endif
-
-
-/*! @function DebugServicesTest
-
- @abstract Unit test.
- */
-
-#if ( DEBUG )
-DEBUG_EXPORT OSStatus DebugServicesTest( void );
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __DEBUG_SERVICES__
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList.c b/sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList.c
deleted file mode 100644
index 6007242539fb..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList.c
+++ /dev/null
@@ -1,319 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-
- File: GenLinkedList.c
-
- Contains: implementation of generic linked lists.
-
- Version: 1.0
- Tabs: 4 spaces
- */
-
-#include "GenLinkedList.h"
-
-
-// Return the link pointer contained within element e at offset o.
-#define GETLINK( e, o) ( *(void**)((char*) (e) + (o)) )
-
-// Assign the link pointer l to element e at offset o.
-#define ASSIGNLINK( e, l, o) ( *((void**)((char*) (e) + (o))) = (l))
-
-
-// GenLinkedList
-
-void InitLinkedList( GenLinkedList *pList, size_t linkOffset)
-/* Initialize the block of memory pointed to by pList as a linked list. */
-{
- pList->Head = NULL;
- pList->Tail = NULL;
- pList->LinkOffset = linkOffset;
-}
-
-
-void AddToTail( GenLinkedList *pList, void *elem)
-/* Add a linked list element to the tail of the list. */
-{
- if ( pList->Tail) {
- ASSIGNLINK( pList->Tail, elem, pList->LinkOffset);
- } else
- pList->Head = elem;
- ASSIGNLINK( elem, NULL, pList->LinkOffset);
-
- pList->Tail = elem;
-}
-
-
-void AddToHead( GenLinkedList *pList, void *elem)
-/* Add a linked list element to the head of the list. */
-{
- ASSIGNLINK( elem, pList->Head, pList->LinkOffset);
- if ( pList->Tail == NULL)
- pList->Tail = elem;
-
- pList->Head = elem;
-}
-
-
-int RemoveFromList( GenLinkedList *pList, void *elem)
-/* Remove a linked list element from the list. Return 0 if it was not found. */
-/* If the element is removed, its link will be set to NULL. */
-{
- void *iElem, *lastElem;
-
- for ( iElem = pList->Head, lastElem = NULL; iElem; iElem = GETLINK( iElem, pList->LinkOffset)) {
- if ( iElem == elem) {
- if ( lastElem) { // somewhere past the head
- ASSIGNLINK( lastElem, GETLINK( elem, pList->LinkOffset), pList->LinkOffset);
- } else { // at the head
- pList->Head = GETLINK( elem, pList->LinkOffset);
- }
- if ( pList->Tail == elem)
- pList->Tail = lastElem ? lastElem : NULL;
- ASSIGNLINK( elem, NULL, pList->LinkOffset); // maybe catch a stale reference bug.
- return 1;
- }
- lastElem = iElem;
- }
-
- return 0;
-}
-
-
-int ReplaceElem( GenLinkedList *pList, void *elemInList, void *newElem)
-/* Replace an element in the list with a new element, in the same position. */
-{
- void *iElem, *lastElem;
-
- if ( elemInList == NULL || newElem == NULL)
- return 0;
-
- for ( iElem = pList->Head, lastElem = NULL; iElem; iElem = GETLINK( iElem, pList->LinkOffset))
- {
- if ( iElem == elemInList)
- {
- ASSIGNLINK( newElem, GETLINK( elemInList, pList->LinkOffset), pList->LinkOffset);
- if ( lastElem) // somewhere past the head
- {
- ASSIGNLINK( lastElem, newElem, pList->LinkOffset);
- }
- else // at the head
- {
- pList->Head = newElem;
- }
- if ( pList->Tail == elemInList)
- pList->Tail = newElem;
- return 1;
- }
- lastElem = iElem;
- }
-
- return 0;
-}
-
-
-// GenDoubleLinkedList
-
-void InitDoubleLinkedList( GenDoubleLinkedList *pList, size_t fwdLinkOffset,
- size_t backLinkOffset)
-/* Initialize the block of memory pointed to by pList as a double linked list. */
-{
- pList->Head = NULL;
- pList->Tail = NULL;
- pList->FwdLinkOffset = fwdLinkOffset;
- pList->BackLinkOffset = backLinkOffset;
-}
-
-
-void DLLAddToHead( GenDoubleLinkedList *pList, void *elem)
-/* Add a linked list element to the head of the list. */
-{
- void *pNext;
-
- pNext = pList->Head;
-
- // fix up the forward links
- ASSIGNLINK( elem, pList->Head, pList->FwdLinkOffset);
- pList->Head = elem;
-
- // fix up the backward links
- if ( pNext) {
- ASSIGNLINK( pNext, elem, pList->BackLinkOffset);
- } else
- pList->Tail = elem;
- ASSIGNLINK( elem, NULL, pList->BackLinkOffset);
-}
-
-
-void DLLRemoveFromList( GenDoubleLinkedList *pList, void *elem)
-/* Remove a linked list element from the list. */
-/* When the element is removed, its link will be set to NULL. */
-{
- void *pNext, *pPrev;
-
- pNext = GETLINK( elem, pList->FwdLinkOffset);
- pPrev = GETLINK( elem, pList->BackLinkOffset);
-
- // fix up the forward links
- if ( pPrev)
- ASSIGNLINK( pPrev, pNext, pList->FwdLinkOffset);
- else
- pList->Head = pNext;
-
- // fix up the backward links
- if ( pNext)
- ASSIGNLINK( pNext, pPrev, pList->BackLinkOffset);
- else
- pList->Tail = pPrev;
-
- ASSIGNLINK( elem, NULL, pList->FwdLinkOffset);
- ASSIGNLINK( elem, NULL, pList->BackLinkOffset);
-}
-
-
-// GenLinkedOffsetList
-
-// Extract the Next offset from element
-#define GETOFFSET( e, o) ( *(size_t*)((char*) (e) + (o)) )
-
-static void AssignOffsetLink( void *elem, void *link, size_t linkOffset);
-
-
-static void AssignOffsetLink( void *elem, void *link, size_t linkOffset)
-// Assign link to elem as an offset from elem. Assign 0 to elem if link is NULL.
-{
- GETOFFSET( elem, linkOffset) = link ? (size_t) link - (size_t) elem : 0;
-}
-
-
-void *GetHeadPtr( GenLinkedOffsetList *pList)
-/* Return a pointer to the head element of a list, or NULL if none. */
-{
- return pList->Head ? ( (char*) (pList) + pList->Head) : NULL;
-}
-
-
-void *GetTailPtr( GenLinkedOffsetList *pList)
-/* Return a pointer to the tail element of a list, or NULL if none. */
-{
- return pList->Tail ? ( (char*) (pList) + pList->Tail) : NULL;
-}
-
-
-void *GetOffsetLink( GenLinkedOffsetList *pList, void *elem)
-/* Return the link pointer contained within element e for pList, or NULL if it is 0. */
-{
- size_t nextOffset;
-
- nextOffset = GETOFFSET( elem, pList->LinkOffset);
-
- return nextOffset ? (char*) elem + nextOffset : NULL;
-}
-
-
-void InitLinkedOffsetList( GenLinkedOffsetList *pList, size_t linkOffset)
-/* Initialize the block of memory pointed to by pList as a linked list. */
-{
- pList->Head = 0;
- pList->Tail = 0;
- pList->LinkOffset = linkOffset;
-}
-
-
-void OffsetAddToTail( GenLinkedOffsetList *pList, void *elem)
-/* Add a linked list element to the tail of the list. */
-{
- if ( pList->Tail) {
- AssignOffsetLink( GetTailPtr( pList), elem, pList->LinkOffset);
- } else
- pList->Head = (size_t) elem - (size_t) pList;
- AssignOffsetLink( elem, NULL, pList->LinkOffset);
-
- pList->Tail = (size_t) elem - (size_t) pList;
-}
-
-
-void OffsetAddToHead( GenLinkedOffsetList *pList, void *elem)
-/* Add a linked list element to the head of the list. */
-{
- AssignOffsetLink( elem, GetHeadPtr( pList), pList->LinkOffset);
- if ( pList->Tail == 0)
- pList->Tail = (size_t) elem - (size_t) pList;
-
- pList->Head = (size_t) elem - (size_t) pList;
-}
-
-
-int OffsetRemoveFromList( GenLinkedOffsetList *pList, void *elem)
-/* Remove a linked list element from the list. Return 0 if it was not found. */
-/* If the element is removed, its link will be set to NULL. */
-{
- void *iElem, *lastElem;
-
- for ( iElem = GetHeadPtr( pList), lastElem = NULL; iElem;
- iElem = GetOffsetLink( pList, iElem))
- {
- if ( iElem == elem) {
- if ( lastElem) { // somewhere past the head
- AssignOffsetLink( lastElem, GetOffsetLink( pList, elem), pList->LinkOffset);
- } else { // at the head
- iElem = GetOffsetLink( pList, elem);
- pList->Head = iElem ? (size_t) iElem - (size_t) pList : 0;
- }
- if ( GetTailPtr( pList) == elem)
- pList->Tail = lastElem ? (size_t) lastElem - (size_t) pList : 0;
- AssignOffsetLink( elem, NULL, pList->LinkOffset); // maybe catch a stale reference bug.
- return 1;
- }
- lastElem = iElem;
- }
-
- return 0;
-}
-
-
-int OffsetReplaceElem( GenLinkedOffsetList *pList, void *elemInList, void *newElem)
-/* Replace an element in the list with a new element, in the same position. */
-{
- void *iElem, *lastElem;
-
- if ( elemInList == NULL || newElem == NULL)
- return 0;
-
- for ( iElem = GetHeadPtr( pList), lastElem = NULL; iElem;
- iElem = GetOffsetLink( pList, iElem))
- {
- if ( iElem == elemInList)
- {
- AssignOffsetLink( newElem, GetOffsetLink( pList, elemInList), pList->LinkOffset);
- if ( lastElem) // somewhere past the head
- {
- AssignOffsetLink( lastElem, newElem, pList->LinkOffset);
- }
- else // at the head
- {
- pList->Head = (size_t) newElem - (size_t) pList;
- }
- if ( GetTailPtr( pList) == elemInList)
- pList->Tail = (size_t) newElem - (size_t) pList;
- return 1;
- }
- lastElem = iElem;
- }
-
- return 0;
-}
-
-
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList.h b/sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList.h
deleted file mode 100644
index 71d5638c03b9..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __GenLinkedList__
-#define __GenLinkedList__
-
-
-#include <stddef.h>
-
-
-struct GenLinkedList
-{
- void *Head,
- *Tail;
- size_t LinkOffset;
-};
-typedef struct GenLinkedList GenLinkedList;
-
-
-void InitLinkedList( GenLinkedList *pList, size_t linkOffset);
-
-void AddToHead( GenLinkedList *pList, void *elem);
-void AddToTail( GenLinkedList *pList, void *elem);
-
-int RemoveFromList( GenLinkedList *pList, void *elem);
-
-int ReplaceElem( GenLinkedList *pList, void *elemInList, void *newElem);
-
-
-
-struct GenDoubleLinkedList
-{
- void *Head,
- *Tail;
- size_t FwdLinkOffset,
- BackLinkOffset;
-};
-typedef struct GenDoubleLinkedList GenDoubleLinkedList;
-
-
-void InitDoubleLinkedList( GenDoubleLinkedList *pList, size_t fwdLinkOffset,
- size_t backLinkOffset);
-
-void DLLAddToHead( GenDoubleLinkedList *pList, void *elem);
-
-void DLLRemoveFromList( GenDoubleLinkedList *pList, void *elem);
-
-
-
-/* A GenLinkedOffsetList is like a GenLinkedList that stores the *Next field as a signed */
-/* offset from the address of the beginning of the element, rather than as a pointer. */
-
-struct GenLinkedOffsetList
-{
- size_t Head,
- Tail;
- size_t LinkOffset;
-};
-typedef struct GenLinkedOffsetList GenLinkedOffsetList;
-
-
-void InitLinkedOffsetList( GenLinkedOffsetList *pList, size_t linkOffset);
-
-void *GetHeadPtr( GenLinkedOffsetList *pList);
-void *GetTailPtr( GenLinkedOffsetList *pList);
-void *GetOffsetLink( GenLinkedOffsetList *pList, void *elem);
-
-void OffsetAddToHead( GenLinkedOffsetList *pList, void *elem);
-void OffsetAddToTail( GenLinkedOffsetList *pList, void *elem);
-
-int OffsetRemoveFromList( GenLinkedOffsetList *pList, void *elem);
-
-int OffsetReplaceElem( GenLinkedOffsetList *pList, void *elemInList, void *newElem);
-
-
-#endif // __GenLinkedList__
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/dllmain.c b/sd/source/ui/remotecontrol/mDNSResponder/dllmain.c
deleted file mode 100644
index 49fd854c96c8..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/dllmain.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// #include <windows.h>
-#include <DebugServices.h>
-#include <stdlib.h>
-
-BOOL APIENTRY DllMain( HANDLE inModule, DWORD inReason, LPVOID inReserved )
-{
- (void) inModule;
- (void) inReserved;
-
- switch( inReason )
- {
- case DLL_PROCESS_ATTACH:
- case DLL_THREAD_ATTACH:
- case DLL_THREAD_DETACH:
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
-}
-
-
-BOOL
-IsSystemServiceDisabled()
-{
- ENUM_SERVICE_STATUS * lpService = NULL;
- SC_HANDLE sc;
- BOOL ret = FALSE;
- BOOL ok;
- DWORD bytesNeeded = 0;
- DWORD srvCount;
- DWORD resumeHandle = 0;
- DWORD srvType;
- DWORD srvState;
- DWORD dwBytes = 0;
- DWORD i;
- OSStatus err;
-
- sc = OpenSCManager( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE );
- err = translate_errno( sc, GetLastError(), kUnknownErr );
- require_noerr( err, exit );
-
- srvType = SERVICE_WIN32;
- srvState = SERVICE_STATE_ALL;
-
- for ( ;; )
- {
- // Call EnumServicesStatus using the handle returned by OpenSCManager
-
- ok = EnumServicesStatus ( sc, srvType, srvState, lpService, dwBytes, &bytesNeeded, &srvCount, &resumeHandle );
-
- if ( ok || ( GetLastError() != ERROR_MORE_DATA ) )
- {
- break;
- }
-
- if ( lpService )
- {
- free( lpService );
- }
-
- dwBytes = bytesNeeded;
-
- lpService = ( ENUM_SERVICE_STATUS* ) malloc( dwBytes );
- require_action( lpService, exit, ret = FALSE );
- }
-
- err = translate_errno( ok, GetLastError(), kUnknownErr );
- require_noerr( err, exit );
-
- for ( i = 0; i < srvCount; i++ )
- {
- if ( strcmp( lpService[i].lpServiceName, "Bonjour Service" ) == 0 )
- {
- if ( ( lpService[i].ServiceStatus.dwCurrentState == SERVICE_PAUSED ) || ( lpService[i].ServiceStatus.dwCurrentState == SERVICE_STOPPED ) )
- {
- ret = TRUE;
- }
-
- break;
- }
- }
-
-exit:
-
- if ( lpService )
- {
- free( lpService );
- }
-
- if ( sc )
- {
- CloseServiceHandle ( sc );
- }
-
- return ret;
-}
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/dns_sd.h b/sd/source/ui/remotecontrol/mDNSResponder/dns_sd.h
deleted file mode 100644
index faaa7416f7b3..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/dns_sd.h
+++ /dev/null
@@ -1,2459 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/*! @header DNS Service Discovery
- *
- * @discussion This section describes the functions, callbacks, and data structures
- * that make up the DNS Service Discovery API.
- *
- * The DNS Service Discovery API is part of Bonjour, Apple's implementation
- * of zero-configuration networking (ZEROCONF).
- *
- * Bonjour allows you to register a network service, such as a
- * printer or file server, so that it can be found by name or browsed
- * for by service type and domain. Using Bonjour, applications can
- * discover what services are available on the network, along with
- * all the information -- such as name, IP address, and port --
- * necessary to access a particular service.
- *
- * In effect, Bonjour combines the functions of a local DNS server and
- * AppleTalk. Bonjour allows applications to provide user-friendly printer
- * and server browsing, among other things, over standard IP networks.
- * This behavior is a result of combining protocols such as multicast and
- * DNS to add new functionality to the network (such as multicast DNS).
- *
- * Bonjour gives applications easy access to services over local IP
- * networks without requiring the service or the application to support
- * an AppleTalk or a Netbeui stack, and without requiring a DNS server
- * for the local network.
- */
-
-
-/* _DNS_SD_H contains the mDNSResponder version number for this header file, formatted as follows:
- * Major part of the build number * 10000 +
- * minor part of the build number * 100
- * For example, Mac OS X 10.4.9 has mDNSResponder-108.4, which would be represented as
- * version 1080400. This allows C code to do simple greater-than and less-than comparisons:
- * e.g. an application that requires the DNSServiceGetProperty() call (new in mDNSResponder-126) can check:
- *
- * #if _DNS_SD_H+0 >= 1260000
- * ... some C code that calls DNSServiceGetProperty() ...
- * #endif
- *
- * The version defined in this header file symbol allows for compile-time
- * checking, so that C code building with earlier versions of the header file
- * can avoid compile errors trying to use functions that aren't even defined
- * in those earlier versions. Similar checks may also be performed at run-time:
- * => weak linking -- to avoid link failures if run with an earlier
- * version of the library that's missing some desired symbol, or
- * => DNSServiceGetProperty(DaemonVersion) -- to verify whether the running daemon
- * ("system service" on Windows) meets some required minimum functionality level.
- */
-
-#ifndef _DNS_SD_H
-#define _DNS_SD_H 3793700
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef WIN32
-#define WIN32
-#endif
-#ifndef NDEBUG
-#define NDEBUG
-#endif
-#ifndef _WINDOWS
-#define _WINDOWS
-#endif
-#ifndef _USRDLL
-#define _USRDLL
-#endif
-#ifndef NOT_HAVE_SA_LEN
-#define NOT_HAVE_SA_LEN
-#endif
-#ifndef MDNS_DEBUGMSGS
-#define MDNS_DEBUGMSGS 0
-#endif
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-#ifndef USE_TCP_LOOPBACK
-#define USE_TCP_LOOPBACK
-#endif
-#ifndef _CRT_SECURE_NO_DEPRECATE
-#define _CRT_SECURE_NO_DEPRECATE
-#endif
-#ifndef _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES
-#define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
-#endif
-
-/* Set to 1 if libdispatch is supported
- * Note: May also be set by project and/or Makefile
- */
-#ifndef _DNS_SD_LIBDISPATCH
-#define _DNS_SD_LIBDISPATCH 0
-#endif /* ndef _DNS_SD_LIBDISPATCH */
-
-/* standard calling convention under Win32 is __stdcall */
-/* Note: When compiling Intel EFI (Extensible Firmware Interface) under MS Visual Studio, the */
-/* _WIN32 symbol is defined by the compiler even though it's NOT compiling code for Windows32 */
-#if defined(_WIN32) && !defined(EFI32) && !defined(EFI64)
-#define DNSSD_API __stdcall
-#else
-#define DNSSD_API
-#endif
-
-/* stdint.h does not exist on FreeBSD 4.x; its types are defined in sys/types.h instead */
-#if defined(__FreeBSD__) && (__FreeBSD__ < 5)
-#include <sys/types.h>
-
-/* Likewise, on Sun, standard integer types are in sys/types.h */
-#elif defined(__sun__)
-#include <sys/types.h>
-
-/* EFI does not have stdint.h, or anything else equivalent */
-#elif defined(EFI32) || defined(EFI64) || defined(EFIX64)
-#include "Tiano.h"
-#if !defined(_STDINT_H_)
-typedef UINT8 uint8_t;
-typedef INT8 int8_t;
-typedef UINT16 uint16_t;
-typedef INT16 int16_t;
-typedef UINT32 uint32_t;
-typedef INT32 int32_t;
-#endif
-/* Windows has its own differences */
-#elif defined(_WIN32)
-#include <windows.h>
-#define _UNUSED
-#ifndef _MSL_STDINT_H
-typedef UINT8 uint8_t;
-typedef INT8 int8_t;
-typedef UINT16 uint16_t;
-typedef INT16 int16_t;
-typedef UINT32 uint32_t;
-typedef INT32 int32_t;
-#endif
-
-/* All other Posix platforms use stdint.h */
-#else
-#include <stdint.h>
-#endif
-
-#if _DNS_SD_LIBDISPATCH
-#include <dispatch/dispatch.h>
-#endif
-
-/* DNSServiceRef, DNSRecordRef
- *
- * Opaque internal data types.
- * Note: client is responsible for serializing access to these structures if
- * they are shared between concurrent threads.
- */
-
-typedef struct _DNSServiceRef_t *DNSServiceRef;
-typedef struct _DNSRecordRef_t *DNSRecordRef;
-
-struct sockaddr;
-
-/*! @enum General flags
- * Most DNS-SD API functions and callbacks include a DNSServiceFlags parameter.
- * As a general rule, any given bit in the 32-bit flags field has a specific fixed meaning,
- * regardless of the function or callback being used. For any given function or callback,
- * typically only a subset of the possible flags are meaningful, and all others should be zero.
- * The discussion section for each API call describes which flags are valid for that call
- * and callback. In some cases, for a particular call, it may be that no flags are currently
- * defined, in which case the DNSServiceFlags parameter exists purely to allow future expansion.
- * In all cases, developers should expect that in future releases, it is possible that new flag
- * values will be defined, and write code with this in mind. For example, code that tests
- * if (flags == kDNSServiceFlagsAdd) ...
- * will fail if, in a future release, another bit in the 32-bit flags field is also set.
- * The reliable way to test whether a particular bit is set is not with an equality test,
- * but with a bitwise mask:
- * if (flags & kDNSServiceFlagsAdd) ...
- */
-enum
-{
- kDNSServiceFlagsMoreComing = 0x1,
- /* MoreComing indicates to a callback that at least one more result is
- * queued and will be delivered following immediately after this one.
- * When the MoreComing flag is set, applications should not immediately
- * update their UI, because this can result in a great deal of ugly flickering
- * on the screen, and can waste a great deal of CPU time repeatedly updating
- * the screen with content that is then immediately erased, over and over.
- * Applications should wait until MoreComing is not set, and then
- * update their UI when no more changes are imminent.
- * When MoreComing is not set, that doesn't mean there will be no more
- * answers EVER, just that there are no more answers immediately
- * available right now at this instant. If more answers become available
- * in the future they will be delivered as usual.
- */
-
- kDNSServiceFlagsAdd = 0x2,
- kDNSServiceFlagsDefault = 0x4,
- /* Flags for domain enumeration and browse/query reply callbacks.
- * "Default" applies only to enumeration and is only valid in
- * conjunction with "Add". An enumeration callback with the "Add"
- * flag NOT set indicates a "Remove", i.e. the domain is no longer
- * valid.
- */
-
- kDNSServiceFlagsNoAutoRename = 0x8,
- /* Flag for specifying renaming behavior on name conflict when registering
- * non-shared records. By default, name conflicts are automatically handled
- * by renaming the service. NoAutoRename overrides this behavior - with this
- * flag set, name conflicts will result in a callback. The NoAutorename flag
- * is only valid if a name is explicitly specified when registering a service
- * (i.e. the default name is not used.)
- */
-
- kDNSServiceFlagsShared = 0x10,
- kDNSServiceFlagsUnique = 0x20,
- /* Flag for registering individual records on a connected
- * DNSServiceRef. Shared indicates that there may be multiple records
- * with this name on the network (e.g. PTR records). Unique indicates that the
- * record's name is to be unique on the network (e.g. SRV records).
- */
-
- kDNSServiceFlagsBrowseDomains = 0x40,
- kDNSServiceFlagsRegistrationDomains = 0x80,
- /* Flags for specifying domain enumeration type in DNSServiceEnumerateDomains.
- * BrowseDomains enumerates domains recommended for browsing, RegistrationDomains
- * enumerates domains recommended for registration.
- */
-
- kDNSServiceFlagsLongLivedQuery = 0x100,
- /* Flag for creating a long-lived unicast query for the DNSServiceQueryRecord call. */
-
- kDNSServiceFlagsAllowRemoteQuery = 0x200,
- /* Flag for creating a record for which we will answer remote queries
- * (queries from hosts more than one hop away; hosts not directly connected to the local link).
- */
-
- kDNSServiceFlagsForceMulticast = 0x400,
- /* Flag for signifying that a query or registration should be performed exclusively via multicast
- * DNS, even for a name in a domain (e.g. foo.apple.com.) that would normally imply unicast DNS.
- */
-
- kDNSServiceFlagsForce = 0x800,
- /* Flag for signifying a "stronger" variant of an operation.
- * Currently defined only for DNSServiceReconfirmRecord(), where it forces a record to
- * be removed from the cache immediately, instead of querying for a few seconds before
- * concluding that the record is no longer valid and then removing it. This flag should
- * be used with caution because if a service browsing PTR record is indeed still valid
- * on the network, forcing its removal will result in a user-interface flap -- the
- * discovered service instance will disappear, and then re-appear moments later.
- */
-
- kDNSServiceFlagsReturnIntermediates = 0x1000,
- /* Flag for returning intermediate results.
- * For example, if a query results in an authoritative NXDomain (name does not exist)
- * then that result is returned to the client. However the query is not implicitly
- * cancelled -- it remains active and if the answer subsequently changes
- * (e.g. because a VPN tunnel is subsequently established) then that positive
- * result will still be returned to the client.
- * Similarly, if a query results in a CNAME record, then in addition to following
- * the CNAME referral, the intermediate CNAME result is also returned to the client.
- * When this flag is not set, NXDomain errors are not returned, and CNAME records
- * are followed silently without informing the client of the intermediate steps.
- * (In earlier builds this flag was briefly calledkDNSServiceFlagsReturnCNAME)
- */
-
- kDNSServiceFlagsNonBrowsable = 0x2000,
- /* A service registered with the NonBrowsable flag set can be resolved using
- * DNSServiceResolve(), but will not be discoverable using DNSServiceBrowse().
- * This is for cases where the name is actually a GUID; it is found by other means;
- * there is no end-user benefit to browsing to find a long list of opaque GUIDs.
- * Using the NonBrowsable flag creates SRV+TXT without the cost of also advertising
- * an associated PTR record.
- */
-
- kDNSServiceFlagsShareConnection = 0x4000,
- /* For efficiency, clients that perform many concurrent operations may want to use a
- * single Unix Domain Socket connection with the background daemon, instead of having a
- * separate connection for each independent operation. To use this mode, clients first
- * call DNSServiceCreateConnection(&MainRef) to initialize the main DNSServiceRef.
- * For each subsequent operation that is to share that same connection, the client copies
- * the MainRef, and then passes the address of that copy, setting the ShareConnection flag
- * to tell the library that this DNSServiceRef is not a typical uninitialized DNSServiceRef;
- * it's a copy of an existing DNSServiceRef whose connection information should be reused.
- *
- * For example:
- *
- * DNSServiceErrorType error;
- * DNSServiceRef MainRef;
- * error = DNSServiceCreateConnection(&MainRef);
- * if (error) ...
- * DNSServiceRef BrowseRef = MainRef; // Important: COPY the primary DNSServiceRef first...
- * error = DNSServiceBrowse(&BrowseRef, kDNSServiceFlagsShareConnection, ...); // then use the copy
- * if (error) ...
- * ...
- * DNSServiceRefDeallocate(BrowseRef); // Terminate the browse operation
- * DNSServiceRefDeallocate(MainRef); // Terminate the shared connection
- *
- * Notes:
- *
- * 1. Collective kDNSServiceFlagsMoreComing flag
- * When callbacks are invoked using a shared DNSServiceRef, the
- * kDNSServiceFlagsMoreComing flag applies collectively to *all* active
- * operations sharing the same parent DNSServiceRef. If the MoreComing flag is
- * set it means that there are more results queued on this parent DNSServiceRef,
- * but not necessarily more results for this particular callback function.
- * The implication of this for client programmers is that when a callback
- * is invoked with the MoreComing flag set, the code should update its
- * internal data structures with the new result, and set a variable indicating
- * that its UI needs to be updated. Then, later when a callback is eventually
- * invoked with the MoreComing flag not set, the code should update *all*
- * stale UI elements related to that shared parent DNSServiceRef that need
- * updating, not just the UI elements related to the particular callback
- * that happened to be the last one to be invoked.
- *
- * 2. Canceling operations and kDNSServiceFlagsMoreComing
- * Whenever you cancel any operation for which you had deferred UI updates
- * waiting because of a kDNSServiceFlagsMoreComing flag, you should perform
- * those deferred UI updates. This is because, after cancelling the operation,
- * you can no longer wait for a callback *without* MoreComing set, to tell
- * you do perform your deferred UI updates (the operation has been canceled,
- * so there will be no more callbacks). An implication of the collective
- * kDNSServiceFlagsMoreComing flag for shared connections is that this
- * guideline applies more broadly -- any time you cancel an operation on
- * a shared connection, you should perform all deferred UI updates for all
- * operations sharing that connection. This is because the MoreComing flag
- * might have been referring to events coming for the operation you canceled,
- * which will now not be coming because the operation has been canceled.
- *
- * 3. Only share DNSServiceRef's created with DNSServiceCreateConnection
- * Calling DNSServiceCreateConnection(&ref) creates a special shareable DNSServiceRef.
- * DNSServiceRef's created by other calls like DNSServiceBrowse() or DNSServiceResolve()
- * cannot be shared by copying them and using kDNSServiceFlagsShareConnection.
- *
- * 4. Don't Double-Deallocate
- * Calling DNSServiceRefDeallocate(ref) for a particular operation's DNSServiceRef terminates
- * just that operation. Calling DNSServiceRefDeallocate(ref) for the main shared DNSServiceRef
- * (the parent DNSServiceRef, originally created by DNSServiceCreateConnection(&ref))
- * automatically terminates the shared connection and all operations that were still using it.
- * After doing this, DO NOT then attempt to deallocate any remaining subordinate DNSServiceRef's.
- * The memory used by those subordinate DNSServiceRef's has already been freed, so any attempt
- * to do a DNSServiceRefDeallocate (or any other operation) on them will result in accesses
- * to freed memory, leading to crashes or other equally undesirable results.
- *
- * 5. Thread Safety
- * The dns_sd.h API does not presuppose any particular threading model, and consequently
- * does no locking of its own (which would require linking some specific threading library).
- * If client code calls API routines on the same DNSServiceRef concurrently
- * from multiple threads, it is the client's responsibility to use a mutext
- * lock or take similar appropriate precautions to serialize those calls.
- */
-
- kDNSServiceFlagsSuppressUnusable = 0x8000,
- /*
- * This flag is meaningful only in DNSServiceQueryRecord which suppresses unusable queries on the
- * wire. If "hostname" is a wide-area unicast DNS hostname (i.e. not a ".local." name)
- * but this host has no routable IPv6 address, then the call will not try to look up IPv6 addresses
- * for "hostname", since any addresses it found would be unlikely to be of any use anyway. Similarly,
- * if this host has no routable IPv4 address, the call will not try to look up IPv4 addresses for
- * "hostname".
- */
-
- kDNSServiceFlagsTimeout = 0x10000,
- /*
- * When kDNServiceFlagsTimeout is passed to DNSServiceQueryRecord or DNSServiceGetAddrInfo, the query is
- * stopped after a certain number of seconds have elapsed. The time at which the query will be stopped
- * is determined by the system and cannot be configured by the user. The query will be stopped irrespective
- * of whether a response was given earlier or not. When the query is stopped, the callback will be called
- * with an error code of kDNSServiceErr_Timeout and a NULL sockaddr will be returned for DNSServiceGetAddrInfo
- * and zero length rdata will be returned for DNSServiceQueryRecord.
- */
-
- kDNSServiceFlagsIncludeP2P = 0x20000,
- /*
- * Include P2P interfaces when kDNSServiceInterfaceIndexAny is specified.
- * By default, specifying kDNSServiceInterfaceIndexAny does not include P2P interfaces.
- */
-
- kDNSServiceFlagsWakeOnResolve = 0x40000,
- /*
- * This flag is meaningful only in DNSServiceResolve. When set, it tries to send a magic packet
- * to wake up the client.
- */
-
- kDNSServiceFlagsBackgroundTrafficClass = 0x80000,
- /*
- * This flag is meaningful in DNSServiceBrowse, DNSServiceGetAddrInfo, DNSServiceQueryRecord,
- * and DNSServiceResolve. When set, it uses the background traffic
- * class for packets that service the request.
- */
-
- kDNSServiceFlagsIncludeAWDL = 0x100000
- /*
- * Include AWDL interface when kDNSServiceInterfaceIndexAny is specified.
- */
-};
-
-/* Possible protocols for DNSServiceNATPortMappingCreate(). */
-enum
-{
- kDNSServiceProtocol_IPv4 = 0x01,
- kDNSServiceProtocol_IPv6 = 0x02,
- /* 0x04 and 0x08 reserved for future internetwork protocols */
-
- kDNSServiceProtocol_UDP = 0x10,
- kDNSServiceProtocol_TCP = 0x20
- /* 0x40 and 0x80 reserved for future transport protocols, e.g. SCTP [RFC 2960]
- * or DCCP [RFC 4340]. If future NAT gateways are created that support port
- * mappings for these protocols, new constants will be defined here.
- */
-};
-
-/*
- * The values for DNS Classes and Types are listed in RFC 1035, and are available
- * on every OS in its DNS header file. Unfortunately every OS does not have the
- * same header file containing DNS Class and Type constants, and the names of
- * the constants are not consistent. For example, BIND 8 uses "T_A",
- * BIND 9 uses "ns_t_a", Windows uses "DNS_TYPE_A", etc.
- * For this reason, these constants are also listed here, so that code using
- * the DNS-SD programming APIs can use these constants, so that the same code
- * can compile on all our supported platforms.
- */
-
-enum
-{
- kDNSServiceClass_IN = 1 /* Internet */
-};
-
-enum
-{
- kDNSServiceType_A = 1, /* Host address. */
- kDNSServiceType_NS = 2, /* Authoritative server. */
- kDNSServiceType_MD = 3, /* Mail destination. */
- kDNSServiceType_MF = 4, /* Mail forwarder. */
- kDNSServiceType_CNAME = 5, /* Canonical name. */
- kDNSServiceType_SOA = 6, /* Start of authority zone. */
- kDNSServiceType_MB = 7, /* Mailbox domain name. */
- kDNSServiceType_MG = 8, /* Mail group member. */
- kDNSServiceType_MR = 9, /* Mail rename name. */
- kDNSServiceType_NULL = 10, /* Null resource record. */
- kDNSServiceType_WKS = 11, /* Well known service. */
- kDNSServiceType_PTR = 12, /* Domain name pointer. */
- kDNSServiceType_HINFO = 13, /* Host information. */
- kDNSServiceType_MINFO = 14, /* Mailbox information. */
- kDNSServiceType_MX = 15, /* Mail routing information. */
- kDNSServiceType_TXT = 16, /* One or more text strings (NOT "zero or more..."). */
- kDNSServiceType_RP = 17, /* Responsible person. */
- kDNSServiceType_AFSDB = 18, /* AFS cell database. */
- kDNSServiceType_X25 = 19, /* X_25 calling address. */
- kDNSServiceType_ISDN = 20, /* ISDN calling address. */
- kDNSServiceType_RT = 21, /* Router. */
- kDNSServiceType_NSAP = 22, /* NSAP address. */
- kDNSServiceType_NSAP_PTR = 23, /* Reverse NSAP lookup (deprecated). */
- kDNSServiceType_SIG = 24, /* Security signature. */
- kDNSServiceType_KEY = 25, /* Security key. */
- kDNSServiceType_PX = 26, /* X.400 mail mapping. */
- kDNSServiceType_GPOS = 27, /* Geographical position (withdrawn). */
- kDNSServiceType_AAAA = 28, /* IPv6 Address. */
- kDNSServiceType_LOC = 29, /* Location Information. */
- kDNSServiceType_NXT = 30, /* Next domain (security). */
- kDNSServiceType_EID = 31, /* Endpoint identifier. */
- kDNSServiceType_NIMLOC = 32, /* Nimrod Locator. */
- kDNSServiceType_SRV = 33, /* Server Selection. */
- kDNSServiceType_ATMA = 34, /* ATM Address */
- kDNSServiceType_NAPTR = 35, /* Naming Authority PoinTeR */
- kDNSServiceType_KX = 36, /* Key Exchange */
- kDNSServiceType_CERT = 37, /* Certification record */
- kDNSServiceType_A6 = 38, /* IPv6 Address (deprecated) */
- kDNSServiceType_DNAME = 39, /* Non-terminal DNAME (for IPv6) */
- kDNSServiceType_SINK = 40, /* Kitchen sink (experimental) */
- kDNSServiceType_OPT = 41, /* EDNS0 option (meta-RR) */
- kDNSServiceType_APL = 42, /* Address Prefix List */
- kDNSServiceType_DS = 43, /* Delegation Signer */
- kDNSServiceType_SSHFP = 44, /* SSH Key Fingerprint */
- kDNSServiceType_IPSECKEY = 45, /* IPSECKEY */
- kDNSServiceType_RRSIG = 46, /* RRSIG */
- kDNSServiceType_NSEC = 47, /* Denial of Existence */
- kDNSServiceType_DNSKEY = 48, /* DNSKEY */
- kDNSServiceType_DHCID = 49, /* DHCP Client Identifier */
- kDNSServiceType_NSEC3 = 50, /* Hashed Authenticated Denial of Existence */
- kDNSServiceType_NSEC3PARAM = 51, /* Hashed Authenticated Denial of Existence */
-
- kDNSServiceType_HIP = 55, /* Host Identity Protocol */
-
- kDNSServiceType_SPF = 99, /* Sender Policy Framework for E-Mail */
- kDNSServiceType_UINFO = 100, /* IANA-Reserved */
- kDNSServiceType_UID = 101, /* IANA-Reserved */
- kDNSServiceType_GID = 102, /* IANA-Reserved */
- kDNSServiceType_UNSPEC = 103, /* IANA-Reserved */
-
- kDNSServiceType_TKEY = 249, /* Transaction key */
- kDNSServiceType_TSIG = 250, /* Transaction signature. */
- kDNSServiceType_IXFR = 251, /* Incremental zone transfer. */
- kDNSServiceType_AXFR = 252, /* Transfer zone of authority. */
- kDNSServiceType_MAILB = 253, /* Transfer mailbox records. */
- kDNSServiceType_MAILA = 254, /* Transfer mail agent records. */
- kDNSServiceType_ANY = 255 /* Wildcard match. */
-};
-
-/* possible error code values */
-enum
-{
- kDNSServiceErr_NoError = 0,
- kDNSServiceErr_Unknown = -65537, /* 0xFFFE FFFF */
- kDNSServiceErr_NoSuchName = -65538,
- kDNSServiceErr_NoMemory = -65539,
- kDNSServiceErr_BadParam = -65540,
- kDNSServiceErr_BadReference = -65541,
- kDNSServiceErr_BadState = -65542,
- kDNSServiceErr_BadFlags = -65543,
- kDNSServiceErr_Unsupported = -65544,
- kDNSServiceErr_NotInitialized = -65545,
- kDNSServiceErr_AlreadyRegistered = -65547,
- kDNSServiceErr_NameConflict = -65548,
- kDNSServiceErr_Invalid = -65549,
- kDNSServiceErr_Firewall = -65550,
- kDNSServiceErr_Incompatible = -65551, /* client library incompatible with daemon */
- kDNSServiceErr_BadInterfaceIndex = -65552,
- kDNSServiceErr_Refused = -65553,
- kDNSServiceErr_NoSuchRecord = -65554,
- kDNSServiceErr_NoAuth = -65555,
- kDNSServiceErr_NoSuchKey = -65556,
- kDNSServiceErr_NATTraversal = -65557,
- kDNSServiceErr_DoubleNAT = -65558,
- kDNSServiceErr_BadTime = -65559, /* Codes up to here existed in Tiger */
- kDNSServiceErr_BadSig = -65560,
- kDNSServiceErr_BadKey = -65561,
- kDNSServiceErr_Transient = -65562,
- kDNSServiceErr_ServiceNotRunning = -65563, /* Background daemon not running */
- kDNSServiceErr_NATPortMappingUnsupported = -65564, /* NAT doesn't support NAT-PMP or UPnP */
- kDNSServiceErr_NATPortMappingDisabled = -65565, /* NAT supports NAT-PMP or UPnP but it's disabled by the administrator */
- kDNSServiceErr_NoRouter = -65566, /* No router currently configured (probably no network connectivity) */
- kDNSServiceErr_PollingMode = -65567,
- kDNSServiceErr_Timeout = -65568
-
- /* mDNS Error codes are in the range
- * FFFE FF00 (-65792) to FFFE FFFF (-65537) */
-};
-
-/* Maximum length, in bytes, of a service name represented as a */
-/* literal C-String, including the terminating NULL at the end. */
-
-
-/* Maximum length, in bytes, of a domain name represented as an *escaped* C-String */
-/* including the final trailing dot, and the C-String terminating NULL at the end. */
-
-#define kDNSServiceMaxDomainName 1009
-
-/*
- * Notes on DNS Name Escaping
- * -- or --
- * "Why is kDNSServiceMaxDomainName 1009, when the maximum legal domain name is 256 bytes?"
- *
- * All strings used in the DNS-SD APIs are UTF-8 strings. Apart from the exceptions noted below,
- * the APIs expect the strings to be properly escaped, using the conventional DNS escaping rules:
- *
- * '\\' represents a single literal '\' in the name
- * '\.' represents a single literal '.' in the name
- * '\ddd', where ddd is a three-digit decimal value from 000 to 255,
- * represents a single literal byte with that value.
- * A bare unescaped '.' is a label separator, marking a boundary between domain and subdomain.
- *
- * The exceptions, that do not use escaping, are the routines where the full
- * DNS name of a resource is broken, for convenience, into servicename/regtype/domain.
- * In these routines, the "servicename" is NOT escaped. It does not need to be, since
- * it is, by definition, just a single literal string. Any characters in that string
- * represent exactly what they are. The "regtype" portion is, technically speaking,
- * escaped, but since legal regtypes are only allowed to contain letters, digits,
- * and hyphens, there is nothing to escape, so the issue is moot. The "domain"
- * portion is also escaped, though most domains in use on the public Internet
- * today, like regtypes, don't contain any characters that need to be escaped.
- * As DNS-SD becomes more popular, rich-text domains for service discovery will
- * become common, so software should be written to cope with domains with escaping.
- *
- * The servicename may be up to 63 bytes of UTF-8 text (not counting the C-String
- * terminating NULL at the end). The regtype is of the form _service._tcp or
- * _service._udp, where the "service" part is 1-15 characters, which may be
- * letters, digits, or hyphens. The domain part of the three-part name may be
- * any legal domain, providing that the resulting servicename+regtype+domain
- * name does not exceed 256 bytes.
- *
- * For most software, these issues are transparent. When browsing, the discovered
- * servicenames should simply be displayed as-is. When resolving, the discovered
- * servicename/regtype/domain are simply passed unchanged to DNSServiceResolve().
- * When a DNSServiceResolve() succeeds, the returned fullname is already in
- * the correct format to pass to standard system DNS APIs such as res_query().
- * For converting from servicename/regtype/domain to a single properly-escaped
- * full DNS name, the helper function DNSServiceConstructFullName() is provided.
- *
- * The following (highly contrived) example illustrates the escaping process.
- * Suppose you have an service called "Dr. Smith\Dr. Johnson", of type "_ftp._tcp"
- * in subdomain "4th. Floor" of subdomain "Building 2" of domain "apple.com."
- * The full (escaped) DNS name of this service's SRV record would be:
- * Dr\.\032Smith\\Dr\.\032Johnson._ftp._tcp.4th\.\032Floor.Building\0322.apple.com.
- */
-
-
-/*
- * Constants for specifying an interface index
- *
- * Specific interface indexes are identified via a 32-bit unsigned integer returned
- * by the if_nametoindex() family of calls.
- *
- * If the client passes 0 for interface index, that means "do the right thing",
- * which (at present) means, "if the name is in an mDNS local multicast domain
- * (e.g. 'local.', '254.169.in-addr.arpa.', '{8,9,A,B}.E.F.ip6.arpa.') then multicast
- * on all applicable interfaces, otherwise send via unicast to the appropriate
- * DNS server." Normally, most clients will use 0 for interface index to
- * automatically get the default sensible behaviour.
- *
- * If the client passes a positive interface index, then for multicast names that
- * indicates to do the operation only on that one interface. For unicast names the
- * interface index is ignored unless kDNSServiceFlagsForceMulticast is also set.
- *
- * If the client passes kDNSServiceInterfaceIndexLocalOnly when registering
- * a service, then that service will be found *only* by other local clients
- * on the same machine that are browsing using kDNSServiceInterfaceIndexLocalOnly
- * or kDNSServiceInterfaceIndexAny.
- * If a client has a 'private' service, accessible only to other processes
- * running on the same machine, this allows the client to advertise that service
- * in a way such that it does not inadvertently appear in service lists on
- * all the other machines on the network.
- *
- * If the client passes kDNSServiceInterfaceIndexLocalOnly when browsing
- * then it will find *all* records registered on that same local machine.
- * Clients explicitly wishing to discover *only* LocalOnly services can
- * accomplish this by inspecting the interfaceIndex of each service reported
- * to their DNSServiceBrowseReply() callback function, and discarding those
- * where the interface index is not kDNSServiceInterfaceIndexLocalOnly.
- *
- * kDNSServiceInterfaceIndexP2P is meaningful only in Browse, QueryRecord,
- * and Resolve operations. It should not be used in other DNSService APIs.
- *
- * - If kDNSServiceInterfaceIndexP2P is passed to DNSServiceBrowse or
- * DNSServiceQueryRecord, it restricts the operation to P2P.
- *
- * - If kDNSServiceInterfaceIndexP2P is passed to DNSServiceResolve, it is
- * mapped internally to kDNSServiceInterfaceIndexAny with the kDNSServiceFlagsIncludeP2P
- * set, because resolving a P2P service may create and/or enable an interface whose
- * index is not known a priori. The resolve callback will indicate the index of the
- * interface via which the service can be accessed.
- *
- * If applications pass kDNSServiceInterfaceIndexAny to DNSServiceBrowse
- * or DNSServiceQueryRecord, they must set the kDNSServiceFlagsIncludeP2P flag
- * to include P2P. In this case, if a service instance or the record being queried
- * is found over P2P, the resulting ADD event will indicate kDNSServiceInterfaceIndexP2P
- * as the interface index.
- */
-
-#define kDNSServiceInterfaceIndexAny 0
-#define kDNSServiceInterfaceIndexLocalOnly ((uint32_t)-1)
-#define kDNSServiceInterfaceIndexUnicast ((uint32_t)-2)
-#define kDNSServiceInterfaceIndexP2P ((uint32_t)-3)
-
-typedef uint32_t DNSServiceFlags;
-typedef uint32_t DNSServiceProtocol;
-typedef int32_t DNSServiceErrorType;
-
-
-/*********************************************************************************************
-*
-* Version checking
-*
-*********************************************************************************************/
-
-/* DNSServiceGetProperty() Parameters:
- *
- * property: The requested property.
- * Currently the only property defined is kDNSServiceProperty_DaemonVersion.
- *
- * result: Place to store result.
- * For retrieving DaemonVersion, this should be the address of a uint32_t.
- *
- * size: Pointer to uint32_t containing size of the result location.
- * For retrieving DaemonVersion, this should be sizeof(uint32_t).
- * On return the uint32_t is updated to the size of the data returned.
- * For DaemonVersion, the returned size is always sizeof(uint32_t), but
- * future properties could be defined which return variable-sized results.
- *
- * return value: Returns kDNSServiceErr_NoError on success, or kDNSServiceErr_ServiceNotRunning
- * if the daemon (or "system service" on Windows) is not running.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceGetProperty
-(
- const char *property, /* Requested property (i.e. kDNSServiceProperty_DaemonVersion) */
- void *result, /* Pointer to place to store result */
- uint32_t *size /* size of result location */
-);
-
-/*
- * When requesting kDNSServiceProperty_DaemonVersion, the result pointer must point
- * to a 32-bit unsigned integer, and the size parameter must be set to sizeof(uint32_t).
- *
- * On return, the 32-bit unsigned integer contains the version number, formatted as follows:
- * Major part of the build number * 10000 +
- * minor part of the build number * 100
- *
- * For example, Mac OS X 10.4.9 has mDNSResponder-108.4, which would be represented as
- * version 1080400. This allows applications to do simple greater-than and less-than comparisons:
- * e.g. an application that requires at least mDNSResponder-108.4 can check:
- *
- * if (version >= 1080400) ...
- *
- * Example usage:
- *
- * uint32_t version;
- * uint32_t size = sizeof(version);
- * DNSServiceErrorType err = DNSServiceGetProperty(kDNSServiceProperty_DaemonVersion, &version, &size);
- * if (!err) printf("Bonjour version is %d.%d\n", version / 10000, version / 100 % 100);
- */
-
-#define kDNSServiceProperty_DaemonVersion "DaemonVersion"
-
-
-/*********************************************************************************************
-*
-* Unix Domain Socket access, DNSServiceRef deallocation, and data processing functions
-*
-*********************************************************************************************/
-
-/* DNSServiceProcessResult()
- *
- * Read a reply from the daemon, calling the appropriate application callback. This call will
- * block until the daemon's response is received. Use DNSServiceRefSockFD() in
- * conjunction with a run loop or select() to determine the presence of a response from the
- * server before calling this function to process the reply without blocking. Call this function
- * at any point if it is acceptable to block until the daemon's response arrives. Note that the
- * client is responsible for ensuring that DNSServiceProcessResult() is called whenever there is
- * a reply from the daemon - the daemon may terminate its connection with a client that does not
- * process the daemon's responses.
- *
- * sdRef: A DNSServiceRef initialized by any of the DNSService calls
- * that take a callback parameter.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns
- * an error code indicating the specific failure that occurred.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef);
-
-
-/* DNSServiceRefDeallocate()
- *
- * Terminate a connection with the daemon and free memory associated with the DNSServiceRef.
- * Any services or records registered with this DNSServiceRef will be deregistered. Any
- * Browse, Resolve, or Query operations called with this reference will be terminated.
- *
- * Note: If the reference's underlying socket is used in a run loop or select() call, it should
- * be removed BEFORE DNSServiceRefDeallocate() is called, as this function closes the reference's
- * socket.
- *
- * Note: If the reference was initialized with DNSServiceCreateConnection(), any DNSRecordRefs
- * created via this reference will be invalidated by this call - the resource records are
- * deregistered, and their DNSRecordRefs may not be used in subsequent functions. Similarly,
- * if the reference was initialized with DNSServiceRegister, and an extra resource record was
- * added to the service via DNSServiceAddRecord(), the DNSRecordRef created by the Add() call
- * is invalidated when this function is called - the DNSRecordRef may not be used in subsequent
- * functions.
- *
- * Note: This call is to be used only with the DNSServiceRef defined by this API. It is
- * not compatible with dns_service_discovery_ref objects defined in the legacy Mach-based
- * DNSServiceDiscovery.h API.
- *
- * sdRef: A DNSServiceRef initialized by any of the DNSService calls.
- *
- */
-
-void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef);
-
-
-/*********************************************************************************************
-*
-* Domain Enumeration
-*
-*********************************************************************************************/
-
-/* DNSServiceEnumerateDomains()
- *
- * Asynchronously enumerate domains available for browsing and registration.
- *
- * The enumeration MUST be cancelled via DNSServiceRefDeallocate() when no more domains
- * are to be found.
- *
- * Note that the names returned are (like all of DNS-SD) UTF-8 strings,
- * and are escaped using standard DNS escaping rules.
- * (See "Notes on DNS Name Escaping" earlier in this file for more details.)
- * A graphical browser displaying a hierarchical tree-structured view should cut
- * the names at the bare dots to yield individual labels, then de-escape each
- * label according to the escaping rules, and then display the resulting UTF-8 text.
- *
- * DNSServiceDomainEnumReply Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceEnumerateDomains().
- *
- * flags: Possible values are:
- * kDNSServiceFlagsMoreComing
- * kDNSServiceFlagsAdd
- * kDNSServiceFlagsDefault
- *
- * interfaceIndex: Specifies the interface on which the domain exists. (The index for a given
- * interface is determined via the if_nametoindex() family of calls.)
- *
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise indicates
- * the failure that occurred (other parameters are undefined if errorCode is nonzero).
- *
- * replyDomain: The name of the domain.
- *
- * context: The context pointer passed to DNSServiceEnumerateDomains.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceDomainEnumReply)
-(
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *replyDomain,
- void *context
-);
-
-
-/* DNSServiceEnumerateDomains() Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
- * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- * and the enumeration operation will run indefinitely until the client
- * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags: Possible values are:
- * kDNSServiceFlagsBrowseDomains to enumerate domains recommended for browsing.
- * kDNSServiceFlagsRegistrationDomains to enumerate domains recommended
- * for registration.
- *
- * interfaceIndex: If non-zero, specifies the interface on which to look for domains.
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to enumerate domains on
- * all interfaces. See "Constants for specifying an interface index" for more details.
- *
- * callBack: The function to be called when a domain is found or the call asynchronously
- * fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is not invoked and the DNSServiceRef
- * is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceDomainEnumReply callBack,
- void *context /* may be NULL */
-);
-
-
-/*********************************************************************************************
-*
-* Service Registration
-*
-*********************************************************************************************/
-
-/* Register a service that is discovered via Browse() and Resolve() calls.
- *
- * DNSServiceRegisterReply() Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceRegister().
- *
- * flags: When a name is successfully registered, the callback will be
- * invoked with the kDNSServiceFlagsAdd flag set. When Wide-Area
- * DNS-SD is in use, it is possible for a single service to get
- * more than one success callback (e.g. one in the "local" multicast
- * DNS domain, and another in a wide-area unicast DNS domain).
- * If a successfully-registered name later suffers a name conflict
- * or similar problem and has to be deregistered, the callback will
- * be invoked with the kDNSServiceFlagsAdd flag not set. The callback
- * is *not* invoked in the case where the caller explicitly terminates
- * the service registration by calling DNSServiceRefDeallocate(ref);
- *
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred (including name conflicts,
- * if the kDNSServiceFlagsNoAutoRename flag was used when registering.)
- * Other parameters are undefined if errorCode is nonzero.
- *
- * name: The service name registered (if the application did not specify a name in
- * DNSServiceRegister(), this indicates what name was automatically chosen).
- *
- * regtype: The type of service registered, as it was passed to the callout.
- *
- * domain: The domain on which the service was registered (if the application did not
- * specify a domain in DNSServiceRegister(), this indicates the default domain
- * on which the service was registered).
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceRegisterReply)
-(
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- DNSServiceErrorType errorCode,
- const char *name,
- const char *regtype,
- const char *domain,
- void *context
-);
-
-
-/* DNSServiceRegister() Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
- * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- * and the registration will remain active indefinitely until the client
- * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * interfaceIndex: If non-zero, specifies the interface on which to register the service
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to register on all
- * available interfaces. See "Constants for specifying an interface index" for more details.
- *
- * flags: Indicates the renaming behavior on name conflict (most applications
- * will pass 0). See flag definitions above for details.
- *
- * name: If non-NULL, specifies the service name to be registered.
- * Most applications will not specify a name, in which case the computer
- * name is used (this name is communicated to the client via the callback).
- * If a name is specified, it must be 1-63 bytes of UTF-8 text.
- * If the name is longer than 63 bytes it will be automatically truncated
- * to a legal length, unless the NoAutoRename flag is set,
- * in which case kDNSServiceErr_BadParam will be returned.
- *
- * regtype: The service type followed by the protocol, separated by a dot
- * (e.g. "_ftp._tcp"). The service type must be an underscore, followed
- * by 1-15 characters, which may be letters, digits, or hyphens.
- * The transport protocol must be "_tcp" or "_udp". New service types
- * should be registered at <http://www.dns-sd.org/ServiceTypes.html>.
- *
- * Additional subtypes of the primary service type (where a service
- * type has defined subtypes) follow the primary service type in a
- * comma-separated list, with no additional spaces, e.g.
- * "_primarytype._tcp,_subtype1,_subtype2,_subtype3"
- * Subtypes provide a mechanism for filtered browsing: A client browsing
- * for "_primarytype._tcp" will discover all instances of this type;
- * a client browsing for "_primarytype._tcp,_subtype2" will discover only
- * those instances that were registered with "_subtype2" in their list of
- * registered subtypes.
- *
- * The subtype mechanism can be illustrated with some examples using the
- * dns-sd command-line tool:
- *
- * % dns-sd -R Simple _test._tcp "" 1001 &
- * % dns-sd -R Better _test._tcp,HasFeatureA "" 1002 &
- * % dns-sd -R Best _test._tcp,HasFeatureA,HasFeatureB "" 1003 &
- *
- * Now:
- * % dns-sd -B _test._tcp # will find all three services
- * % dns-sd -B _test._tcp,HasFeatureA # finds "Better" and "Best"
- * % dns-sd -B _test._tcp,HasFeatureB # finds only "Best"
- *
- * Subtype labels may be up to 63 bytes long, and may contain any eight-
- * bit byte values, including zero bytes. However, due to the nature of
- * using a C-string-based API, conventional DNS escaping must be used for
- * dots ('.'), commas (','), backslashes ('\') and zero bytes, as shown below:
- *
- * % dns-sd -R Test '_test._tcp,s\.one,s\,two,s\\three,s\000four' local 123
- *
- * domain: If non-NULL, specifies the domain on which to advertise the service.
- * Most applications will not specify a domain, instead automatically
- * registering in the default domain(s).
- *
- * host: If non-NULL, specifies the SRV target host name. Most applications
- * will not specify a host, instead automatically using the machine's
- * default host name(s). Note that specifying a non-NULL host does NOT
- * create an address record for that host - the application is responsible
- * for ensuring that the appropriate address record exists, or creating it
- * via DNSServiceRegisterRecord().
- *
- * port: The port, in network byte order, on which the service accepts connections.
- * Pass 0 for a "placeholder" service (i.e. a service that will not be discovered
- * by browsing, but will cause a name conflict if another client tries to
- * register that same name). Most clients will not use placeholder services.
- *
- * txtLen: The length of the txtRecord, in bytes. Must be zero if the txtRecord is NULL.
- *
- * txtRecord: The TXT record rdata. A non-NULL txtRecord MUST be a properly formatted DNS
- * TXT record, i.e. <length byte> <data> <length byte> <data> ...
- * Passing NULL for the txtRecord is allowed as a synonym for txtLen=1, txtRecord="",
- * i.e. it creates a TXT record of length one containing a single empty string.
- * RFC 1035 doesn't allow a TXT record to contain *zero* strings, so a single empty
- * string is the smallest legal DNS TXT record.
- * As with the other parameters, the DNSServiceRegister call copies the txtRecord
- * data; e.g. if you allocated the storage for the txtRecord parameter with malloc()
- * then you can safely free that memory right after the DNSServiceRegister call returns.
- *
- * callBack: The function to be called when the registration completes or asynchronously
- * fails. The client MAY pass NULL for the callback - The client will NOT be notified
- * of the default values picked on its behalf, and the client will NOT be notified of any
- * asynchronous errors (e.g. out of memory errors, etc.) that may prevent the registration
- * of the service. The client may NOT pass the NoAutoRename flag if the callback is NULL.
- * The client may still deregister the service at any time via DNSServiceRefDeallocate().
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSServiceRef
- * is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceRegister
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *name, /* may be NULL */
- const char *regtype,
- const char *domain, /* may be NULL */
- const char *host, /* may be NULL */
- uint16_t port, /* In network byte order */
- uint16_t txtLen,
- const void *txtRecord, /* may be NULL */
- DNSServiceRegisterReply callBack, /* may be NULL */
- void *context /* may be NULL */
-);
-
-
-/* DNSServiceAddRecord()
- *
- * Add a record to a registered service. The name of the record will be the same as the
- * registered service's name.
- * The record can later be updated or deregistered by passing the RecordRef initialized
- * by this function to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- *
- * Note that the DNSServiceAddRecord/UpdateRecord/RemoveRecord are *NOT* thread-safe
- * with respect to a single DNSServiceRef. If you plan to have multiple threads
- * in your program simultaneously add, update, or remove records from the same
- * DNSServiceRef, then it's the caller's responsibility to use a mutext lock
- * or take similar appropriate precautions to serialize those calls.
- *
- * Parameters;
- *
- * sdRef: A DNSServiceRef initialized by DNSServiceRegister().
- *
- * RecordRef: A pointer to an uninitialized DNSRecordRef. Upon successful completion of this
- * call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- * If the above DNSServiceRef is passed to DNSServiceRefDeallocate(), RecordRef is also
- * invalidated and may not be used further.
- *
- * flags: Currently ignored, reserved for future use.
- *
- * rrtype: The type of the record (e.g. kDNSServiceType_TXT, kDNSServiceType_SRV, etc)
- *
- * rdlen: The length, in bytes, of the rdata.
- *
- * rdata: The raw rdata to be contained in the added resource record.
- *
- * ttl: The time to live of the resource record, in seconds.
- * Most clients should pass 0 to indicate that the system should
- * select a sensible default value.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
- * error code indicating the error that occurred (the RecordRef is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceAddRecord
-(
- DNSServiceRef sdRef,
- DNSRecordRef *RecordRef,
- DNSServiceFlags flags,
- uint16_t rrtype,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl
-);
-
-
-/* DNSServiceUpdateRecord
- *
- * Update a registered resource record. The record must either be:
- * - The primary txt record of a service registered via DNSServiceRegister()
- * - A record added to a registered service via DNSServiceAddRecord()
- * - An individual record registered by DNSServiceRegisterRecord()
- *
- * Parameters:
- *
- * sdRef: A DNSServiceRef that was initialized by DNSServiceRegister()
- * or DNSServiceCreateConnection().
- *
- * RecordRef: A DNSRecordRef initialized by DNSServiceAddRecord, or NULL to update the
- * service's primary txt record.
- *
- * flags: Currently ignored, reserved for future use.
- *
- * rdlen: The length, in bytes, of the new rdata.
- *
- * rdata: The new rdata to be contained in the updated resource record.
- *
- * ttl: The time to live of the updated resource record, in seconds.
- * Most clients should pass 0 to indicate that the system should
- * select a sensible default value.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
- * error code indicating the error that occurred.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
-(
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef, /* may be NULL */
- DNSServiceFlags flags,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl
-);
-
-
-/* DNSServiceRemoveRecord
- *
- * Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
- * an record registered individually via DNSServiceRegisterRecord().
- *
- * Parameters:
- *
- * sdRef: A DNSServiceRef initialized by DNSServiceRegister() (if the
- * record being removed was registered via DNSServiceAddRecord()) or by
- * DNSServiceCreateConnection() (if the record being removed was registered via
- * DNSServiceRegisterRecord()).
- *
- * recordRef: A DNSRecordRef initialized by a successful call to DNSServiceAddRecord()
- * or DNSServiceRegisterRecord().
- *
- * flags: Currently ignored, reserved for future use.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns an
- * error code indicating the error that occurred.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
-(
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef,
- DNSServiceFlags flags
-);
-
-
-/*********************************************************************************************
-*
-* Service Discovery
-*
-*********************************************************************************************/
-
-/* Browse for instances of a service.
- *
- * DNSServiceBrowseReply() Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceBrowse().
- *
- * flags: Possible values are kDNSServiceFlagsMoreComing and kDNSServiceFlagsAdd.
- * See flag definitions for details.
- *
- * interfaceIndex: The interface on which the service is advertised. This index should
- * be passed to DNSServiceResolve() when resolving the service.
- *
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will
- * indicate the failure that occurred. Other parameters are undefined if
- * the errorCode is nonzero.
- *
- * serviceName: The discovered service name. This name should be displayed to the user,
- * and stored for subsequent use in the DNSServiceResolve() call.
- *
- * regtype: The service type, which is usually (but not always) the same as was passed
- * to DNSServiceBrowse(). One case where the discovered service type may
- * not be the same as the requested service type is when using subtypes:
- * The client may want to browse for only those ftp servers that allow
- * anonymous connections. The client will pass the string "_ftp._tcp,_anon"
- * to DNSServiceBrowse(), but the type of the service that's discovered
- * is simply "_ftp._tcp". The regtype for each discovered service instance
- * should be stored along with the name, so that it can be passed to
- * DNSServiceResolve() when the service is later resolved.
- *
- * domain: The domain of the discovered service instance. This may or may not be the
- * same as the domain that was passed to DNSServiceBrowse(). The domain for each
- * discovered service instance should be stored along with the name, so that
- * it can be passed to DNSServiceResolve() when the service is later resolved.
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceBrowseReply)
-(
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *serviceName,
- const char *regtype,
- const char *replyDomain,
- void *context
-);
-
-
-/* DNSServiceBrowse() Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
- * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- * and the browse operation will run indefinitely until the client
- * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags: Currently ignored, reserved for future use.
- *
- * interfaceIndex: If non-zero, specifies the interface on which to browse for services
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Most applications will pass 0 to browse on all available
- * interfaces. See "Constants for specifying an interface index" for more details.
- *
- * regtype: The service type being browsed for followed by the protocol, separated by a
- * dot (e.g. "_ftp._tcp"). The transport protocol must be "_tcp" or "_udp".
- * A client may optionally specify a single subtype to perform filtered browsing:
- * e.g. browsing for "_primarytype._tcp,_subtype" will discover only those
- * instances of "_primarytype._tcp" that were registered specifying "_subtype"
- * in their list of registered subtypes.
- *
- * domain: If non-NULL, specifies the domain on which to browse for services.
- * Most applications will not specify a domain, instead browsing on the
- * default domain(s).
- *
- * callBack: The function to be called when an instance of the service being browsed for
- * is found, or if the call asynchronously fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is not invoked and the DNSServiceRef
- * is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceBrowse
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *regtype,
- const char *domain, /* may be NULL */
- DNSServiceBrowseReply callBack,
- void *context /* may be NULL */
-);
-
-
-/* DNSServiceResolve()
- *
- * Resolve a service name discovered via DNSServiceBrowse() to a target host name, port number, and
- * txt record.
- *
- * Note: Applications should NOT use DNSServiceResolve() solely for txt record monitoring - use
- * DNSServiceQueryRecord() instead, as it is more efficient for this task.
- *
- * Note: When the desired results have been returned, the client MUST terminate the resolve by calling
- * DNSServiceRefDeallocate().
- *
- * Note: DNSServiceResolve() behaves correctly for typical services that have a single SRV record
- * and a single TXT record. To resolve non-standard services with multiple SRV or TXT records,
- * DNSServiceQueryRecord() should be used.
- *
- * DNSServiceResolveReply Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceResolve().
- *
- * flags: Possible values: kDNSServiceFlagsMoreComing
- *
- * interfaceIndex: The interface on which the service was resolved.
- *
- * errorCode: Will be kDNSServiceErr_NoError (0) on success, otherwise will
- * indicate the failure that occurred. Other parameters are undefined if
- * the errorCode is nonzero.
- *
- * fullname: The full service domain name, in the form <servicename>.<protocol>.<domain>.
- * (This name is escaped following standard DNS rules, making it suitable for
- * passing to standard system DNS APIs such as res_query(), or to the
- * special-purpose functions included in this API that take fullname parameters.
- * See "Notes on DNS Name Escaping" earlier in this file for more details.)
- *
- * hosttarget: The target hostname of the machine providing the service. This name can
- * be passed to functions like gethostbyname() to identify the host's IP address.
- *
- * port: The port, in network byte order, on which connections are accepted for this service.
- *
- * txtLen: The length of the txt record, in bytes.
- *
- * txtRecord: The service's primary txt record, in standard txt record format.
- *
- * context: The context pointer that was passed to the callout.
- *
- * NOTE: In earlier versions of this header file, the txtRecord parameter was declared "const char *"
- * This is incorrect, since it contains length bytes which are values in the range 0 to 255, not -128 to +127.
- * Depending on your compiler settings, this change may cause signed/unsigned mismatch warnings.
- * These should be fixed by updating your own callback function definition to match the corrected
- * function signature using "const unsigned char *txtRecord". Making this change may also fix inadvertent
- * bugs in your callback function, where it could have incorrectly interpreted a length byte with value 250
- * as being -6 instead, with various bad consequences ranging from incorrect operation to software crashes.
- * If you need to maintain portable code that will compile cleanly with both the old and new versions of
- * this header file, you should update your callback function definition to use the correct unsigned value,
- * and then in the place where you pass your callback function to DNSServiceResolve(), use a cast to eliminate
- * the compiler warning, e.g.:
- * DNSServiceResolve(sd, flags, index, name, regtype, domain, (DNSServiceResolveReply)MyCallback, context);
- * This will ensure that your code compiles cleanly without warnings (and more importantly, works correctly)
- * with both the old header and with the new corrected version.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceResolveReply)
-(
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *fullname,
- const char *hosttarget,
- uint16_t port, /* In network byte order */
- uint16_t txtLen,
- const unsigned char *txtRecord,
- void *context
-);
-
-
-/* DNSServiceResolve() Parameters
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
- * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- * and the resolve operation will run indefinitely until the client
- * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags: Specifying kDNSServiceFlagsForceMulticast will cause query to be
- * performed with a link-local mDNS query, even if the name is an
- * apparently non-local name (i.e. a name not ending in ".local.")
- *
- * interfaceIndex: The interface on which to resolve the service. If this resolve call is
- * as a result of a currently active DNSServiceBrowse() operation, then the
- * interfaceIndex should be the index reported in the DNSServiceBrowseReply
- * callback. If this resolve call is using information previously saved
- * (e.g. in a preference file) for later use, then use interfaceIndex 0, because
- * the desired service may now be reachable via a different physical interface.
- * See "Constants for specifying an interface index" for more details.
- *
- * name: The name of the service instance to be resolved, as reported to the
- * DNSServiceBrowseReply() callback.
- *
- * regtype: The type of the service instance to be resolved, as reported to the
- * DNSServiceBrowseReply() callback.
- *
- * domain: The domain of the service instance to be resolved, as reported to the
- * DNSServiceBrowseReply() callback.
- *
- * callBack: The function to be called when a result is found, or if the call
- * asynchronously fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSServiceRef
- * is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceResolve
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *name,
- const char *regtype,
- const char *domain,
- DNSServiceResolveReply callBack,
- void *context /* may be NULL */
-);
-
-
-/*********************************************************************************************
-*
-* Querying Individual Specific Records
-*
-*********************************************************************************************/
-
-/* DNSServiceQueryRecord
- *
- * Query for an arbitrary DNS record.
- *
- * DNSServiceQueryRecordReply() Callback Parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceQueryRecord().
- *
- * flags: Possible values are kDNSServiceFlagsMoreComing and
- * kDNSServiceFlagsAdd. The Add flag is NOT set for PTR records
- * with a ttl of 0, i.e. "Remove" events.
- *
- * interfaceIndex: The interface on which the query was resolved (the index for a given
- * interface is determined via the if_nametoindex() family of calls).
- * See "Constants for specifying an interface index" for more details.
- *
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred. Other parameters are undefined if
- * errorCode is nonzero.
- *
- * fullname: The resource record's full domain name.
- *
- * rrtype: The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass: The class of the resource record (usually kDNSServiceClass_IN).
- *
- * rdlen: The length, in bytes, of the resource record rdata.
- *
- * rdata: The raw rdata of the resource record.
- *
- * ttl: If the client wishes to cache the result for performance reasons,
- * the TTL indicates how long the client may legitimately hold onto
- * this result, in seconds. After the TTL expires, the client should
- * consider the result no longer valid, and if it requires this data
- * again, it should be re-fetched with a new query. Of course, this
- * only applies to clients that cancel the asynchronous operation when
- * they get a result. Clients that leave the asynchronous operation
- * running can safely assume that the data remains valid until they
- * get another callback telling them otherwise.
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceQueryRecordReply)
-(
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl,
- void *context
-);
-
-
-/* DNSServiceQueryRecord() Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds
- * then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- * and the query operation will run indefinitely until the client
- * terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags: kDNSServiceFlagsForceMulticast or kDNSServiceFlagsLongLivedQuery.
- * Pass kDNSServiceFlagsLongLivedQuery to create a "long-lived" unicast
- * query to a unicast DNS server that implements the protocol. This flag
- * has no effect on link-local multicast queries.
- *
- * interfaceIndex: If non-zero, specifies the interface on which to issue the query
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Passing 0 causes the name to be queried for on all
- * interfaces. See "Constants for specifying an interface index" for more details.
- *
- * fullname: The full domain name of the resource record to be queried for.
- *
- * rrtype: The numerical type of the resource record to be queried for
- * (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass: The class of the resource record (usually kDNSServiceClass_IN).
- *
- * callBack: The function to be called when a result is found, or if the call
- * asynchronously fails.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSServiceRef
- * is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- DNSServiceQueryRecordReply callBack,
- void *context /* may be NULL */
-);
-
-
-/*********************************************************************************************
-*
-* Unified lookup of both IPv4 and IPv6 addresses for a fully qualified hostname
-*
-*********************************************************************************************/
-
-/* DNSServiceGetAddrInfo
- *
- * Queries for the IP address of a hostname by using either Multicast or Unicast DNS.
- *
- * DNSServiceGetAddrInfoReply() parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceGetAddrInfo().
- *
- * flags: Possible values are kDNSServiceFlagsMoreComing and
- * kDNSServiceFlagsAdd.
- *
- * interfaceIndex: The interface to which the answers pertain.
- *
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred. Other parameters are
- * undefined if errorCode is nonzero.
- *
- * hostname: The fully qualified domain name of the host to be queried for.
- *
- * address: IPv4 or IPv6 address.
- *
- * ttl: If the client wishes to cache the result for performance reasons,
- * the TTL indicates how long the client may legitimately hold onto
- * this result, in seconds. After the TTL expires, the client should
- * consider the result no longer valid, and if it requires this data
- * again, it should be re-fetched with a new query. Of course, this
- * only applies to clients that cancel the asynchronous operation when
- * they get a result. Clients that leave the asynchronous operation
- * running can safely assume that the data remains valid until they
- * get another callback telling them otherwise.
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceGetAddrInfoReply)
-(
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- const char *hostname,
- const struct sockaddr *address,
- uint32_t ttl,
- void *context
-);
-
-
-/* DNSServiceGetAddrInfo() Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds then it
- * initializes the DNSServiceRef, returns kDNSServiceErr_NoError, and the query
- * begins and will last indefinitely until the client terminates the query
- * by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags: kDNSServiceFlagsForceMulticast or kDNSServiceFlagsLongLivedQuery.
- * Pass kDNSServiceFlagsLongLivedQuery to create a "long-lived" unicast
- * query to a unicast DNS server that implements the protocol. This flag
- * has no effect on link-local multicast queries.
- *
- * interfaceIndex: The interface on which to issue the query. Passing 0 causes the query to be
- * sent on all active interfaces via Multicast or the primary interface via Unicast.
- *
- * protocol: Pass in kDNSServiceProtocol_IPv4 to look up IPv4 addresses, or kDNSServiceProtocol_IPv6
- * to look up IPv6 addresses, or both to look up both kinds. If neither flag is
- * set, the system will apply an intelligent heuristic, which is (currently)
- * that it will attempt to look up both, except:
- *
- * * If "hostname" is a wide-area unicast DNS hostname (i.e. not a ".local." name)
- * but this host has no routable IPv6 address, then the call will not try to
- * look up IPv6 addresses for "hostname", since any addresses it found would be
- * unlikely to be of any use anyway. Similarly, if this host has no routable
- * IPv4 address, the call will not try to look up IPv4 addresses for "hostname".
- *
- * hostname: The fully qualified domain name of the host to be queried for.
- *
- * callBack: The function to be called when the query succeeds or fails asynchronously.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceProtocol protocol,
- const char *hostname,
- DNSServiceGetAddrInfoReply callBack,
- void *context /* may be NULL */
-);
-
-
-/*********************************************************************************************
-*
-* Special Purpose Calls:
-* DNSServiceCreateConnection(), DNSServiceRegisterRecord(), DNSServiceReconfirmRecord()
-* (most applications will not use these)
-*
-*********************************************************************************************/
-
-/* DNSServiceCreateConnection()
- *
- * Create a connection to the daemon allowing efficient registration of
- * multiple individual records.
- *
- * Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. Deallocating
- * the reference (via DNSServiceRefDeallocate()) severs the
- * connection and deregisters all records registered on this connection.
- *
- * return value: Returns kDNSServiceErr_NoError on success, otherwise returns
- * an error code indicating the specific failure that occurred (in which
- * case the DNSServiceRef is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef);
-
-
-/* DNSServiceRegisterRecord
- *
- * Register an individual resource record on a connected DNSServiceRef.
- *
- * Note that name conflicts occurring for records registered via this call must be handled
- * by the client in the callback.
- *
- * DNSServiceRegisterRecordReply() parameters:
- *
- * sdRef: The connected DNSServiceRef initialized by
- * DNSServiceCreateConnection().
- *
- * RecordRef: The DNSRecordRef initialized by DNSServiceRegisterRecord(). If the above
- * DNSServiceRef is passed to DNSServiceRefDeallocate(), this DNSRecordRef is
- * invalidated, and may not be used further.
- *
- * flags: Currently unused, reserved for future use.
- *
- * errorCode: Will be kDNSServiceErr_NoError on success, otherwise will
- * indicate the failure that occurred (including name conflicts.)
- * Other parameters are undefined if errorCode is nonzero.
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceRegisterRecordReply)
-(
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef,
- DNSServiceFlags flags,
- DNSServiceErrorType errorCode,
- void *context
-);
-
-
-/* DNSServiceRegisterRecord() Parameters:
- *
- * sdRef: A DNSServiceRef initialized by DNSServiceCreateConnection().
- *
- * RecordRef: A pointer to an uninitialized DNSRecordRef. Upon successful completion of this
- * call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- * (To deregister ALL records registered on a single connected DNSServiceRef
- * and deallocate each of their corresponding DNSServiceRecordRefs, call
- * DNSServiceRefDeallocate()).
- *
- * flags: Possible values are kDNSServiceFlagsShared or kDNSServiceFlagsUnique
- * (see flag type definitions for details).
- *
- * interfaceIndex: If non-zero, specifies the interface on which to register the record
- * (the index for a given interface is determined via the if_nametoindex()
- * family of calls.) Passing 0 causes the record to be registered on all interfaces.
- * See "Constants for specifying an interface index" for more details.
- *
- * fullname: The full domain name of the resource record.
- *
- * rrtype: The numerical type of the resource record (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass: The class of the resource record (usually kDNSServiceClass_IN)
- *
- * rdlen: Length, in bytes, of the rdata.
- *
- * rdata: A pointer to the raw rdata, as it is to appear in the DNS record.
- *
- * ttl: The time to live of the resource record, in seconds.
- * Most clients should pass 0 to indicate that the system should
- * select a sensible default value.
- *
- * callBack: The function to be called when a result is found, or if the call
- * asynchronously fails (e.g. because of a name conflict.)
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred (the callback is never invoked and the DNSRecordRef is
- * not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
-(
- DNSServiceRef sdRef,
- DNSRecordRef *RecordRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl,
- DNSServiceRegisterRecordReply callBack,
- void *context /* may be NULL */
-);
-
-
-/* DNSServiceReconfirmRecord
- *
- * Instruct the daemon to verify the validity of a resource record that appears
- * to be out of date (e.g. because TCP connection to a service's target failed.)
- * Causes the record to be flushed from the daemon's cache (as well as all other
- * daemons' caches on the network) if the record is determined to be invalid.
- * Use this routine conservatively. Reconfirming a record necessarily consumes
- * network bandwidth, so this should not be done indiscriminately.
- *
- * Parameters:
- *
- * flags: Pass kDNSServiceFlagsForce to force immediate deletion of record,
- * instead of after some number of reconfirmation queries have gone unanswered.
- *
- * interfaceIndex: Specifies the interface of the record in question.
- * The caller must specify the interface.
- * This API (by design) causes increased network traffic, so it requires
- * the caller to be precise about which record should be reconfirmed.
- * It is not possible to pass zero for the interface index to perform
- * a "wildcard" reconfirmation, where *all* matching records are reconfirmed.
- *
- * fullname: The resource record's full domain name.
- *
- * rrtype: The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass: The class of the resource record (usually kDNSServiceClass_IN).
- *
- * rdlen: The length, in bytes, of the resource record rdata.
- *
- * rdata: The raw rdata of the resource record.
- *
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
-(
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata
-);
-
-/*********************************************************************************************
-*
-* NAT Port Mapping
-*
-*********************************************************************************************/
-
-/* DNSServiceNATPortMappingCreate
- *
- * Request a port mapping in the NAT gateway, which maps a port on the local machine
- * to an external port on the NAT. The NAT should support either the NAT-PMP or the UPnP IGD
- * protocol for this API to create a successful mapping.
- *
- * The port mapping will be renewed indefinitely until the client process exits, or
- * explicitly terminates the port mapping request by calling DNSServiceRefDeallocate().
- * The client callback will be invoked, informing the client of the NAT gateway's
- * external IP address and the external port that has been allocated for this client.
- * The client should then record this external IP address and port using whatever
- * directory service mechanism it is using to enable peers to connect to it.
- * (Clients advertising services using Wide-Area DNS-SD DO NOT need to use this API
- * -- when a client calls DNSServiceRegister() NAT mappings are automatically created
- * and the external IP address and port for the service are recorded in the global DNS.
- * Only clients using some directory mechanism other than Wide-Area DNS-SD need to use
- * this API to explicitly map their own ports.)
- *
- * It's possible that the client callback could be called multiple times, for example
- * if the NAT gateway's IP address changes, or if a configuration change results in a
- * different external port being mapped for this client. Over the lifetime of any long-lived
- * port mapping, the client should be prepared to handle these notifications of changes
- * in the environment, and should update its recorded address and/or port as appropriate.
- *
- * NOTE: There are two unusual aspects of how the DNSServiceNATPortMappingCreate API works,
- * which were intentionally designed to help simplify client code:
- *
- * 1. It's not an error to request a NAT mapping when the machine is not behind a NAT gateway.
- * In other NAT mapping APIs, if you request a NAT mapping and the machine is not behind a NAT
- * gateway, then the API returns an error code -- it can't get you a NAT mapping if there's no
- * NAT gateway. The DNSServiceNATPortMappingCreate API takes a different view. Working out
- * whether or not you need a NAT mapping can be tricky and non-obvious, particularly on
- * a machine with multiple active network interfaces. Rather than make every client recreate
- * this logic for deciding whether a NAT mapping is required, the PortMapping API does that
- * work for you. If the client calls the PortMapping API when the machine already has a
- * routable public IP address, then instead of complaining about it and giving an error,
- * the PortMapping API just invokes your callback, giving the machine's public address
- * and your own port number. This means you don't need to write code to work out whether
- * your client needs to call the PortMapping API -- just call it anyway, and if it wasn't
- * necessary, no harm is done:
- *
- * - If the machine already has a routable public IP address, then your callback
- * will just be invoked giving your own address and port.
- * - If a NAT mapping is required and obtained, then your callback will be invoked
- * giving you the external address and port.
- * - If a NAT mapping is required but not obtained from the local NAT gateway,
- * or the machine has no network connectivity, then your callback will be
- * invoked giving zero address and port.
- *
- * 2. In other NAT mapping APIs, if a laptop computer is put to sleep and woken up on a new
- * network, it's the client's job to notice this, and work out whether a NAT mapping
- * is required on the new network, and make a new NAT mapping request if necessary.
- * The DNSServiceNATPortMappingCreate API does this for you, automatically.
- * The client just needs to make one call to the PortMapping API, and its callback will
- * be invoked any time the mapping state changes. This property complements point (1) above.
- * If the client didn't make a NAT mapping request just because it determined that one was
- * not required at that particular moment in time, the client would then have to monitor
- * for network state changes to determine if a NAT port mapping later became necessary.
- * By unconditionally making a NAT mapping request, even when a NAT mapping not to be
- * necessary, the PortMapping API will then begin monitoring network state changes on behalf of
- * the client, and if a NAT mapping later becomes necessary, it will automatically create a NAT
- * mapping and inform the client with a new callback giving the new address and port information.
- *
- * DNSServiceNATPortMappingReply() parameters:
- *
- * sdRef: The DNSServiceRef initialized by DNSServiceNATPortMappingCreate().
- *
- * flags: Currently unused, reserved for future use.
- *
- * interfaceIndex: The interface through which the NAT gateway is reached.
- *
- * errorCode: Will be kDNSServiceErr_NoError on success.
- * Will be kDNSServiceErr_DoubleNAT when the NAT gateway is itself behind one or
- * more layers of NAT, in which case the other parameters have the defined values.
- * For other failures, will indicate the failure that occurred, and the other
- * parameters are undefined.
- *
- * externalAddress: Four byte IPv4 address in network byte order.
- *
- * protocol: Will be kDNSServiceProtocol_UDP or kDNSServiceProtocol_TCP or both.
- *
- * internalPort: The port on the local machine that was mapped.
- *
- * externalPort: The actual external port in the NAT gateway that was mapped.
- * This is likely to be different than the requested external port.
- *
- * ttl: The lifetime of the NAT port mapping created on the gateway.
- * This controls how quickly stale mappings will be garbage-collected
- * if the client machine crashes, suffers a power failure, is disconnected
- * from the network, or suffers some other unfortunate demise which
- * causes it to vanish without explicitly removing its NAT port mapping.
- * It's possible that the ttl value will differ from the requested ttl value.
- *
- * context: The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceNATPortMappingReply)
-(
- DNSServiceRef sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceErrorType errorCode,
- uint32_t externalAddress, /* four byte IPv4 address in network byte order */
- DNSServiceProtocol protocol,
- uint16_t internalPort, /* In network byte order */
- uint16_t externalPort, /* In network byte order and may be different than the requested port */
- uint32_t ttl, /* may be different than the requested ttl */
- void *context
-);
-
-
-/* DNSServiceNATPortMappingCreate() Parameters:
- *
- * sdRef: A pointer to an uninitialized DNSServiceRef. If the call succeeds then it
- * initializes the DNSServiceRef, returns kDNSServiceErr_NoError, and the nat
- * port mapping will last indefinitely until the client terminates the port
- * mapping request by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags: Currently ignored, reserved for future use.
- *
- * interfaceIndex: The interface on which to create port mappings in a NAT gateway. Passing 0 causes
- * the port mapping request to be sent on the primary interface.
- *
- * protocol: To request a port mapping, pass in kDNSServiceProtocol_UDP, or kDNSServiceProtocol_TCP,
- * or (kDNSServiceProtocol_UDP | kDNSServiceProtocol_TCP) to map both.
- * The local listening port number must also be specified in the internalPort parameter.
- * To just discover the NAT gateway's external IP address, pass zero for protocol,
- * internalPort, externalPort and ttl.
- *
- * internalPort: The port number in network byte order on the local machine which is listening for packets.
- *
- * externalPort: The requested external port in network byte order in the NAT gateway that you would
- * like to map to the internal port. Pass 0 if you don't care which external port is chosen for you.
- *
- * ttl: The requested renewal period of the NAT port mapping, in seconds.
- * If the client machine crashes, suffers a power failure, is disconnected from
- * the network, or suffers some other unfortunate demise which causes it to vanish
- * unexpectedly without explicitly removing its NAT port mappings, then the NAT gateway
- * will garbage-collect old stale NAT port mappings when their lifetime expires.
- * Requesting a short TTL causes such orphaned mappings to be garbage-collected
- * more promptly, but consumes system resources and network bandwidth with
- * frequent renewal packets to keep the mapping from expiring.
- * Requesting a long TTL is more efficient on the network, but in the event of the
- * client vanishing, stale NAT port mappings will not be garbage-collected as quickly.
- * Most clients should pass 0 to use a system-wide default value.
- *
- * callBack: The function to be called when the port mapping request succeeds or fails asynchronously.
- *
- * context: An application context pointer which is passed to the callback function
- * (may be NULL).
- *
- * return value: Returns kDNSServiceErr_NoError on success (any subsequent, asynchronous
- * errors are delivered to the callback), otherwise returns an error code indicating
- * the error that occurred.
- *
- * If you don't actually want a port mapped, and are just calling the API
- * because you want to find out the NAT's external IP address (e.g. for UI
- * display) then pass zero for protocol, internalPort, externalPort and ttl.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceNATPortMappingCreate
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceProtocol protocol, /* TCP and/or UDP */
- uint16_t internalPort, /* network byte order */
- uint16_t externalPort, /* network byte order */
- uint32_t ttl, /* time to live in seconds */
- DNSServiceNATPortMappingReply callBack,
- void *context /* may be NULL */
-);
-
-
-/*********************************************************************************************
-*
-* General Utility Functions
-*
-*********************************************************************************************/
-
-/* DNSServiceConstructFullName()
- *
- * Concatenate a three-part domain name (as returned by the above callbacks) into a
- * properly-escaped full domain name. Note that callbacks in the above functions ALREADY ESCAPE
- * strings where necessary.
- *
- * Parameters:
- *
- * fullName: A pointer to a buffer that where the resulting full domain name is to be written.
- * The buffer must be kDNSServiceMaxDomainName (1009) bytes in length to
- * accommodate the longest legal domain name without buffer overrun.
- *
- * service: The service name - any dots or backslashes must NOT be escaped.
- * May be NULL (to construct a PTR record name, e.g.
- * "_ftp._tcp.apple.com.").
- *
- * regtype: The service type followed by the protocol, separated by a dot
- * (e.g. "_ftp._tcp").
- *
- * domain: The domain name, e.g. "apple.com.". Literal dots or backslashes,
- * if any, must be escaped, e.g. "1st\. Floor.apple.com."
- *
- * return value: Returns kDNSServiceErr_NoError (0) on success, kDNSServiceErr_BadParam on error.
- *
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
-(
- char * const fullName,
- const char * const service, /* may be NULL */
- const char * const regtype,
- const char * const domain
-);
-
-
-/*********************************************************************************************
-*
-* TXT Record Construction Functions
-*
-*********************************************************************************************/
-
-/*
- * A typical calling sequence for TXT record construction is something like:
- *
- * Client allocates storage for TXTRecord data (e.g. declare buffer on the stack)
- * TXTRecordCreate();
- * TXTRecordSetValue();
- * TXTRecordSetValue();
- * TXTRecordSetValue();
- * ...
- * DNSServiceRegister( ... TXTRecordGetLength(), TXTRecordGetBytesPtr() ... );
- * TXTRecordDeallocate();
- * Explicitly deallocate storage for TXTRecord data (if not allocated on the stack)
- */
-
-
-/* TXTRecordRef
- *
- * Opaque internal data type.
- * Note: Represents a DNS-SD TXT record.
- */
-
-typedef union _TXTRecordRef_t { char PrivateData[16]; char *ForceNaturalAlignment; } TXTRecordRef;
-
-
-/* TXTRecordCreate()
- *
- * Creates a new empty TXTRecordRef referencing the specified storage.
- *
- * If the buffer parameter is NULL, or the specified storage size is not
- * large enough to hold a key subsequently added using TXTRecordSetValue(),
- * then additional memory will be added as needed using malloc().
- *
- * On some platforms, when memory is low, malloc() may fail. In this
- * case, TXTRecordSetValue() will return kDNSServiceErr_NoMemory, and this
- * error condition will need to be handled as appropriate by the caller.
- *
- * You can avoid the need to handle this error condition if you ensure
- * that the storage you initially provide is large enough to hold all
- * the key/value pairs that are to be added to the record.
- * The caller can precompute the exact length required for all of the
- * key/value pairs to be added, or simply provide a fixed-sized buffer
- * known in advance to be large enough.
- * A no-value (key-only) key requires (1 + key length) bytes.
- * A key with empty value requires (1 + key length + 1) bytes.
- * A key with non-empty value requires (1 + key length + 1 + value length).
- * For most applications, DNS-SD TXT records are generally
- * less than 100 bytes, so in most cases a simple fixed-sized
- * 256-byte buffer will be more than sufficient.
- * Recommended size limits for DNS-SD TXT Records are discussed in
- * <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
- *
- * Note: When passing parameters to and from these TXT record APIs,
- * the key name does not include the '=' character. The '=' character
- * is the separator between the key and value in the on-the-wire
- * packet format; it is not part of either the key or the value.
- *
- * txtRecord: A pointer to an uninitialized TXTRecordRef.
- *
- * bufferLen: The size of the storage provided in the "buffer" parameter.
- *
- * buffer: Optional caller-supplied storage used to hold the TXTRecord data.
- * This storage must remain valid for as long as
- * the TXTRecordRef.
- */
-
-void DNSSD_API TXTRecordCreate
-(
- TXTRecordRef *txtRecord,
- uint16_t bufferLen,
- void *buffer
-);
-
-
-/* TXTRecordDeallocate()
- *
- * Releases any resources allocated in the course of preparing a TXT Record
- * using TXTRecordCreate()/TXTRecordSetValue()/TXTRecordRemoveValue().
- * Ownership of the buffer provided in TXTRecordCreate() returns to the client.
- *
- * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- */
-
-void DNSSD_API TXTRecordDeallocate
-(
- TXTRecordRef *txtRecord
-);
-
-
-/* TXTRecordSetValue()
- *
- * Adds a key (optionally with value) to a TXTRecordRef. If the "key" already
- * exists in the TXTRecordRef, then the current value will be replaced with
- * the new value.
- * Keys may exist in four states with respect to a given TXT record:
- * - Absent (key does not appear at all)
- * - Present with no value ("key" appears alone)
- * - Present with empty value ("key=" appears in TXT record)
- * - Present with non-empty value ("key=value" appears in TXT record)
- * For more details refer to "Data Syntax for DNS-SD TXT Records" in
- * <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
- *
- * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * key: A null-terminated string which only contains printable ASCII
- * values (0x20-0x7E), excluding '=' (0x3D). Keys should be
- * 9 characters or fewer (not counting the terminating null).
- *
- * valueSize: The size of the value.
- *
- * value: Any binary value. For values that represent
- * textual data, UTF-8 is STRONGLY recommended.
- * For values that represent textual data, valueSize
- * should NOT include the terminating null (if any)
- * at the end of the string.
- * If NULL, then "key" will be added with no value.
- * If non-NULL but valueSize is zero, then "key=" will be
- * added with empty value.
- *
- * return value: Returns kDNSServiceErr_NoError on success.
- * Returns kDNSServiceErr_Invalid if the "key" string contains
- * illegal characters.
- * Returns kDNSServiceErr_NoMemory if adding this key would
- * exceed the available storage.
- */
-
-DNSServiceErrorType DNSSD_API TXTRecordSetValue
-(
- TXTRecordRef *txtRecord,
- const char *key,
- uint8_t valueSize, /* may be zero */
- const void *value /* may be NULL */
-);
-
-
-/* TXTRecordRemoveValue()
- *
- * Removes a key from a TXTRecordRef. The "key" must be an
- * ASCII string which exists in the TXTRecordRef.
- *
- * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * key: A key name which exists in the TXTRecordRef.
- *
- * return value: Returns kDNSServiceErr_NoError on success.
- * Returns kDNSServiceErr_NoSuchKey if the "key" does not
- * exist in the TXTRecordRef.
- */
-
-DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
-(
- TXTRecordRef *txtRecord,
- const char *key
-);
-
-
-/* TXTRecordGetLength()
- *
- * Allows you to determine the length of the raw bytes within a TXTRecordRef.
- *
- * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * return value: Returns the size of the raw bytes inside a TXTRecordRef
- * which you can pass directly to DNSServiceRegister() or
- * to DNSServiceUpdateRecord().
- * Returns 0 if the TXTRecordRef is empty.
- */
-
-uint16_t DNSSD_API TXTRecordGetLength
-(
- const TXTRecordRef *txtRecord
-);
-
-
-/* TXTRecordGetBytesPtr()
- *
- * Allows you to retrieve a pointer to the raw bytes within a TXTRecordRef.
- *
- * txtRecord: A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * return value: Returns a pointer to the raw bytes inside the TXTRecordRef
- * which you can pass directly to DNSServiceRegister() or
- * to DNSServiceUpdateRecord().
- */
-
-const void * DNSSD_API TXTRecordGetBytesPtr
-(
- const TXTRecordRef *txtRecord
-);
-
-
-/*********************************************************************************************
-*
-* TXT Record Parsing Functions
-*
-*********************************************************************************************/
-
-/*
- * A typical calling sequence for TXT record parsing is something like:
- *
- * Receive TXT record data in DNSServiceResolve() callback
- * if (TXTRecordContainsKey(txtLen, txtRecord, "key")) then do something
- * val1ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key1", &len1);
- * val2ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key2", &len2);
- * ...
- * memcpy(myval1, val1ptr, len1);
- * memcpy(myval2, val2ptr, len2);
- * ...
- * return;
- *
- * If you wish to retain the values after return from the DNSServiceResolve()
- * callback, then you need to copy the data to your own storage using memcpy()
- * or similar, as shown in the example above.
- *
- * If for some reason you need to parse a TXT record you built yourself
- * using the TXT record construction functions above, then you can do
- * that using TXTRecordGetLength and TXTRecordGetBytesPtr calls:
- * TXTRecordGetValue(TXTRecordGetLength(x), TXTRecordGetBytesPtr(x), key, &len);
- *
- * Most applications only fetch keys they know about from a TXT record and
- * ignore the rest.
- * However, some debugging tools wish to fetch and display all keys.
- * To do that, use the TXTRecordGetCount() and TXTRecordGetItemAtIndex() calls.
- */
-
-/* TXTRecordContainsKey()
- *
- * Allows you to determine if a given TXT Record contains a specified key.
- *
- * txtLen: The size of the received TXT Record.
- *
- * txtRecord: Pointer to the received TXT Record bytes.
- *
- * key: A null-terminated ASCII string containing the key name.
- *
- * return value: Returns 1 if the TXT Record contains the specified key.
- * Otherwise, it returns 0.
- */
-
-int DNSSD_API TXTRecordContainsKey
-(
- uint16_t txtLen,
- const void *txtRecord,
- const char *key
-);
-
-
-/* TXTRecordGetValuePtr()
- *
- * Allows you to retrieve the value for a given key from a TXT Record.
- *
- * txtLen: The size of the received TXT Record
- *
- * txtRecord: Pointer to the received TXT Record bytes.
- *
- * key: A null-terminated ASCII string containing the key name.
- *
- * valueLen: On output, will be set to the size of the "value" data.
- *
- * return value: Returns NULL if the key does not exist in this TXT record,
- * or exists with no value (to differentiate between
- * these two cases use TXTRecordContainsKey()).
- * Returns pointer to location within TXT Record bytes
- * if the key exists with empty or non-empty value.
- * For empty value, valueLen will be zero.
- * For non-empty value, valueLen will be length of value data.
- */
-
-const void * DNSSD_API TXTRecordGetValuePtr
-(
- uint16_t txtLen,
- const void *txtRecord,
- const char *key,
- uint8_t *valueLen
-);
-
-
-/* TXTRecordGetCount()
- *
- * Returns the number of keys stored in the TXT Record. The count
- * can be used with TXTRecordGetItemAtIndex() to iterate through the keys.
- *
- * txtLen: The size of the received TXT Record.
- *
- * txtRecord: Pointer to the received TXT Record bytes.
- *
- * return value: Returns the total number of keys in the TXT Record.
- *
- */
-
-uint16_t DNSSD_API TXTRecordGetCount
-(
- uint16_t txtLen,
- const void *txtRecord
-);
-
-
-/* TXTRecordGetItemAtIndex()
- *
- * Allows you to retrieve a key name and value pointer, given an index into
- * a TXT Record. Legal index values range from zero to TXTRecordGetCount()-1.
- * It's also possible to iterate through keys in a TXT record by simply
- * calling TXTRecordGetItemAtIndex() repeatedly, beginning with index zero
- * and increasing until TXTRecordGetItemAtIndex() returns kDNSServiceErr_Invalid.
- *
- * On return:
- * For keys with no value, *value is set to NULL and *valueLen is zero.
- * For keys with empty value, *value is non-NULL and *valueLen is zero.
- * For keys with non-empty value, *value is non-NULL and *valueLen is non-zero.
- *
- * txtLen: The size of the received TXT Record.
- *
- * txtRecord: Pointer to the received TXT Record bytes.
- *
- * itemIndex: An index into the TXT Record.
- *
- * keyBufLen: The size of the string buffer being supplied.
- *
- * key: A string buffer used to store the key name.
- * On return, the buffer contains a null-terminated C string
- * giving the key name. DNS-SD TXT keys are usually
- * 9 characters or fewer. To hold the maximum possible
- * key name, the buffer should be 256 bytes long.
- *
- * valueLen: On output, will be set to the size of the "value" data.
- *
- * value: On output, *value is set to point to location within TXT
- * Record bytes that holds the value data.
- *
- * return value: Returns kDNSServiceErr_NoError on success.
- * Returns kDNSServiceErr_NoMemory if keyBufLen is too short.
- * Returns kDNSServiceErr_Invalid if index is greater than
- * TXTRecordGetCount()-1.
- */
-
-DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
-(
- uint16_t txtLen,
- const void *txtRecord,
- uint16_t itemIndex,
- uint16_t keyBufLen,
- char *key,
- uint8_t *valueLen,
- const void **value
-);
-
-#if _DNS_SD_LIBDISPATCH
-/*
- * DNSServiceSetDispatchQueue
- *
- * Allows you to schedule a DNSServiceRef on a serial dispatch queue for receiving asynchronous
- * callbacks. It's the clients responsibility to ensure that the provided dispatch queue is running.
- *
- * A typical application that uses CFRunLoopRun or dispatch_main on its main thread will
- * usually schedule DNSServiceRefs on its main queue (which is always a serial queue)
- * using "DNSServiceSetDispatchQueue(sdref, dispatch_get_main_queue());"
- *
- * If there is any error during the processing of events, the application callback will
- * be called with an error code. For shared connections, each subordinate DNSServiceRef
- * will get its own error callback. Currently these error callbacks only happen
- * if the mDNSResponder daemon is manually terminated or crashes, and the error
- * code in this case is kDNSServiceErr_ServiceNotRunning. The application must call
- * DNSServiceRefDeallocate to free the DNSServiceRef when it gets such an error code.
- * These error callbacks are rare and should not normally happen on customer machines,
- * but application code should be written defensively to handle such error callbacks
- * gracefully if they occur.
- *
- * After using DNSServiceSetDispatchQueue on a DNSServiceRef, calling DNSServiceProcessResult
- * on the same DNSServiceRef will result in undefined behavior and should be avoided.
- *
- * Once the application successfully schedules a DNSServiceRef on a serial dispatch queue using
- * DNSServiceSetDispatchQueue, it cannot remove the DNSServiceRef from the dispatch queue, or use
- * DNSServiceSetDispatchQueue a second time to schedule the DNSServiceRef onto a different serial dispatch
- * queue. Once scheduled onto a dispatch queue a DNSServiceRef will deliver events to that queue until
- * the application no longer requires that operation and terminates it using DNSServiceRefDeallocate.
- *
- * service: DNSServiceRef that was allocated and returned to the application, when the
- * application calls one of the DNSService API.
- *
- * queue: dispatch queue where the application callback will be scheduled
- *
- * return value: Returns kDNSServiceErr_NoError on success.
- * Returns kDNSServiceErr_NoMemory if it cannot create a dispatch source
- * Returns kDNSServiceErr_BadParam if the service param is invalid or the
- * queue param is invalid
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceSetDispatchQueue
-(
- DNSServiceRef service,
- dispatch_queue_t queue
-);
-#endif //_DNS_SD_LIBDISPATCH
-
-#if !defined(_WIN32)
-typedef void (DNSSD_API *DNSServiceSleepKeepaliveReply)
-(
- DNSServiceRef sdRef,
- DNSServiceErrorType errorCode,
- void *context
-);
-DNSServiceErrorType DNSSD_API DNSServiceSleepKeepalive
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- int fd,
- unsigned int timeout,
- DNSServiceSleepKeepaliveReply callBack,
- void *context
-);
-#endif
-
-#ifdef __APPLE_API_PRIVATE
-
-
-#endif //__APPLE_API_PRIVATE
-
-/* Some C compiler cleverness. We can make the compiler check certain things for us,
- * and report errors at compile-time if anything is wrong. The usual way to do this would
- * be to use a run-time "if" statement or the conventional run-time "assert" mechanism, but
- * then you don't find out what's wrong until you run the software. This way, if the assertion
- * condition is false, the array size is negative, and the compiler complains immediately.
- */
-
-struct CompileTimeAssertionChecks_DNS_SD
-{
- char assert0[(sizeof(union _TXTRecordRef_t) == 16) ? 1 : -1];
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DNS_SD_H */
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientlib.c b/sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientlib.c
deleted file mode 100644
index a2c0dc6ad949..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientlib.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2004, Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "dns_sd.h"
-
-#if MDNS_BUILDINGSHAREDLIBRARY || MDNS_BUILDINGSTUBLIBRARY
-#pragma export on
-#endif
-
-#if defined(_WIN32)
-// disable warning "conversion from <data> to uint16_t"
-#pragma warning(disable:4244)
-#define strncasecmp _strnicmp
-#define strcasecmp _stricmp
-#endif
-
-/*********************************************************************************************
-*
-* Supporting Functions
-*
-*********************************************************************************************/
-
-#define mDNSIsDigit(X) ((X) >= '0' && (X) <= '9')
-
-// DomainEndsInDot returns 1 if name ends with a dot, 0 otherwise
-// (DNSServiceConstructFullName depends this returning 1 for true, rather than any non-zero value meaning true)
-
-static int DomainEndsInDot(const char *dom)
-{
- while (dom[0] && dom[1])
- {
- if (dom[0] == '\\') // advance past escaped byte sequence
- {
- if (mDNSIsDigit(dom[1]) && mDNSIsDigit(dom[2]) && mDNSIsDigit(dom[3]))
- dom += 4; // If "\ddd" then skip four
- else dom += 2; // else if "\x" then skip two
- }
- else dom++; // else goto next character
- }
- return (dom[0] == '.');
-}
-
-static uint8_t *InternalTXTRecordSearch
-(
- uint16_t txtLen,
- const void *txtRecord,
- const char *key,
- unsigned long *keylen
-)
-{
- uint8_t *p = (uint8_t*)txtRecord;
- uint8_t *e = p + txtLen;
- *keylen = (unsigned long) strlen(key);
- while (p<e)
- {
- uint8_t *x = p;
- p += 1 + p[0];
- if (p <= e && *keylen <= x[0] && !strncasecmp(key, (char*)x+1, *keylen))
- if (*keylen == x[0] || x[1+*keylen] == '=') return x;
- }
- return NULL;
-}
-
-/*********************************************************************************************
-*
-* General Utility Functions
-*
-*********************************************************************************************/
-
-// Note: Need to make sure we don't write more than kDNSServiceMaxDomainName (1009) bytes to fullName
-// In earlier builds this constant was defined to be 1005, so to avoid buffer overruns on clients
-// compiled with that constant we'll actually limit the output to 1005 bytes.
-
-DNSServiceErrorType DNSSD_API DNSServiceConstructFullName
-(
- char *const fullName,
- const char *const service, // May be NULL
- const char *const regtype,
- const char *const domain
-)
-{
- const size_t len = !regtype ? 0 : strlen(regtype) - DomainEndsInDot(regtype);
- char *fn = fullName;
- char *const lim = fullName + 1005;
- const char *s = service;
- const char *r = regtype;
- const char *d = domain;
-
- // regtype must be at least "x._udp" or "x._tcp"
- if (len < 6 || !domain || !domain[0]) return kDNSServiceErr_BadParam;
- if (strncasecmp((regtype + len - 4), "_tcp", 4) && strncasecmp((regtype + len - 4), "_udp", 4)) return kDNSServiceErr_BadParam;
-
- if (service && *service)
- {
- while (*s)
- {
- unsigned char c = *s++; // Needs to be unsigned, or values like 0xFF will be interpreted as < 32
- if (c <= ' ') // Escape non-printable characters
- {
- if (fn+4 >= lim) goto fail;
- *fn++ = '\\';
- *fn++ = '0' + (c / 100);
- *fn++ = '0' + (c / 10) % 10;
- c = '0' + (c ) % 10;
- }
- else if (c == '.' || (c == '\\')) // Escape dot and backslash literals
- {
- if (fn+2 >= lim) goto fail;
- *fn++ = '\\';
- }
- else
- if (fn+1 >= lim) goto fail;
- *fn++ = (char)c;
- }
- *fn++ = '.';
- }
-
- while (*r) if (fn+1 >= lim) goto fail;else *fn++ = *r++;
- if (!DomainEndsInDot(regtype)) { if (fn+1 >= lim) goto fail;else *fn++ = '.';}
-
- while (*d) if (fn+1 >= lim) goto fail;else *fn++ = *d++;
- if (!DomainEndsInDot(domain)) { if (fn+1 >= lim) goto fail;else *fn++ = '.';}
-
- *fn = '\0';
- return kDNSServiceErr_NoError;
-
-fail:
- *fn = '\0';
- return kDNSServiceErr_BadParam;
-}
-
-/*********************************************************************************************
-*
-* TXT Record Construction Functions
-*
-*********************************************************************************************/
-
-typedef struct _TXTRecordRefRealType
-{
- uint8_t *buffer; // Pointer to data
- uint16_t buflen; // Length of buffer
- uint16_t datalen; // Length currently in use
- uint16_t malloced; // Non-zero if buffer was allocated via malloc()
-} TXTRecordRefRealType;
-
-#define txtRec ((TXTRecordRefRealType*)txtRecord)
-
-// The opaque storage defined in the public dns_sd.h header is 16 bytes;
-// make sure we don't exceed that.
-struct CompileTimeAssertionCheck_dnssd_clientlib
-{
- char assert0[(sizeof(TXTRecordRefRealType) <= 16) ? 1 : -1];
-};
-
-void DNSSD_API TXTRecordCreate
-(
- TXTRecordRef *txtRecord,
- uint16_t bufferLen,
- void *buffer
-)
-{
- txtRec->buffer = buffer;
- txtRec->buflen = buffer ? bufferLen : (uint16_t)0;
- txtRec->datalen = 0;
- txtRec->malloced = 0;
-}
-
-void DNSSD_API TXTRecordDeallocate(TXTRecordRef *txtRecord)
-{
- if (txtRec->malloced) free(txtRec->buffer);
-}
-
-DNSServiceErrorType DNSSD_API TXTRecordSetValue
-(
- TXTRecordRef *txtRecord,
- const char *key,
- uint8_t valueSize,
- const void *value
-)
-{
- uint8_t *start, *p;
- const char *k;
- unsigned long keysize, keyvalsize;
-
- for (k = key; *k; k++) if (*k < 0x20 || *k > 0x7E || *k == '=') return kDNSServiceErr_Invalid;
- keysize = (unsigned long)(k - key);
- keyvalsize = 1 + keysize + (value ? (1 + valueSize) : 0);
- if (keysize < 1 || keyvalsize > 255) return kDNSServiceErr_Invalid;
- (void)TXTRecordRemoveValue(txtRecord, key);
- if (txtRec->datalen + keyvalsize > txtRec->buflen)
- {
- unsigned char *newbuf;
- unsigned long newlen = txtRec->datalen + keyvalsize;
- if (newlen > 0xFFFF) return kDNSServiceErr_Invalid;
- newbuf = malloc((size_t)newlen);
- if (!newbuf) return kDNSServiceErr_NoMemory;
- memcpy(newbuf, txtRec->buffer, txtRec->datalen);
- if (txtRec->malloced) free(txtRec->buffer);
- txtRec->buffer = newbuf;
- txtRec->buflen = (uint16_t)(newlen);
- txtRec->malloced = 1;
- }
- start = txtRec->buffer + txtRec->datalen;
- p = start + 1;
- memcpy(p, key, keysize);
- p += keysize;
- if (value)
- {
- *p++ = '=';
- memcpy(p, value, valueSize);
- p += valueSize;
- }
- *start = (uint8_t)(p - start - 1);
- txtRec->datalen += p - start;
- return kDNSServiceErr_NoError;
-}
-
-DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
-(
- TXTRecordRef *txtRecord,
- const char *key
-)
-{
- unsigned long keylen, itemlen, remainder;
- uint8_t *item = InternalTXTRecordSearch(txtRec->datalen, txtRec->buffer, key, &keylen);
- if (!item) return kDNSServiceErr_NoSuchKey;
- itemlen = (unsigned long)(1 + item[0]);
- remainder = (unsigned long)((txtRec->buffer + txtRec->datalen) - (item + itemlen));
- // Use memmove because memcpy behaviour is undefined for overlapping regions
- memmove(item, item + itemlen, remainder);
- txtRec->datalen -= itemlen;
- return kDNSServiceErr_NoError;
-}
-
-uint16_t DNSSD_API TXTRecordGetLength (const TXTRecordRef *txtRecord) { return txtRec->datalen; }
-const void * DNSSD_API TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) { return txtRec->buffer; }
-
-/*********************************************************************************************
-*
-* TXT Record Parsing Functions
-*
-*********************************************************************************************/
-
-int DNSSD_API TXTRecordContainsKey
-(
- uint16_t txtLen,
- const void *txtRecord,
- const char *key
-)
-{
- unsigned long keylen;
- return (InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen) ? 1 : 0);
-}
-
-const void * DNSSD_API TXTRecordGetValuePtr
-(
- uint16_t txtLen,
- const void *txtRecord,
- const char *key,
- uint8_t *valueLen
-)
-{
- unsigned long keylen;
- uint8_t *item = InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen);
- if (!item || item[0] <= keylen) return NULL; // If key not found, or found with no value, return NULL
- *valueLen = (uint8_t)(item[0] - (keylen + 1));
- return (item + 1 + keylen + 1);
-}
-
-uint16_t DNSSD_API TXTRecordGetCount
-(
- uint16_t txtLen,
- const void *txtRecord
-)
-{
- uint16_t count = 0;
- uint8_t *p = (uint8_t*)txtRecord;
- uint8_t *e = p + txtLen;
- while (p<e) { p += 1 + p[0]; count++; }
- return ((p>e) ? (uint16_t)0 : count);
-}
-
-DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
-(
- uint16_t txtLen,
- const void *txtRecord,
- uint16_t itemIndex,
- uint16_t keyBufLen,
- char *key,
- uint8_t *valueLen,
- const void **value
-)
-{
- uint16_t count = 0;
- uint8_t *p = (uint8_t*)txtRecord;
- uint8_t *e = p + txtLen;
- while (p<e && count<itemIndex) { p += 1 + p[0]; count++; } // Find requested item
- if (p<e && p + 1 + p[0] <= e) // If valid
- {
- uint8_t *x = p+1;
- unsigned long len = 0;
- e = p + 1 + p[0];
- while (x+len<e && x[len] != '=') len++;
- if (len >= keyBufLen) return kDNSServiceErr_NoMemory;
- memcpy(key, x, len);
- key[len] = 0;
- if (x+len<e) // If we found '='
- {
- *value = x + len + 1;
- *valueLen = (uint8_t)(p[0] - (len + 1));
- }
- else
- {
- *value = NULL;
- *valueLen = 0;
- }
- return kDNSServiceErr_NoError;
- }
- return kDNSServiceErr_Invalid;
-}
-
-/*********************************************************************************************
-*
-* SCCS-compatible version string
-*
-*********************************************************************************************/
-
-// For convenience when using the "strings" command, this is the last thing in the file
-
-// Note: The C preprocessor stringify operator ('#') makes a string from its argument, without macro expansion
-// e.g. If "version" is #define'd to be "4", then STRINGIFY_AWE(version) will return the string "version", not "4"
-// To expand "version" to its value before making the string, use STRINGIFY(version) instead
-#define STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s) # s
-#define STRINGIFY(s) STRINGIFY_ARGUMENT_WITHOUT_EXPANSION(s)
-
-// NOT static -- otherwise the compiler may optimize it out
-// The "@(#) " pattern is a special prefix the "what" command looks for
-const char VersionString_SCCS_libdnssd[] = "@(#) libdns_sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientstub.c b/sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientstub.c
deleted file mode 100644
index c6b50a2cd34e..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientstub.c
+++ /dev/null
@@ -1,2219 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <sal/config.h>
-
-#if defined _WIN32
-#define _WINSOCK_DEPRECATED_NO_WARNINGS // warnings about inet_addr
-#endif
-
-#include <errno.h>
-#include <stdlib.h>
-
-#if APPLE_OSX_mDNSResponder
-#include <mach-o/dyld.h>
-#endif
-
-#include "dnssd_ipc.h"
-
-static int gDaemonErr = kDNSServiceErr_NoError;
-
-#if defined(_WIN32)
-
- #define _SSIZE_T
- #include <CommonServices.h>
- #include <DebugServices.h>
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <windows.h>
- #include <stdarg.h>
- #include <stdio.h>
-
- #define sockaddr_mdns sockaddr_in
- #define AF_MDNS AF_INET
-
-// Disable warning: "'type cast' : from data pointer 'void *' to function pointer"
- #pragma warning(disable:4055)
-
-// Disable warning: "nonstandard extension, function/data pointer conversion in expression"
- #pragma warning(disable:4152)
-
-extern BOOL IsSystemServiceDisabled();
-
- #define sleep(X) Sleep((X) * 1000)
-
-static int g_initWinsock = 0;
- #define LOG_WARNING kDebugLevelWarning
- #define LOG_INFO kDebugLevelInfo
-static void syslog( int priority, const char * message, ...)
-{
- va_list args;
- int len;
- char * buffer;
- DWORD err = WSAGetLastError();
- (void) priority;
- va_start( args, message );
- len = _vscprintf( message, args ) + 1;
- buffer = malloc( len * sizeof(char) );
- if ( buffer ) { vsprintf( buffer, message, args ); OutputDebugString( buffer ); free( buffer ); }
- WSASetLastError( err );
- va_end(args);
-}
-#else
-
- #include <sys/fcntl.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <syslog.h>
-
- #define sockaddr_mdns sockaddr_un
- #define AF_MDNS AF_LOCAL
-
-#endif
-
-// <rdar://problem/4096913> Specifies how many times we'll try and connect to the server.
-
-#define DNSSD_CLIENT_MAXTRIES 4
-
-// Uncomment the line below to use the old error return mechanism of creating a temporary named socket (e.g. in /var/tmp)
-//#define USE_NAMED_ERROR_RETURN_SOCKET 1
-
-#define DNSSD_CLIENT_TIMEOUT 10 // In seconds
-
-#ifndef CTL_PATH_PREFIX
-#define CTL_PATH_PREFIX "/var/tmp/dnssd_result_socket."
-#endif
-
-typedef struct
-{
- ipc_msg_hdr ipc_hdr;
- DNSServiceFlags cb_flags;
- uint32_t cb_interface;
- DNSServiceErrorType cb_err;
-} CallbackHeader;
-
-typedef struct _DNSServiceRef_t DNSServiceOp;
-typedef struct _DNSRecordRef_t DNSRecord;
-
-#if !defined(_WIN32)
-typedef struct
-{
- void *AppCallback; // Client callback function and context
- void *AppContext;
-} SleepKAContext;
-#endif
-
-// client stub callback to process message from server and deliver results to client application
-typedef void (*ProcessReplyFn)(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *msg, const char *const end);
-
-#define ValidatorBits 0x12345678
-#define DNSServiceRefValid(X) (dnssd_SocketValid((X)->sockfd) && (((X)->sockfd ^ (X)->validator) == ValidatorBits))
-
-// When using kDNSServiceFlagsShareConnection, there is one primary _DNSServiceOp_t, and zero or more subordinates
-// For the primary, the 'next' field points to the first subordinate, and its 'next' field points to the next, and so on.
-// For the primary, the 'primary' field is NULL; for subordinates the 'primary' field points back to the associated primary
-
-// _DNS_SD_LIBDISPATCH is defined where libdispatch/GCD is available. This does not mean that the application will use the
-// DNSServiceSetDispatchQueue API. Hence any new code guarded with _DNS_SD_LIBDISPATCH should still be backwards compatible.
-struct _DNSServiceRef_t
-{
- DNSServiceOp *next; // For shared connection
- DNSServiceOp *primary; // For shared connection
- dnssd_sock_t sockfd; // Connected socket between client and daemon
- dnssd_sock_t validator; // Used to detect memory corruption, double disposals, etc.
- client_context_t uid; // For shared connection requests, each subordinate DNSServiceRef has its own ID,
- // unique within the scope of the same shared parent DNSServiceRef
- uint32_t op; // request_op_t or reply_op_t
- uint32_t max_index; // Largest assigned record index - 0 if no additional records registered
- uint32_t logcounter; // Counter used to control number of syslog messages we write
- int *moreptr; // Set while DNSServiceProcessResult working on this particular DNSServiceRef
- ProcessReplyFn ProcessReply; // Function pointer to the code to handle received messages
- void *AppCallback; // Client callback function and context
- void *AppContext;
- DNSRecord *rec;
-#if _DNS_SD_LIBDISPATCH
- dispatch_source_t disp_source;
- dispatch_queue_t disp_queue;
-#endif
- void *kacontext;
-};
-
-struct _DNSRecordRef_t
-{
- DNSRecord *recnext;
- void *AppContext;
- DNSServiceRegisterRecordReply AppCallback;
- DNSRecordRef recref;
- uint32_t record_index; // index is unique to the ServiceDiscoveryRef
- client_context_t uid; // For demultiplexing multiple DNSServiceRegisterRecord calls
- DNSServiceOp *sdr;
-};
-
-// Write len bytes. Return 0 on success, -1 on error
-static int write_all(dnssd_sock_t sd, char *buf, size_t len)
-{
- // Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead.
- //if (send(sd, buf, len, MSG_WAITALL) != len) return -1;
- while (len)
- {
- ssize_t num_written = send(sd, buf, (long)len, 0);
- if (num_written < 0 || (size_t)num_written > len)
- {
- // Should never happen. If it does, it indicates some OS bug,
- // or that the mDNSResponder daemon crashed (which should never happen).
- #if !defined(__ppc__) && defined(SO_ISDEFUNCT)
- int defunct;
- socklen_t dlen = sizeof (defunct);
- if (getsockopt(sd, SOL_SOCKET, SO_ISDEFUNCT, &defunct, &dlen) < 0)
- syslog(LOG_WARNING, "dnssd_clientstub write_all: SO_ISDEFUNCT failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
- if (!defunct)
- syslog(LOG_WARNING, "dnssd_clientstub write_all(%d) failed %ld/%ld %d %s", sd,
- (long)num_written, (long)len,
- (num_written < 0) ? dnssd_errno : 0,
- (num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
- else
- syslog(LOG_INFO, "dnssd_clientstub write_all(%d) DEFUNCT", sd);
- #else
- syslog(LOG_WARNING, "dnssd_clientstub write_all(%d) failed %ld/%ld %d %s", sd,
- (long)num_written, (long)len,
- (num_written < 0) ? dnssd_errno : 0,
- (num_written < 0) ? dnssd_strerror(dnssd_errno) : "");
- #endif
- return -1;
- }
- buf += num_written;
- len -= num_written;
- }
- return 0;
-}
-
-enum { read_all_success = 0, read_all_fail = -1, read_all_wouldblock = -2 };
-
-// Read len bytes. Return 0 on success, read_all_fail on error, or read_all_wouldblock for
-static int read_all(dnssd_sock_t sd, char *buf, int len)
-{
- // Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead.
- //if (recv(sd, buf, len, MSG_WAITALL) != len) return -1;
-
- while (len)
- {
- ssize_t num_read = recv(sd, buf, len, 0);
- // It is valid to get an interrupted system call error e.g., somebody attaching
- // in a debugger, retry without failing
- if ((num_read < 0) && (errno == EINTR)) { syslog(LOG_INFO, "dnssd_clientstub read_all: EINTR continue"); continue; }
- if ((num_read == 0) || (num_read < 0) || (num_read > len))
- {
- int printWarn = 0;
- int defunct = 0;
- // Should never happen. If it does, it indicates some OS bug,
- // or that the mDNSResponder daemon crashed (which should never happen).
-#if defined(WIN32)
- // <rdar://problem/7481776> Suppress logs for "A non-blocking socket operation
- // could not be completed immediately"
- if (WSAGetLastError() != WSAEWOULDBLOCK)
- printWarn = 1;
-#endif
-#if !defined(__ppc__) && defined(SO_ISDEFUNCT)
- {
- socklen_t dlen = sizeof (defunct);
- if (getsockopt(sd, SOL_SOCKET, SO_ISDEFUNCT, &defunct, &dlen) < 0)
- syslog(LOG_WARNING, "dnssd_clientstub read_all: SO_ISDEFUNCT failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
- }
- if (!defunct)
- printWarn = 1;
-#endif
- if (printWarn)
- syslog(LOG_WARNING, "dnssd_clientstub read_all(%d) failed %ld/%ld %d %s", sd,
- (long)num_read, (long)len,
- (num_read < 0) ? dnssd_errno : 0,
- (num_read < 0) ? dnssd_strerror(dnssd_errno) : "");
- else if (defunct)
- syslog(LOG_INFO, "dnssd_clientstub read_all(%d) DEFUNCT", sd);
- return (num_read < 0 && dnssd_errno == dnssd_EWOULDBLOCK) ? read_all_wouldblock : read_all_fail;
- }
- buf += num_read;
- len -= num_read;
- }
- return read_all_success;
-}
-
-// Returns 1 if more bytes remain to be read on socket descriptor sd, 0 otherwise
-static int more_bytes(dnssd_sock_t sd)
-{
- struct timeval tv = { 0, 0 };
- fd_set readfds;
- fd_set *fs;
- int ret;
-
- if (sd < FD_SETSIZE)
- {
- fs = &readfds;
- FD_ZERO(fs);
- }
- else
- {
- // Compute the number of integers needed for storing "sd". Internally fd_set is stored
- // as an array of ints with one bit for each fd and hence we need to compute
- // the number of ints needed rather than the number of bytes. If "sd" is 32, we need
- // two ints and not just one.
- int nfdbits = sizeof (int) * 8;
- int nints = (sd/nfdbits) + 1;
- fs = (fd_set *)calloc(nints, sizeof(int));
- if (fs == NULL) { syslog(LOG_WARNING, "dnssd_clientstub more_bytes: malloc failed"); return 0; }
- }
- FD_SET(sd, fs);
- ret = select((int)sd+1, fs, (fd_set*)NULL, (fd_set*)NULL, &tv);
- if (fs != &readfds) free(fs);
- return (ret > 0);
-}
-
-// Wait for daemon to write to socket
-static int wait_for_daemon(dnssd_sock_t sock, int timeout)
-{
-#ifndef WIN32
- // At this point the next operation (accept() or read()) on this socket may block for a few milliseconds waiting
- // for the daemon to respond, but that's okay -- the daemon is a trusted service and we know if won't take more
- // than a few milliseconds to respond. So we'll forego checking for readability of the socket.
- (void) sock;
- (void) timeout;
-#else
- // Windows on the other hand suffers from 3rd party software (primarily 3rd party firewall software) that
- // interferes with proper functioning of the TCP protocol stack. Because of this and because we depend on TCP
- // to communicate with the system service, we want to make sure that the next operation on this socket (accept() or
- // read()) doesn't block indefinitely.
- if (!gDaemonErr)
- {
- struct timeval tv;
- fd_set set;
-
- FD_ZERO(&set);
- FD_SET(sock, &set);
- tv.tv_sec = timeout;
- tv.tv_usec = 0;
- if (!select((int)(sock + 1), &set, NULL, NULL, &tv))
- {
- syslog(LOG_WARNING, "dnssd_clientstub wait_for_daemon timed out");
- gDaemonErr = kDNSServiceErr_Timeout;
- }
- }
-#endif
- return gDaemonErr;
-}
-
-/* create_hdr
- *
- * allocate and initialize an ipc message header. Value of len should initially be the
- * length of the data, and is set to the value of the data plus the header. data_start
- * is set to point to the beginning of the data section. SeparateReturnSocket should be
- * non-zero for calls that can't receive an immediate error return value on their primary
- * socket, and therefore require a separate return path for the error code result.
- * if zero, the path to a control socket is appended at the beginning of the message buffer.
- * data_start is set past this string.
- */
-static ipc_msg_hdr *create_hdr(uint32_t op, size_t *len, char **data_start, int SeparateReturnSocket, DNSServiceOp *ref)
-{
- char *msg = NULL;
- ipc_msg_hdr *hdr;
- int datalen;
-#if !defined(USE_TCP_LOOPBACK)
- char ctrl_path[64] = ""; // "/var/tmp/dnssd_result_socket.xxxxxxxxxx-xxx-xxxxxx"
-#endif
-
- if (SeparateReturnSocket)
- {
-#if defined(USE_TCP_LOOPBACK)
- *len += 2; // Allocate space for two-byte port number
-#elif defined(USE_NAMED_ERROR_RETURN_SOCKET)
- struct timeval tv;
- if (gettimeofday(&tv, NULL) < 0)
- { syslog(LOG_WARNING, "dnssd_clientstub create_hdr: gettimeofday failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno)); return NULL; }
- sprintf(ctrl_path, "%s%d-%.3lx-%.6lu", CTL_PATH_PREFIX, (int)getpid(),
- (unsigned long)(tv.tv_sec & 0xFFF), (unsigned long)(tv.tv_usec));
- *len += strlen(ctrl_path) + 1;
-#else
- *len += 1; // Allocate space for single zero byte (empty C string)
-#endif
- }
-
- datalen = (int) *len;
- *len += sizeof(ipc_msg_hdr);
-
- // Write message to buffer
- msg = malloc(*len);
- if (!msg) { syslog(LOG_WARNING, "dnssd_clientstub create_hdr: malloc failed"); return NULL; }
-
- memset(msg, 0, *len);
- hdr = (ipc_msg_hdr *)msg;
- hdr->version = VERSION;
- hdr->datalen = datalen;
- hdr->ipc_flags = 0;
- hdr->op = op;
- hdr->client_context = ref->uid;
- hdr->reg_index = 0;
- *data_start = msg + sizeof(ipc_msg_hdr);
-#if defined(USE_TCP_LOOPBACK)
- // Put dummy data in for the port, since we don't know what it is yet.
- // The data will get filled in before we send the message. This happens in deliver_request().
- if (SeparateReturnSocket) put_uint16(0, data_start);
-#else
- if (SeparateReturnSocket) put_string(ctrl_path, data_start);
-#endif
- return hdr;
-}
-
-static void FreeDNSRecords(DNSServiceOp *sdRef)
-{
- DNSRecord *rec = sdRef->rec;
- while (rec)
- {
- DNSRecord *next = rec->recnext;
- free(rec);
- rec = next;
- }
-}
-
-static void FreeDNSServiceOp(DNSServiceOp *x)
-{
- // We don't use our DNSServiceRefValid macro here because if we're cleaning up after a socket() call failed
- // then sockfd could legitimately contain a failing value (e.g. dnssd_InvalidSocket)
- if ((x->sockfd ^ x->validator) != ValidatorBits)
- syslog(LOG_WARNING, "dnssd_clientstub attempt to dispose invalid DNSServiceRef %p %08X %08X", x, x->sockfd, x->validator);
- else
- {
- x->next = NULL;
- x->primary = NULL;
- x->sockfd = dnssd_InvalidSocket;
- x->validator = 0xDDDDDDDD;
- x->op = request_op_none;
- x->max_index = 0;
- x->logcounter = 0;
- x->moreptr = NULL;
- x->ProcessReply = NULL;
- x->AppCallback = NULL;
- x->AppContext = NULL;
-#if _DNS_SD_LIBDISPATCH
- if (x->disp_source) dispatch_release(x->disp_source);
- x->disp_source = NULL;
- x->disp_queue = NULL;
-#endif
- // DNSRecords may have been added to subordinate sdRef e.g., DNSServiceRegister/DNSServiceAddRecord
- // or on the main sdRef e.g., DNSServiceCreateConnection/DNSServiveRegisterRecord. DNSRecords may have
- // been freed if the application called DNSRemoveRecord
- FreeDNSRecords(x);
- if (x->kacontext)
- {
- free(x->kacontext);
- x->kacontext = NULL;
- }
- free(x);
- }
-}
-
-// Return a connected service ref (deallocate with DNSServiceRefDeallocate)
-static DNSServiceErrorType ConnectToServer(DNSServiceRef *ref, DNSServiceFlags flags, uint32_t op, ProcessReplyFn ProcessReply, void *AppCallback, void *AppContext)
-{
- #if APPLE_OSX_mDNSResponder
- int NumTries = DNSSD_CLIENT_MAXTRIES;
- #else
- int NumTries = 0;
- #endif
-
- dnssd_sockaddr_t saddr;
- DNSServiceOp *sdr;
-
- if (!ref) { syslog(LOG_WARNING, "dnssd_clientstub DNSService operation with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
-
- if (flags & kDNSServiceFlagsShareConnection)
- {
- if (!*ref)
- {
- syslog(LOG_WARNING, "dnssd_clientstub kDNSServiceFlagsShareConnection used with NULL DNSServiceRef");
- return kDNSServiceErr_BadParam;
- }
- if (!DNSServiceRefValid(*ref) || (*ref)->op != connection_request || (*ref)->primary)
- {
- syslog(LOG_WARNING, "dnssd_clientstub kDNSServiceFlagsShareConnection used with invalid DNSServiceRef %p %08X %08X",
- (*ref), (*ref)->sockfd, (*ref)->validator);
- *ref = NULL;
- return kDNSServiceErr_BadReference;
- }
- }
-
- #if defined(_WIN32)
- if (!g_initWinsock)
- {
- WSADATA wsaData;
- g_initWinsock = 1;
- if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { *ref = NULL; return kDNSServiceErr_ServiceNotRunning; }
- }
- // <rdar://problem/4096913> If the system service is disabled, we only want to try to connect once
- if (IsSystemServiceDisabled()) NumTries = DNSSD_CLIENT_MAXTRIES;
- #endif
-
- sdr = malloc(sizeof(DNSServiceOp));
- if (!sdr) { syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: malloc failed"); *ref = NULL; return kDNSServiceErr_NoMemory; }
- sdr->next = NULL;
- sdr->primary = NULL;
- sdr->sockfd = dnssd_InvalidSocket;
- sdr->validator = sdr->sockfd ^ ValidatorBits;
- sdr->op = op;
- sdr->max_index = 0;
- sdr->logcounter = 0;
- sdr->moreptr = NULL;
- sdr->uid.u32[0] = 0;
- sdr->uid.u32[1] = 0;
- sdr->ProcessReply = ProcessReply;
- sdr->AppCallback = AppCallback;
- sdr->AppContext = AppContext;
- sdr->rec = NULL;
-#if _DNS_SD_LIBDISPATCH
- sdr->disp_source = NULL;
- sdr->disp_queue = NULL;
-#endif
- sdr->kacontext = NULL;
-
- if (flags & kDNSServiceFlagsShareConnection)
- {
- DNSServiceOp **p = &(*ref)->next; // Append ourselves to end of primary's list
- while (*p) p = &(*p)->next;
- *p = sdr;
- // Preincrement counter before we use it -- it helps with debugging if we know the all-zeroes ID should never appear
- if (++(*ref)->uid.u32[0] == 0) ++(*ref)->uid.u32[1]; // In parent DNSServiceOp increment UID counter
- sdr->primary = *ref; // Set our primary pointer
- sdr->sockfd = (*ref)->sockfd; // Inherit primary's socket
- sdr->validator = (*ref)->validator;
- sdr->uid = (*ref)->uid;
- //printf("ConnectToServer sharing socket %d\n", sdr->sockfd);
- }
- else
- {
- #ifdef SO_NOSIGPIPE
- const unsigned long optval = 1;
- #endif
- *ref = NULL;
- sdr->sockfd = socket(AF_DNSSD, SOCK_STREAM, 0);
- sdr->validator = sdr->sockfd ^ ValidatorBits;
- if (!dnssd_SocketValid(sdr->sockfd))
- {
- syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: socket failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
- FreeDNSServiceOp(sdr);
- return kDNSServiceErr_NoMemory;
- }
- #ifdef SO_NOSIGPIPE
- // Some environments (e.g. OS X) support turning off SIGPIPE for a socket
- if (setsockopt(sdr->sockfd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)) < 0)
- syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_NOSIGPIPE failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
- #endif
- #if defined(USE_TCP_LOOPBACK)
- saddr.sin_family = AF_INET;
- saddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
- saddr.sin_port = htons(MDNS_TCP_SERVERPORT);
- #else
- saddr.sun_family = AF_LOCAL;
- strcpy(saddr.sun_path, MDNS_UDS_SERVERPATH);
- #if !defined(__ppc__) && defined(SO_DEFUNCTOK)
- {
- int defunct = 1;
- if (setsockopt(sdr->sockfd, SOL_SOCKET, SO_DEFUNCTOK, &defunct, sizeof(defunct)) < 0)
- syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_DEFUNCTOK failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
- }
- #endif
- #endif
-
- while (1)
- {
- int err = connect(sdr->sockfd, (struct sockaddr *) &saddr, sizeof(saddr));
- if (!err) break; // If we succeeded, return sdr
- // If we failed, then it may be because the daemon is still launching.
- // This can happen for processes that launch early in the boot process, while the
- // daemon is still coming up. Rather than fail here, we'll wait a bit and try again.
- // If, after four seconds, we still can't connect to the daemon,
- // then we give up and return a failure code.
- if (++NumTries < DNSSD_CLIENT_MAXTRIES) sleep(1); // Sleep a bit, then try again
- else { dnssd_close(sdr->sockfd); FreeDNSServiceOp(sdr); return kDNSServiceErr_ServiceNotRunning; }
- }
- //printf("ConnectToServer opened socket %d\n", sdr->sockfd);
- }
-
- *ref = sdr;
- return kDNSServiceErr_NoError;
-}
-
-#define deliver_request_bailout(MSG) \
- do { syslog(LOG_WARNING, "dnssd_clientstub deliver_request: %s failed %d (%s)", (MSG), dnssd_errno, dnssd_strerror(dnssd_errno)); goto cleanup; } while(0)
-
-static DNSServiceErrorType deliver_request(ipc_msg_hdr *hdr, DNSServiceOp *sdr)
-{
- uint32_t datalen = hdr->datalen; // We take a copy here because we're going to convert hdr->datalen to network byte order
- #if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
- char *const data = (char *)hdr + sizeof(ipc_msg_hdr);
- #endif
- dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
- DNSServiceErrorType err = kDNSServiceErr_Unknown; // Default for the "goto cleanup" cases
- int MakeSeparateReturnSocket = 0;
-
- // Note: need to check hdr->op, not sdr->op.
- // hdr->op contains the code for the specific operation we're currently doing, whereas sdr->op
- // contains the original parent DNSServiceOp (e.g. for an add_record_request, hdr->op will be
- // add_record_request but the parent sdr->op will be connection_request or reg_service_request)
- if (sdr->primary ||
- hdr->op == reg_record_request || hdr->op == add_record_request || hdr->op == update_record_request || hdr->op == remove_record_request)
- MakeSeparateReturnSocket = 1;
-
- if (!DNSServiceRefValid(sdr))
- {
- syslog(LOG_WARNING, "dnssd_clientstub deliver_request: invalid DNSServiceRef %p %08X %08X", sdr, sdr->sockfd, sdr->validator);
- return kDNSServiceErr_BadReference;
- }
-
- if (!hdr) { syslog(LOG_WARNING, "dnssd_clientstub deliver_request: !hdr"); return kDNSServiceErr_Unknown; }
-
- if (MakeSeparateReturnSocket)
- {
- #if defined(USE_TCP_LOOPBACK)
- {
- union { uint16_t s; u_char b[2]; } port;
- dnssd_sockaddr_t caddr;
- dnssd_socklen_t len = (dnssd_socklen_t) sizeof(caddr);
- listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
- if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("TCP socket");
-
- caddr.sin_family = AF_INET;
- caddr.sin_port = 0;
- caddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
- if (bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr)) < 0) deliver_request_bailout("TCP bind");
- if (getsockname(listenfd, (struct sockaddr*) &caddr, &len) < 0) deliver_request_bailout("TCP getsockname");
- if (listen(listenfd, 1) < 0) deliver_request_bailout("TCP listen");
- port.s = caddr.sin_port;
- data[0] = port.b[0]; // don't switch the byte order, as the
- data[1] = port.b[1]; // daemon expects it in network byte order
- }
- #elif defined(USE_NAMED_ERROR_RETURN_SOCKET)
- {
- mode_t mask;
- int bindresult;
- dnssd_sockaddr_t caddr;
- listenfd = socket(AF_DNSSD, SOCK_STREAM, 0);
- if (!dnssd_SocketValid(listenfd)) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET socket");
-
- caddr.sun_family = AF_LOCAL;
- // According to Stevens (section 3.2), there is no portable way to
- // determine whether sa_len is defined on a particular platform.
- #ifndef NOT_HAVE_SA_LEN
- caddr.sun_len = sizeof(struct sockaddr_un);
- #endif
- strcpy(caddr.sun_path, data);
-#error "the below umask(3) calls are bad in a MT program (cf. fdo#60338):"
- mask = umask(0);
- bindresult = bind(listenfd, (struct sockaddr *)&caddr, sizeof(caddr));
- umask(mask);
- if (bindresult < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET bind");
- if (listen(listenfd, 1) < 0) deliver_request_bailout("USE_NAMED_ERROR_RETURN_SOCKET listen");
- }
- #else
- {
- dnssd_sock_t sp[2];
- if (socketpair(AF_DNSSD, SOCK_STREAM, 0, sp) < 0) deliver_request_bailout("socketpair");
- else
- {
- errsd = sp[0]; // We'll read our four-byte error code from sp[0]
- listenfd = sp[1]; // We'll send sp[1] to the daemon
- #if !defined(__ppc__) && defined(SO_DEFUNCTOK)
- {
- int defunct = 1;
- if (setsockopt(errsd, SOL_SOCKET, SO_DEFUNCTOK, &defunct, sizeof(defunct)) < 0)
- syslog(LOG_WARNING, "dnssd_clientstub ConnectToServer: SO_DEFUNCTOK failed %d %s", dnssd_errno, dnssd_strerror(dnssd_errno));
- }
- #endif
- }
- }
- #endif
- }
-
-#if !defined(USE_TCP_LOOPBACK) && !defined(USE_NAMED_ERROR_RETURN_SOCKET)
- // If we're going to make a separate error return socket, and pass it to the daemon
- // using sendmsg, then we'll hold back one data byte to go with it.
- // On some versions of Unix (including Leopard) sending a control message without
- // any associated data does not work reliably -- e.g. one particular issue we ran
- // into is that if the receiving program is in a kqueue loop waiting to be notified
- // of the received message, it doesn't get woken up when the control message arrives.
- if (MakeSeparateReturnSocket || sdr->op == send_bpf) datalen--; // Okay to use sdr->op when checking for op == send_bpf
-#endif
-
- // At this point, our listening socket is set up and waiting, if necessary, for the daemon to connect back to
- ConvertHeaderBytes(hdr);
- //syslog(LOG_WARNING, "dnssd_clientstub deliver_request writing %lu bytes", (unsigned long)(datalen + sizeof(ipc_msg_hdr)));
- //if (MakeSeparateReturnSocket) syslog(LOG_WARNING, "dnssd_clientstub deliver_request name is %s", data);
-#if TEST_SENDING_ONE_BYTE_AT_A_TIME
- unsigned int i;
- for (i=0; i<datalen + sizeof(ipc_msg_hdr); i++)
- {
- syslog(LOG_WARNING, "dnssd_clientstub deliver_request writing %d", i);
- if (write_all(sdr->sockfd, ((char *)hdr)+i, 1) < 0)
- { syslog(LOG_WARNING, "write_all (byte %u) failed", i); goto cleanup; }
- usleep(10000);
- }
-#else
- if (write_all(sdr->sockfd, (char *)hdr, datalen + sizeof(ipc_msg_hdr)) < 0)
- {
- // write_all already prints an error message if there is an error writing to
- // the socket except for DEFUNCT. Logging here is unnecessary and also wrong
- // in the case of DEFUNCT sockets
- syslog(LOG_INFO, "dnssd_clientstub deliver_request ERROR: write_all(%d, %lu bytes) failed",
- sdr->sockfd, (unsigned long)(datalen + sizeof(ipc_msg_hdr)));
- goto cleanup;
- }
-#endif
-
- if (!MakeSeparateReturnSocket) errsd = sdr->sockfd;
- if (MakeSeparateReturnSocket || sdr->op == send_bpf) // Okay to use sdr->op when checking for op == send_bpf
- {
-#if defined(USE_TCP_LOOPBACK) || defined(USE_NAMED_ERROR_RETURN_SOCKET)
- // At this point we may block in accept for a few milliseconds waiting for the daemon to connect back to us,
- // but that's okay -- the daemon is a trusted service and we know if won't take more than a few milliseconds to respond.
- dnssd_sockaddr_t daddr;
- dnssd_socklen_t len = sizeof(daddr);
- if ((err = wait_for_daemon(listenfd, DNSSD_CLIENT_TIMEOUT)) != kDNSServiceErr_NoError) goto cleanup;
- errsd = accept(listenfd, (struct sockaddr *)&daddr, &len);
- if (!dnssd_SocketValid(errsd)) deliver_request_bailout("accept");
-#else
-
- struct iovec vec = { ((char *)hdr) + sizeof(ipc_msg_hdr) + datalen, 1 }; // Send the last byte along with the SCM_RIGHTS
- struct msghdr msg;
- struct cmsghdr *cmsg;
- char cbuf[CMSG_SPACE(sizeof(dnssd_sock_t))];
-
- if (sdr->op == send_bpf) // Okay to use sdr->op when checking for op == send_bpf
- {
- int i;
- char p[12]; // Room for "/dev/bpf999" with terminating null
- for (i=0; i<100; i++)
- {
- snprintf(p, sizeof(p), "/dev/bpf%d", i);
- listenfd = open(p, O_RDWR, 0);
- //if (dnssd_SocketValid(listenfd)) syslog(LOG_WARNING, "Sending fd %d for %s", listenfd, p);
- if (!dnssd_SocketValid(listenfd) && dnssd_errno != EBUSY)
- syslog(LOG_WARNING, "Error opening %s %d (%s)", p, dnssd_errno, dnssd_strerror(dnssd_errno));
- if (dnssd_SocketValid(listenfd) || dnssd_errno != EBUSY) break;
- }
- }
-
- msg.msg_name = 0;
- msg.msg_namelen = 0;
- msg.msg_iov = &vec;
- msg.msg_iovlen = 1;
- msg.msg_control = cbuf;
- msg.msg_controllen = CMSG_LEN(sizeof(dnssd_sock_t));
- msg.msg_flags = 0;
- cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_len = CMSG_LEN(sizeof(dnssd_sock_t));
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- *((dnssd_sock_t *)CMSG_DATA(cmsg)) = listenfd;
-
-#if TEST_KQUEUE_CONTROL_MESSAGE_BUG
- sleep(1);
-#endif
-
-#if DEBUG_64BIT_SCM_RIGHTS
- syslog(LOG_WARNING, "dnssd_clientstub sendmsg read sd=%d write sd=%d %ld %ld %ld/%ld/%ld/%ld",
- errsd, listenfd, sizeof(dnssd_sock_t), sizeof(void*),
- sizeof(struct cmsghdr) + sizeof(dnssd_sock_t),
- CMSG_LEN(sizeof(dnssd_sock_t)), (long)CMSG_SPACE(sizeof(dnssd_sock_t)),
- (long)((char*)CMSG_DATA(cmsg) + 4 - cbuf));
-#endif // DEBUG_64BIT_SCM_RIGHTS
-
- if (sendmsg(sdr->sockfd, &msg, 0) < 0)
- {
- syslog(LOG_WARNING, "dnssd_clientstub deliver_request ERROR: sendmsg failed read sd=%d write sd=%d errno %d (%s)",
- errsd, listenfd, dnssd_errno, dnssd_strerror(dnssd_errno));
- err = kDNSServiceErr_Incompatible;
- goto cleanup;
- }
-
-#if DEBUG_64BIT_SCM_RIGHTS
- syslog(LOG_WARNING, "dnssd_clientstub sendmsg read sd=%d write sd=%d okay", errsd, listenfd);
-#endif // DEBUG_64BIT_SCM_RIGHTS
-
-#endif
- // Close our end of the socketpair *before* blocking in read_all to get the four-byte error code.
- // Otherwise, if the daemon closes our socket (or crashes), we block in read_all() forever
- // because the socket is not closed (we still have an open reference to it ourselves).
- dnssd_close(listenfd);
- listenfd = dnssd_InvalidSocket; // Make sure we don't close it a second time in the cleanup handling below
- }
-
- // At this point we may block in read_all for a few milliseconds waiting for the daemon to send us the error code,
- // but that's okay -- the daemon is a trusted service and we know if won't take more than a few milliseconds to respond.
- if (sdr->op == send_bpf) // Okay to use sdr->op when checking for op == send_bpf
- err = kDNSServiceErr_NoError;
- else if ((err = wait_for_daemon(errsd, DNSSD_CLIENT_TIMEOUT)) == kDNSServiceErr_NoError)
- {
- if (read_all(errsd, (char*)&err, (int)sizeof(err)) < 0)
- err = kDNSServiceErr_ServiceNotRunning; // On failure read_all will have written a message to syslog for us
- else
- err = ntohl(err);
- }
-
- //syslog(LOG_WARNING, "dnssd_clientstub deliver_request: retrieved error code %d", err);
-
-cleanup:
- if (MakeSeparateReturnSocket)
- {
- if (dnssd_SocketValid(listenfd)) dnssd_close(listenfd);
- if (dnssd_SocketValid(errsd)) dnssd_close(errsd);
-#if defined(USE_NAMED_ERROR_RETURN_SOCKET)
- // syslog(LOG_WARNING, "dnssd_clientstub deliver_request: removing UDS: %s", data);
- if (unlink(data) != 0)
- syslog(LOG_WARNING, "dnssd_clientstub WARNING: unlink(\"%s\") failed errno %d (%s)", data, dnssd_errno, dnssd_strerror(dnssd_errno));
- // else syslog(LOG_WARNING, "dnssd_clientstub deliver_request: removed UDS: %s", data);
-#endif
- }
-
- free(hdr);
- return err;
-}
-
-dnssd_sock_t DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
-{
- if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD called with NULL DNSServiceRef"); return dnssd_InvalidSocket; }
-
- if (!DNSServiceRefValid(sdRef))
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD called with invalid DNSServiceRef %p %08X %08X",
- sdRef, sdRef->sockfd, sdRef->validator);
- return dnssd_InvalidSocket;
- }
-
- if (sdRef->primary)
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefSockFD undefined for kDNSServiceFlagsShareConnection subordinate DNSServiceRef %p", sdRef);
- return dnssd_InvalidSocket;
- }
-
- return sdRef->sockfd;
-}
-
-#if _DNS_SD_LIBDISPATCH
-static void CallbackWithError(DNSServiceRef sdRef, DNSServiceErrorType error)
-{
- DNSServiceOp *sdr = sdRef;
- DNSServiceOp *sdrNext;
- DNSRecord *rec;
- DNSRecord *recnext;
- int morebytes;
-
- while (sdr)
- {
- // We can't touch the sdr after the callback as it can be deallocated in the callback
- sdrNext = sdr->next;
- morebytes = 1;
- sdr->moreptr = &morebytes;
- switch (sdr->op)
- {
- case resolve_request:
- if (sdr->AppCallback) ((DNSServiceResolveReply) sdr->AppCallback)(sdr, 0, 0, error, NULL, 0, 0, 0, NULL, sdr->AppContext);
- break;
- case query_request:
- if (sdr->AppCallback) ((DNSServiceQueryRecordReply)sdr->AppCallback)(sdr, 0, 0, error, NULL, 0, 0, 0, NULL, 0, sdr->AppContext);
- break;
- case addrinfo_request:
- if (sdr->AppCallback) ((DNSServiceGetAddrInfoReply)sdr->AppCallback)(sdr, 0, 0, error, NULL, NULL, 0, sdr->AppContext);
- break;
- case browse_request:
- if (sdr->AppCallback) ((DNSServiceBrowseReply) sdr->AppCallback)(sdr, 0, 0, error, NULL, 0, NULL, sdr->AppContext);
- break;
- case reg_service_request:
- if (sdr->AppCallback) ((DNSServiceRegisterReply) sdr->AppCallback)(sdr, 0, error, NULL, 0, NULL, sdr->AppContext);
- break;
- case enumeration_request:
- if (sdr->AppCallback) ((DNSServiceDomainEnumReply) sdr->AppCallback)(sdr, 0, 0, error, NULL, sdr->AppContext);
- break;
- case connection_request:
- // This means Register Record, walk the list of DNSRecords to do the callback
- rec = sdr->rec;
- while (rec)
- {
- recnext = rec->recnext;
- if (rec->AppCallback) ((DNSServiceRegisterRecordReply)rec->AppCallback)(sdr, 0, 0, error, rec->AppContext);
- // The Callback can call DNSServiceRefDeallocate which in turn frees sdr and all the records.
- // Detect that and return early
- if (!morebytes) {syslog(LOG_WARNING, "dnssdclientstub:Record: CallbackwithError morebytes zero"); return;}
- rec = recnext;
- }
- break;
- case port_mapping_request:
- if (sdr->AppCallback) ((DNSServiceNATPortMappingReply)sdr->AppCallback)(sdr, 0, 0, error, 0, 0, 0, 0, 0, sdr->AppContext);
- break;
- default:
- syslog(LOG_WARNING, "dnssd_clientstub CallbackWithError called with bad op %d", sdr->op);
- }
- // If DNSServiceRefDeallocate was called in the callback, morebytes will be zero. As the sdRef
- // (and its subordinates) have been freed, we should not proceed further. Note that when we
- // call the callback with a subordinate sdRef the application can call DNSServiceRefDeallocate
- // on the main sdRef and DNSServiceRefDeallocate handles this case by walking all the sdRefs and
- // clears the moreptr so that we can terminate here.
-
- // If DNSServiceRefDeallocate was not called in the callback, then set moreptr to NULL so that
- // we don't access the stack variable after we return from this function.
- if (!morebytes) {syslog(LOG_WARNING, "dnssdclientstub:sdRef: CallbackwithError morebytes zero sdr %p", sdr); return;}
- else {sdr->moreptr = NULL;}
- sdr = sdrNext;
- }
-}
-#endif // _DNS_SD_LIBDISPATCH
-
-// Handle reply from server, calling application client callback. If there is no reply
-// from the daemon on the socket contained in sdRef, the call will block.
-DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef)
-{
- int morebytes = 0;
-
- if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
-
- if (!DNSServiceRefValid(sdRef))
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
- return kDNSServiceErr_BadReference;
- }
-
- if (sdRef->primary)
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult undefined for kDNSServiceFlagsShareConnection subordinate DNSServiceRef %p", sdRef);
- return kDNSServiceErr_BadReference;
- }
-
- if (!sdRef->ProcessReply)
- {
- static int num_logs = 0;
- if (num_logs < 10) syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult called with DNSServiceRef with no ProcessReply function");
- if (num_logs < 1000) num_logs++;else sleep(1);
- return kDNSServiceErr_BadReference;
- }
-
- do
- {
- CallbackHeader cbh;
- char *data;
-
- // return NoError on EWOULDBLOCK. This will handle the case
- // where a non-blocking socket is told there is data, but it was a false positive.
- // On error, read_all will write a message to syslog for us, so don't need to duplicate that here
- // Note: If we want to properly support using non-blocking sockets in the future
- int result = read_all(sdRef->sockfd, (void *)&cbh.ipc_hdr, sizeof(cbh.ipc_hdr));
- if (result == read_all_fail)
- {
- // Set the ProcessReply to NULL before callback as the sdRef can get deallocated
- // in the callback.
- sdRef->ProcessReply = NULL;
-#if _DNS_SD_LIBDISPATCH
- // Call the callbacks with an error if using the dispatch API, as DNSServiceProcessResult
- // is not called by the application and hence need to communicate the error. Cancel the
- // source so that we don't get any more events
- // Note: read_all fails if we could not read from the daemon which can happen if the
- // daemon dies or the file descriptor is disconnected (defunct).
- if (sdRef->disp_source)
- {
- dispatch_source_cancel(sdRef->disp_source);
- dispatch_release(sdRef->disp_source);
- sdRef->disp_source = NULL;
- CallbackWithError(sdRef, kDNSServiceErr_ServiceNotRunning);
- }
-#endif
- // Don't touch sdRef anymore as it might have been deallocated
- return kDNSServiceErr_ServiceNotRunning;
- }
- else if (result == read_all_wouldblock)
- {
- if (morebytes && sdRef->logcounter < 100)
- {
- sdRef->logcounter++;
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult error: select indicated data was waiting but read_all returned EWOULDBLOCK");
- }
- return kDNSServiceErr_NoError;
- }
-
- ConvertHeaderBytes(&cbh.ipc_hdr);
- if (cbh.ipc_hdr.version != VERSION)
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceProcessResult daemon version %d does not match client version %d", cbh.ipc_hdr.version, VERSION);
- sdRef->ProcessReply = NULL;
- return kDNSServiceErr_Incompatible;
- }
-
- data = malloc(cbh.ipc_hdr.datalen);
- if (!data) return kDNSServiceErr_NoMemory;
- if (read_all(sdRef->sockfd, data, cbh.ipc_hdr.datalen) < 0) // On error, read_all will write a message to syslog for us
- {
- // Set the ProcessReply to NULL before callback as the sdRef can get deallocated
- // in the callback.
- sdRef->ProcessReply = NULL;
-#if _DNS_SD_LIBDISPATCH
- // Call the callbacks with an error if using the dispatch API, as DNSServiceProcessResult
- // is not called by the application and hence need to communicate the error. Cancel the
- // source so that we don't get any more events
- if (sdRef->disp_source)
- {
- dispatch_source_cancel(sdRef->disp_source);
- dispatch_release(sdRef->disp_source);
- sdRef->disp_source = NULL;
- CallbackWithError(sdRef, kDNSServiceErr_ServiceNotRunning);
- }
-#endif
- // Don't touch sdRef anymore as it might have been deallocated
- free(data);
- return kDNSServiceErr_ServiceNotRunning;
- }
- else
- {
- const char *ptr = data;
- cbh.cb_flags = get_flags (&ptr, data + cbh.ipc_hdr.datalen);
- cbh.cb_interface = get_uint32 (&ptr, data + cbh.ipc_hdr.datalen);
- cbh.cb_err = get_error_code(&ptr, data + cbh.ipc_hdr.datalen);
-
- // CAUTION: We have to handle the case where the client calls DNSServiceRefDeallocate from within the callback function.
- // To do this we set moreptr to point to morebytes. If the client does call DNSServiceRefDeallocate(),
- // then that routine will clear morebytes for us, and cause us to exit our loop.
- morebytes = more_bytes(sdRef->sockfd);
- if (morebytes)
- {
- cbh.cb_flags |= kDNSServiceFlagsMoreComing;
- sdRef->moreptr = &morebytes;
- }
- if (ptr) sdRef->ProcessReply(sdRef, &cbh, ptr, data + cbh.ipc_hdr.datalen);
- // Careful code here:
- // If morebytes is non-zero, that means we set sdRef->moreptr above, and the operation was not
- // cancelled out from under us, so now we need to clear sdRef->moreptr so we don't leave a stray
- // dangling pointer pointing to a long-gone stack variable.
- // If morebytes is zero, then one of two thing happened:
- // (a) morebytes was 0 above, so we didn't set sdRef->moreptr, so we don't need to clear it
- // (b) morebytes was 1 above, and we set sdRef->moreptr, but the operation was cancelled (with DNSServiceRefDeallocate()),
- // so we MUST NOT try to dereference our stale sdRef pointer.
- if (morebytes) sdRef->moreptr = NULL;
- }
- free(data);
- } while (morebytes);
-
- return kDNSServiceErr_NoError;
-}
-
-void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef)
-{
- if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefDeallocate called with NULL DNSServiceRef"); return; }
-
- if (!DNSServiceRefValid(sdRef)) // Also verifies dnssd_SocketValid(sdRef->sockfd) for us too
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRefDeallocate called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
- return;
- }
-
- // If we're in the middle of a DNSServiceProcessResult() invocation for this DNSServiceRef, clear its morebytes flag to break it out of its while loop
- if (sdRef->moreptr) *(sdRef->moreptr) = 0;
-
- if (sdRef->primary) // If this is a subordinate DNSServiceOp, just send a 'stop' command
- {
- DNSServiceOp **p = &sdRef->primary->next;
- while (*p && *p != sdRef) p = &(*p)->next;
- if (*p)
- {
- char *ptr;
- size_t len = 0;
- ipc_msg_hdr *hdr = create_hdr(cancel_request, &len, &ptr, 0, sdRef);
- if (hdr)
- {
- ConvertHeaderBytes(hdr);
- write_all(sdRef->sockfd, (char *)hdr, len);
- free(hdr);
- }
- *p = sdRef->next;
- FreeDNSServiceOp(sdRef);
- }
- }
- else // else, make sure to terminate all subordinates as well
- {
-#if _DNS_SD_LIBDISPATCH
- // The cancel handler will close the fd if a dispatch source has been set
- if (sdRef->disp_source)
- {
- // By setting the ProcessReply to NULL, we make sure that we never call
- // the application callbacks ever, after returning from this function. We
- // assume that DNSServiceRefDeallocate is called from the serial queue
- // that was passed to DNSServiceSetDispatchQueue. Hence, dispatch_source_cancel
- // should cancel all the blocks on the queue and hence there should be no more
- // callbacks when we return from this function. Setting ProcessReply to NULL
- // provides extra protection.
- sdRef->ProcessReply = NULL;
- dispatch_source_cancel(sdRef->disp_source);
- dispatch_release(sdRef->disp_source);
- sdRef->disp_source = NULL;
- }
- // if disp_queue is set, it means it used the DNSServiceSetDispatchQueue API. In that case,
- // when the source was cancelled, the fd was closed in the handler. Currently the source
- // is cancelled only when the mDNSResponder daemon dies
- else if (!sdRef->disp_queue) dnssd_close(sdRef->sockfd);
-#else
- dnssd_close(sdRef->sockfd);
-#endif
- // Free DNSRecords added in DNSRegisterRecord if they have not
- // been freed in DNSRemoveRecord
- while (sdRef)
- {
- DNSServiceOp *p = sdRef;
- sdRef = sdRef->next;
- // When there is an error reading from the daemon e.g., bad fd, CallbackWithError
- // is called which sets moreptr. It might set the moreptr on a subordinate sdRef
- // but the application might call DNSServiceRefDeallocate with the main sdRef from
- // the callback. Hence, when we loop through the subordinate sdRefs, we need
- // to clear the moreptr so that CallbackWithError can terminate itself instead of
- // walking through the freed sdRefs.
- if (p->moreptr) *(p->moreptr) = 0;
- FreeDNSServiceOp(p);
- }
- }
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceGetProperty(const char *property, void *result, uint32_t *size)
-{
- char *ptr;
- size_t len = strlen(property) + 1;
- ipc_msg_hdr *hdr;
- DNSServiceOp *tmp;
- uint32_t actualsize;
-
- DNSServiceErrorType err = ConnectToServer(&tmp, 0, getproperty_request, NULL, NULL, NULL);
- if (err) return err;
-
- hdr = create_hdr(getproperty_request, &len, &ptr, 0, tmp);
- if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }
-
- put_string(property, &ptr);
- err = deliver_request(hdr, tmp); // Will free hdr for us
- if (read_all(tmp->sockfd, (char*)&actualsize, (int)sizeof(actualsize)) < 0)
- { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_ServiceNotRunning; }
-
- actualsize = ntohl(actualsize);
- if (read_all(tmp->sockfd, (char*)result, actualsize < *size ? actualsize : *size) < 0)
- { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_ServiceNotRunning; }
- DNSServiceRefDeallocate(tmp);
-
- // Swap version result back to local process byte order
- if (!strcmp(property, kDNSServiceProperty_DaemonVersion) && *size >= 4)
- *(uint32_t*)result = ntohl(*(uint32_t*)result);
-
- *size = actualsize;
- return kDNSServiceErr_NoError;
-}
-
-static void handle_resolve_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *end)
-{
- char fullname[kDNSServiceMaxDomainName];
- char target[kDNSServiceMaxDomainName];
- uint16_t txtlen;
- union { uint16_t s; u_char b[2]; } port;
- unsigned char *txtrecord;
-
- get_string(&data, end, fullname, kDNSServiceMaxDomainName);
- get_string(&data, end, target, kDNSServiceMaxDomainName);
- if (!data || data + 2 > end) goto fail;
-
- port.b[0] = *data++;
- port.b[1] = *data++;
- txtlen = get_uint16(&data, end);
- txtrecord = (unsigned char *)get_rdata(&data, end, txtlen);
-
- if (!data) goto fail;
- ((DNSServiceResolveReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, fullname, target, port.s, txtlen, txtrecord, sdr->AppContext);
- return;
- // MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
-fail:
- syslog(LOG_WARNING, "dnssd_clientstub handle_resolve_response: error reading result from daemon");
-}
-
-#if APPLE_OSX_mDNSResponder
-
-static int32_t libSystemVersion = 0;
-
-// Return true if the application linked against a version of libsystem where P2P
-// interfaces were included by default when using kDNSServiceInterfaceIndexAny.
-// Using 160.0.0 == 0xa00000 as the version threshold.
-static int includeP2PWithIndexAny()
-{
- if (libSystemVersion == 0)
- libSystemVersion = NSVersionOfLinkTimeLibrary("System");
-
- if (libSystemVersion < 0xa00000)
- return 1;
- else
- return 0;
-}
-
-#else // APPLE_OSX_mDNSResponder
-
-// always return false for non Apple platforms
-static int includeP2PWithIndexAny()
-{
- return 0;
-}
-
-#endif // APPLE_OSX_mDNSResponder
-
-DNSServiceErrorType DNSSD_API DNSServiceResolve
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *name,
- const char *regtype,
- const char *domain,
- DNSServiceResolveReply callBack,
- void *context
-)
-{
- char *ptr;
- size_t len;
- ipc_msg_hdr *hdr;
- DNSServiceErrorType err;
-
- if (!name || !regtype || !domain || !callBack) return kDNSServiceErr_BadParam;
-
- // Need a real InterfaceID for WakeOnResolve
- if ((flags & kDNSServiceFlagsWakeOnResolve) != 0 &&
- ((interfaceIndex == kDNSServiceInterfaceIndexAny) ||
- (interfaceIndex == kDNSServiceInterfaceIndexLocalOnly) ||
- (interfaceIndex == kDNSServiceInterfaceIndexUnicast) ||
- (interfaceIndex == kDNSServiceInterfaceIndexP2P)))
- {
- return kDNSServiceErr_BadParam;
- }
-
- if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
- flags |= kDNSServiceFlagsIncludeP2P;
-
- err = ConnectToServer(sdRef, flags, resolve_request, handle_resolve_response, callBack, context);
- if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
-
- // Calculate total message length
- len = sizeof(flags);
- len += sizeof(interfaceIndex);
- len += strlen(name) + 1;
- len += strlen(regtype) + 1;
- len += strlen(domain) + 1;
-
- hdr = create_hdr(resolve_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
- if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
-
- put_flags(flags, &ptr);
- put_uint32(interfaceIndex, &ptr);
- put_string(name, &ptr);
- put_string(regtype, &ptr);
- put_string(domain, &ptr);
-
- err = deliver_request(hdr, *sdRef); // Will free hdr for us
- if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
- return err;
-}
-
-static void handle_query_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
-{
- uint32_t ttl;
- char name[kDNSServiceMaxDomainName];
- uint16_t rrtype, rrclass, rdlen;
- const char *rdata;
-
- get_string(&data, end, name, kDNSServiceMaxDomainName);
- rrtype = get_uint16(&data, end);
- rrclass = get_uint16(&data, end);
- rdlen = get_uint16(&data, end);
- rdata = get_rdata(&data, end, rdlen);
- ttl = get_uint32(&data, end);
-
- if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_query_response: error reading result from daemon");
- else ((DNSServiceQueryRecordReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, name, rrtype, rrclass, rdlen, rdata, ttl, sdr->AppContext);
- // MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *name,
- uint16_t rrtype,
- uint16_t rrclass,
- DNSServiceQueryRecordReply callBack,
- void *context
-)
-{
- char *ptr;
- size_t len;
- ipc_msg_hdr *hdr;
- DNSServiceErrorType err;
-
- if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
- flags |= kDNSServiceFlagsIncludeP2P;
-
- err = ConnectToServer(sdRef, flags, query_request, handle_query_response, callBack, context);
- if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
-
- if (!name) name = "\0";
-
- // Calculate total message length
- len = sizeof(flags);
- len += sizeof(uint32_t); // interfaceIndex
- len += strlen(name) + 1;
- len += 2 * sizeof(uint16_t); // rrtype, rrclass
-
- hdr = create_hdr(query_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
- if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
-
- put_flags(flags, &ptr);
- put_uint32(interfaceIndex, &ptr);
- put_string(name, &ptr);
- put_uint16(rrtype, &ptr);
- put_uint16(rrclass, &ptr);
-
- err = deliver_request(hdr, *sdRef); // Will free hdr for us
- if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
- return err;
-}
-
-static void handle_addrinfo_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
-{
- char hostname[kDNSServiceMaxDomainName];
- uint16_t rrtype, rrclass, rdlen;
- const char *rdata;
- uint32_t ttl;
-
- get_string(&data, end, hostname, kDNSServiceMaxDomainName);
- rrtype = get_uint16(&data, end);
- rrclass = get_uint16(&data, end);
- rdlen = get_uint16(&data, end);
- rdata = get_rdata (&data, end, rdlen);
- ttl = get_uint32(&data, end);
-
- // We only generate client callbacks for A and AAAA results (including NXDOMAIN results for
- // those types, if the client has requested those with the kDNSServiceFlagsReturnIntermediates).
- // Other result types, specifically CNAME referrals, are not communicated to the client, because
- // the DNSServiceGetAddrInfoReply interface doesn't have any meaningful way to communiate CNAME referrals.
- if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_addrinfo_response: error reading result from daemon");
- else if (rrtype == kDNSServiceType_A || rrtype == kDNSServiceType_AAAA)
- {
- struct sockaddr_in sa4;
- struct sockaddr_in6 sa6;
- const struct sockaddr *const sa = (rrtype == kDNSServiceType_A) ? (struct sockaddr*)&sa4 : (struct sockaddr*)&sa6;
- if (rrtype == kDNSServiceType_A)
- {
- memset(&sa4, 0, sizeof(sa4));
- #ifndef NOT_HAVE_SA_LEN
- sa4.sin_len = sizeof(struct sockaddr_in);
- #endif
- sa4.sin_family = AF_INET;
- // sin_port = 0;
- if (!cbh->cb_err) memcpy(&sa4.sin_addr, rdata, rdlen);
- }
- else
- {
- memset(&sa6, 0, sizeof(sa6));
- #ifndef NOT_HAVE_SA_LEN
- sa6.sin6_len = sizeof(struct sockaddr_in6);
- #endif
- sa6.sin6_family = AF_INET6;
- // sin6_port = 0;
- // sin6_flowinfo = 0;
- // sin6_scope_id = 0;
- if (!cbh->cb_err)
- {
- memcpy(&sa6.sin6_addr, rdata, rdlen);
- if (IN6_IS_ADDR_LINKLOCAL(&sa6.sin6_addr)) sa6.sin6_scope_id = cbh->cb_interface;
- }
- }
- ((DNSServiceGetAddrInfoReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, hostname, sa, ttl, sdr->AppContext);
- // MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
- }
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceGetAddrInfo
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- uint32_t protocol,
- const char *hostname,
- DNSServiceGetAddrInfoReply callBack,
- void *context /* may be NULL */
-)
-{
- char *ptr;
- size_t len;
- ipc_msg_hdr *hdr;
- DNSServiceErrorType err;
-
- if (!hostname) return kDNSServiceErr_BadParam;
-
- err = ConnectToServer(sdRef, flags, addrinfo_request, handle_addrinfo_response, callBack, context);
- if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
-
- // Calculate total message length
- len = sizeof(flags);
- len += sizeof(uint32_t); // interfaceIndex
- len += sizeof(uint32_t); // protocol
- len += strlen(hostname) + 1;
-
- hdr = create_hdr(addrinfo_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
- if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
-
- put_flags(flags, &ptr);
- put_uint32(interfaceIndex, &ptr);
- put_uint32(protocol, &ptr);
- put_string(hostname, &ptr);
-
- err = deliver_request(hdr, *sdRef); // Will free hdr for us
- if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
- return err;
-}
-
-static void handle_browse_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
-{
- char replyName[256], replyType[kDNSServiceMaxDomainName], replyDomain[kDNSServiceMaxDomainName];
- get_string(&data, end, replyName, 256);
- get_string(&data, end, replyType, kDNSServiceMaxDomainName);
- get_string(&data, end, replyDomain, kDNSServiceMaxDomainName);
- if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_browse_response: error reading result from daemon");
- else ((DNSServiceBrowseReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, replyName, replyType, replyDomain, sdr->AppContext);
- // MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceBrowse
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *regtype,
- const char *domain,
- DNSServiceBrowseReply callBack,
- void *context
-)
-{
- char *ptr;
- size_t len;
- ipc_msg_hdr *hdr;
- DNSServiceErrorType err;
-
- if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
- flags |= kDNSServiceFlagsIncludeP2P;
-
- err = ConnectToServer(sdRef, flags, browse_request, handle_browse_response, callBack, context);
- if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
-
- if (!domain) domain = "";
- len = sizeof(flags);
- len += sizeof(interfaceIndex);
- len += strlen(regtype) + 1;
- len += strlen(domain) + 1;
-
- hdr = create_hdr(browse_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
- if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
-
- put_flags(flags, &ptr);
- put_uint32(interfaceIndex, &ptr);
- put_string(regtype, &ptr);
- put_string(domain, &ptr);
-
- err = deliver_request(hdr, *sdRef); // Will free hdr for us
- if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
- return err;
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain);
-DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser(DNSServiceFlags flags, const char *domain)
-{
- DNSServiceOp *tmp;
- char *ptr;
- size_t len = sizeof(flags) + strlen(domain) + 1;
- ipc_msg_hdr *hdr;
- DNSServiceErrorType err = ConnectToServer(&tmp, 0, setdomain_request, NULL, NULL, NULL);
- if (err) return err;
-
- hdr = create_hdr(setdomain_request, &len, &ptr, 0, tmp);
- if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }
-
- put_flags(flags, &ptr);
- put_string(domain, &ptr);
- err = deliver_request(hdr, tmp); // Will free hdr for us
- DNSServiceRefDeallocate(tmp);
- return err;
-}
-
-static void handle_regservice_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
-{
- char name[256], regtype[kDNSServiceMaxDomainName], domain[kDNSServiceMaxDomainName];
- get_string(&data, end, name, 256);
- get_string(&data, end, regtype, kDNSServiceMaxDomainName);
- get_string(&data, end, domain, kDNSServiceMaxDomainName);
- if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_regservice_response: error reading result from daemon");
- else ((DNSServiceRegisterReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_err, name, regtype, domain, sdr->AppContext);
- // MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceRegister
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *name,
- const char *regtype,
- const char *domain,
- const char *host,
- uint16_t PortInNetworkByteOrder,
- uint16_t txtLen,
- const void *txtRecord,
- DNSServiceRegisterReply callBack,
- void *context
-)
-{
- char *ptr;
- size_t len;
- ipc_msg_hdr *hdr;
- DNSServiceErrorType err;
- union { uint16_t s; u_char b[2]; } port;
-
- port.s = PortInNetworkByteOrder;
-
- if (!name) name = "";
- if (!regtype) return kDNSServiceErr_BadParam;
- if (!domain) domain = "";
- if (!host) host = "";
- if (!txtRecord) txtRecord = (void*)"";
-
- // No callback must have auto-rename
- if (!callBack && (flags & kDNSServiceFlagsNoAutoRename)) return kDNSServiceErr_BadParam;
-
- if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
- flags |= kDNSServiceFlagsIncludeP2P;
-
- err = ConnectToServer(sdRef, flags, reg_service_request, callBack ? handle_regservice_response : NULL, callBack, context);
- if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
-
- len = sizeof(DNSServiceFlags);
- len += sizeof(uint32_t); // interfaceIndex
- len += strlen(name) + strlen(regtype) + strlen(domain) + strlen(host) + 4;
- len += 2 * sizeof(uint16_t); // port, txtLen
- len += txtLen;
-
- hdr = create_hdr(reg_service_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
- if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
-
- // If it is going over a shared connection, then don't set the IPC_FLAGS_NOREPLY
- // as it affects all the operations over the shared connection. This is not
- // a normal case and hence receiving the response back from the daemon and
- // discarding it in ConnectionResponse is okay.
-
- if (!(flags & kDNSServiceFlagsShareConnection) && !callBack) hdr->ipc_flags |= IPC_FLAGS_NOREPLY;
-
- put_flags(flags, &ptr);
- put_uint32(interfaceIndex, &ptr);
- put_string(name, &ptr);
- put_string(regtype, &ptr);
- put_string(domain, &ptr);
- put_string(host, &ptr);
- *ptr++ = port.b[0];
- *ptr++ = port.b[1];
- put_uint16(txtLen, &ptr);
- put_rdata(txtLen, txtRecord, &ptr);
-
- err = deliver_request(hdr, *sdRef); // Will free hdr for us
- if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
- return err;
-}
-
-static void handle_enumeration_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
-{
- char domain[kDNSServiceMaxDomainName];
- get_string(&data, end, domain, kDNSServiceMaxDomainName);
- if (!data) syslog(LOG_WARNING, "dnssd_clientstub handle_enumeration_response: error reading result from daemon");
- else ((DNSServiceDomainEnumReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, domain, sdr->AppContext);
- // MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- DNSServiceDomainEnumReply callBack,
- void *context
-)
-{
- char *ptr;
- size_t len;
- ipc_msg_hdr *hdr;
- DNSServiceErrorType err;
-
- int f1 = (flags & kDNSServiceFlagsBrowseDomains) != 0;
- int f2 = (flags & kDNSServiceFlagsRegistrationDomains) != 0;
- if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
-
- err = ConnectToServer(sdRef, flags, enumeration_request, handle_enumeration_response, callBack, context);
- if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
-
- len = sizeof(DNSServiceFlags);
- len += sizeof(uint32_t);
-
- hdr = create_hdr(enumeration_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
- if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
-
- put_flags(flags, &ptr);
- put_uint32(interfaceIndex, &ptr);
-
- err = deliver_request(hdr, *sdRef); // Will free hdr for us
- if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
- return err;
-}
-
-static void ConnectionResponse(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *const data, const char *const end)
-{
- (void)data; // Unused
-
- //printf("ConnectionResponse got %d\n", cbh->ipc_hdr.op);
- if (cbh->ipc_hdr.op != reg_record_reply_op)
- {
- // When using kDNSServiceFlagsShareConnection, need to search the list of associated DNSServiceOps
- // to find the one this response is intended for, and then call through to its ProcessReply handler.
- // We start with our first subordinate DNSServiceRef -- don't want to accidentally match the parent DNSServiceRef.
- DNSServiceOp *op = sdr->next;
- while (op && (op->uid.u32[0] != cbh->ipc_hdr.client_context.u32[0] || op->uid.u32[1] != cbh->ipc_hdr.client_context.u32[1]))
- op = op->next;
- // Note: We may sometimes not find a matching DNSServiceOp, in the case where the client has
- // cancelled the subordinate DNSServiceOp, but there are still messages in the pipeline from the daemon
- if (op && op->ProcessReply) op->ProcessReply(op, cbh, data, end);
- // WARNING: Don't touch op or sdr after this -- client may have called DNSServiceRefDeallocate
- return;
- }
- else
- {
- DNSRecordRef rec;
- for (rec = sdr->rec; rec; rec = rec->recnext)
- {
- if (rec->uid.u32[0] == cbh->ipc_hdr.client_context.u32[0] && rec->uid.u32[1] == cbh->ipc_hdr.client_context.u32[1])
- break;
- }
- // The record might have been freed already and hence not an
- // error if the record is not found.
- if (!rec)
- {
- syslog(LOG_INFO, "ConnectionResponse: Record not found");
- return;
- }
- if (rec->sdr != sdr)
- {
- syslog(LOG_WARNING, "ConnectionResponse: Record sdr mismatch: rec %p sdr %p", rec->sdr, sdr);
- return;
- }
-
- if (sdr->op == connection_request)
- {
- rec->AppCallback(rec->sdr, rec, cbh->cb_flags, cbh->cb_err, rec->AppContext);
- }
- else
- {
- syslog(LOG_WARNING, "dnssd_clientstub ConnectionResponse: sdr->op != connection_request");
- rec->AppCallback(rec->sdr, rec, 0, kDNSServiceErr_Unknown, rec->AppContext);
- }
- // MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
- }
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef)
-{
- char *ptr;
- size_t len = 0;
- ipc_msg_hdr *hdr;
- DNSServiceErrorType err = ConnectToServer(sdRef, 0, connection_request, ConnectionResponse, NULL, NULL);
- if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
-
- hdr = create_hdr(connection_request, &len, &ptr, 0, *sdRef);
- if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
-
- err = deliver_request(hdr, *sdRef); // Will free hdr for us
- if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
- return err;
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
-(
- DNSServiceRef sdRef,
- DNSRecordRef *RecordRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl,
- DNSServiceRegisterRecordReply callBack,
- void *context
-)
-{
- char *ptr;
- size_t len;
- ipc_msg_hdr *hdr = NULL;
- DNSRecordRef rref = NULL;
- DNSRecord **p;
- int f1 = (flags & kDNSServiceFlagsShared) != 0;
- int f2 = (flags & kDNSServiceFlagsUnique) != 0;
- if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
-
- if ((interfaceIndex == kDNSServiceInterfaceIndexAny) && includeP2PWithIndexAny())
- flags |= kDNSServiceFlagsIncludeP2P;
-
- if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
-
- if (!DNSServiceRefValid(sdRef))
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
- return kDNSServiceErr_BadReference;
- }
-
- if (sdRef->op != connection_request)
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRegisterRecord called with non-DNSServiceCreateConnection DNSServiceRef %p %d", sdRef, sdRef->op);
- return kDNSServiceErr_BadReference;
- }
-
- *RecordRef = NULL;
-
- len = sizeof(DNSServiceFlags);
- len += 2 * sizeof(uint32_t); // interfaceIndex, ttl
- len += 3 * sizeof(uint16_t); // rrtype, rrclass, rdlen
- len += strlen(fullname) + 1;
- len += rdlen;
-
- // Bump up the uid. Normally for shared operations (kDNSServiceFlagsShareConnection), this
- // is done in ConnectToServer. For DNSServiceRegisterRecord, ConnectToServer has already
- // been called. As multiple DNSServiceRegisterRecords can be multiplexed over a single
- // connection, we need a way to demultiplex the response so that the callback corresponding
- // to the right DNSServiceRegisterRecord instance can be called. Use the same mechanism that
- // is used by kDNSServiceFlagsShareConnection. create_hdr copies the uid value to ipc
- // hdr->client_context which will be returned in the ipc response.
- if (++sdRef->uid.u32[0] == 0)
- ++sdRef->uid.u32[1];
- hdr = create_hdr(reg_record_request, &len, &ptr, 1, sdRef);
- if (!hdr) return kDNSServiceErr_NoMemory;
-
- put_flags(flags, &ptr);
- put_uint32(interfaceIndex, &ptr);
- put_string(fullname, &ptr);
- put_uint16(rrtype, &ptr);
- put_uint16(rrclass, &ptr);
- put_uint16(rdlen, &ptr);
- put_rdata(rdlen, rdata, &ptr);
- put_uint32(ttl, &ptr);
-
- rref = malloc(sizeof(DNSRecord));
- if (!rref) { free(hdr); return kDNSServiceErr_NoMemory; }
- rref->AppContext = context;
- rref->AppCallback = callBack;
- rref->record_index = sdRef->max_index++;
- rref->sdr = sdRef;
- rref->recnext = NULL;
- *RecordRef = rref;
- // Remember the uid that we are sending across so that we can match
- // when the response comes back.
- rref->uid = sdRef->uid;
- hdr->reg_index = rref->record_index;
-
- p = &(sdRef)->rec;
- while (*p) p = &(*p)->recnext;
- *p = rref;
-
- return deliver_request(hdr, sdRef); // Will free hdr for us
-}
-
-// sdRef returned by DNSServiceRegister()
-DNSServiceErrorType DNSSD_API DNSServiceAddRecord
-(
- DNSServiceRef sdRef,
- DNSRecordRef *RecordRef,
- DNSServiceFlags flags,
- uint16_t rrtype,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl
-)
-{
- ipc_msg_hdr *hdr;
- size_t len = 0;
- char *ptr;
- DNSRecordRef rref;
- DNSRecord **p;
-
- if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
- if (!RecordRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with NULL DNSRecordRef pointer"); return kDNSServiceErr_BadParam; }
- if (sdRef->op != reg_service_request)
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with non-DNSServiceRegister DNSServiceRef %p %d", sdRef, sdRef->op);
- return kDNSServiceErr_BadReference;
- }
-
- if (!DNSServiceRefValid(sdRef))
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceAddRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
- return kDNSServiceErr_BadReference;
- }
-
- *RecordRef = NULL;
-
- len += 2 * sizeof(uint16_t); // rrtype, rdlen
- len += rdlen;
- len += sizeof(uint32_t);
- len += sizeof(DNSServiceFlags);
-
- hdr = create_hdr(add_record_request, &len, &ptr, 1, sdRef);
- if (!hdr) return kDNSServiceErr_NoMemory;
- put_flags(flags, &ptr);
- put_uint16(rrtype, &ptr);
- put_uint16(rdlen, &ptr);
- put_rdata(rdlen, rdata, &ptr);
- put_uint32(ttl, &ptr);
-
- rref = malloc(sizeof(DNSRecord));
- if (!rref) { free(hdr); return kDNSServiceErr_NoMemory; }
- rref->AppContext = NULL;
- rref->AppCallback = NULL;
- rref->record_index = sdRef->max_index++;
- rref->sdr = sdRef;
- rref->recnext = NULL;
- *RecordRef = rref;
- hdr->reg_index = rref->record_index;
-
- p = &(sdRef)->rec;
- while (*p) p = &(*p)->recnext;
- *p = rref;
-
- return deliver_request(hdr, sdRef); // Will free hdr for us
-}
-
-// DNSRecordRef returned by DNSServiceRegisterRecord or DNSServiceAddRecord
-DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
-(
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef,
- DNSServiceFlags flags,
- uint16_t rdlen,
- const void *rdata,
- uint32_t ttl
-)
-{
- ipc_msg_hdr *hdr;
- size_t len = 0;
- char *ptr;
-
- if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceUpdateRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
-
- if (!DNSServiceRefValid(sdRef))
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceUpdateRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
- return kDNSServiceErr_BadReference;
- }
-
- // Note: RecordRef is allowed to be NULL
-
- len += sizeof(uint16_t);
- len += rdlen;
- len += sizeof(uint32_t);
- len += sizeof(DNSServiceFlags);
-
- hdr = create_hdr(update_record_request, &len, &ptr, 1, sdRef);
- if (!hdr) return kDNSServiceErr_NoMemory;
- hdr->reg_index = RecordRef ? RecordRef->record_index : TXT_RECORD_INDEX;
- put_flags(flags, &ptr);
- put_uint16(rdlen, &ptr);
- put_rdata(rdlen, rdata, &ptr);
- put_uint32(ttl, &ptr);
- return deliver_request(hdr, sdRef); // Will free hdr for us
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
-(
- DNSServiceRef sdRef,
- DNSRecordRef RecordRef,
- DNSServiceFlags flags
-)
-{
- ipc_msg_hdr *hdr;
- size_t len = 0;
- char *ptr;
- DNSServiceErrorType err;
-
- if (!sdRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with NULL DNSServiceRef"); return kDNSServiceErr_BadParam; }
- if (!RecordRef) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with NULL DNSRecordRef"); return kDNSServiceErr_BadParam; }
- if (!sdRef->max_index) { syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with bad DNSServiceRef"); return kDNSServiceErr_BadReference; }
-
- if (!DNSServiceRefValid(sdRef))
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceRemoveRecord called with invalid DNSServiceRef %p %08X %08X", sdRef, sdRef->sockfd, sdRef->validator);
- return kDNSServiceErr_BadReference;
- }
-
- len += sizeof(flags);
- hdr = create_hdr(remove_record_request, &len, &ptr, 1, sdRef);
- if (!hdr) return kDNSServiceErr_NoMemory;
- hdr->reg_index = RecordRef->record_index;
- put_flags(flags, &ptr);
- err = deliver_request(hdr, sdRef); // Will free hdr for us
- if (!err)
- {
- // This RecordRef could have been allocated in DNSServiceRegisterRecord or DNSServiceAddRecord.
- // If so, unlink from the list before freeing
- DNSRecord **p = &sdRef->rec;
- while (*p && *p != RecordRef) p = &(*p)->recnext;
- if (*p) *p = RecordRef->recnext;
- free(RecordRef);
- }
- return err;
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceReconfirmRecord
-(
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- const char *fullname,
- uint16_t rrtype,
- uint16_t rrclass,
- uint16_t rdlen,
- const void *rdata
-)
-{
- char *ptr;
- size_t len;
- ipc_msg_hdr *hdr;
- DNSServiceOp *tmp;
-
- DNSServiceErrorType err = ConnectToServer(&tmp, flags, reconfirm_record_request, NULL, NULL, NULL);
- if (err) return err;
-
- len = sizeof(DNSServiceFlags);
- len += sizeof(uint32_t);
- len += strlen(fullname) + 1;
- len += 3 * sizeof(uint16_t);
- len += rdlen;
- hdr = create_hdr(reconfirm_record_request, &len, &ptr, 0, tmp);
- if (!hdr) { DNSServiceRefDeallocate(tmp); return kDNSServiceErr_NoMemory; }
-
- put_flags(flags, &ptr);
- put_uint32(interfaceIndex, &ptr);
- put_string(fullname, &ptr);
- put_uint16(rrtype, &ptr);
- put_uint16(rrclass, &ptr);
- put_uint16(rdlen, &ptr);
- put_rdata(rdlen, rdata, &ptr);
-
- err = deliver_request(hdr, tmp); // Will free hdr for us
- DNSServiceRefDeallocate(tmp);
- return err;
-}
-
-static void handle_port_mapping_response(DNSServiceOp *const sdr, const CallbackHeader *const cbh, const char *data, const char *const end)
-{
- union { uint32_t l; u_char b[4]; } addr;
- uint8_t protocol;
- union { uint16_t s; u_char b[2]; } internalPort;
- union { uint16_t s; u_char b[2]; } externalPort;
- uint32_t ttl;
-
- if (!data || data + 13 > end) goto fail;
-
- addr.b[0] = *data++;
- addr.b[1] = *data++;
- addr.b[2] = *data++;
- addr.b[3] = *data++;
- protocol = *data++;
- internalPort.b[0] = *data++;
- internalPort.b[1] = *data++;
- externalPort.b[0] = *data++;
- externalPort.b[1] = *data++;
- ttl = get_uint32(&data, end);
- if (!data) goto fail;
-
- ((DNSServiceNATPortMappingReply)sdr->AppCallback)(sdr, cbh->cb_flags, cbh->cb_interface, cbh->cb_err, addr.l, protocol, internalPort.s, externalPort.s, ttl, sdr->AppContext);
- return;
- // MUST NOT touch sdr after invoking AppCallback -- client is allowed to dispose it from within callback function
-
- fail :
- syslog(LOG_WARNING, "dnssd_clientstub handle_port_mapping_response: error reading result from daemon");
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceNATPortMappingCreate
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- uint32_t interfaceIndex,
- uint32_t protocol, /* TCP and/or UDP */
- uint16_t internalPortInNetworkByteOrder,
- uint16_t externalPortInNetworkByteOrder,
- uint32_t ttl, /* time to live in seconds */
- DNSServiceNATPortMappingReply callBack,
- void *context /* may be NULL */
-)
-{
- char *ptr;
- size_t len;
- ipc_msg_hdr *hdr;
- union { uint16_t s; u_char b[2]; } internalPort;
- union { uint16_t s; u_char b[2]; } externalPort;
-
- DNSServiceErrorType err = ConnectToServer(sdRef, flags, port_mapping_request, handle_port_mapping_response, callBack, context);
- if (err) return err; // On error ConnectToServer leaves *sdRef set to NULL
-
- internalPort.s = internalPortInNetworkByteOrder;
- externalPort.s = externalPortInNetworkByteOrder;
-
- len = sizeof(flags);
- len += sizeof(interfaceIndex);
- len += sizeof(protocol);
- len += sizeof(internalPort);
- len += sizeof(externalPort);
- len += sizeof(ttl);
-
- hdr = create_hdr(port_mapping_request, &len, &ptr, (*sdRef)->primary ? 1 : 0, *sdRef);
- if (!hdr) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; return kDNSServiceErr_NoMemory; }
-
- put_flags(flags, &ptr);
- put_uint32(interfaceIndex, &ptr);
- put_uint32(protocol, &ptr);
- *ptr++ = internalPort.b[0];
- *ptr++ = internalPort.b[1];
- *ptr++ = externalPort.b[0];
- *ptr++ = externalPort.b[1];
- put_uint32(ttl, &ptr);
-
- err = deliver_request(hdr, *sdRef); // Will free hdr for us
- if (err) { DNSServiceRefDeallocate(*sdRef); *sdRef = NULL; }
- return err;
-}
-
-#if _DNS_SD_LIBDISPATCH
-DNSServiceErrorType DNSSD_API DNSServiceSetDispatchQueue
-(
- DNSServiceRef service,
- dispatch_queue_t queue
-)
-{
- dnssd_sock_t dnssd_fd = DNSServiceRefSockFD(service);
- if (dnssd_fd == dnssd_InvalidSocket) return kDNSServiceErr_BadParam;
- if (!queue)
- {
- syslog(LOG_WARNING, "dnssd_clientstub: DNSServiceSetDispatchQueue dispatch queue NULL");
- return kDNSServiceErr_BadParam;
- }
- if (service->disp_queue)
- {
- syslog(LOG_WARNING, "dnssd_clientstub DNSServiceSetDispatchQueue dispatch queue set already");
- return kDNSServiceErr_BadParam;
- }
- if (service->disp_source)
- {
- syslog(LOG_WARNING, "DNSServiceSetDispatchQueue dispatch source set already");
- return kDNSServiceErr_BadParam;
- }
- service->disp_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, dnssd_fd, 0, queue);
- if (!service->disp_source)
- {
- syslog(LOG_WARNING, "DNSServiceSetDispatchQueue dispatch_source_create failed");
- return kDNSServiceErr_NoMemory;
- }
- service->disp_queue = queue;
- dispatch_source_set_event_handler(service->disp_source, ^{DNSServiceProcessResult(service);});
- dispatch_source_set_cancel_handler(service->disp_source, ^{dnssd_close(dnssd_fd);});
- dispatch_resume(service->disp_source);
- return kDNSServiceErr_NoError;
-}
-#endif // _DNS_SD_LIBDISPATCH
-
-#if !defined(_WIN32)
-
-static void DNSSD_API SleepKeepaliveCallback(DNSServiceRef sdRef, DNSRecordRef rec, const DNSServiceFlags flags,
- DNSServiceErrorType errorCode, void *context)
-{
- SleepKAContext *ka = (SleepKAContext *)context;
- (void)rec; // Unused
- (void)flags; // Unused
-
- if (sdRef->kacontext != context)
- syslog(LOG_WARNING, "SleepKeepaliveCallback context mismatch");
-
- if (ka->AppCallback)
- ((DNSServiceSleepKeepaliveReply)ka->AppCallback)(sdRef, errorCode, ka->AppContext);
-}
-
-DNSServiceErrorType DNSSD_API DNSServiceSleepKeepalive
-(
- DNSServiceRef *sdRef,
- DNSServiceFlags flags,
- int fd,
- unsigned int timeout,
- DNSServiceSleepKeepaliveReply callBack,
- void *context
-)
-{
- char source_str[INET6_ADDRSTRLEN];
- char target_str[INET6_ADDRSTRLEN];
- struct sockaddr_storage lss;
- struct sockaddr_storage rss;
- socklen_t len1, len2;
- unsigned int len, proxyreclen;
- char buf[256];
- DNSServiceErrorType err;
- DNSRecordRef record = NULL;
- char name[10];
- char recname[128];
- SleepKAContext *ka;
- unsigned int i, unique;
-
-
- (void) flags; //unused
- if (!timeout) return kDNSServiceErr_BadParam;
-
-
- len1 = sizeof(lss);
- if (getsockname(fd, (struct sockaddr *)&lss, &len1) < 0)
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive: getsockname %d\n", errno);
- return kDNSServiceErr_BadParam;
- }
-
- len2 = sizeof(rss);
- if (getpeername(fd, (struct sockaddr *)&rss, &len2) < 0)
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive: getpeername %d\n", errno);
- return kDNSServiceErr_BadParam;
- }
-
- if (len1 != len2)
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive local/remote info not same");
- return kDNSServiceErr_Unknown;
- }
-
- unique = 0;
- if (lss.ss_family == AF_INET)
- {
- struct sockaddr_in *sl = (struct sockaddr_in *)&lss;
- struct sockaddr_in *sr = (struct sockaddr_in *)&rss;
- unsigned char *ptr = (unsigned char *)&sl->sin_addr;
-
- if (!inet_ntop(AF_INET, (const void *)&sr->sin_addr, target_str, sizeof (target_str)))
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive remote info failed %d", errno);
- return kDNSServiceErr_Unknown;
- }
- if (!inet_ntop(AF_INET, (const void *)&sl->sin_addr, source_str, sizeof (source_str)))
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive local info failed %d", errno);
- return kDNSServiceErr_Unknown;
- }
- // Sum of all bytes in the local address and port should result in a unique
- // number in the local network
- for (i = 0; i < sizeof(struct in_addr); i++)
- unique += ptr[i];
- unique += sl->sin_port;
- len = snprintf(buf+1, sizeof(buf) - 1, "t=%u h=%s d=%s l=%u r=%u", timeout, source_str, target_str, ntohs(sl->sin_port), ntohs(sr->sin_port));
- }
- else
- {
- struct sockaddr_in6 *sl6 = (struct sockaddr_in6 *)&lss;
- struct sockaddr_in6 *sr6 = (struct sockaddr_in6 *)&rss;
- unsigned char *ptr = (unsigned char *)&sl6->sin6_addr;
-
- if (!inet_ntop(AF_INET6, (const void *)&sr6->sin6_addr, target_str, sizeof (target_str)))
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive remote6 info failed %d", errno);
- return kDNSServiceErr_Unknown;
- }
- if (!inet_ntop(AF_INET6, (const void *)&sl6->sin6_addr, source_str, sizeof (source_str)))
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive local6 info failed %d", errno);
- return kDNSServiceErr_Unknown;
- }
- for (i = 0; i < sizeof(struct in6_addr); i++)
- unique += ptr[i];
- unique += sl6->sin6_port;
- len = snprintf(buf+1, sizeof(buf) - 1, "t=%u H=%s D=%s l=%u r=%u", timeout, source_str, target_str, ntohs(sl6->sin6_port), ntohs(sr6->sin6_port));
- }
-
- if (len >= (sizeof(buf) - 1))
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive could not fit local/remote info");
- return kDNSServiceErr_Unknown;
- }
- // Include the NULL byte also in the first byte. The total length of the record includes the
- // first byte also.
- buf[0] = len + 1;
- proxyreclen = len + 2;
-
- len = snprintf(name, sizeof(name), "%u", unique);
- if (len >= sizeof(name))
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive could not fit unique");
- return kDNSServiceErr_Unknown;
- }
-
- len = snprintf(recname, sizeof(recname), "%s.%s", name, "_keepalive._dns-sd._udp.local");
- if (len >= sizeof(recname))
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive could not fit name");
- return kDNSServiceErr_Unknown;
- }
-
- ka = malloc(sizeof(SleepKAContext));
- if (!ka) return kDNSServiceErr_NoMemory;
- ka->AppCallback = callBack;
- ka->AppContext = context;
-
- err = DNSServiceCreateConnection(sdRef);
- if (err)
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive cannot create connection");
- free(ka);
- return err;
- }
-
- // we don't care about the "record". When sdRef gets deallocated later, it will be freed too
- err = DNSServiceRegisterRecord(*sdRef, &record, kDNSServiceFlagsUnique, 0, recname,
- kDNSServiceType_NULL, kDNSServiceClass_IN, proxyreclen, buf, kDNSServiceInterfaceIndexAny, SleepKeepaliveCallback, ka);
- if (err)
- {
- syslog(LOG_WARNING, "DNSServiceSleepKeepalive cannot create connection");
- free(ka);
- return err;
- }
- (*sdRef)->kacontext = ka;
- return kDNSServiceErr_NoError;
-}
-#endif
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.c b/sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.c
deleted file mode 100644
index a538f4709001..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "dnssd_ipc.h"
-
-#if defined(_WIN32)
-
-char *win32_strerror(int inErrorCode)
-{
- static char buffer[1024];
- DWORD n;
- memset(buffer, 0, sizeof(buffer));
- n = FormatMessageA(
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- (DWORD) inErrorCode,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- buffer,
- sizeof(buffer),
- NULL);
- if (n > 0)
- {
- // Remove any trailing CR's or LF's since some messages have them.
- while ((n > 0) && isspace(((unsigned char *) buffer)[n - 1]))
- buffer[--n] = '\0';
- }
- return buffer;
-}
-
-#endif
-
-void put_uint32(const uint32_t l, char **ptr)
-{
- (*ptr)[0] = (char)((l >> 24) & 0xFF);
- (*ptr)[1] = (char)((l >> 16) & 0xFF);
- (*ptr)[2] = (char)((l >> 8) & 0xFF);
- (*ptr)[3] = (char)((l ) & 0xFF);
- *ptr += sizeof(uint32_t);
-}
-
-uint32_t get_uint32(const char **ptr, const char *end)
-{
- if (!*ptr || *ptr + sizeof(uint32_t) > end)
- {
- *ptr = NULL;
- return 0;
- }
- else
- {
- uint8_t *p = (uint8_t*) *ptr;
- *ptr += sizeof(uint32_t);
- return((uint32_t) ((uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | p[3]));
- }
-}
-
-void put_uint16(uint16_t s, char **ptr)
-{
- (*ptr)[0] = (char)((s >> 8) & 0xFF);
- (*ptr)[1] = (char)((s ) & 0xFF);
- *ptr += sizeof(uint16_t);
-}
-
-uint16_t get_uint16(const char **ptr, const char *end)
-{
- if (!*ptr || *ptr + sizeof(uint16_t) > end)
- {
- *ptr = NULL;
- return 0;
- }
- else
- {
- uint8_t *p = (uint8_t*) *ptr;
- *ptr += sizeof(uint16_t);
- return((uint16_t) ((uint16_t)p[0] << 8 | p[1]));
- }
-}
-
-int put_string(const char *str, char **ptr)
-{
- if (!str) str = "";
- strcpy(*ptr, str);
- *ptr += strlen(str) + 1;
- return 0;
-}
-
-int get_string(const char **ptr, const char *const end, char *buffer, int buflen)
-{
- if (!*ptr)
- {
- *buffer = 0;
- return(-1);
- }
- else
- {
- char *lim = buffer + buflen; // Calculate limit
- while (*ptr < end && buffer < lim)
- {
- char c = *buffer++ = *(*ptr)++;
- if (c == 0) return 0; // Success
- }
- if (buffer == lim) buffer--;
- *buffer = 0; // Failed, so terminate string,
- *ptr = NULL; // clear pointer,
- return(-1); // and return failure indication
- }
-}
-
-void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr)
-{
- memcpy(*ptr, rdata, rdlen);
- *ptr += rdlen;
-}
-
-const char *get_rdata(const char **ptr, const char *end, int rdlen)
-{
- if (!*ptr || *ptr + rdlen > end)
- {
- *ptr = NULL;
- return 0;
- }
- else
- {
- const char *rd = *ptr;
- *ptr += rdlen;
- return rd;
- }
-}
-
-void ConvertHeaderBytes(ipc_msg_hdr *hdr)
-{
- hdr->version = htonl(hdr->version);
- hdr->datalen = htonl(hdr->datalen);
- hdr->ipc_flags = htonl(hdr->ipc_flags);
- hdr->op = htonl(hdr->op );
- hdr->reg_index = htonl(hdr->reg_index);
-}
diff --git a/sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.h b/sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.h
deleted file mode 100644
index 568c5218dcb8..000000000000
--- a/sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef INCLUDED_SD_SOURCE_UI_REMOTECONTROL_MDNSRESPONDER_DNSSD_IPC_H
-#define INCLUDED_SD_SOURCE_UI_REMOTECONTROL_MDNSRESPONDER_DNSSD_IPC_H
-
-
-
-// Common cross platform services
-
-#if defined(WIN32)
-# include <winsock2.h>
-#endif
-
-#include "dns_sd.h"
-
-#if defined(WIN32)
-# define dnssd_InvalidSocket INVALID_SOCKET
-# define dnssd_SocketValid(s) ((s) != INVALID_SOCKET)
-# define dnssd_EWOULDBLOCK WSAEWOULDBLOCK
-# define dnssd_EINTR WSAEINTR
-# define dnssd_ECONNRESET WSAECONNRESET
-# define dnssd_sock_t SOCKET
-# define dnssd_socklen_t int
-# define dnssd_close(sock) closesocket(sock)
-# define dnssd_errno WSAGetLastError()
-# define dnssd_strerror(X) win32_strerror(X)
-# define ssize_t int
-# define getpid _getpid
-# define unlink _unlink
-extern char *win32_strerror(int inErrorCode);
-#else
-# include <sys/types.h>
-# include <unistd.h>
-# include <sys/un.h>
-# include <string.h>
-# include <stdio.h>
-# include <stdlib.h>
-# include <sys/stat.h>
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <arpa/inet.h>
-# define dnssd_InvalidSocket -1
-# define dnssd_SocketValid(s) ((s) >= 0)
-# define dnssd_EWOULDBLOCK EWOULDBLOCK
-# define dnssd_EINTR EINTR
-# define dnssd_ECONNRESET ECONNRESET
-# define dnssd_EPIPE EPIPE
-# define dnssd_sock_t int
-# define dnssd_socklen_t unsigned int
-# define dnssd_close(sock) close(sock)
-# define dnssd_errno errno
-# define dnssd_strerror(X) strerror(X)
-#endif
-
-#if defined(USE_TCP_LOOPBACK)
-# define AF_DNSSD AF_INET
-# define MDNS_TCP_SERVERADDR "127.0.0.1"
-# define MDNS_TCP_SERVERPORT 5354
-# define LISTENQ 5
-# define dnssd_sockaddr_t struct sockaddr_in
-#else
-# define AF_DNSSD AF_LOCAL
-# ifndef MDNS_UDS_SERVERPATH
-# define MDNS_UDS_SERVERPATH "/var/run/mDNSResponder"
-# endif
-# define LISTENQ 100
-// longest legal control path length
-# define MAX_CTLPATH 256
-# define dnssd_sockaddr_t struct sockaddr_un
-#endif
-
-// Compatibility workaround
-#ifndef AF_LOCAL
-#define AF_LOCAL AF_UNIX
-#endif
-
-// General UDS constants
-#define TXT_RECORD_INDEX ((uint32_t)(-1)) // record index for default text record
-
-// IPC data encoding constants and types
-#define VERSION 1
-#define IPC_FLAGS_NOREPLY 1 // set flag if no asynchronous replies are to be sent to client
-
-// Structure packing macro. If we're not using GNUC, it's not fatal. Most compilers naturally pack the on-the-wire
-// structures correctly anyway, so a plain "struct" is usually fine. In the event that structures are not packed
-// correctly, our compile-time assertion checks will catch it and prevent inadvertent generation of non-working code.
-#ifndef packedstruct
- #if ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 9)))
- #define packedstruct struct __attribute__((__packed__))
- #define packedunion union __attribute__((__packed__))
- #else
- #define packedstruct struct
- #define packedunion union
- #endif
-#endif
-
-typedef enum
-{
- request_op_none = 0, // No request yet received on this connection
- connection_request = 1, // connected socket via DNSServiceConnect()
- reg_record_request, // reg/remove record only valid for connected sockets
- remove_record_request,
- enumeration_request,
- reg_service_request,
- browse_request,
- resolve_request,
- query_request,
- reconfirm_record_request,
- add_record_request,
- update_record_request,
- setdomain_request, // Up to here is in Tiger and B4W 1.0.3
- getproperty_request, // New in B4W 1.0.4
- port_mapping_request, // New in Leopard and B4W 2.0
- addrinfo_request,
- send_bpf, // New in SL
- release_request,
-
- cancel_request = 63
-} request_op_t;
-
-typedef enum
-{
- enumeration_reply_op = 64,
- reg_service_reply_op,
- browse_reply_op,
- resolve_reply_op,
- query_reply_op,
- reg_record_reply_op, // Up to here is in Tiger and B4W 1.0.3
- getproperty_reply_op, // New in B4W 1.0.4
- port_mapping_reply_op, // New in Leopard and B4W 2.0
- addrinfo_reply_op
-} reply_op_t;
-
-#if defined(_WIN64)
-# pragma pack(push,4)
-#endif
-
-// Define context object big enough to hold a 64-bit pointer,
-// to accommodate 64-bit clients communicating with 32-bit daemon.
-// There's no reason for the daemon to ever be a 64-bit process, but its clients might be
-typedef packedunion
-{
- void *context;
- uint32_t u32[2];
-} client_context_t;
-
-typedef packedstruct
-{
- uint32_t version;
- uint32_t datalen;
- uint32_t ipc_flags;
- uint32_t op; // request_op_t or reply_op_t
- client_context_t client_context; // context passed from client, returned by server in corresponding reply
- uint32_t reg_index; // identifier for a record registered via DNSServiceRegisterRecord() on a
- // socket connected by DNSServiceCreateConnection(). Must be unique in the scope of the connection, such that and
- // index/socket pair uniquely identifies a record. (Used to select records for removal by DNSServiceRemoveRecord())
-} ipc_msg_hdr;
-
-#if defined(_WIN64)
-# pragma pack(pop)
-#endif
-
-// routines to write to and extract data from message buffers.
-// caller responsible for bounds checking.
-// ptr is the address of the pointer to the start of the field.
-// it is advanced to point to the next field, or the end of the message
-
-void put_uint32(const uint32_t l, char **ptr);
-uint32_t get_uint32(const char **ptr, const char *end);
-
-void put_uint16(uint16_t s, char **ptr);
-uint16_t get_uint16(const char **ptr, const char *end);
-
-#define put_flags put_uint32
-#define get_flags get_uint32
-
-#define get_error_code get_uint32
-
-int put_string(const char *str, char **ptr);
-int get_string(const char **ptr, const char *const end, char *buffer, int buflen);
-
-void put_rdata(const int rdlen, const unsigned char *rdata, char **ptr);
-const char *get_rdata(const char **ptr, const char *end, int rdlen); // return value is rdata pointed to by *ptr -
-// rdata is not copied from buffer.
-
-void ConvertHeaderBytes(ipc_msg_hdr *hdr);
-
-struct CompileTimeAssertionChecks_dnssd_ipc
-{
- // Check that the compiler generated our on-the-wire packet format structure definitions
- // properly packed, without adding padding bytes to align fields on 32-bit or 64-bit boundaries.
- char assert0[(sizeof(client_context_t) == 8) ? 1 : -1];
- char assert1[(sizeof(ipc_msg_hdr) == 28) ? 1 : -1];
-};
-
-#endif // INCLUDED_SD_SOURCE_UI_REMOTECONTROL_MDNSRESPONDER_DNSSD_IPC_H