diff options
author | Michael Stahl <mstahl@redhat.com> | 2015-11-27 23:54:40 +0100 |
---|---|---|
committer | Michael Stahl <mstahl@redhat.com> | 2015-11-30 13:11:10 +0000 |
commit | 9ec0e6d9cbb0b61e5cf37917baee31f2af1a2897 (patch) | |
tree | 1509d2ccdb5b7aeacd4b6f28037e3d323ace1ba2 /sd/source/ui/remotecontrol | |
parent | 883321e141906f5dad47f0021a2fa8cadc3b9a01 (diff) |
sd: replace embedded mDNSResponder code with proper external tarball
The diff against the 379.37 release is 2500 lines, one of which
actually does anything at runtime (missing va_end()).
Change-Id: I1824e61fd4ac6c3ce28084913a2661134a03fd51
Reviewed-on: https://gerrit.libreoffice.org/20248
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Michael Stahl <mstahl@redhat.com>
Diffstat (limited to 'sd/source/ui/remotecontrol')
-rw-r--r-- | sd/source/ui/remotecontrol/WINNetworkService.cxx | 1 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/WINNetworkService.hxx | 2 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/CommonServices.h | 1213 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/DebugServices.c | 2978 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/DebugServices.h | 1576 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList.c | 319 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/GenLinkedList.h | 90 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/dllmain.c | 113 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/dns_sd.h | 2459 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientlib.c | 366 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/dnssd_clientstub.c | 2219 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.c | 161 | ||||
-rw-r--r-- | sd/source/ui/remotecontrol/mDNSResponder/dnssd_ipc.h | 222 |
13 files changed, 1 insertions, 11718 deletions
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 |