blob: 2417b4eec67b1ef81fa78b52d02d4411a0b4ccc2 [file] [log] [blame]
/*
* Copyright 2008, 2012 Oakland Software Incorporated and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Oakland Software Incorporated - initial API and implementation
* IBM Corporation - enabling JNI calls for gconfInit method (bug 232495)
* IBM Corporation - gnomeproxy cannot be built with latest versions of glib (bug 385047)
*/
#include <jni.h>
#include <glib.h>
#include <gconf/gconf-value.h>
#include <gconf/gconf-client.h>
#ifdef __linux__
#include <string.h>
#else
#include <strings.h>
#endif
#include "gnomeproxy.h"
static GConfClient *client= NULL;
static jclass proxyInfoClass;
static jclass stringClass;
static jmethodID proxyInfoConstructor;
static jmethodID toString;
static jmethodID hostMethod;
static jmethodID portMethod;
static jmethodID userMethod;
static jmethodID passwordMethod;
#define CHECK_NULL(X) { if ((X) == NULL) fprintf (stderr,"JNI error at line %d\n", __LINE__); }
/*
* Class: org_eclipse_core_internal_net_proxy_unix_UnixProxyProvider
* Method: gconfInit
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_org_eclipse_core_internal_net_proxy_unix_UnixProxyProvider_gconfInit(
JNIEnv *env, jclass clazz) {
g_type_init();
client = gconf_client_get_default();
jclass cls= NULL;
CHECK_NULL(cls = (*env)->FindClass(env, "org/eclipse/core/internal/net/ProxyData"));
proxyInfoClass = (*env)->NewGlobalRef(env, cls);
CHECK_NULL(cls = (*env)->FindClass(env, "java/lang/String"));
stringClass = (*env)->NewGlobalRef(env, cls);
CHECK_NULL(proxyInfoConstructor = (*env)->GetMethodID(env, proxyInfoClass, "<init>", "(Ljava/lang/String;)V"));
CHECK_NULL(toString = (*env)->GetMethodID(env, proxyInfoClass, "toString", "()Ljava/lang/String;"));
CHECK_NULL(hostMethod = (*env)->GetMethodID(env, proxyInfoClass, "setHost",
"(Ljava/lang/String;)V"));
CHECK_NULL(portMethod = (*env)->GetMethodID(env, proxyInfoClass, "setPort",
"(I)V"));
CHECK_NULL(userMethod = (*env)->GetMethodID(env, proxyInfoClass, "setUserid",
"(Ljava/lang/String;)V"));
CHECK_NULL(passwordMethod = (*env)->GetMethodID(env, proxyInfoClass, "setPassword",
"(Ljava/lang/String;)V"));
}
/*
* Class: org_eclipse_core_internal_net_UnixProxyProvider
* Method: getGConfProxyInfo
* Signature: ([Ljava/lang/String);
*/
JNIEXPORT jobject JNICALL Java_org_eclipse_core_internal_net_proxy_unix_UnixProxyProvider_getGConfProxyInfo(
JNIEnv *env, jclass clazz, jstring protocol) {
jboolean isCopy;
const char *cprotocol;
jobject proxyInfo= NULL;
if (client == NULL) {
Java_org_eclipse_core_internal_net_proxy_unix_UnixProxyProvider_gconfInit(env, clazz);
}
CHECK_NULL(proxyInfo = (*env)->NewObject(env, proxyInfoClass, proxyInfoConstructor, protocol));
cprotocol = (*env)->GetStringUTFChars(env, protocol, &isCopy);
if (cprotocol == NULL)
return NULL;
//printf("cprotocol: %s\n", cprotocol);
// use_same_proxy means we use the http value for everything
gboolean useSame = gconf_client_get_bool(client,
"/system/http_proxy/use_same_proxy", NULL);
if (strcasecmp(cprotocol, "http") == 0 || useSame) {
gboolean useProxy = gconf_client_get_bool(client,
"/system/http_proxy/use_http_proxy", NULL);
if (!useProxy) {
proxyInfo = NULL;
goto exit;
}
gchar *host = gconf_client_get_string(client,
"/system/http_proxy/host", NULL);
jobject jhost = (*env)->NewStringUTF(env, host);
(*env)->CallVoidMethod(env, proxyInfo, hostMethod, jhost);
gint port = gconf_client_get_int(client, "/system/http_proxy/port",
NULL);
(*env)->CallVoidMethod(env, proxyInfo, portMethod, port);
gboolean reqAuth = gconf_client_get_bool(client,
"/system/http_proxy/use_authentication", NULL);
if (reqAuth) {
gchar *user = gconf_client_get_string(client,
"/system/http_proxy/authentication_user", NULL);
jobject juser = (*env)->NewStringUTF(env, user);
(*env)->CallVoidMethod(env, proxyInfo, userMethod, juser);
gchar *password = gconf_client_get_string(client,
"/system/http_proxy/authentication_password", NULL);
jobject jpassword = (*env)->NewStringUTF(env, password);
(*env)->CallVoidMethod(env, proxyInfo, passwordMethod,
jpassword);
}
goto exit;
}
// Everything else applies only if the system proxy mode is manual
gchar *mode = gconf_client_get_string(client, "/system/proxy/mode", NULL);
if (strcasecmp(mode, "manual") != 0) {
proxyInfo = NULL;
goto exit;
}
char selector[100];
if (strcasecmp(cprotocol, "https") == 0) {
strcpy(selector, "/system/proxy/secure_");
} else if (strcasecmp(cprotocol, "socks") == 0) {
strcpy(selector, "/system/proxy/socks_");
} else if (strcasecmp(cprotocol, "ftp") == 0) {
strcpy(selector, "/system/proxy/ftp_");
} else {
proxyInfo = NULL;
goto exit;
}
char useSelector[100];
strcpy(useSelector, selector);
gchar *host = gconf_client_get_string(client, strcat(useSelector, "host"),
NULL);
jobject jhost = (*env)->NewStringUTF(env, host);
(*env)->CallVoidMethod(env, proxyInfo, hostMethod, jhost);
strcpy(useSelector, selector);
gint port = gconf_client_get_int(client, strcat(useSelector, "port"), NULL);
(*env)->CallVoidMethod(env, proxyInfo, portMethod, port);
exit: if (isCopy == JNI_TRUE)
(*env)->ReleaseStringUTFChars(env, protocol, cprotocol);
return proxyInfo;
}
typedef struct {
jobjectArray npHostArray;
JNIEnv *env;
int index;
} ListProcContext;
// user_data is the ListProcContext
void listProc(gpointer data, gpointer user_data) {
ListProcContext *lpc = user_data;
jobject jnpHost = (*lpc->env)->NewStringUTF(lpc->env, (char *)data);
(*lpc->env)->SetObjectArrayElement(lpc->env, lpc->npHostArray,
lpc->index++, jnpHost);
}
/*
* Class: org_eclipse_core_internal_net_UnixProxyProvider
* Method: getGConfNonProxyHosts
* Signature: ()[Ljava/lang/String;
*/
JNIEXPORT jobjectArray JNICALL Java_org_eclipse_core_internal_net_proxy_unix_UnixProxyProvider_getGConfNonProxyHosts(
JNIEnv *env, jclass clazz) {
if (client == NULL) {
Java_org_eclipse_core_internal_net_proxy_unix_UnixProxyProvider_gconfInit(env, clazz);
}
GSList *npHosts;
int size;
npHosts = gconf_client_get_list(client, "/system/http_proxy/ignore_hosts",
GCONF_VALUE_STRING, NULL);
size = g_slist_length(npHosts);
// TODO - I'm not sure this is really valid, it's from the JVM implementation
// of ProxySelector
if (size == 0) {
npHosts = gconf_client_get_list(client, "/system/proxy/no_proxy_for",
GCONF_VALUE_STRING, NULL);
}
size = g_slist_length(npHosts);
jobjectArray ret = (*env)->NewObjectArray(env, size, stringClass, NULL);
ListProcContext lpc;
lpc.env = env;
lpc.npHostArray = ret;
lpc.index = 0;
g_slist_foreach(npHosts, listProc, &lpc);
return ret;
}