2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License, Version 1.0 only
2N/A * (the "License"). You may not use this file except in compliance
2N/A * with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A/*
2N/A * Copyright 1998,2003 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A#pragma ident "%Z%%M% %I% %E% SMI"
2N/A
2N/A/*
2N/A * This file contains native methods for the Java SLP implementation.
2N/A * So far this is just the syslog function.
2N/A *
2N/A * The file also contains two support functions, one for throwing exceptions
2N/A * given a class name, and one for correctly converting unicode Strings to C
2N/A * byte arrays.
2N/A */
2N/A
2N/A#include <malloc.h>
2N/A#include <jni.h>
2N/A#include <syslog.h>
2N/A
2N/A#define CLASS_JAVA_LANG_OUTOFMEMORYERROR "java/lang/OutOfMemoryError"
2N/A#define CLASS_JAVA_LANG_STRING "java/lang/String"
2N/A
2N/A#define METHOD_GETBYTES "getBytes"
2N/A
2N/A#define SIG_JAVA_LANG_STRING_GETBYTES "()[B"
2N/A
2N/A/*
2N/A * Given a class name of an exception and a message attempt to throw
2N/A * a new instance of the exception.
2N/A */
2N/Astatic void
2N/AJNU_ThrowByName(JNIEnv *env, const char *name, const char *msg)
2N/A{
2N/A jclass class = (*env)->FindClass(env, name);
2N/A
2N/A /*
2N/A * If class is NULL FindClass() encountered a problem locating the
2N/A * desired class and has already called ThrowNew() with an
2N/A * exception.
2N/A */
2N/A if (class == NULL) {
2N/A return;
2N/A }
2N/A
2N/A (*env)->ThrowNew(env, class, msg);
2N/A (*env)->DeleteLocalRef(env, class);
2N/A}
2N/A
2N/A/*
2N/A * Convert a Java String into a native set of characters using the
2N/A * method String.getBytes(). This will ensure that the appropriate
2N/A * character set encoding will be used. This is necessary if the
2N/A * Java String uses unicode characters that cannot be easily
2N/A * encoded into native chars.
2N/A *
2N/A * The buffer returned must be released by using free() once it is
2N/A * finished with.
2N/A *
2N/A * This function returns NULL if an exception has been thrown during its
2N/A * execution.
2N/A */
2N/Astatic char
2N/A*JNU_GetStringNativeChars(JNIEnv *env, jstring jstr)
2N/A{
2N/A jclass class;
2N/A jmethodID method;
2N/A jint len;
2N/A jbyteArray bytes = NULL;
2N/A char *result = NULL;
2N/A
2N/A /*
2N/A * Need a local reference for (1) FindClass(), (2) the bytes and
2N/A * (3) the FindClass() in ThrowByName() if all goes wrong.
2N/A */
2N/A if ((*env)->EnsureLocalCapacity(env, 3) < 0) {
2N/A JNU_ThrowByName(
2N/A env,
2N/A CLASS_JAVA_LANG_OUTOFMEMORYERROR,
2N/A NULL);
2N/A
2N/A return (NULL);
2N/A }
2N/A
2N/A class = (*env)->FindClass(env, CLASS_JAVA_LANG_STRING);
2N/A
2N/A /*
2N/A * If class is NULL FindClass() encountered a problem locating the
2N/A * desired class and has already called ThrowNew() with an
2N/A * exception.
2N/A */
2N/A if (class == NULL) {
2N/A return (NULL);
2N/A }
2N/A
2N/A method = (*env)->GetMethodID(
2N/A env,
2N/A class,
2N/A METHOD_GETBYTES,
2N/A SIG_JAVA_LANG_STRING_GETBYTES);
2N/A
2N/A /*
2N/A * If method is NULL GetMethodID() encountered a problem
2N/A * locating the desired method and has already called
2N/A * ThrowNew() with an exception.
2N/A */
2N/A if (method != NULL) {
2N/A /*
2N/A * Call String.getBytes(), creating our temporary
2N/A * byte array
2N/A */
2N/A bytes = (*env)->CallObjectMethod(env, jstr, method);
2N/A
2N/A /* See if CallObjectMethod() threw an exception */
2N/A if ((*env)->ExceptionCheck(env) == JNI_FALSE) {
2N/A
2N/A len = (*env)->GetArrayLength(env, bytes);
2N/A
2N/A /*
2N/A * Allocate a buffer for the native characters,
2N/A * need an extra char for string terminator.
2N/A * Note: calloc will provide the terminating
2N/A * '\0' for us.
2N/A */
2N/A result = (char *)calloc(len + 1, sizeof (char));
2N/A
2N/A /*
2N/A * If allocation failed assume we are out of
2N/A * memory
2N/A */
2N/A if (result == NULL) {
2N/A JNU_ThrowByName(
2N/A env,
2N/A CLASS_JAVA_LANG_OUTOFMEMORYERROR,
2N/A NULL);
2N/A } else {
2N/A /*
2N/A * Copy the encoded bytes into the
2N/A * native string buffer
2N/A */
2N/A (*env)->GetByteArrayRegion(
2N/A env,
2N/A bytes,
2N/A 0,
2N/A len,
2N/A (jbyte *)result);
2N/A }
2N/A }
2N/A
2N/A if (bytes != NULL) {
2N/A (*env)->DeleteLocalRef(env, bytes);
2N/A }
2N/A }
2N/A
2N/A /* Clean up by deleting the local references */
2N/A (*env)->DeleteLocalRef(env, class);
2N/A
2N/A return (result);
2N/A}
2N/A
2N/A/*
2N/A * Class: com_sun_slp_Syslog
2N/A * Method: syslog
2N/A * Signature: (ILjava/lang/String;)V
2N/A */
2N/A/* ARGSUSED */
2N/AJNIEXPORT
2N/Avoid JNICALL Java_com_sun_slp_Syslog_syslog(JNIEnv *env,
2N/A jobject obj,
2N/A jint priority,
2N/A jstring jmsg) {
2N/A
2N/A char *msg = JNU_GetStringNativeChars(env, jmsg);
2N/A
2N/A /*
2N/A * Check to see if the String conversion was successful,
2N/A * if it wasn't an exception will have already been thrown.
2N/A */
2N/A if (msg != NULL) {
2N/A openlog("slpd", LOG_PID, LOG_DAEMON);
2N/A syslog(priority, "%s", msg);
2N/A closelog();
2N/A
2N/A free(msg);
2N/A }
2N/A}