| /* |
| * 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; |
| } |
| |