-/*
+/* -*- Mode: C; tab-width: 4 -*-
+ *
* Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * 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
*
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
+ * 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.
- *
- * @APPLE_LICENSE_HEADER_END@
Change History (most recent first):
$Log: JNISupport.c,v $
+Revision 1.21 2007/09/18 19:09:02 cheshire
+<rdar://problem/5489549> mDNSResponderHelper (and other binaries) missing SCCS version strings
+
+Revision 1.20 2007/03/13 01:41:46 cheshire
+Fixed compile warnings when building 32-bit
+
+Revision 1.19 2007/03/13 00:28:03 vazquez
+<rdar://problem/4625928> Java: Rename exported symbols in libjdns_sd.jnilib
+
+Revision 1.18 2007/03/13 00:10:14 vazquez
+<rdar://problem/4455206> Java: 64 bit JNI patch
+
+Revision 1.17 2006/08/14 23:25:08 cheshire
+Re-licensed mDNSResponder daemon source code under Apache License, Version 2.0
+
+Revision 1.16 2006/07/14 02:35:47 cheshire
+Added (commented out) syslog debugging messages
+
+Revision 1.15 2006/06/27 19:34:43 cheshire
+<rdar://problem/4430023> txtRecord parameter of DNSServiceResolveReply() should be unsigned char *
+
+Revision 1.14 2006/06/20 23:03:35 rpantos
+<rdar://problem/3839132> Java needs to implement DNSServiceRegisterRecord equivalent
+
Revision 1.13 2005/10/26 01:52:24 cheshire
<rdar://problem/4316286> Race condition in Java code (doesn't work at all on Linux)
#include "DNSSD.java.h"
+//#include <syslog.h>
+
// convenience definition
#ifdef __GNUC__
#define _UNUSED __attribute__ ((unused))
#endif
enum {
- kInterfaceVersion = 1 // Must match version in .jar file
+ kInterfaceVersionOne = 1,
+ kInterfaceVersionCurrent // Must match version in .jar file
};
typedef struct OpContext OpContext;
jint callerVersion)
{
/* Ensure that caller & interface versions match. */
- if ( callerVersion != kInterfaceVersion)
+ if ( callerVersion != kInterfaceVersionCurrent)
return kDNSServiceErr_Incompatible;
#if AUTO_CALLBACKS
/* Deallocate the dns_sd service browser and set the Java object's fNativeContext field to 0. */
{
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
if ( contextField != 0)
{
- OpContext *pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, pThis, contextField);
+ OpContext *pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
if ( pContext != NULL)
{
// MUST clear fNativeContext first, BEFORE calling DNSServiceRefDeallocate()
- (*pEnv)->SetIntField( pEnv, pThis, contextField, 0);
+ (*pEnv)->SetLongField(pEnv, pThis, contextField, 0);
if ( pContext->ServiceRef != NULL)
DNSServiceRefDeallocate( pContext->ServiceRef);
// BlockForData() not supported with AUTO_CALLBACKS
#if !AUTO_CALLBACKS
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
if ( contextField != 0)
{
- OpContext *pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, pThis, contextField);
+ OpContext *pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
if ( pContext != NULL)
{
fd_set readFDs;
#if !AUTO_CALLBACKS // ProcessResults() not supported with AUTO_CALLBACKS
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
- OpContext *pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, pThis, contextField);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
+ OpContext *pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
DNSServiceErrorType err = kDNSServiceErr_BadState;
if ( pContext != NULL)
jint flags, jint ifIndex, jstring regType, jstring domain)
{
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
OpContext *pContext = NULL;
DNSServiceErrorType err = kDNSServiceErr_NoError;
err = DNSServiceBrowse( &pContext->ServiceRef, flags, ifIndex, regStr, domainStr, ServiceBrowseReply, pContext);
if ( err == kDNSServiceErr_NoError)
{
- (*pEnv)->SetIntField( pEnv, pThis, contextField, (jint) pContext);
+ (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
}
SafeReleaseUTFChars( pEnv, regType, regStr);
static void DNSSD_API ServiceResolveReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget,
- uint16_t port, uint16_t txtLen, const char *txtRecord, void *context)
+ uint16_t port, uint16_t txtLen, const unsigned char *txtRecord, void *context)
{
OpContext *pContext = (OpContext*) context;
jclass txtCls;
jint flags, jint ifIndex, jstring serviceName, jstring regType, jstring domain)
{
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
OpContext *pContext = NULL;
DNSServiceErrorType err = kDNSServiceErr_NoError;
servStr, regStr, domainStr, ServiceResolveReply, pContext);
if ( err == kDNSServiceErr_NoError)
{
- (*pEnv)->SetIntField( pEnv, pThis, contextField, (jint) pContext);
+ (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
}
SafeReleaseUTFChars( pEnv, serviceName, servStr);
jint ifIndex, jint flags, jstring serviceName, jstring regType,
jstring domain, jstring host, jint port, jbyteArray txtRecord)
{
+ //syslog(LOG_ERR, "BR");
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
OpContext *pContext = NULL;
DNSServiceErrorType err = kDNSServiceErr_NoError;
jbyte *pBytes;
jsize numBytes;
+ //syslog(LOG_ERR, "BR: contextField %d", contextField);
+
if ( contextField != 0)
pContext = NewContext( pEnv, pThis, "serviceRegistered",
"(Lcom/apple/dnssd/DNSSDRegistration;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
const char *domainStr = SafeGetUTFChars( pEnv, domain);
const char *hostStr = SafeGetUTFChars( pEnv, host);
+ //syslog(LOG_ERR, "BR: regStr %s", regStr);
+
// Since Java ints are defined to be big-endian, we de-canonicalize 'port' from a
// big-endian number into a 16-bit pattern here.
uint16_t portBits = port;
numBytes, pBytes, ServiceRegisterReply, pContext);
if ( err == kDNSServiceErr_NoError)
{
- (*pEnv)->SetIntField( pEnv, pThis, contextField, (jint) pContext);
+ (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
}
if ( pBytes != NULL)
jint flags, jint rrType, jbyteArray rData, jint ttl, jobject destObj)
{
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
jclass destCls = (*pEnv)->GetObjectClass( pEnv, destObj);
- jfieldID recField = (*pEnv)->GetFieldID( pEnv, destCls, "fRecord", "I");
+ jfieldID recField = (*pEnv)->GetFieldID( pEnv, destCls, "fRecord", "J");
OpContext *pContext = NULL;
DNSServiceErrorType err = kDNSServiceErr_NoError;
jbyte *pBytes;
DNSRecordRef recRef;
if ( contextField != 0)
- pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, pThis, contextField);
+ pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
if ( pContext == NULL || pContext->ServiceRef == NULL)
return kDNSServiceErr_BadParam;
err = DNSServiceAddRecord( pContext->ServiceRef, &recRef, flags, rrType, numBytes, pBytes, ttl);
if ( err == kDNSServiceErr_NoError)
{
- (*pEnv)->SetIntField( pEnv, destObj, recField, (jint) recRef);
+ (*pEnv)->SetLongField(pEnv, destObj, recField, (long) recRef);
}
if ( pBytes != NULL)
{
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
jfieldID ownerField = (*pEnv)->GetFieldID( pEnv, cls, "fOwner", "Lcom/apple/dnssd/AppleService;");
- jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "I");
+ jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "J");
OpContext *pContext = NULL;
DNSServiceErrorType err = kDNSServiceErr_NoError;
jbyte *pBytes;
{
jobject ownerObj = (*pEnv)->GetObjectField( pEnv, pThis, ownerField);
jclass ownerClass = (*pEnv)->GetObjectClass( pEnv, ownerObj);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "I");
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "J");
if ( contextField != 0)
- pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, ownerObj, contextField);
+ pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, ownerObj, contextField);
}
if ( recField != 0)
- recRef = (DNSRecordRef) (*pEnv)->GetIntField( pEnv, pThis, recField);
+ recRef = (DNSRecordRef) (long) (*pEnv)->GetLongField(pEnv, pThis, recField);
if ( pContext == NULL || pContext->ServiceRef == NULL)
return kDNSServiceErr_BadParam;
{
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
jfieldID ownerField = (*pEnv)->GetFieldID( pEnv, cls, "fOwner", "Lcom/apple/dnssd/AppleService;");
- jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "I");
+ jfieldID recField = (*pEnv)->GetFieldID( pEnv, cls, "fRecord", "J");
OpContext *pContext = NULL;
DNSServiceErrorType err = kDNSServiceErr_NoError;
DNSRecordRef recRef = NULL;
{
jobject ownerObj = (*pEnv)->GetObjectField( pEnv, pThis, ownerField);
jclass ownerClass = (*pEnv)->GetObjectClass( pEnv, ownerObj);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "I");
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, ownerClass, "fNativeContext", "J");
if ( contextField != 0)
- pContext = (OpContext*) (*pEnv)->GetIntField( pEnv, ownerObj, contextField);
+ pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, ownerObj, contextField);
}
if ( recField != 0)
- recRef = (DNSRecordRef) (*pEnv)->GetIntField( pEnv, pThis, recField);
+ recRef = (DNSRecordRef) (long) (*pEnv)->GetLongField(pEnv, pThis, recField);
if ( pContext == NULL || pContext->ServiceRef == NULL)
return kDNSServiceErr_BadParam;
}
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRecordRegistrar_CreateConnection( JNIEnv *pEnv, jobject pThis)
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
+ OpContext *pContext = NULL;
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+
+ if ( contextField != 0)
+ pContext = NewContext( pEnv, pThis, "recordRegistered", "(Lcom/apple/dnssd/DNSRecord;I)V");
+ else
+ err = kDNSServiceErr_BadParam;
+
+ if ( pContext != NULL)
+ {
+ err = DNSServiceCreateConnection( &pContext->ServiceRef);
+ if ( err == kDNSServiceErr_NoError)
+ {
+ (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
+ }
+ }
+ else
+ err = kDNSServiceErr_NoMemory;
+
+ return err;
+}
+
+struct RecordRegistrationRef
+{
+ OpContext *Context;
+ jobject RecordObj;
+};
+typedef struct RecordRegistrationRef RecordRegistrationRef;
+
+static void DNSSD_API RegisterRecordReply( DNSServiceRef sdRef _UNUSED,
+ DNSRecordRef recordRef _UNUSED, DNSServiceFlags flags,
+ DNSServiceErrorType errorCode, void *context)
+{
+ RecordRegistrationRef *regEnvelope = (RecordRegistrationRef*) context;
+ OpContext *pContext = regEnvelope->Context;
+
+ SetupCallbackState( &pContext->Env);
+
+ if ( pContext->ClientObj != NULL && pContext->Callback != NULL)
+ {
+ if ( errorCode == kDNSServiceErr_NoError)
+ {
+ (*pContext->Env)->CallVoidMethod( pContext->Env, pContext->ClientObj, pContext->Callback,
+ regEnvelope->RecordObj, flags);
+ }
+ else
+ ReportError( pContext->Env, pContext->ClientObj, pContext->JavaObj, errorCode);
+ }
+
+ (*pContext->Env)->DeleteWeakGlobalRef( pContext->Env, regEnvelope->RecordObj);
+ free( regEnvelope);
+
+ TeardownCallbackState();
+}
+
+JNIEXPORT jint JNICALL Java_com_apple_dnssd_AppleRecordRegistrar_RegisterRecord( JNIEnv *pEnv, jobject pThis,
+ jint flags, jint ifIndex, jstring fullname, jint rrType, jint rrClass,
+ jbyteArray rData, jint ttl, jobject destObj)
+{
+ jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
+ jclass destCls = (*pEnv)->GetObjectClass( pEnv, destObj);
+ jfieldID recField = (*pEnv)->GetFieldID( pEnv, destCls, "fRecord", "J");
+ const char *nameStr = SafeGetUTFChars( pEnv, fullname);
+ OpContext *pContext = NULL;
+ DNSServiceErrorType err = kDNSServiceErr_NoError;
+ jbyte *pBytes;
+ jsize numBytes;
+ DNSRecordRef recRef;
+ RecordRegistrationRef *regEnvelope;
+
+ if ( contextField != 0)
+ pContext = (OpContext*) (long) (*pEnv)->GetLongField(pEnv, pThis, contextField);
+ if ( pContext == NULL || pContext->ServiceRef == NULL || nameStr == NULL)
+ return kDNSServiceErr_BadParam;
+
+ regEnvelope = calloc( 1, sizeof *regEnvelope);
+ if ( regEnvelope == NULL)
+ return kDNSServiceErr_NoMemory;
+ regEnvelope->Context = pContext;
+ regEnvelope->RecordObj = (*pEnv)->NewWeakGlobalRef( pEnv, destObj); // must convert local ref to global to cache
+
+ pBytes = (*pEnv)->GetByteArrayElements( pEnv, rData, NULL);
+ numBytes = (*pEnv)->GetArrayLength( pEnv, rData);
+
+ err = DNSServiceRegisterRecord( pContext->ServiceRef, &recRef, flags, ifIndex,
+ nameStr, rrType, rrClass, numBytes, pBytes, ttl,
+ RegisterRecordReply, regEnvelope);
+
+ if ( err == kDNSServiceErr_NoError)
+ {
+ (*pEnv)->SetLongField(pEnv, destObj, recField, (long) recRef);
+ }
+ else
+ {
+ if ( regEnvelope->RecordObj != NULL)
+ (*pEnv)->DeleteWeakGlobalRef( pEnv, regEnvelope->RecordObj);
+ free( regEnvelope);
+ }
+
+ if ( pBytes != NULL)
+ (*pEnv)->ReleaseByteArrayElements( pEnv, rData, pBytes, 0);
+
+ SafeReleaseUTFChars( pEnv, fullname, nameStr);
+
+ return err;
+}
+
+
static void DNSSD_API ServiceQueryReply( DNSServiceRef sdRef _UNUSED, DNSServiceFlags flags, uint32_t interfaceIndex,
DNSServiceErrorType errorCode, const char *serviceName,
uint16_t rrtype, uint16_t rrclass, uint16_t rdlen,
jint flags, jint ifIndex, jstring serviceName, jint rrtype, jint rrclass)
{
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
OpContext *pContext = NULL;
DNSServiceErrorType err = kDNSServiceErr_NoError;
rrtype, rrclass, ServiceQueryReply, pContext);
if ( err == kDNSServiceErr_NoError)
{
- (*pEnv)->SetIntField( pEnv, pThis, contextField, (jint) pContext);
+ (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
}
SafeReleaseUTFChars( pEnv, serviceName, servStr);
jint flags, jint ifIndex)
{
jclass cls = (*pEnv)->GetObjectClass( pEnv, pThis);
- jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "I");
+ jfieldID contextField = (*pEnv)->GetFieldID( pEnv, cls, "fNativeContext", "J");
OpContext *pContext = NULL;
DNSServiceErrorType err = kDNSServiceErr_NoError;
DomainEnumReply, pContext);
if ( err == kDNSServiceErr_NoError)
{
- (*pEnv)->SetIntField( pEnv, pThis, contextField, (jint) pContext);
+ (*pEnv)->SetLongField(pEnv, pThis, contextField, (long) pContext);
}
}
else
{
char *p = LOCAL_ONLY_NAME, nameBuff[IF_NAMESIZE];
- if (ifIndex != kDNSServiceInterfaceIndexLocalOnly)
+ if (ifIndex != (jint) kDNSServiceInterfaceIndexLocalOnly)
p = if_indextoname( ifIndex, nameBuff );
return (*pEnv)->NewStringUTF( pEnv, p);
return ifIndex;
}
#endif
+
+
+// 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[] = "@(#) libjdns_sd " STRINGIFY(mDNSResponderVersion) " (" __DATE__ " " __TIME__ ")";