1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate * Copyright 1998,2003 Sun Microsystems, Inc. All rights reserved.
24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate
27*7c478bd9Sstevel@tonic-gate /*
28*7c478bd9Sstevel@tonic-gate * This file contains native methods for the Java SLP implementation.
29*7c478bd9Sstevel@tonic-gate * So far this is just the syslog function.
30*7c478bd9Sstevel@tonic-gate *
31*7c478bd9Sstevel@tonic-gate * The file also contains two support functions, one for throwing exceptions
32*7c478bd9Sstevel@tonic-gate * given a class name, and one for correctly converting unicode Strings to C
33*7c478bd9Sstevel@tonic-gate * byte arrays.
34*7c478bd9Sstevel@tonic-gate */
35*7c478bd9Sstevel@tonic-gate
36*7c478bd9Sstevel@tonic-gate #include <malloc.h>
37*7c478bd9Sstevel@tonic-gate #include <jni.h>
38*7c478bd9Sstevel@tonic-gate #include <syslog.h>
39*7c478bd9Sstevel@tonic-gate
40*7c478bd9Sstevel@tonic-gate #define CLASS_JAVA_LANG_OUTOFMEMORYERROR "java/lang/OutOfMemoryError"
41*7c478bd9Sstevel@tonic-gate #define CLASS_JAVA_LANG_STRING "java/lang/String"
42*7c478bd9Sstevel@tonic-gate
43*7c478bd9Sstevel@tonic-gate #define METHOD_GETBYTES "getBytes"
44*7c478bd9Sstevel@tonic-gate
45*7c478bd9Sstevel@tonic-gate #define SIG_JAVA_LANG_STRING_GETBYTES "()[B"
46*7c478bd9Sstevel@tonic-gate
47*7c478bd9Sstevel@tonic-gate /*
48*7c478bd9Sstevel@tonic-gate * Given a class name of an exception and a message attempt to throw
49*7c478bd9Sstevel@tonic-gate * a new instance of the exception.
50*7c478bd9Sstevel@tonic-gate */
51*7c478bd9Sstevel@tonic-gate static void
JNU_ThrowByName(JNIEnv * env,const char * name,const char * msg)52*7c478bd9Sstevel@tonic-gate JNU_ThrowByName(JNIEnv *env, const char *name, const char *msg)
53*7c478bd9Sstevel@tonic-gate {
54*7c478bd9Sstevel@tonic-gate jclass class = (*env)->FindClass(env, name);
55*7c478bd9Sstevel@tonic-gate
56*7c478bd9Sstevel@tonic-gate /*
57*7c478bd9Sstevel@tonic-gate * If class is NULL FindClass() encountered a problem locating the
58*7c478bd9Sstevel@tonic-gate * desired class and has already called ThrowNew() with an
59*7c478bd9Sstevel@tonic-gate * exception.
60*7c478bd9Sstevel@tonic-gate */
61*7c478bd9Sstevel@tonic-gate if (class == NULL) {
62*7c478bd9Sstevel@tonic-gate return;
63*7c478bd9Sstevel@tonic-gate }
64*7c478bd9Sstevel@tonic-gate
65*7c478bd9Sstevel@tonic-gate (*env)->ThrowNew(env, class, msg);
66*7c478bd9Sstevel@tonic-gate (*env)->DeleteLocalRef(env, class);
67*7c478bd9Sstevel@tonic-gate }
68*7c478bd9Sstevel@tonic-gate
69*7c478bd9Sstevel@tonic-gate /*
70*7c478bd9Sstevel@tonic-gate * Convert a Java String into a native set of characters using the
71*7c478bd9Sstevel@tonic-gate * method String.getBytes(). This will ensure that the appropriate
72*7c478bd9Sstevel@tonic-gate * character set encoding will be used. This is necessary if the
73*7c478bd9Sstevel@tonic-gate * Java String uses unicode characters that cannot be easily
74*7c478bd9Sstevel@tonic-gate * encoded into native chars.
75*7c478bd9Sstevel@tonic-gate *
76*7c478bd9Sstevel@tonic-gate * The buffer returned must be released by using free() once it is
77*7c478bd9Sstevel@tonic-gate * finished with.
78*7c478bd9Sstevel@tonic-gate *
79*7c478bd9Sstevel@tonic-gate * This function returns NULL if an exception has been thrown during its
80*7c478bd9Sstevel@tonic-gate * execution.
81*7c478bd9Sstevel@tonic-gate */
82*7c478bd9Sstevel@tonic-gate static char
JNU_GetStringNativeChars(JNIEnv * env,jstring jstr)83*7c478bd9Sstevel@tonic-gate *JNU_GetStringNativeChars(JNIEnv *env, jstring jstr)
84*7c478bd9Sstevel@tonic-gate {
85*7c478bd9Sstevel@tonic-gate jclass class;
86*7c478bd9Sstevel@tonic-gate jmethodID method;
87*7c478bd9Sstevel@tonic-gate jint len;
88*7c478bd9Sstevel@tonic-gate jbyteArray bytes = NULL;
89*7c478bd9Sstevel@tonic-gate char *result = NULL;
90*7c478bd9Sstevel@tonic-gate
91*7c478bd9Sstevel@tonic-gate /*
92*7c478bd9Sstevel@tonic-gate * Need a local reference for (1) FindClass(), (2) the bytes and
93*7c478bd9Sstevel@tonic-gate * (3) the FindClass() in ThrowByName() if all goes wrong.
94*7c478bd9Sstevel@tonic-gate */
95*7c478bd9Sstevel@tonic-gate if ((*env)->EnsureLocalCapacity(env, 3) < 0) {
96*7c478bd9Sstevel@tonic-gate JNU_ThrowByName(
97*7c478bd9Sstevel@tonic-gate env,
98*7c478bd9Sstevel@tonic-gate CLASS_JAVA_LANG_OUTOFMEMORYERROR,
99*7c478bd9Sstevel@tonic-gate NULL);
100*7c478bd9Sstevel@tonic-gate
101*7c478bd9Sstevel@tonic-gate return (NULL);
102*7c478bd9Sstevel@tonic-gate }
103*7c478bd9Sstevel@tonic-gate
104*7c478bd9Sstevel@tonic-gate class = (*env)->FindClass(env, CLASS_JAVA_LANG_STRING);
105*7c478bd9Sstevel@tonic-gate
106*7c478bd9Sstevel@tonic-gate /*
107*7c478bd9Sstevel@tonic-gate * If class is NULL FindClass() encountered a problem locating the
108*7c478bd9Sstevel@tonic-gate * desired class and has already called ThrowNew() with an
109*7c478bd9Sstevel@tonic-gate * exception.
110*7c478bd9Sstevel@tonic-gate */
111*7c478bd9Sstevel@tonic-gate if (class == NULL) {
112*7c478bd9Sstevel@tonic-gate return (NULL);
113*7c478bd9Sstevel@tonic-gate }
114*7c478bd9Sstevel@tonic-gate
115*7c478bd9Sstevel@tonic-gate method = (*env)->GetMethodID(
116*7c478bd9Sstevel@tonic-gate env,
117*7c478bd9Sstevel@tonic-gate class,
118*7c478bd9Sstevel@tonic-gate METHOD_GETBYTES,
119*7c478bd9Sstevel@tonic-gate SIG_JAVA_LANG_STRING_GETBYTES);
120*7c478bd9Sstevel@tonic-gate
121*7c478bd9Sstevel@tonic-gate /*
122*7c478bd9Sstevel@tonic-gate * If method is NULL GetMethodID() encountered a problem
123*7c478bd9Sstevel@tonic-gate * locating the desired method and has already called
124*7c478bd9Sstevel@tonic-gate * ThrowNew() with an exception.
125*7c478bd9Sstevel@tonic-gate */
126*7c478bd9Sstevel@tonic-gate if (method != NULL) {
127*7c478bd9Sstevel@tonic-gate /*
128*7c478bd9Sstevel@tonic-gate * Call String.getBytes(), creating our temporary
129*7c478bd9Sstevel@tonic-gate * byte array
130*7c478bd9Sstevel@tonic-gate */
131*7c478bd9Sstevel@tonic-gate bytes = (*env)->CallObjectMethod(env, jstr, method);
132*7c478bd9Sstevel@tonic-gate
133*7c478bd9Sstevel@tonic-gate /* See if CallObjectMethod() threw an exception */
134*7c478bd9Sstevel@tonic-gate if ((*env)->ExceptionCheck(env) == JNI_FALSE) {
135*7c478bd9Sstevel@tonic-gate
136*7c478bd9Sstevel@tonic-gate len = (*env)->GetArrayLength(env, bytes);
137*7c478bd9Sstevel@tonic-gate
138*7c478bd9Sstevel@tonic-gate /*
139*7c478bd9Sstevel@tonic-gate * Allocate a buffer for the native characters,
140*7c478bd9Sstevel@tonic-gate * need an extra char for string terminator.
141*7c478bd9Sstevel@tonic-gate * Note: calloc will provide the terminating
142*7c478bd9Sstevel@tonic-gate * '\0' for us.
143*7c478bd9Sstevel@tonic-gate */
144*7c478bd9Sstevel@tonic-gate result = (char *)calloc(len + 1, sizeof (char));
145*7c478bd9Sstevel@tonic-gate
146*7c478bd9Sstevel@tonic-gate /*
147*7c478bd9Sstevel@tonic-gate * If allocation failed assume we are out of
148*7c478bd9Sstevel@tonic-gate * memory
149*7c478bd9Sstevel@tonic-gate */
150*7c478bd9Sstevel@tonic-gate if (result == NULL) {
151*7c478bd9Sstevel@tonic-gate JNU_ThrowByName(
152*7c478bd9Sstevel@tonic-gate env,
153*7c478bd9Sstevel@tonic-gate CLASS_JAVA_LANG_OUTOFMEMORYERROR,
154*7c478bd9Sstevel@tonic-gate NULL);
155*7c478bd9Sstevel@tonic-gate } else {
156*7c478bd9Sstevel@tonic-gate /*
157*7c478bd9Sstevel@tonic-gate * Copy the encoded bytes into the
158*7c478bd9Sstevel@tonic-gate * native string buffer
159*7c478bd9Sstevel@tonic-gate */
160*7c478bd9Sstevel@tonic-gate (*env)->GetByteArrayRegion(
161*7c478bd9Sstevel@tonic-gate env,
162*7c478bd9Sstevel@tonic-gate bytes,
163*7c478bd9Sstevel@tonic-gate 0,
164*7c478bd9Sstevel@tonic-gate len,
165*7c478bd9Sstevel@tonic-gate (jbyte *)result);
166*7c478bd9Sstevel@tonic-gate }
167*7c478bd9Sstevel@tonic-gate }
168*7c478bd9Sstevel@tonic-gate
169*7c478bd9Sstevel@tonic-gate if (bytes != NULL) {
170*7c478bd9Sstevel@tonic-gate (*env)->DeleteLocalRef(env, bytes);
171*7c478bd9Sstevel@tonic-gate }
172*7c478bd9Sstevel@tonic-gate }
173*7c478bd9Sstevel@tonic-gate
174*7c478bd9Sstevel@tonic-gate /* Clean up by deleting the local references */
175*7c478bd9Sstevel@tonic-gate (*env)->DeleteLocalRef(env, class);
176*7c478bd9Sstevel@tonic-gate
177*7c478bd9Sstevel@tonic-gate return (result);
178*7c478bd9Sstevel@tonic-gate }
179*7c478bd9Sstevel@tonic-gate
180*7c478bd9Sstevel@tonic-gate /*
181*7c478bd9Sstevel@tonic-gate * Class: com_sun_slp_Syslog
182*7c478bd9Sstevel@tonic-gate * Method: syslog
183*7c478bd9Sstevel@tonic-gate * Signature: (ILjava/lang/String;)V
184*7c478bd9Sstevel@tonic-gate */
185*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
186*7c478bd9Sstevel@tonic-gate JNIEXPORT
Java_com_sun_slp_Syslog_syslog(JNIEnv * env,jobject obj,jint priority,jstring jmsg)187*7c478bd9Sstevel@tonic-gate void JNICALL Java_com_sun_slp_Syslog_syslog(JNIEnv *env,
188*7c478bd9Sstevel@tonic-gate jobject obj,
189*7c478bd9Sstevel@tonic-gate jint priority,
190*7c478bd9Sstevel@tonic-gate jstring jmsg) {
191*7c478bd9Sstevel@tonic-gate
192*7c478bd9Sstevel@tonic-gate char *msg = JNU_GetStringNativeChars(env, jmsg);
193*7c478bd9Sstevel@tonic-gate
194*7c478bd9Sstevel@tonic-gate /*
195*7c478bd9Sstevel@tonic-gate * Check to see if the String conversion was successful,
196*7c478bd9Sstevel@tonic-gate * if it wasn't an exception will have already been thrown.
197*7c478bd9Sstevel@tonic-gate */
198*7c478bd9Sstevel@tonic-gate if (msg != NULL) {
199*7c478bd9Sstevel@tonic-gate openlog("slpd", LOG_PID, LOG_DAEMON);
200*7c478bd9Sstevel@tonic-gate syslog(priority, "%s", msg);
201*7c478bd9Sstevel@tonic-gate closelog();
202*7c478bd9Sstevel@tonic-gate
203*7c478bd9Sstevel@tonic-gate free(msg);
204*7c478bd9Sstevel@tonic-gate }
205*7c478bd9Sstevel@tonic-gate }
206