summaryrefslogtreecommitdiff
path: root/libproxy/modules
diff options
context:
space:
mode:
Diffstat (limited to 'libproxy/modules')
-rw-r--r--libproxy/modules/config_direct.cpp62
-rw-r--r--libproxy/modules/config_envvar.cpp101
-rw-r--r--libproxy/modules/config_file.cpp118
-rw-r--r--libproxy/modules/config_gnome.cpp411
-rw-r--r--libproxy/modules/config_kde4.cpp169
-rw-r--r--libproxy/modules/config_w32reg.cpp194
-rw-r--r--libproxy/modules/config_wpad.cpp51
-rw-r--r--libproxy/modules/ignore_domain.cpp101
-rw-r--r--libproxy/modules/ignore_ip.cpp320
-rw-r--r--libproxy/modules/network_networkmanager.cpp143
-rw-r--r--libproxy/modules/pacrunner_mozjs.cpp232
-rw-r--r--libproxy/modules/pacrunner_webkit.cpp213
-rw-r--r--libproxy/modules/pxgconf.cpp180
-rw-r--r--libproxy/modules/wpad_dns.cpp67
-rw-r--r--libproxy/modules/wpad_dnsdevolution.cpp199
-rw-r--r--libproxy/modules/xhasclient.cpp36
16 files changed, 1076 insertions, 1521 deletions
diff --git a/libproxy/modules/config_direct.cpp b/libproxy/modules/config_direct.cpp
deleted file mode 100644
index 446e7fb..0000000
--- a/libproxy/modules/config_direct.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-/*******************************************************************************
- * libproxy - A library for proxy configuration
- * Copyright (C) 2006 Nathaniel McCallum <nathaniel@natemccallum.com>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- ******************************************************************************/
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "../misc.hpp"
-#include "../modules.hpp"
-
-static char *
-_get_config(pxConfigModule *self, pxURL *url)
-{
- return px_strdup("direct://");
-}
-
-static char *
-_get_ignore(pxConfigModule *self, pxURL *url)
-{
- return px_strdup("");
-}
-
-static bool
-_get_credentials(pxConfigModule *self, pxURL *url, char **username, char **password)
-{
- return false;
-}
-
-static bool
-_set_credentials(pxConfigModule *self, pxURL *url, const char *username, const char *password)
-{
- return false;
-}
-
-static void *
-_constructor()
-{
- pxConfigModule *self = px_malloc0(sizeof(pxConfigModule));
- PX_CONFIG_MODULE_BUILD(self, PX_CONFIG_MODULE_CATEGORY_NONE, _get_config, _get_ignore, _get_credentials, _set_credentials);
- return self;
-}
-
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxConfigModule, _constructor, px_free);
-}
diff --git a/libproxy/modules/config_envvar.cpp b/libproxy/modules/config_envvar.cpp
index 315bd0c..b8620b5 100644
--- a/libproxy/modules/config_envvar.cpp
+++ b/libproxy/modules/config_envvar.cpp
@@ -17,60 +17,47 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-
-#include "../misc.hpp"
-#include "../modules.hpp"
-
-static char *
-_get_config(pxConfigModule *self, pxURL *url)
-{
- char *proxy = NULL;
-
- // If the URL is an ftp url, try to read the ftp proxy
- if (!strcmp(px_url_get_scheme(url), "ftp"))
- proxy = getenv("ftp_proxy");
-
- // If the URL is an https url, try to read the https proxy
- else if (!strcmp(px_url_get_scheme(url), "https"))
- proxy = getenv("https_proxy");
-
- // If the URL is not ftp or no ftp_proxy was found, get the http_proxy
- if (!proxy)
- proxy = getenv("http_proxy");
-
- return px_strdup(proxy);
-}
-
-static char *
-_get_ignore(pxConfigModule *self, pxURL *url)
-{
- return px_strdup(getenv("no_proxy"));
-}
-
-static bool
-_get_credentials(pxConfigModule *self, pxURL *url, char **username, char **password)
-{
- return false;
-}
-
-static bool
-_set_credentials(pxConfigModule *self, pxURL *url, const char *username, const char *password)
-{
- return false;
-}
-
-static void *
-_constructor()
-{
- pxConfigModule *self = (pxConfigModule *) px_malloc0(sizeof(pxConfigModule));
- PX_CONFIG_MODULE_BUILD(self, PX_CONFIG_MODULE_CATEGORY_NONE, _get_config, _get_ignore, _get_credentials, _set_credentials);
- return self;
-}
-
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxConfigModule, _constructor, px_free);
-}
+#include <cstdlib>
+
+#include "../module_types.hpp"
+using namespace com::googlecode::libproxy;
+
+class envvar_config_module : public config_module {
+public:
+ PX_MODULE_ID(NULL);
+ PX_MODULE_CONFIG_CATEGORY(config_module::CATEGORY_NONE);
+
+ url get_config(url url) throw (runtime_error) {
+ char *proxy = NULL;
+
+ // If the URL is an ftp url, try to read the ftp proxy
+ if (url.get_scheme() == "ftp") {
+ if (!(proxy = getenv("ftp_proxy")))
+ proxy = getenv("FTP_PROXY");
+ }
+
+ // If the URL is an https url, try to read the https proxy
+ if (url.get_scheme() == "https") {
+ if (!(proxy = getenv("https_proxy")))
+ proxy = getenv("HTTPS_PROXY");
+ }
+
+ // If the URL is not ftp or no ftp_proxy was found, get the http_proxy
+ if (!proxy) {
+ if (!(proxy = getenv("http_proxy")))
+ proxy = getenv("HTTP_PROXY");
+ }
+
+ if (!proxy)
+ throw runtime_error("Unable to read configuration");
+ return com::googlecode::libproxy::url(proxy);
+ }
+
+ string get_ignore(url dst) {
+ char *ignore = getenv("no_proxy");
+ ignore = ignore ? ignore : getenv("NO_PROXY");
+ return string(ignore ? ignore : "");
+ }
+};
+
+PX_MODULE_LOAD(config_module, envvar, true);
diff --git a/libproxy/modules/config_file.cpp b/libproxy/modules/config_file.cpp
index 39cd01f..bd5640a 100644
--- a/libproxy/modules/config_file.cpp
+++ b/libproxy/modules/config_file.cpp
@@ -17,98 +17,48 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-
-#include "../misc.hpp"
-#include "../modules.hpp"
#include "../config_file.hpp"
+#include "../module_types.hpp"
+using namespace com::googlecode::libproxy;
-typedef struct _pxFileConfigModule {
- PX_MODULE_SUBCLASS(pxConfigModule);
- char *filename;
- pxConfigFile *cf;
-} pxFileConfigModule;
-
-static void
-_destructor(void *s)
-{
- pxFileConfigModule *self = (pxFileConfigModule *) self;
-
- px_config_file_free(self->cf);
- px_free(self->filename);
- px_free(self);
-}
-
-static char *
-_get_config(pxConfigModule *ss, pxURL *url)
-{
- pxFileConfigModule *self = (pxFileConfigModule *) self;
-
- if (!self->cf)
- self->cf = px_config_file_new(self->filename);
- if (!self->cf)
- return NULL;
- return px_config_file_get_value(self->cf, PX_CONFIG_FILE_DEFAULT_SECTION, "proxy");
-}
-
-static char *
-_get_ignore(pxConfigModule *s, pxURL *url)
-{
- pxFileConfigModule *self = (pxFileConfigModule *) self;
-
- if (!self->cf)
- self->cf = px_config_file_new(self->filename);
- if (!self->cf)
- return NULL;
- return px_config_file_get_value(self->cf, PX_CONFIG_FILE_DEFAULT_SECTION, "ignore");
-}
+class system_file_config_module : public config_module {
+public:
+ PX_MODULE_ID("config_file_system");
+ PX_MODULE_CONFIG_CATEGORY(config_module::CATEGORY_SYSTEM);
-static bool
-_get_credentials(pxConfigModule *s, pxURL *proxy, char **username, char **password)
-{
- pxFileConfigModule *self = (pxFileConfigModule *) self;
-
- return false;
-}
+ system_file_config_module() {
+ this->cf.load(this->get_filename());
+ }
-static bool
-_set_credentials(pxConfigModule *s, pxURL *proxy, const char *username, const char *password)
-{
- pxFileConfigModule *self = (pxFileConfigModule *) self;
+ url get_config(url url) throw (runtime_error) {
+ if (this->cf.is_stale())
+ this->cf.load(this->get_filename());
+ return this->cf.get_value("proxy");
+ }
- return false;
-}
+ string get_ignore(url& url) {
+ if (this->cf.is_stale())
+ this->cf.load(this->get_filename());
+ return this->cf.get_value("ignore");
+ }
-static void *
-_system_constructor()
-{
- pxFileConfigModule *self = (pxFileConfigModule *) px_malloc0(sizeof(pxFileConfigModule));
- PX_CONFIG_MODULE_BUILD(self, PX_CONFIG_MODULE_CATEGORY_SYSTEM, _get_config, _get_ignore, _get_credentials, _set_credentials);
- self->filename = px_strdup(SYSCONFDIR "proxy.conf");
+protected:
+ virtual string get_filename() { return SYSCONFDIR "proxy.conf"; }
- return self;
-}
+private:
+ config_file cf;
+};
-static void *
-_user_constructor()
-{
- pxFileConfigModule *self = (pxFileConfigModule *) px_malloc0(sizeof(pxFileConfigModule));
- PX_CONFIG_MODULE_BUILD(self, PX_CONFIG_MODULE_CATEGORY_USER, _get_config, _get_ignore, _get_credentials, _set_credentials);
- self->filename = px_strcat(getenv("HOME"), "/", ".proxy.conf", NULL);
+class user_file_config_module : public system_file_config_module {
+public:
+ PX_MODULE_ID("config_file_user");
+ PX_MODULE_CONFIG_CATEGORY(config_module::CATEGORY_USER);
- if (!self->filename || !strcmp(self->filename, ""))
- {
- _destructor((void *) self);
- return NULL;
- }
- return self;
-}
+protected:
+ virtual string get_filename() { return string(getenv("HOME")) + string("/.proxy.conf"); }
+};
-bool
-px_module_load(pxModuleManager *self)
-{
- bool a = px_module_manager_register_module_with_name(self, pxConfigFile, "config_file_system", _system_constructor, _destructor);
- bool b = px_module_manager_register_module_with_name(self, pxConfigFile, "config_file_user", _user_constructor, _destructor);
- return (a || b);
+extern "C" bool px_module_load(module_manager& mm) {
+ bool success = mm.register_module<config_module>(new user_file_config_module);
+ return mm.register_module<config_module>(new system_file_config_module) || success;
}
diff --git a/libproxy/modules/config_gnome.cpp b/libproxy/modules/config_gnome.cpp
index 91907ae..3675924 100644
--- a/libproxy/modules/config_gnome.cpp
+++ b/libproxy/modules/config_gnome.cpp
@@ -17,261 +17,220 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-#include <time.h>
-
-#include "../misc.hpp"
-#include "../modules.hpp"
-#include "../strdict.hpp"
-#include "xhasclient.cpp"
-
-#define BUFFERSIZE 10240
-#define CACHETIME 5
-
-typedef struct _pxGConfConfigModule {
- PX_MODULE_SUBCLASS(pxConfigModule);
- FILE *pipe;
- pxStrDict *data;
- time_t last;
-} pxGConfConfigModule;
+#include <cstdio> // For fileno(), fread(), pclose(), popen(), sscanf()
+#include <sys/select.h> // For select(...)
+#include <fcntl.h> // For fcntl(...)
+#include "xhasclient.cpp" // For xhasclient(...)
-static const char *_all_keys[] = {
- "/system/proxy/mode", "/system/proxy/autoconfig_url",
- "/system/http_proxy/host", "/system/http_proxy/port",
- "/system/proxy/secure_host", "/system/proxy/secure_port",
- "/system/proxy/ftp_host", "/system/proxy/ftp_port",
- "/system/proxy/socks_host", "/system/proxy/socks_port",
- "/system/http_proxy/ignore_hosts",
- "/system/http_proxy/use_authentication",
- "/system/http_proxy/authentication_user",
- "/system/http_proxy/authentication_password", NULL
-};
+/*
+int popen2(const char *program, FILE **read, FILE **write) {
+ int wpipe[2];
+
+ if (!read || !write || !program || !*program)
+ return EINVAL;
+
+ *read = NULL;
+ *write = NULL;
+
+ if (pipe(wpipe) < 0)
+ return errno;
+
+ switch (pid = vfork()) {
+ case -1: // Error
+ close(wpipe[0]);
+ close(wpipe[1]);
+ return ASOIMWE;
+ case 0: // Child
+ close(wpipe[1]);
+ dup2(wpipe[0], STDIN_FILENO);
+ close(wpipe[0]);
-static FILE *
-_start_get_config()
-{
- char buffer[BUFFERSIZE] = "";
-
- // Build our command
- if (strlen(GCONFTOOLBIN " -g") + 1 > BUFFERSIZE)
- return NULL;
- strcpy(buffer, GCONFTOOLBIN " -g");
- for (int i=0 ; _all_keys[i] ; i++)
- {
- if (strlen(buffer) + strlen(_all_keys[i]) + 2 > BUFFERSIZE)
- return NULL;
- strcat(buffer, " ");
- strcat(buffer, _all_keys[i]);
- }
- if (strlen(buffer) + strlen(" 2>&1") + 1 > BUFFERSIZE)
- return NULL;
- strcat(buffer, " 2>&1");
- // Open our pipe
- return popen(buffer, "r");
-}
-static pxStrDict *
-_finish_get_config(FILE *pipe)
-{
- char buffer[BUFFERSIZE] = "";
- char **values = NULL;
- pxStrDict *kv = NULL;
-
- if (!pipe) return NULL;
-
- // Read the output and split it into its separate values (one per line)
- if (fread(buffer, sizeof(char), BUFFERSIZE, pipe) == 0) goto error;
- if (!(values = px_strsplit(buffer, "\n"))) goto error;
-
- // Build up our dictionary with the values
- kv = px_strdict_new((pxStrDictItemCallback) px_free);
- for (int i=0 ; _all_keys[i] ; i++)
- {
- if (!values[i])
- goto error;
- if (strchr(values[i], ' '))
- strcpy(values[i], "");
- if (!px_strdict_set(kv, _all_keys[i], px_strdup(values[i])))
- goto error;
+ execl(_PATH_BSHELL, "sh", "-c", program, (char *)NULL);
+ _exit(127);
+ // NOTREACHED
+ }
}
- // Cleanup
- px_strfreev(values);
- if (pclose(pipe) < 0)
- {
- px_strdict_free(kv);
- return NULL;
+ // Parent; assume fdopen can't fail.
+ if (*type == 'r') {
+ iop = fdopen(pdes[0], type);
+ (void)close(pdes[1]);
+ } else {
+ iop = fdopen(pdes[1], type);
+ (void)close(pdes[0]);
}
- return kv;
- error:
- pclose(pipe);
- px_strfreev(values);
- px_strdict_free(kv);
- return NULL;
-}
+ // Link into list of file descriptors.
+ cur->fp = iop;
+ cur->pid = pid;
+ cur->next = pidlist;
+ pidlist = cur;
-static void
-_destructor(void *s)
-{
- pxGConfConfigModule *self = (pxGConfConfigModule *) s;
+ return (iop);
+}*/
- if (self->pipe) pclose(self->pipe);
- px_strdict_free(self->data);
- px_free(self);
-}
+#include "../module_types.hpp"
+using namespace com::googlecode::libproxy;
-static char *
-_get_config(pxConfigModule *s, pxURL *url)
-{
- pxGConfConfigModule *self = (pxGConfConfigModule *) s;
-
- // Update our config if possible
- if (self->pipe)
- {
- pxStrDict *tmp = _finish_get_config(self->pipe);
- self->pipe = NULL;
- if (tmp)
- {
- px_strdict_free(self->data);
- self->data = tmp;
- self->last = time(NULL);
+static const char *_all_keys[] = {
+ "/system/proxy/mode", "/system/proxy/autoconfig_url",
+ "/system/http_proxy/host", "/system/http_proxy/port",
+ "/system/proxy/secure_host", "/system/proxy/secure_port",
+ "/system/proxy/ftp_host", "/system/proxy/ftp_port",
+ "/system/proxy/socks_host", "/system/proxy/socks_port",
+ "/system/http_proxy/ignore_hosts",
+ "/system/http_proxy/use_authentication",
+ "/system/http_proxy/authentication_user",
+ "/system/http_proxy/authentication_password",
+ NULL
+};
+
+class gnome_config_module : public config_module {
+public:
+ PX_MODULE_ID(NULL);
+ PX_MODULE_CONFIG_CATEGORY(config_module::CATEGORY_SESSION);
+
+ gnome_config_module() {
+ int count;
+ string cmd = LIBEXECDIR "pxgconf";
+ for (count=0 ; _all_keys[count] ; count++)
+ cmd += string(" ", 1) + _all_keys[count];
+
+ this->pipe = popen(cmd.c_str(), "r");
+ if (!this->pipe)
+ throw io_error("Unable to open gconf helper!");
+ if (fcntl(fileno(this->pipe), F_SETFL, FNONBLOCK) == -1) {
+ pclose(this->pipe);
+ throw io_error("Unable to set pipe to non-blocking!");
}
+
+ this->update_data(count);
}
- if (!px_strdict_get(self->data, "/system/proxy/mode"))
- return NULL;
+ ~gnome_config_module() {
+ if (this->pipe)
+ pclose(this->pipe);
+ }
- char *curl = NULL;
+ url get_config(url dest) throw (runtime_error) {
+ // Check for changes in the config
+ if (this->pipe) this->update_data();
- // Mode is direct://
- if (!strcmp((const char *) px_strdict_get(self->data, "/system/proxy/mode"), "none"))
- curl = px_strdup("direct://");
+ // Mode is wpad:// or pac+http://...
+ if (this->data["/system/proxy/mode"] == "auto") {
+ string pac = this->data["/system/proxy/autoconfig_url"];
+ return url::is_valid(pac) ? url(string("pac+") + pac) : url("wpad://");
+ }
- // Mode is wpad:// or pac+http://...
- else if (!strcmp((const char *) px_strdict_get(self->data, "/system/proxy/mode"), "auto"))
- {
- if (px_url_is_valid((const char *) px_strdict_get(self->data, "/system/proxy/autoconfig_url")))
- curl = px_strcat("pac+", px_strdict_get(self->data, "/system/proxy/autoconfig_url"), NULL);
- else
- curl = px_strdup("wpad://");
- }
+ // Mode is http://... or socks://...
+ else if (this->data["/system/proxy/mode"] == "manual") {
+ string type = "http", host, port;
+ bool auth = this->data["/system/http_proxy/use_authentication"] == "true";
+ string username = this->data["/system/http_proxy/authentication_user"];
+ string password = this->data["/system/http_proxy/authentication_password"];
+ uint16_t p = 0;
+
+ // Get the per-scheme proxy settings
+ if (dest.get_scheme() == "https") {
+ host = this->data["/system/proxy/secure_host"];
+ port = this->data["/system/proxy/secure_port"];
+ if (sscanf(port.c_str(), "%hu", &p) != 1) p = 0;
+ }
+ else if (dest.get_scheme() == "ftp") {
+ host = this->data["/system/proxy/ftp_host"];
+ port = this->data["/system/proxy/ftp_port"];
+ if (sscanf(port.c_str(), "%hu", &p) != 1) p = 0;
+ }
+ if (host == "" || p == 0)
+ {
+ host = this->data["/system/http_proxy/host"];
+ port = this->data["/system/http_proxy/port"];
+ if (sscanf(port.c_str(), "%hu", &p) != 1) p = 0;
+ }
- // Mode is http://... or socks://...
- else if (!strcmp((const char *) px_strdict_get(self->data, "/system/proxy/mode"), "manual"))
- {
- char *type = px_strdup("http");
- char *host = NULL;
- char *port = NULL;
- char *username = NULL;
- char *password = NULL;
-
- uint16_t p = 0;
-
- // Get the per-scheme proxy settings
- if (!strcmp(px_url_get_scheme(url), "https"))
- {
- host = px_strdup((const char *) px_strdict_get(self->data, "/system/proxy/secure_host"));
- port = px_strdup((const char *) px_strdict_get(self->data, "/system/proxy/secure_port"));
- if (!port || sscanf(port, "%hu", &p) != 1) p = 0;
- }
- else if (!strcmp(px_url_get_scheme(url), "ftp"))
- {
- host = px_strdup((const char *) px_strdict_get(self->data, "/system/proxy/ftp_host"));
- port = px_strdup((const char *) px_strdict_get(self->data, "/system/proxy/ftp_port"));
- if (!port || sscanf(port, "%hu", &p) != 1) p = 0;
- }
- if (!host || !strcmp(host, "") || !p)
- {
- px_free(host);
- px_free(port);
-
- host = px_strdup((const char *) px_strdict_get(self->data, "/system/http_proxy/host"));
- port = px_strdup((const char *) px_strdict_get(self->data, "/system/http_proxy/port"));
- if (!strcmp((const char *) px_strdict_get(self->data, "/system/http_proxy/use_authentication"), "true")) {
- username = px_strdup((const char *) px_strdict_get(self->data, "/system/http_proxy/authentication_user"));
- password = px_strdup((const char *) px_strdict_get(self->data, "/system/http_proxy/authentication_password"));
+ // If http(s)/ftp proxy is not set, try socks
+ if (host == "" || p == 0)
+ {
+ host = this->data["/system/proxy/socks_host"];
+ port = this->data["/system/proxy/socks_port"];
+ if (sscanf(port.c_str(), "%hu", &p) != 1) p = 0;
}
- if (!port || sscanf(port, "%hu", &p) != 1) p = 0;
- }
- // If http(s)/ftp proxy is not set, try socks
- if (!host || !strcmp(host, "") || !p)
- {
- px_free(type);
- px_free(host);
- px_free(port);
-
- type = px_strdup("socks");
- host = px_strdup((const char *) px_strdict_get(self->data, "/system/proxy/socks_host"));
- port = px_strdup((const char *) px_strdict_get(self->data, "/system/proxy/socks_port"));
- if (!port || sscanf(port, "%hu", &p) != 1) p = 0;
+ // If host and port were found, build config url
+ if (host != "" && p != 0) {
+ string tmp = type + "://";
+ if (auth)
+ tmp += username + ":" + password + "@";
+ tmp += host + ":" + port;
+ return url(tmp);
+ }
}
- // If host and port were found, build config url
- if (host && strcmp(host, "") && p)
- curl = px_strcat(type, "://", username && password ? px_strcat(username, ":", password, "@", NULL) : "", host, ":", port, NULL);
+ // Mode is direct://
+ return url("direct://");
+ }
- px_free(type);
- px_free(host);
- px_free(port);
- px_free(username);
- px_free(password);
+ string get_ignore(url url) {
+ return this->data["/system/http_proxy/ignore_hosts"];
}
- // Start a refresh in the background
- if (time(NULL) - self->last > CACHETIME)
- self->pipe = _start_get_config();
+private:
+ FILE *pipe;
+ map<string, string> data;
- return curl;
-}
+ string readline(string buffer="") {
+ char c;
-static char *
-_get_ignore(pxConfigModule *s, pxURL *url)
-{
- pxGConfConfigModule *self = (pxGConfConfigModule *) s;
-
- char *ignores = px_strdup((const char *) px_strdict_get(self->data, "/system/http_proxy/ignore_hosts"));
- if (ignores && ignores[strlen(ignores)-1] == ']' && ignores[0] == '[')
- {
- char *tmp = px_strndup(ignores+1, strlen(ignores+1)-1);
- px_free(ignores);
- ignores = tmp;
- }
-
- return ignores ? ignores : px_strdup("");
-}
+ // If the fread() call would block, an error occurred or
+ // we are at the end of the line, we're done
+ if (fread(&c, sizeof(char), 1, this->pipe) != 1 || c == '\n')
+ return buffer;
-static bool
-_get_credentials(pxConfigModule *self, pxURL *proxy, char **username, char **password)
-{
- return false;
-}
+ // Process the next character
+ return this->readline(buffer + string(&c, 1));
+ }
-static bool
-_set_credentials(pxConfigModule *self, pxURL *proxy, const char *username, const char *password)
-{
- return false;
-}
+ // This method attempts to update data
+ // If called with no arguments, it will check for new data (sleeping for <=1000
+ // useconds) and returning true or false depending on if at least one line of
+ // data was found.
+ // However, if req > 0, we will keep checking for new lines (at 1000 usec ivals)
+ // until enough lines are found. This allows us to wait for *all* the initial
+ // values to be read in before we start processing gconf requests.
+ bool update_data(int req=0, int found=0) {
+ // If we have collected the correct number of lines, return true
+ if (req > 0 && found >= req)
+ return true;
+
+ // We need the pipe to be open
+ if (!this->pipe) return false;
+
+ fd_set rfds;
+ struct timeval timeout = { 0, 1000 };
+ FD_ZERO(&rfds);
+ FD_SET(fileno(this->pipe), &rfds);
+ if (select(fileno(this->pipe)+1, &rfds, NULL, NULL, &timeout) < 1)
+ return req > 0 ? this->update_data(req, found) : false; // If we still haven't met
+ // our req quota, try again
+
+ bool retval = false;
+ for (string line = this->readline() ; line != "" ; line = this->readline()) {
+ string key = line.substr(0, line.find("\t"));
+ string val = line.substr(line.find("\t")+1);
+ this->data[key] = val;
+ retval = ++found > req;
+ }
-static void *
-_constructor()
-{
- pxGConfConfigModule *self = (pxGConfConfigModule *) px_malloc0(sizeof(pxGConfConfigModule));
- PX_CONFIG_MODULE_BUILD(self, PX_CONFIG_MODULE_CATEGORY_SESSION, _get_config, _get_ignore, _get_credentials, _set_credentials);
- self->pipe = _start_get_config();
- return self;
-}
+ return (this->update_data(req, found) || retval);
+ }
+};
-bool
-px_module_load(pxModuleManager *self)
-{
- // If we are running in GNOME, then make sure this plugin is registered.
- if (!x_has_client("gnome-session", "gnome-settings-daemon", "gnome-panel", NULL))
- return false;
- return px_module_manager_register_module(self, pxConfigModule, _constructor, _destructor);
+// If we are running in GNOME, then make sure this plugin is registered.
+extern "C" bool px_module_load(module_manager& mm) {
+ if (xhasclient("gnome-session", "gnome-settings-daemon", "gnome-panel", NULL)) {
+ try { return mm.register_module<config_module>(new gnome_config_module); }
+ catch (io_error) { return false; }
+ }
}
diff --git a/libproxy/modules/config_kde4.cpp b/libproxy/modules/config_kde4.cpp
index afa3720..b5e8684 100644
--- a/libproxy/modules/config_kde4.cpp
+++ b/libproxy/modules/config_kde4.cpp
@@ -17,122 +17,63 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
+#include <kstandarddirs.h> // For KStandardDirs
+#include "xhasclient.cpp" // For xhasclient(...)
-#include "../misc.hpp"
-#include "../modules.hpp"
#include "../config_file.hpp"
-
-#include <kstandarddirs.h>
-
-typedef struct _pxKConfigConfigModule {
- PX_MODULE_SUBCLASS(pxConfigModule);
- pxConfigFile *cf;
-} pxKConfigConfigModule;
-
-static void
-_destructor(void *s)
-{
- pxKConfigConfigModule *self = (pxKConfigConfigModule *) s;
-
- px_config_file_free(self->cf);
- px_free(self);
-}
-
-static char *
-_get_config(pxConfigModule *s, pxURL *url)
-{
- pxKConfigConfigModule *self = (pxKConfigConfigModule *) s;
-
- // TODO: make ignores work w/ KDE
- char *curl = NULL, *tmp = NULL;
-
- // Open the config file
- pxConfigFile *cf = self->cf;
- if (!cf || px_config_file_is_stale(cf))
- {
- if (cf) px_config_file_free(cf);
- QString localdir = KStandardDirs().localkdedir();
- QByteArray ba = localdir.toLatin1();
- tmp = px_strcat(ba.data(), "/share/config/kioslaverc", NULL);
- cf = px_config_file_new(tmp);
- px_free(tmp);
- self->cf = cf;
- }
- if (!cf) goto out;
-
- // Read the config file to find out what type of proxy to use
- tmp = px_config_file_get_value(cf, "Proxy Settings", "ProxyType");
- if (!tmp) goto out;
-
- // Don't use any proxy
- if (!strcmp(tmp, "0"))
- curl = px_strdup("direct://");
-
- // Use a manual proxy
- else if (!strcmp(tmp, "1"))
- curl = px_config_file_get_value(cf, "Proxy Settings", "httpProxy");
-
- // Use a manual PAC
- else if (!strcmp(tmp, "2"))
- {
- px_free(tmp);
- tmp = px_config_file_get_value(cf, "Proxy Settings", "Proxy Config Script");
- if (tmp) curl = px_strcat("pac+", tmp);
- else curl = px_strdup("wpad://");
+#include "../module_types.hpp"
+using namespace com::googlecode::libproxy;
+
+class kde_config_module : public config_module {
+public:
+ PX_MODULE_ID(NULL);
+ PX_MODULE_CONFIG_CATEGORY(config_module::CATEGORY_SESSION);
+
+ url get_config(url url) throw (runtime_error) {
+ // Open the config file
+ if (this->cf.is_stale())
+ {
+ QString localdir = KStandardDirs().localkdedir();
+ QByteArray ba = localdir.toLatin1();
+ if (!cf.load(string(ba.data()) + "/share/config/kioslaverc"))
+ throw runtime_error("Unable to load kde config file!");
+ }
+
+ try {
+ // Read the config file to find out what type of proxy to use
+ string ptype = this->cf.get_value("Proxy Settings", "ProxyType");
+
+ // Use a manual proxy
+ if (ptype == "1")
+ return com::googlecode::libproxy::url(this->cf.get_value("Proxy Settings", "httpProxy"));
+
+ // Use a manual PAC
+ else if (ptype == "2")
+ {
+ string tmp = "";
+ try { tmp = this->cf.get_value("Proxy Settings", "Proxy Config Script"); }
+ catch (key_error&) {}
+
+ if (tmp != "") return com::googlecode::libproxy::url(string("pac+") + tmp);
+ else return com::googlecode::libproxy::url("wpad://");
+ }
+
+ // Use WPAD
+ else if (ptype == "3")
+ return com::googlecode::libproxy::url("wpad://");
+
+ // Use envvar
+ else if (ptype == "4")
+ throw runtime_error("User config_envvar"); // We'll bypass this config plugin and let the envvar plugin work
+ }
+ catch (key_error&) { }
+
+ // Don't use any proxy
+ return com::googlecode::libproxy::url("direct://");
}
- // Use WPAD
- else if (!strcmp(tmp, "3"))
- curl = px_strdup("wpad://");
-
- // Use envvar
- else if (!strcmp(tmp, "4"))
- curl = NULL; // We'll bypass this config plugin and let the envvar plugin work
-
- // Cleanup
- px_free(tmp);
-
- out:
- return curl;
-}
+private:
+ config_file cf;
+};
-static char *
-_get_ignore(pxConfigModule *self, pxURL *url)
-{
- return px_strdup("");
-}
-
-static bool
-_get_credentials(pxConfigModule *self, pxURL *proxy, char **username, char **password)
-{
- return false;
-}
-
-static bool
-_set_credentials(pxConfigModule *self, pxURL *proxy, const char *username, const char *password)
-{
- return false;
-}
-
-static void *
-_constructor()
-{
- pxKConfigConfigModule *self = (pxKConfigConfigModule *)px_malloc0(sizeof(pxKConfigConfigModule));
- PX_CONFIG_MODULE_BUILD(self, PX_CONFIG_MODULE_CATEGORY_SESSION, _get_config, _get_ignore, _get_credentials, _set_credentials);
- return self;
-}
-
-extern "C" bool
-px_module_load(pxModuleManager *self)
-{
- // If we are running in KDE, then make sure this plugin is registered.
- char *tmp = getenv("KDE_FULL_SESSION");
- if (tmp == NULL) {
- return false;
- }
- return px_module_manager_register_module(self, pxConfigModule, _constructor, _destructor);
-}
+PX_MODULE_LOAD(config_module, kde, xhasclient("kicker", NULL));
diff --git a/libproxy/modules/config_w32reg.cpp b/libproxy/modules/config_w32reg.cpp
index 95321fc..3f3ac95 100644
--- a/libproxy/modules/config_w32reg.cpp
+++ b/libproxy/modules/config_w32reg.cpp
@@ -18,19 +18,14 @@
#include <windows.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../misc.hpp"
-#include "../modules.hpp"
+#include "../module_types.hpp"
+using namespace com::googlecode::libproxy;
#define W32REG_OFFSET_PAC (1 << 2)
#define W32REG_OFFSET_WPAD (1 << 3)
#define W32REG_BASEKEY "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"
-static bool
-_get_registry(const char *key, const char *name, uchar **sval, uint32_t *slen, uint32_t *ival)
-{
+static bool _get_registry(const char *key, const char *name, uchar **sval, uint32_t *slen, uint32_t *ival) {
HKEY hkey;
LONG result;
DWORD type;
@@ -40,7 +35,7 @@ _get_registry(const char *key, const char *name, uchar **sval, uint32_t *slen, u
// Don't allow the caller to specify both sval and ival
if (sval && ival)
return false;
-
+
// Open the key
if (RegOpenKeyExA(HKEY_CURRENT_USER, key, 0, KEY_READ, &hkey) != ERROR_SUCCESS)
return false;
@@ -61,7 +56,7 @@ _get_registry(const char *key, const char *name, uchar **sval, uint32_t *slen, u
case REG_SZ:
if (!sval) return false;
if (slen) *slen = buflen;
- *sval = px_malloc(buflen);
+ *sval = new char[buflen];
return !memcpy_s(*sval, buflen, buffer, buflen);
case REG_DWORD:
if (ival) return !memcpy_s(ival, sizeof(uint32_t), buffer, buflen);
@@ -69,10 +64,7 @@ _get_registry(const char *key, const char *name, uchar **sval, uint32_t *slen, u
return false;
}
-
-static bool
-_is_enabled(uint8_t type)
-{
+static bool _is_enabled(uint8_t type) {
uchar *data = NULL;
uint32_t dlen = 0;
bool result = false;
@@ -85,127 +77,81 @@ _is_enabled(uint8_t type)
if (dlen >= 9)
result = data[8] & type == type; // Check to see if the bit is set
- px_free(data);
+ delete data;
return result;
}
-static char *
-_get_pac()
-{
- char *pac = NULL;
- char *url = NULL;
-
- if (!_is_enabled(W32REG_OFFSET_PAC)) return NULL;
- if (!_get_registry(W32REG_BASEKEY, "AutoConfigURL", &pac, NULL, NULL)) return NULL;
-
- url = px_strcat("pac+", pac, NULL);
- px_free(pac);
- return url;
-}
-
-static char *
-_get_manual(pxURL *url)
-{
- char *val = NULL;
- char *url = NULL;
- char **vals = NULL;
- uint32_t enabled = 0;
-
- // Check to see if we are enabled
- if (!_get_registry(W32REG_BASEKEY, "ProxyEnable", NULL, NULL, &enabled) || !enabled) return NULL;
-
- // Get the value of ProxyServer
- if (!_get_registry(W32REG_BASEKEY, "ProxyServer", &val, NULL, NULL)) return NULL;
-
+static map<string, string> _parse_manual(string data) {
// ProxyServer comes in two formats:
// 1.2.3.4:8080 or ftp=1.2.3.4:8080;https=1.2.3.4:8080...
- // If we have the first format, just prepend "http://" and we're done
- if (!strchr(val, ';'))
- {
- url = px_strcat("http://", val, NULL);
- px_free(val);
- return url;
- }
-
- // Ok, now we have the more difficult format...
- // ... so split up all the various proxies
- vals = px_strsplit(val, ";");
- px_free(val);
+ map<string, url> rval;
- // First we look for an exact match
- for (int i=0 ; !url && vals[i] ; i++)
- {
- char *tmp = px_strcat(px_url_get_scheme(url), "=", NULL);
-
- // If we've found an exact match, use it
- if (!strncmp(tmp, vals[i], strlen(tmp)))
- url = px_strcat(px_url_get_scheme(url), "://", vals[i]+strlen(tmp), NULL);
-
- px_free(tmp);
+ // If we have the second format, do recursive parsing,
+ // then handle just the first entry
+ if (data.find(";") != string::npos) {
+ rval = _parse_manual(data.substr(data.find(";")+1));
+ data = data.substr(0, data.find(";"));
}
- // Second we look for http=
- for (int i=0 ; !url && vals[i] ; i++)
- if (!strncmp("http=", vals[i], strlen("http=")))
- url = px_strcat("http://", vals[i]+strlen("http="), NULL);
-
- // Last we look for socks=
- for (int i=0 ; !url && vals[i] ; i++)
- if (!strncmp("socks=", vals[i], strlen("socks=")))
- url = px_strcat("socks://", vals[i]+strlen("socks="), NULL);
-
- return url;
-}
-
-static char *
-_get_config(pxConfigModule *self, pxURL *url)
-{
- char *config = NULL;
-
- // WPAD
- if (_is_enabled(W32REG_OFFSET_WPAD))
- return px_strdup("wpad://");
-
- // PAC
- if ((config = _get_pac()))
- return config;
-
- // Manual proxy
- if ((config = _get_manual(url)))
- return config;
-
- // Direct
- return px_strdup("direct://");
-}
-
-static char *
-_get_ignore(pxConfigModule *self, pxURL *url)
-{
- return px_strdup("");
-}
+ // If we have the first format, just assign HTTP and we're done
+ if (data.find("=") == string::npos) {
+ rval["http"] = data;
+ return rval;
+ }
-static bool
-_get_credentials(pxConfigModule *self, pxURL *url, char **username, char **password)
-{
- return false;
-}
+ // Otherwise set the value for this single entry and return
+ string protocol = data.substr(0, data.find("="));
+ try { rval[protocol] = url(protocol + "://" + data.substr(data.find("=")+1)); }
+ catch (parse_error&) {}
-static bool
-_set_credentials(pxConfigModule *self, pxURL *url, const char *username, const char *password)
-{
- return false;
+ return rval;
}
-static void *
-_constructor()
-{
- pxConfigModule *self = px_malloc0(sizeof(pxConfigModule));
- PX_CONFIG_MODULE_BUILD(self, PX_CONFIG_MODULE_CATEGORY_USER, _get_config, _get_ignore, _get_credentials, _set_credentials);
- return self;
+class w32reg_config_module : public config_module {
+public:
+ PX_MODULE_ID(NULL);
+ PX_MODULE_CONFIG_CATEGORY(config_module::CATEGORY_SYSTEM);
+
+ url get_config(url dst) throw (runtime_error) {
+ char *tmp = NULL;
+ uint32_t enabled = 0;
+
+ // WPAD
+ if (_is_enabled(W32REG_OFFSET_WPAD))
+ return url("wpad://");
+
+ // PAC
+ if (_is_enabled(W32REG_OFFSET_PAC) &&
+ _get_registry(W32REG_BASEKEY, "AutoConfigURL", &tmp, NULL, NULL) &&
+ url::is_valid(string("pac+") + tmp)) {
+ url cfg(string("pac+") + tmp);
+ delete tmp;
+ return cfg;
+ }
+
+ // Manual proxy
+ // Check to see if we are enabled and get the value of ProxyServer
+ if (_get_registry(W32REG_BASEKEY, "ProxyEnable", NULL, NULL, &enabled) && enabled &&
+ _get_registry(W32REG_BASEKEY, "ProxyServer", &tmp, NULL, NULL)) {
+ map<string, string> manual = _parse_manual(tmp);
+ delete tmp;
+
+ // First we look for an exact match
+ if (manual.find(dst.get_scheme()) != map<string, url>::end)
+ return manual[dst.get_scheme()];
+
+ // Next we look for http
+ else if (manual.find("http") != map<string, url>::end)
+ return manual["http"];
+
+ // Last we look for socks
+ else if (manual.find("socks") != map<string, url>::end)
+ return manual["socks"];
+ }
+
+ // Direct
+ return url("direct://");
+ }
}
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxConfigModule, _constructor, px_free);
-}
+PX_MODULE_LOAD(config_module, w32reg, true);
diff --git a/libproxy/modules/config_wpad.cpp b/libproxy/modules/config_wpad.cpp
index d194e4b..ef440a4 100644
--- a/libproxy/modules/config_wpad.cpp
+++ b/libproxy/modules/config_wpad.cpp
@@ -17,46 +17,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <string.h>
+#include "../module_types.hpp"
+using namespace com::googlecode::libproxy;
-#include "../misc.hpp"
-#include "../modules.hpp"
+class wpad_config_module : public config_module {
+public:
+ PX_MODULE_ID(NULL);
+ PX_MODULE_CONFIG_CATEGORY(config_module::CATEGORY_NONE);
-static char *
-_get_config(pxConfigModule *self, pxURL *url)
-{
- return px_strdup("wpad://");
-}
+ url get_config(url dst) throw (runtime_error) {
+ return url("wpad://");
+ }
+};
-static char *
-_get_ignore(pxConfigModule *self, pxURL *url)
-{
- return px_strdup("");
-}
-
-static bool
-_get_credentials(pxConfigModule *self, pxURL *url, char **username, char **password)
-{
- return false;
-}
-
-static bool
-_set_credentials(pxConfigModule *self, pxURL *url, const char *username, const char *password)
-{
- return false;
-}
-
-static void *
-_constructor()
-{
- pxConfigModule *self = (pxConfigModule *) px_malloc0(sizeof(pxConfigModule));
- PX_CONFIG_MODULE_BUILD(self, PX_CONFIG_MODULE_CATEGORY_NONE, _get_config, _get_ignore, _get_credentials, _set_credentials);
- return self;
-}
-
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxConfigModule, _constructor, px_free);
-}
+PX_MODULE_LOAD(config_module, wpad, true);
diff --git a/libproxy/modules/ignore_domain.cpp b/libproxy/modules/ignore_domain.cpp
index ceca7d5..b9bd990 100644
--- a/libproxy/modules/ignore_domain.cpp
+++ b/libproxy/modules/ignore_domain.cpp
@@ -17,81 +17,46 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
+#include <cstdio>
-#include "../misc.hpp"
-#include "../modules.hpp"
+#include "../module_types.hpp"
-static inline bool
-_endswith(char *string, char *suffix)
-{
- int st_len = strlen(string);
- int su_len = strlen(suffix);
+using namespace com::googlecode::libproxy;
- return (st_len >= su_len && !strcmp(string + (st_len-su_len), suffix));
-}
+class domain_ignore_module : public ignore_module {
+public:
+ PX_MODULE_ID(NULL);
-static bool
-_ignore(pxIgnoreModule *self, pxURL *url, const char *ignore)
-{
- if (!url || !ignore)
- return false;
+ virtual bool ignore(url& url, string ignorestr) {
+ /* Get our URL's hostname and port */
+ string host = url.get_host();
+ int port = url.get_port();
- /* Get our URL's hostname and port */
- char *host = px_strdup(px_url_get_host(url));
- int port = px_url_get_port(url);
+ /* Get our ignore pattern's hostname and port */
+ string ihost = ignorestr;
+ int iport = 0;
+ if (ihost.find(':') != string::npos) {
+ if (sscanf(ignorestr.substr(ihost.find(':')+1).c_str(), "%d", &iport) == 1)
+ ihost = ihost.substr(0, ihost.find(':'));
+ else
+ iport = 0;
+ }
- /* Get our ignore pattern's hostname and port */
- char *ihost = px_strdup(ignore);
- int iport = 0;
- if (strchr(ihost, ':'))
- {
- char *tmp = strchr(ihost, ':');
- if (sscanf(tmp+1, "%d", &iport) == 1)
- *tmp = '\0';
- else
- iport = 0;
- }
-
- /* Hostname match (domain.com or domain.com:80) */
- if (!strcmp(host, ihost))
- if (!iport || port == iport)
- goto match;
-
- /* Endswith (.domain.com or .domain.com:80) */
- if (ihost[0] == '.' && _endswith(host, ihost))
- if (!iport || port == iport)
- goto match;
+ /* Hostname match (domain.com or domain.com:80) */
+ if (host == ihost)
+ return (iport == 0 || port == iport);
- /* Glob (*.domain.com or *.domain.com:80) */
- if (ihost[0] == '*' && _endswith(host, ihost+1))
- if (!iport || port == iport)
- goto match;
+ /* Endswith (.domain.com or .domain.com:80) */
+ if (ihost[0] == '.' && host.find(ihost) == host.size() - ihost.size())
+ return (iport == 0 || port == iport);
- /* No match was found */
- px_free(host);
- px_free(ihost);
- return false;
+ /* Glob (*.domain.com or *.domain.com:80) */
+ if (ihost[0] == '*' && host.find(ihost.substr(1)) == host.size() - ihost.substr(1).size())
+ return (iport == 0 || port == iport);
- /* A match was found */
- match:
- px_free(host);
- px_free(ihost);
- return true;
-}
-
-static void *
-_constructor()
-{
- pxIgnoreModule *self = (pxIgnoreModule *) px_malloc0(sizeof(pxIgnoreModule));
- self->ignore = _ignore;
- return self;
-}
+ /* No match was found */
+ return false;
+ }
+};
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxIgnoreModule, _constructor, px_free);
-}
+PX_MODULE_LOAD(ignore_module, domain, true);
diff --git a/libproxy/modules/ignore_ip.cpp b/libproxy/modules/ignore_ip.cpp
index 2ea20ae..81be231 100644
--- a/libproxy/modules/ignore_ip.cpp
+++ b/libproxy/modules/ignore_ip.cpp
@@ -17,10 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
+#include <cstdio>
+#include <cstring>
#ifdef _WIN32
#define _WIN32_WINNT 0x0501
@@ -35,183 +33,161 @@ typedef unsigned short int sa_family_t;
#include <netinet/in.h>
#endif
-#include "../misc.hpp"
-#include "../modules.hpp"
+#include "../module_types.hpp"
-static bool
+using namespace com::googlecode::libproxy;
+
+static inline bool
_sockaddr_equals(const struct sockaddr *ip_a, const struct sockaddr *ip_b, const struct sockaddr *nm)
{
- if (!ip_a || !ip_b) return false;
- if (ip_a->sa_family != ip_b->sa_family) return false;
- if (nm && ip_a->sa_family != nm->sa_family) return false;
-
- /* Setup the arrays */
- uint8_t bytes = 0, *a_data = NULL, *b_data = NULL, *nm_data = NULL;
- if (ip_a->sa_family == AF_INET)
- {
- bytes = 32 / 8;
- a_data = (uint8_t *) &((struct sockaddr_in *) ip_a)->sin_addr;
- b_data = (uint8_t *) &((struct sockaddr_in *) ip_b)->sin_addr;
- nm_data = nm ? (uint8_t *) &((struct sockaddr_in *) nm)->sin_addr : NULL;
- }
- else if (ip_a->sa_family == AF_INET6)
- {
- bytes = 128 / 8;
- a_data = (uint8_t *) &((struct sockaddr_in6 *) ip_a)->sin6_addr;
- b_data = (uint8_t *) &((struct sockaddr_in6 *) ip_b)->sin6_addr;
- nm_data = nm ? (uint8_t *) &((struct sockaddr_in6 *) nm)->sin6_addr : NULL;
- }
- else
- return false;
-
- for (int i=0 ; i < bytes ; i++)
- {
- if (nm && (a_data[i] & nm_data[i]) != (b_data[i] & nm_data[i]))
- return false;
- else if (!nm && (a_data[i] != b_data[i]))
- return false;
- }
- return true;
+ if (!ip_a || !ip_b) return false;
+ if (ip_a->sa_family != ip_b->sa_family) return false;
+ if (nm && ip_a->sa_family != nm->sa_family) return false;
+
+ /* Setup the arrays */
+ uint8_t bytes = 0, *a_data = NULL, *b_data = NULL, *nm_data = NULL;
+ if (ip_a->sa_family == AF_INET)
+ {
+ bytes = 32 / 8;
+ a_data = (uint8_t *) &((struct sockaddr_in *) ip_a)->sin_addr;
+ b_data = (uint8_t *) &((struct sockaddr_in *) ip_b)->sin_addr;
+ nm_data = nm ? (uint8_t *) &((struct sockaddr_in *) nm)->sin_addr : NULL;
+ }
+ else if (ip_a->sa_family == AF_INET6)
+ {
+ bytes = 128 / 8;
+ a_data = (uint8_t *) &((struct sockaddr_in6 *) ip_a)->sin6_addr;
+ b_data = (uint8_t *) &((struct sockaddr_in6 *) ip_b)->sin6_addr;
+ nm_data = nm ? (uint8_t *) &((struct sockaddr_in6 *) nm)->sin6_addr : NULL;
+ }
+ else
+ return false;
+
+ for (int i=0 ; i < bytes ; i++)
+ {
+ if (nm && (a_data[i] & nm_data[i]) != (b_data[i] & nm_data[i]))
+ return false;
+ else if (!nm && (a_data[i] != b_data[i]))
+ return false;
+ }
+ return true;
}
-static struct sockaddr *
-_sockaddr_from_string(const char *ip, int len)
+static inline sockaddr *
+_sockaddr_from_string(string ip)
{
- if (!ip) return NULL;
- struct sockaddr *result = NULL;
-
- /* Copy the string */
- if (len >= 0)
- ip = px_strndup(ip, len);
- else
- ip = px_strdup(ip);
-
- /* Try to parse */
- struct addrinfo *info = NULL;
- struct addrinfo flags;
- flags.ai_family = AF_UNSPEC;
- flags.ai_socktype = 0;
- flags.ai_protocol = 0;
- flags.ai_flags = AI_NUMERICHOST;
- if (getaddrinfo(ip, NULL, &flags, &info) != 0 || !info) goto out;
-
- /* Copy the results into our buffer */
- result = (struct sockaddr *) px_malloc0(info->ai_addrlen);
- memcpy(result, info->ai_addr, info->ai_addrlen);
-
- out:
- px_free((char *) ip);
- return result;
+ struct sockaddr *result = NULL;
+
+ /* Try to parse */
+ struct addrinfo *info = NULL;
+ struct addrinfo flags;
+ flags.ai_family = AF_UNSPEC;
+ flags.ai_socktype = 0;
+ flags.ai_protocol = 0;
+ flags.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(ip.c_str(), NULL, &flags, &info) != 0 || !info) return result;
+
+ /* Copy the results into our buffer */
+ if (!(result = (sockaddr *) new char[info->ai_addrlen])) return result;
+ memcpy(result, info->ai_addr, info->ai_addrlen);
+ return result;
}
-static struct sockaddr *
+static inline sockaddr *
_sockaddr_from_cidr(sa_family_t af, uint8_t cidr)
{
- /* IPv4 */
- if (af == AF_INET)
- {
- struct sockaddr_in *mask = (sockaddr_in *) px_malloc0(sizeof(struct sockaddr_in));
- mask->sin_family = af;
- mask->sin_addr.s_addr = htonl(~0 << (32 - (cidr > 32 ? 32 : cidr)));
-
- return (struct sockaddr *) mask;
- }
-
- /* IPv6 */
- else if (af == AF_INET6)
- {
- struct sockaddr_in6 *mask = (sockaddr_in6 *) px_malloc0(sizeof(struct sockaddr_in6));
- mask->sin6_family = af;
- for (uint8_t i=0 ; i < sizeof(mask->sin6_addr) ; i++)
- mask->sin6_addr.s6_addr[i] = ~0 << (8 - (8*i > cidr ? 0 : cidr-8*i < 8 ? cidr-8*i : 8) );
-
- return (struct sockaddr *) mask;
- }
-
- return NULL;
+ /* IPv4 */
+ if (af == AF_INET)
+ {
+ sockaddr_in *mask = new sockaddr_in;
+ mask->sin_family = af;
+ mask->sin_addr.s_addr = htonl(~0 << (32 - (cidr > 32 ? 32 : cidr)));
+
+ return (struct sockaddr *) mask;
+ }
+
+ /* IPv6 */
+ else if (af == AF_INET6)
+ {
+ sockaddr_in6 *mask = new sockaddr_in6;
+ mask->sin6_family = af;
+ for (uint8_t i=0 ; i < sizeof(mask->sin6_addr) ; i++)
+ mask->sin6_addr.s6_addr[i] = ~0 << (8 - (8*i > cidr ? 0 : cidr-8*i < 8 ? cidr-8*i : 8) );
+
+ return (sockaddr *) mask;
+ }
+
+ return NULL;
}
-static bool
-_ignore(struct _pxIgnoreModule *self, pxURL *url, const char *ignore)
-{
- if (!url || !ignore) return false;
-
-
- bool result = false;
- uint32_t port = 0;
- const struct sockaddr **dst_ips = px_url_get_ips(url, false);
- const struct sockaddr *dst_ip = dst_ips && dst_ips[0] ? dst_ips[0] : NULL;
- struct sockaddr *ign_ip = NULL, *net_ip = NULL;
-
- /*
- * IPv4
- * IPv6
- */
- if ((ign_ip = _sockaddr_from_string(ignore, -1)))
- goto out;
-
- /*
- * IPv4/CIDR
- * IPv4/IPv4
- * IPv6/CIDR
- * IPv6/IPv6
- */
- if (strchr(ignore, '/'))
- {
- ign_ip = _sockaddr_from_string(ignore, strchr(ignore, '/') - ignore);
- net_ip = _sockaddr_from_string(strchr(ignore, '/') + 1, -1);
-
- /* If CIDR notation was used, get the netmask */
- if (ign_ip && !net_ip)
- {
- uint32_t cidr = 0;
- if (sscanf(strchr(ignore, '/') + 1, "%d", &cidr) == 1)
- net_ip = _sockaddr_from_cidr(ign_ip->sa_family, cidr);
- }
-
- if (ign_ip && net_ip && ign_ip->sa_family == net_ip->sa_family)
- goto out;
-
- px_free(ign_ip);
- px_free(net_ip);
- ign_ip = NULL;
- net_ip = NULL;
- }
-
- /*
- * IPv4:port
- * [IPv6]:port
- */
- if (strrchr(ignore, ':') && sscanf(strrchr(ignore, ':'), ":%u", &port) == 1 && port > 0)
- {
- ign_ip = _sockaddr_from_string(ignore, strrchr(ignore, ':') - ignore);
-
- /* Make sure this really is just a port and not just an IPv6 address */
- if (ign_ip && (ign_ip->sa_family != AF_INET6 || ignore[0] == '['))
- goto out;
-
- px_free(ign_ip);
- ign_ip = NULL;
- port = 0;
- }
-
- out:
- result = _sockaddr_equals(dst_ip, ign_ip, net_ip);
- px_free(ign_ip);
- px_free(net_ip);
- return port != 0 ? (port == px_url_get_port(url) && result): result;
-}
-
-static void *
-_constructor()
-{
- pxIgnoreModule *self = (pxIgnoreModule*) px_malloc0(sizeof(pxIgnoreModule));
- self->ignore = _ignore;
- return self;
-}
-
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxIgnoreModule, _constructor, px_free);
-}
+class ip_ignore_module : public ignore_module {
+public:
+ PX_MODULE_ID(NULL);
+
+ virtual bool ignore(url& url, string ignore) {
+ bool result = false;
+ uint32_t port = 0;
+ const struct sockaddr *dst_ip = url.get_ips(false)->size() > 0 ? (*url.get_ips(false))[0] : NULL;
+ struct sockaddr *ign_ip = NULL, *net_ip = NULL;
+
+ /*
+ * IPv4
+ * IPv6
+ */
+ if ((ign_ip = _sockaddr_from_string(ignore)))
+ goto out;
+
+ /*
+ * IPv4/CIDR
+ * IPv4/IPv4
+ * IPv6/CIDR
+ * IPv6/IPv6
+ */
+ if (ignore.find('/') != string::npos)
+ {
+ ign_ip = _sockaddr_from_string(ignore.substr(0, ignore.find('/')));
+ net_ip = _sockaddr_from_string(ignore.substr(ignore.find('/') + 1));
+
+ /* If CIDR notation was used, get the netmask */
+ if (ign_ip && !net_ip)
+ {
+ uint32_t cidr = 0;
+ if (sscanf(ignore.substr(ignore.find('/') + 1).c_str(), "%d", &cidr) == 1)
+ net_ip = _sockaddr_from_cidr(ign_ip->sa_family, cidr);
+ }
+
+ if (ign_ip && net_ip && ign_ip->sa_family == net_ip->sa_family)
+ goto out;
+
+ delete ign_ip;
+ delete net_ip;
+ ign_ip = NULL;
+ net_ip = NULL;
+ }
+
+ /*
+ * IPv4:port
+ * [IPv6]:port
+ */
+ if (ignore.rfind(':') != string::npos && sscanf(ignore.substr(ignore.rfind(':')).c_str(), ":%u", &port) == 1 && port > 0)
+ {
+ ign_ip = _sockaddr_from_string(ignore.substr(ignore.rfind(':')).c_str());
+
+ /* Make sure this really is just a port and not just an IPv6 address */
+ if (ign_ip && (ign_ip->sa_family != AF_INET6 || ignore[0] == '['))
+ goto out;
+
+ delete ign_ip;
+ ign_ip = NULL;
+ port = 0;
+ }
+
+ out:
+ result = _sockaddr_equals(dst_ip, ign_ip, net_ip);
+ free(ign_ip);
+ free(net_ip);
+ return port != 0 ? (port == url.get_port() && result) : result;
+ }
+};
+
+PX_MODULE_LOAD(ignore_module, ip, true);
diff --git a/libproxy/modules/network_networkmanager.cpp b/libproxy/modules/network_networkmanager.cpp
index 40b98df..e37a4c7 100644
--- a/libproxy/modules/network_networkmanager.cpp
+++ b/libproxy/modules/network_networkmanager.cpp
@@ -17,94 +17,77 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-
-#include "../misc.hpp"
-#include "../modules.hpp"
+#include "../module_types.hpp"
#include <dbus/dbus.h>
#include <NetworkManager/NetworkManager.h>
-typedef struct _pxNetworkManagerNetworkModule {
- PX_MODULE_SUBCLASS(pxNetworkModule);
- DBusConnection *conn;
-} pxNetworkManagerNetworkModule;
-
-static void
-_destructor(void *s)
-{
- pxNetworkManagerNetworkModule *self = (pxNetworkManagerNetworkModule *) s;
-
- dbus_connection_close(self->conn);
- px_free(self);
-}
-
-static bool
-_changed(pxNetworkModule *s)
-{
- pxNetworkManagerNetworkModule *self = (pxNetworkManagerNetworkModule *) s;
-
- // Make sure we have a valid connection with a proper match
- DBusConnection *conn = self->conn;
- if (!conn || !dbus_connection_get_is_connected(conn))
- {
- // If the connection was disconnected,
- // close it an clear the queue
- if (conn)
+using namespace com::googlecode::libproxy;
+
+class networkmanager_network_module : public network_module {
+public:
+ PX_MODULE_ID(NULL);
+
+ networkmanager_network_module() {
+ this->conn = NULL;
+ }
+
+ ~networkmanager_network_module() {
+ if (this->conn) dbus_connection_close(this->conn);
+ }
+
+ bool changed() {
+ // Make sure we have a valid connection with a proper match
+ DBusConnection *conn = this->conn;
+ if (!conn || !dbus_connection_get_is_connected(conn))
{
- dbus_connection_close(conn);
- dbus_connection_read_write(conn, 0);
- for (DBusMessage *msg=NULL ; (msg = dbus_connection_pop_message(conn)) ; dbus_message_unref(msg));
+ // If the connection was disconnected,
+ // close it an clear the queue
+ if (conn)
+ {
+ dbus_connection_close(conn);
+ dbus_connection_read_write(conn, 0);
+ for (DBusMessage *msg=NULL ; (msg = dbus_connection_pop_message(conn)) ; dbus_message_unref(msg));
+ }
+
+ // Create a new connections
+ conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL);
+ this->conn = conn;
+ if (!conn) return false;
+
+ // If connection was successful, set it up
+ dbus_connection_set_exit_on_disconnect(conn, false);
+ dbus_bus_add_match(conn, "type='signal',interface='" NM_DBUS_INTERFACE "',member='StateChange'", NULL);
+ dbus_connection_flush(conn);
}
- // Create a new connections
- conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, NULL);
- self->conn = conn;
- if (!conn) return false;
+ // We are guaranteed a connection,
+ // so check for incoming messages
+ bool changed = false;
+ while (true)
+ {
+ DBusMessage *msg = NULL;
+ uint32_t state;
- // If connection was successful, set it up
- dbus_connection_set_exit_on_disconnect(conn, false);
- dbus_bus_add_match(conn, "type='signal',interface='" NM_DBUS_INTERFACE "',member='StateChange'", NULL);
- dbus_connection_flush(conn);
- }
+ // Pull messages off the queue
+ dbus_connection_read_write(conn, 0);
+ if (!(msg = dbus_connection_pop_message(conn)))
+ break;
+
+ // If a message is the right type and value,
+ // we'll reset the network
+ if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID))
+ if (state == NM_STATE_CONNECTED)
+ changed = true;
- // We are guaranteed a connection,
- // so check for incoming messages
- bool changed = false;
- while (true)
- {
- DBusMessage *msg = NULL;
- uint32_t state;
-
- // Pull messages off the queue
- dbus_connection_read_write(conn, 0);
- if (!(msg = dbus_connection_pop_message(conn)))
- break;
-
- // If a message is the right type and value,
- // we'll reset the network
- if (dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID))
- if (state == NM_STATE_CONNECTED)
- changed = true;
-
- dbus_message_unref(msg);
+ dbus_message_unref(msg);
+ }
+
+ return changed;
}
- return changed;
-}
-
-static void *
-_constructor()
-{
- pxNetworkManagerNetworkModule *self = (pxNetworkManagerNetworkModule*) px_malloc0(sizeof(pxNetworkManagerNetworkModule));
- self->__parent__.changed = _changed;
- return self;
-}
-
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxNetworkModule, _constructor, _destructor);
-}
+private:
+ DBusConnection *conn;
+};
+
+PX_MODULE_LOAD(network_module, networkmanager, true);
diff --git a/libproxy/modules/pacrunner_mozjs.cpp b/libproxy/modules/pacrunner_mozjs.cpp
index d24dea1..74cbeaa 100644
--- a/libproxy/modules/pacrunner_mozjs.cpp
+++ b/libproxy/modules/pacrunner_mozjs.cpp
@@ -17,18 +17,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#define __USE_BSD
-#include <unistd.h>
-
-#include "../misc.hpp"
-#include "../modules.hpp"
+#include <cstring> // ?
+
+#include "../module_types.hpp"
+using namespace com::googlecode::libproxy;
#include <jsapi.h>
#include "pacutils.h"
@@ -41,21 +33,9 @@
#define INET6_ADDRSTRLEN 46
#endif
-typedef struct {
- JSRuntime *run;
- JSContext *ctx;
- JSClass *cls;
- char *pac;
-} ctxStore;
-
-typedef struct _pxMozillaPACRunnerModule {
- PX_MODULE_SUBCLASS(pxPACRunnerModule);
- ctxStore *ctxs;
-} pxMozillaPACRunnerModule;
-
static JSBool dnsResolve(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) {
// Get hostname argument
- char *tmp = px_strdup(JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
+ char *tmp = JS_strdup(cx, JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
// Set the default return value
*rval = JSVAL_NULL;
@@ -66,8 +46,9 @@ static JSBool dnsResolve(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
goto out;
// Allocate the IP address
- px_free(tmp);
- tmp = (char *) px_malloc0(INET6_ADDRSTRLEN+1);
+ JS_free(cx, tmp);
+ tmp = (char *) JS_malloc(cx, INET6_ADDRSTRLEN+1);
+ memset(tmp, 0, INET6_ADDRSTRLEN+1);
// Try for IPv4 and IPv6
if (!inet_ntop(info->ai_family,
@@ -84,7 +65,7 @@ static JSBool dnsResolve(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
out:
if (info) freeaddrinfo(info);
- px_free(tmp);
+ JS_free(cx, tmp);
return true;
}
@@ -95,136 +76,87 @@ static JSBool myIpAddress(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
jsval arg = STRING_TO_JSVAL(myhost);
return dnsResolve(cx, obj, 1, &arg, rval);
}
- px_free(hostname);
+ JS_free(cx, hostname);
*rval = JSVAL_NULL;
return true;
}
-static void ctxs_free(ctxStore *self)
-{
- if (!self) return;
- if (self->ctx) JS_DestroyContext(self->ctx);
- if (self->run) JS_DestroyRuntime(self->run);
- if (self->cls) px_free(self->cls);
- px_free(self->pac);
- px_free(self);
-}
-
-static ctxStore *ctxs_new(pxPAC *pac)
-{
- JSObject *global = NULL;
- jsval rval;
-
- // Create the basic context
- ctxStore *self = (ctxStore*) px_malloc0(sizeof(ctxStore));
-
- // Setup Javascript global class
- self->cls = (JSClass*) px_malloc0(sizeof(JSClass));
- self->cls->name = "global";
- self->cls->flags = 0;
- self->cls->addProperty = JS_PropertyStub;
- self->cls->delProperty = JS_PropertyStub;
- self->cls->getProperty = JS_PropertyStub;
- self->cls->setProperty = JS_PropertyStub;
- self->cls->enumerate = JS_EnumerateStub;
- self->cls->resolve = JS_ResolveStub;
- self->cls->convert = JS_ConvertStub;
- self->cls->finalize = JS_FinalizeStub;
-
- // Initialize Javascript runtime environment
- if (!(self->run = JS_NewRuntime(1024 * 1024))) goto error;
- if (!(self->ctx = JS_NewContext(self->run, 1024 * 1024))) goto error;
- if (!(global = JS_NewObject(self->ctx, self->cls, NULL, NULL))) goto error;
- JS_InitStandardClasses(self->ctx, global);
-
- // Define Javascript functions
- JS_DefineFunction(self->ctx, global, "dnsResolve", dnsResolve, 1, 0);
- JS_DefineFunction(self->ctx, global, "myIpAddress", myIpAddress, 0, 0);
- JS_EvaluateScript(self->ctx, global, JAVASCRIPT_ROUTINES,
- strlen(JAVASCRIPT_ROUTINES), "pacutils.js", 0, &rval);
-
- // Add PAC to the environment
- JS_EvaluateScript(self->ctx, global, px_pac_to_string(pac),
- strlen(px_pac_to_string(pac)),
- px_url_to_string((pxURL *) px_pac_get_url(pac)),
- 0, &rval);
-
- // Save the pac
- self->pac = px_strdup(px_pac_to_string(pac));
- return self;
-
-error:
- ctxs_free(self);
- return NULL;
-}
-
-static void
-_destructor(void *s)
-{
- pxMozillaPACRunnerModule * self = (pxMozillaPACRunnerModule *) s;
-
- ctxs_free(self->ctxs);
- px_free(self);
-}
-
-static char *
-_run(pxPACRunnerModule *self, pxPAC *pac, pxURL *url)
-{
- // Make sure we have the pac file and url
- if (!pac) return NULL;
- if (!url) return NULL;
- if (!px_pac_to_string(pac) && !px_pac_reload(pac)) return NULL;
-
- // Get the cached context
- ctxStore *ctxs = ((pxMozillaPACRunnerModule *) self)->ctxs;
-
- // If there is a cached context, make sure it is the same pac
- if (ctxs && strcmp(ctxs->pac, px_pac_to_string(pac)))
- {
- ctxs_free(ctxs);
- ctxs = NULL;
- ((pxMozillaPACRunnerModule *) self)->ctxs = NULL;
+class mozjs_pacrunner : public pacrunner {
+public:
+ mozjs_pacrunner(const pac pac) throw (bad_alloc) {
+ jsval rval;
+
+ // Set defaults
+ this->jsrun = NULL;
+ this->jsctx = NULL;
+
+ // Setup Javascript global class
+ JSClass cls = {
+ "global", JSCLASS_GLOBAL_FLAGS,
+ JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+ JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
+ };
+
+ // Initialize Javascript runtime environment
+ if (!(this->jsrun = JS_NewRuntime(1024 * 1024))) goto error;
+ if (!(this->jsctx = JS_NewContext(this->jsrun, 1024 * 1024))) goto error;
+ //JS_SetOptions(this->jsctx, JSOPTION_VAROBJFIX);
+ //JS_SetVersion(this->jsctx, JSVERSION_LATEST);
+ //JS_SetErrorReporter(cx, reportError);
+ if (!(this->jsglb = JS_NewObject(this->jsctx, &cls, NULL, NULL))) goto error;
+ if (!JS_InitStandardClasses(this->jsctx, this->jsglb)) goto error;
+
+ // Define Javascript functions
+ JS_DefineFunction(this->jsctx, this->jsglb, "dnsResolve", dnsResolve, 1, 0);
+ JS_DefineFunction(this->jsctx, this->jsglb, "myIpAddress", myIpAddress, 0, 0);
+ JS_EvaluateScript(this->jsctx, this->jsglb, JAVASCRIPT_ROUTINES,
+ strlen(JAVASCRIPT_ROUTINES), "pacutils.js", 0, &rval);
+
+ // Add PAC to the environment
+ JS_EvaluateScript(this->jsctx, this->jsglb, pac.to_string().c_str(),
+ strlen(pac.to_string().c_str()),
+ pac.get_url().to_string().c_str(), 0, &rval);
+ return;
+
+ error:
+ if (this->jsctx) JS_DestroyContext(this->jsctx);
+ if (this->jsrun) JS_DestroyRuntime(this->jsrun);
+ throw bad_alloc();
}
- // If no context exists (or if the pac was changed), create one
- if (!ctxs)
- {
- if ((ctxs = ctxs_new(pac)))
- ((pxMozillaPACRunnerModule *) self)->ctxs = ctxs;
- else
- return NULL;
+ ~mozjs_pacrunner() {
+ if (this->jsctx) JS_DestroyContext(this->jsctx);
+ if (this->jsrun) JS_DestroyRuntime(this->jsrun);
+ // JS_ShutDown()?
}
- // Build arguments to the FindProxyForURL() function
- char *tmpurl = px_strdup(px_url_to_string(url));
- char *tmphost = px_strdup(px_url_get_host(url));
- jsval args[2] = {
- STRING_TO_JSVAL(JS_NewString(ctxs->ctx, tmpurl, strlen(tmpurl))),
- STRING_TO_JSVAL(JS_NewString(ctxs->ctx, tmphost, strlen(tmphost)))
- };
-
- // Find the proxy (call FindProxyForURL())
- jsval rval;
- JSBool result = JS_CallFunctionName(ctxs->ctx, JS_GetGlobalObject(ctxs->ctx), "FindProxyForURL", 2, args, &rval);
- if (!result) return NULL;
- char *answer = px_strdup(JS_GetStringBytes(JS_ValueToString(ctxs->ctx, rval)));
- if (!answer || !strcmp(answer, "undefined")) {
- px_free(answer);
- return NULL;
+ string run(const url url) throw (bad_alloc) {
+ // Build arguments to the FindProxyForURL() function
+ char *tmpurl = JS_strdup(this->jsctx, url.to_string().c_str());
+ char *tmphost = JS_strdup(this->jsctx, url.get_host().c_str());
+ if (!tmpurl || !tmphost) {
+ if (tmpurl) JS_free(this->jsctx, tmpurl);
+ if (tmphost) JS_free(this->jsctx, tmphost);
+ throw bad_alloc();
+ }
+ jsval args[2] = {
+ STRING_TO_JSVAL(JS_NewString(this->jsctx, tmpurl, strlen(tmpurl))),
+ STRING_TO_JSVAL(JS_NewString(this->jsctx, tmphost, strlen(tmphost)))
+ };
+
+ // Find the proxy (call FindProxyForURL())
+ jsval rval;
+ JSBool result = JS_CallFunctionName(this->jsctx, this->jsglb, "FindProxyForURL", 2, args, &rval);
+ if (!result) return "";
+ string answer = string(JS_GetStringBytes(JS_ValueToString(this->jsctx, rval)));
+ if (answer == "undefined") return "";
+ return answer;
}
- return answer;
-}
-static void *
-_constructor()
-{
- pxMozillaPACRunnerModule *self = (pxMozillaPACRunnerModule*) px_malloc0(sizeof(pxMozillaPACRunnerModule));
- self->__parent__.run = _run;
- return self;
-}
+private:
+ JSRuntime *jsrun;
+ JSContext *jsctx;
+ JSObject *jsglb;
+};
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxPACRunnerModule, _constructor, _destructor);
-}
+PX_DEFINE_PACRUNNER_MODULE(mozjs, true);
diff --git a/libproxy/modules/pacrunner_webkit.cpp b/libproxy/modules/pacrunner_webkit.cpp
index eb7d661..592bbae 100644
--- a/libproxy/modules/pacrunner_webkit.cpp
+++ b/libproxy/modules/pacrunner_webkit.cpp
@@ -17,25 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#ifdef _WIN32
-#define _WIN32_WINNT 0x0501
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <../platform/win32/inet.h>
-#else
-#include <sys/socket.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#endif
-#define __USE_BSD
-#include <unistd.h>
-
-#include "../misc.hpp"
-#include "../modules.hpp"
+#include "../module_types.hpp"
+using namespace com::googlecode::libproxy;
#include <JavaScriptCore/JavaScript.h>
#include "pacutils.h"
@@ -48,19 +31,9 @@
#define INET6_ADDRSTRLEN 46
#endif
-typedef struct {
- JSGlobalContextRef ctx;
- char *pac;
-} ctxStore;
-
-typedef struct _pxWebKitPACRunnerModule {
- PX_MODULE_SUBCLASS(pxPACRunnerModule);
- ctxStore *ctxs;
-} pxWebKitPACRunnerModule;
-
-static char *jstr2str(JSStringRef str, bool release)
+static char *jstr2str(JSStringRef str, bool release) throw (bad_alloc)
{
- char *tmp = (char*) px_malloc0(JSStringGetMaximumUTF8CStringSize(str)+1);
+ char *tmp = new char[JSStringGetMaximumUTF8CStringSize(str)+1];
JSStringGetUTF8CString(str, tmp, JSStringGetMaximumUTF8CStringSize(str)+1);
if (release) JSStringRelease(str);
return tmp;
@@ -78,10 +51,10 @@ static JSValueRef dnsResolve(JSContextRef ctx, JSObjectRef func, JSObjectRef sel
struct addrinfo *info;
if (getaddrinfo(tmp, NULL, NULL, &info))
return NULL;
- px_free(tmp);
+ delete tmp;
// Try for IPv4
- tmp = (char*) px_malloc0(INET6_ADDRSTRLEN+1);
+ tmp = new char[INET6_ADDRSTRLEN+1];
if (!inet_ntop(info->ai_family,
&((struct sockaddr_in *) info->ai_addr)->sin_addr,
tmp, INET_ADDRSTRLEN+1) > 0)
@@ -91,7 +64,7 @@ static JSValueRef dnsResolve(JSContextRef ctx, JSObjectRef func, JSObjectRef sel
tmp, INET6_ADDRSTRLEN+1) > 0)
{
freeaddrinfo(info);
- px_free(tmp);
+ delete tmp;
return NULL;
}
freeaddrinfo(info);
@@ -100,7 +73,7 @@ static JSValueRef dnsResolve(JSContextRef ctx, JSObjectRef func, JSObjectRef sel
JSStringRef str = JSStringCreateWithUTF8CString(tmp);
JSValueRef ret = JSValueMakeString(ctx, str);
JSStringRelease(str);
- px_free(tmp);
+ delete tmp;
return ret;
}
@@ -118,125 +91,77 @@ static JSValueRef myIpAddress(JSContextRef ctx, JSObjectRef func, JSObjectRef se
return NULL;
}
-static void ctxs_free(ctxStore *self)
-{
- if (!self) return;
- JSGarbageCollect(self->ctx);
- JSGlobalContextRelease(self->ctx);
- px_free(self->pac);
- px_free(self);
-}
-
-static ctxStore *ctxs_new(pxPAC *pac)
-{
- JSStringRef str = NULL;
- JSObjectRef func = NULL;
-
- // Create the basic context
- ctxStore *self = (ctxStore*) px_malloc0(sizeof(ctxStore));
- self->pac = px_strdup(px_pac_to_string(pac));
- if (!(self->ctx = JSGlobalContextCreate(NULL))) goto error;
-
- // Add dnsResolve into the context
- str = JSStringCreateWithUTF8CString("dnsResolve");
- func = JSObjectMakeFunctionWithCallback(self->ctx, str, dnsResolve);
- JSObjectSetProperty(self->ctx, JSContextGetGlobalObject(self->ctx), str, func, kJSPropertyAttributeNone, NULL);
- JSStringRelease(str);
-
- // Add myIpAddress into the context
- str = JSStringCreateWithUTF8CString("myIpAddress");
- func = JSObjectMakeFunctionWithCallback(self->ctx, str, myIpAddress);
- JSObjectSetProperty(self->ctx, JSContextGetGlobalObject(self->ctx), str, func, kJSPropertyAttributeNone, NULL);
- JSStringRelease(str);
+class webkit_pacrunner : public pacrunner {
+public:
+ ~webkit_pacrunner() {
+ JSGarbageCollect(this->jsctx);
+ JSGlobalContextRelease(this->jsctx);
+ }
- // Add all other routines into the context
- str = JSStringCreateWithUTF8CString(JAVASCRIPT_ROUTINES);
- if (!JSCheckScriptSyntax(self->ctx, str, NULL, 0, NULL)) goto error;
- JSEvaluateScript(self->ctx, str, NULL, NULL, 1, NULL);
- JSStringRelease(str);
+ webkit_pacrunner(const pac pac) throw (bad_alloc) {
+ JSStringRef str = NULL;
+ JSObjectRef func = NULL;
- // Add the PAC into the context
- str = JSStringCreateWithUTF8CString(self->pac);
- if (!JSCheckScriptSyntax(self->ctx, str, NULL, 0, NULL)) goto error;
- JSEvaluateScript(self->ctx, str, NULL, NULL, 1, NULL);
- JSStringRelease(str);
+ // Create the basic context
+ if (!(this->jsctx = JSGlobalContextCreate(NULL))) goto error;
- return self;
-
-error:
- if (str) JSStringRelease(str);
- ctxs_free(self);
- return NULL;
-}
+ // Add dnsResolve into the context
+ str = JSStringCreateWithUTF8CString("dnsResolve");
+ func = JSObjectMakeFunctionWithCallback(this->jsctx, str, dnsResolve);
+ JSObjectSetProperty(this->jsctx, JSContextGetGlobalObject(this->jsctx), str, func, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(str);
-static void
-_destructor(void *s)
-{
- pxWebKitPACRunnerModule *self = (pxWebKitPACRunnerModule *) s;
+ // Add myIpAddress into the context
+ str = JSStringCreateWithUTF8CString("myIpAddress");
+ func = JSObjectMakeFunctionWithCallback(this->jsctx, str, myIpAddress);
+ JSObjectSetProperty(this->jsctx, JSContextGetGlobalObject(this->jsctx), str, func, kJSPropertyAttributeNone, NULL);
+ JSStringRelease(str);
- ctxs_free(self->ctxs);
- px_free(self);
-}
+ // Add all other routines into the context
+ str = JSStringCreateWithUTF8CString(JAVASCRIPT_ROUTINES);
+ if (!JSCheckScriptSyntax(this->jsctx, str, NULL, 0, NULL)) goto error;
+ JSEvaluateScript(this->jsctx, str, NULL, NULL, 1, NULL);
+ JSStringRelease(str);
-static char *
-_run(pxPACRunnerModule *self, pxPAC *pac, pxURL *url)
-{
- JSStringRef str = NULL;
- JSValueRef val = NULL;
- char *tmp = NULL;
-
- // Make sure we have the pac file and url
- if (!pac) return NULL;
- if (!url) return NULL;
- if (!px_pac_to_string(pac) && !px_pac_reload(pac)) return NULL;
-
- // Get the cached context
- ctxStore *ctxs = ((pxWebKitPACRunnerModule *) self)->ctxs;
-
- // If there is a cached context, make sure it is the same pac
- if (ctxs && strcmp(ctxs->pac, px_pac_to_string(pac)))
- {
- ctxs_free(ctxs);
- ctxs = NULL;
- }
+ // Add the PAC into the context
+ str = JSStringCreateWithUTF8CString(pac.to_string().c_str());
+ if (!JSCheckScriptSyntax(this->jsctx, str, NULL, 0, NULL)) goto error;
+ JSEvaluateScript(this->jsctx, str, NULL, NULL, 1, NULL);
+ JSStringRelease(str);
+ return;
- // If no context exists (or if the pac was changed), create one
- if (!ctxs)
- {
- if ((ctxs = ctxs_new(pac)))
- ((pxWebKitPACRunnerModule *) self)->ctxs = ctxs;
- else
- return NULL;
+ error:
+ if (str) JSStringRelease(str);
+ if (this->jsctx) {
+ JSGarbageCollect(this->jsctx);
+ JSGlobalContextRelease(this->jsctx);
+ }
+ throw bad_alloc();
}
- // Run the PAC
- tmp = px_strcat("FindProxyForURL(\"", px_url_to_string(url), "\", \"", px_url_get_host(url), "\");", NULL);
- str = JSStringCreateWithUTF8CString(tmp);
- px_free(tmp); tmp = NULL;
- if (!JSCheckScriptSyntax(ctxs->ctx, str, NULL, 0, NULL)) goto error;
- if (!(val = JSEvaluateScript(ctxs->ctx, str, NULL, NULL, 1, NULL))) goto error;
- if (!JSValueIsString(ctxs->ctx, val)) goto error;
- JSStringRelease(str);
+ string run(const url url) throw (bad_alloc) {
+ JSStringRef str = NULL;
+ JSValueRef val = NULL;
+ string tmp;
+
+ // Run the PAC
+ tmp = string("FindProxyForURL(\"") + url.to_string() + string("\", \"") + url.get_host() + "\");";
+ str = JSStringCreateWithUTF8CString(tmp.c_str());
+ if (!JSCheckScriptSyntax(this->jsctx, str, NULL, 0, NULL)) goto error;
+ if (!(val = JSEvaluateScript(this->jsctx, str, NULL, NULL, 1, NULL))) goto error;
+ if (!JSValueIsString(this->jsctx, val)) goto error;
+ JSStringRelease(str);
- // Convert the return value to a string
- return jstr2str(JSValueToStringCopy(ctxs->ctx, val, NULL), true);
+ // Convert the return value to a string
+ return jstr2str(JSValueToStringCopy(this->jsctx, val, NULL), true);
-error:
- if (str) JSStringRelease(str);
- ctxs_free(ctxs);
- return tmp;
-}
+ error:
+ if (str) JSStringRelease(str);
+ throw bad_alloc();
+ }
-static void *
-_constructor()
-{
- pxWebKitPACRunnerModule *self = (pxWebKitPACRunnerModule*) px_malloc0(sizeof(pxWebKitPACRunnerModule));
- self->__parent__.run = _run;
- return self;
-}
+private:
+ JSGlobalContextRef jsctx;
+};
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxPACRunnerModule, _constructor, _destructor);
-}
+PX_DEFINE_PACRUNNER_MODULE(webkit, true);
diff --git a/libproxy/modules/pxgconf.cpp b/libproxy/modules/pxgconf.cpp
new file mode 100644
index 0000000..0164413
--- /dev/null
+++ b/libproxy/modules/pxgconf.cpp
@@ -0,0 +1,180 @@
+#include <cstdio>
+#include <unistd.h>
+#include <signal.h>
+
+#include <glib.h>
+#include <gconf/gconf.h>
+#include <gconf/gconf-client.h>
+
+using namespace std;
+
+static GMainLoop* loop = NULL;
+
+static int _print_value(const GConfValue *value, const char *suffix) {
+ int count = 0;
+ GSList* cursor = NULL;
+
+ if (!value) return 0;
+
+ switch (value->type) {
+ case GCONF_VALUE_STRING:
+ return printf("%s%s", gconf_value_get_string(value), suffix);
+ case GCONF_VALUE_INT:
+ return printf("%d%s", gconf_value_get_int(value), suffix);
+ case GCONF_VALUE_FLOAT:
+ return printf("%f%s", gconf_value_get_float(value), suffix);
+ case GCONF_VALUE_BOOL:
+ if (gconf_value_get_bool(value))
+ return printf("true%s", suffix);
+ return printf("false%s", suffix);
+ case GCONF_VALUE_LIST:
+ cursor = gconf_value_get_list(value);
+ for ( ; cursor ; cursor = g_slist_next(cursor))
+ count += _print_value((const GConfValue *) cursor->data, cursor->next ? "," : suffix);
+ return count;
+ case GCONF_VALUE_PAIR:
+ return _print_value(gconf_value_get_car(value), ",") +
+ _print_value(gconf_value_get_cdr(value), suffix);
+ }
+ return 0;
+}
+
+static void _on_value_change(GConfClient *client, guint cnxn_id, GConfEntry *entry, void *user_data) {
+ printf("%s\t", gconf_entry_get_key(entry));
+ _print_value(gconf_entry_get_value(entry), "\n");
+}
+
+static void _on_sig(int signal) {
+ g_main_loop_quit(loop);
+}
+
+static gboolean _error(GIOChannel *source, GIOCondition condition, gpointer data) {
+ g_main_loop_quit(loop);
+ return false;
+}
+
+static gboolean _set_key(const char *key, const char *val) {
+ gboolean error = false;
+ GConfClient *client = gconf_client_get_default();
+ GConfValue *value = gconf_client_get(client, key, NULL);
+ GConfValueType type = value ? value->type : GCONF_VALUE_STRING;
+ gconf_value_free(value);
+
+ switch (type) {
+ case GCONF_VALUE_STRING:
+ error = !gconf_client_set_string(client, key, val, NULL);
+ break;
+ case GCONF_VALUE_INT:
+ int ival;
+ error = sscanf(val, "%d", &ival) != 1;
+ error = error || !gconf_client_set_int(client, key, ival, NULL);
+ break;
+ case GCONF_VALUE_FLOAT:
+ int fval;
+ error = sscanf(val, "%f", &fval) != 1;
+ error = error || !gconf_client_set_float(client, key, fval, NULL);
+ break;
+ case GCONF_VALUE_BOOL:
+ error = !gconf_client_set_float(client, key, !g_strcmp0(val, "true"), NULL);
+ break;
+ case GCONF_VALUE_LIST:
+ case GCONF_VALUE_PAIR:
+ default:
+ g_critical("Invalid value type!");
+ error = true;
+ }
+
+ g_object_unref(client);
+ return !error;
+}
+
+static gboolean _stdin(GIOChannel *source, GIOCondition condition, gpointer data) {
+ gchar *key, *val;
+ GIOStatus st = g_io_channel_read_line(source, &key, NULL, NULL, NULL);
+
+ // Remove the trailing '\n'
+ for (int i=0 ; key && key[i] ; i++)
+ if (key[i] == '\n')
+ key[i] = NULL;
+
+ // If we were successful
+ if (key && st == G_IO_STATUS_NORMAL) {
+ if (!g_strrstr(key, "\t"))
+ goto exit;
+
+ val = g_strrstr(key, "\t") + 1;
+ *(val-1) = NULL;
+
+ if (!_set_key(key, val))
+ goto exit;
+
+ g_free(key);
+ return true;
+ }
+ else if (key && st == G_IO_STATUS_AGAIN) {
+ g_free(key);
+ return _stdin(source, condition, data);
+ }
+
+exit:
+ g_free(key);
+ return _error(source, condition, data);
+}
+
+int main(int argc, char **argv) {
+ if (argc < 2) return 1;
+
+ // Register sighup handler
+ if (signal(SIGHUP, _on_sig) == SIG_ERR || signal(SIGPIPE, _on_sig) == SIG_ERR) {
+ fprintf(stderr, "Unable to trap signals!");
+ return 2;
+ }
+
+ // Switch stdout to line buffering
+ if (setvbuf(stdout, NULL, _IOLBF, 0)) {
+ fprintf(stderr, "Unable to switch stdout to line buffering!");
+ return 3;
+ }
+
+ // Switch stdin to line buffering
+ if (setvbuf(stdin, NULL, _IOLBF, 0)) {
+ fprintf(stderr, "Unable to switch stdin to line buffering!");
+ return 4;
+ }
+
+ // Init
+ g_type_init();
+
+ // Get the main loop
+ loop = g_main_loop_new(NULL, false);
+
+ // Setup our GIO Channels
+ GIOChannel* inchan = g_io_channel_unix_new(fileno(stdin));
+ GIOChannel* outchan = g_io_channel_unix_new(fileno(stdout));
+ g_io_add_watch(inchan, G_IO_IN, _stdin, NULL);
+ g_io_add_watch(inchan, G_IO_PRI, _stdin, NULL);
+ g_io_add_watch(inchan, G_IO_ERR, _error, NULL);
+ g_io_add_watch(inchan, G_IO_HUP, _error, NULL);
+ g_io_add_watch(outchan, G_IO_ERR, _error, NULL);
+ g_io_add_watch(outchan, G_IO_HUP, _error, NULL);
+
+ // Get GConf client
+ GConfClient* client = gconf_client_get_default();
+
+ // Add server notifications for all keys
+ for (int i=1 ; i < argc ; i++) {
+ gconf_client_add_dir(client, argv[i], GCONF_CLIENT_PRELOAD_NONE, NULL);
+ gconf_client_notify_add(client, argv[i], _on_value_change, NULL, NULL, NULL);
+ gconf_client_notify(client, argv[i]);
+ }
+
+ g_main_loop_run(loop);
+
+ // Cleanup
+ g_object_unref(client);
+ g_io_channel_shutdown(inchan, FALSE, NULL);
+ g_io_channel_shutdown(outchan, FALSE, NULL);
+ g_io_channel_unref(inchan);
+ g_io_channel_unref(outchan);
+ g_main_loop_unref(loop);
+}
diff --git a/libproxy/modules/wpad_dns.cpp b/libproxy/modules/wpad_dns.cpp
index a8858e5..8918560 100644
--- a/libproxy/modules/wpad_dns.cpp
+++ b/libproxy/modules/wpad_dns.cpp
@@ -17,50 +17,37 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <stdlib.h>
-#include <string.h>
+#include "../module_types.hpp"
-#include "../misc.hpp"
-#include "../modules.hpp"
-#include "../pac.hpp"
+using namespace com::googlecode::libproxy;
-typedef struct _pxDNSWPADModule {
- PX_MODULE_SUBCLASS(pxWPADModule);
- bool rewound;
-} pxDNSWPADModule;
+class dns_wpad_module : public wpad_module {
+public:
+ PX_MODULE_ID(NULL);
-static pxPAC *
-_next(pxWPADModule *self)
-{
- if (((pxDNSWPADModule *) self)->rewound)
- {
- pxPAC *pac = px_pac_new_from_string("http://wpad/wpad.dat");
- self->found = pac != NULL;
- return pac;
+ dns_wpad_module() {
+ this->last = NULL;
}
- else
- return NULL;
-}
-static void
-_rewind(pxWPADModule *self)
-{
- ((pxDNSWPADModule *) self)->rewound = true;
-}
+ bool found() {
+ return this->last != NULL;
+ }
+
+ pac* next() {
+ if (this->last) return NULL;
+
+ try { this->last = new pac(url("http://wpad/wpad.dat")); }
+ catch (io_error& e) { }
+
+ return this->last;
+ }
+
+ void rewind() {
+ this->last = NULL;
+ }
-static void *
-_constructor()
-{
- pxDNSWPADModule *self = (pxDNSWPADModule*) px_malloc0(sizeof(pxDNSWPADModule));
- self->rewound = true;
- self->__parent__.found = false;
- self->__parent__.next = _next;
- self->__parent__.rewind = _rewind;
- return self;
-}
+private:
+ pac* last;
+};
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxWPADModule, _constructor, px_free);
-}
+PX_MODULE_LOAD(wpad_module, dns, true);
diff --git a/libproxy/modules/wpad_dnsdevolution.cpp b/libproxy/modules/wpad_dnsdevolution.cpp
index 05019b7..37e7770 100644
--- a/libproxy/modules/wpad_dnsdevolution.cpp
+++ b/libproxy/modules/wpad_dnsdevolution.cpp
@@ -17,165 +17,88 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
******************************************************************************/
-#include <string.h>
-#include <errno.h>
-#include <stdio.h>
-#define __USE_BSD
-#include <unistd.h>
-
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-#include <netdb.h>
-#endif
-
-#include "../misc.hpp"
-#include "../array.hpp"
-#include "../modules.hpp"
-#include "../pac.hpp"
-
-/* The top-level domain blacklist */
+#include <cstring>
+
+#include "../module_types.hpp"
+using namespace com::googlecode::libproxy;
+
+/* The domain blacklist */
/* TODO: Make this not suck */
-static char *tld[] = {
- /* General top-level domains */
- "arpa", "root", "aero", "biz", "cat", "com", "coop", "edu", "gov", "info",
- "int", "jobs", "mil", "mobi", "museum", "name", "net", "org", "pro", "travel",
-
- /* Country codes */
- "ac", "ad", "ae", "af", "ag", "ai", "al", "am", "an", "ao", "aq", "ar",
- "as", "at", "au", "aw", "ax", "az", "ba", "bb", "bd", "be", "bf", "bg",
- "bh", "bi", "bj", "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by",
- "bz", "ca", "cc", "cd", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn",
- "co", "cr", "cu", "cv", "cx", "cy", "cz", "de", "dj", "dk", "dm", "do",
- "dz", "ec", "ee", "eg", "er", "es", "et", "eu", "fi", "fj", "fk", "fm",
- "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gg", "gh", "gi", "gl", "gm",
- "gn", "gp", "gq", "gr", "gs", "gt", "gu", "gw", "gy", "hk", "hm", "hn",
- "hr", "ht", "hu", "id", "ie", "il", "im", "in", "io", "iq", "ir", "is",
- "it", "je", "jm", "jo", "jp", "ke", "kg", "kh", "ki", "km", "kn", "kr",
- "kw", "ky", "kz", "la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu",
- "lv", "ly", "ma", "mc", "md", "mg", "mh", "mk", "ml", "mm", "mn", "mo",
- "mp", "mq", "mr", "ms", "mt", "mu", "mv", "mw", "mx", "my", "mz", "na",
- "nc", "ne", "nf", "ng", "ni", "nl", "no", "np", "nr", "nu", "nz", "om",
- "pa", "pe", "pf", "pg", "ph", "pk", "pl", "pm", "pn", "pr", "ps", "pt",
- "pw", "py", "qa", "re", "ro", "ru", "rw", "sa", "sb", "sc", "sd", "se",
- "sg", "sh", "si", "sj", "sk", "sl", "sm", "sn", "sr", "st", "su", "sv",
- "sy", "sz", "tc", "td", "tf", "tg", "th", "tj", "tk", "tl", "tm", "tn",
- "to", "tp", "tr", "tt", "tv", "tw", "tz", "ua", "ug", "uk", "um", "us",
- "uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws", "ye",
- "yt", "yu", "za", "zm", "zw",
-
- /* Other domains to blacklist */
+/* Is there a list of 'public' domains somewhere? */
+static const char *blacklist[] = {
"co.uk", "com.au",
/* Terminator */
NULL
};
-typedef struct _pxDNSDevolutionWPADModule {
- PX_MODULE_SUBCLASS(pxWPADModule);
- pxArray *urls;
- int next;
-} pxDNSDevolutionWPADModule;
-
-static char *
-_get_domain_name()
+static string
+_get_fqdn()
{
- /* Get the hostname */
- char *hostname = (char *) px_malloc0(128);
- for (int i = 0 ; gethostname(hostname, (i + 1) * 128) && errno == ENAMETOOLONG ; )
- hostname = (char *) px_malloc0((++i + 1) * 128);
+#define BUFLEN 512
+ char hostname[BUFLEN];
+
+ // Zero out the buffer
+ memset(hostname, 0, BUFLEN);
+
+ // Get the hostname
+ if (gethostname(hostname, BUFLEN)) return "";
/* Lookup the hostname */
/* TODO: Make this whole process not suck */
struct hostent *host_info = gethostbyname(hostname);
if (host_info)
- {
- px_free(hostname);
- hostname = px_strdup(host_info->h_name);
- }
+ strncpy(hostname, host_info->h_name, BUFLEN-1);
- /* Get domain portion */
- if (!strchr(hostname, '.')) return NULL;
- if (!strcmp(".", strchr(hostname, '.'))) return NULL;
- char *tmp = px_strdup(strchr(hostname, '.') + 1);
- px_free(hostname);
- return tmp;
+ try { return string(hostname).substr(string(hostname).find(".")).substr(1); }
+ catch (out_of_range& e) { return ""; }
}
-static pxArray *
-_get_urls()
-{
- char *domain = _get_domain_name();
- if (!domain) return NULL;
-
- /* Split up the domain */
- char **domainv = px_strsplit(domain, ".");
- px_free(domain);
- if (!domainv) return NULL;
-
- pxArray *urls = px_array_new(NULL, px_free, false, false);
- for (int i=1 ; domainv[i] ; i++)
- {
- /* Check the domain against the blacklist */
- domain = px_strjoin((const char **) (domainv + i), ".");
- for (int k=0; tld[k] ; k++)
- if (!strcmp(domain, tld[k])) { px_free(domain); domain = NULL; break; }
- if (!domain) continue;
-
- /* Create a URL */
- char *url = px_strcat("http://wpad.", domain, "/wpad.dat", NULL);
- px_array_add(urls, url);
- px_free(domain);
+class dnsdevolution_wpad_module : public wpad_module {
+public:
+ PX_MODULE_ID(NULL);
+
+ dnsdevolution_wpad_module() {
+ this->rewind();
}
- return urls;
-}
+ bool found() {
+ return this->lpac != NULL;
+ }
-static pxPAC *
-_next(pxWPADModule *self)
-{
- pxDNSDevolutionWPADModule *dnsd = (pxDNSDevolutionWPADModule *) self;
- if (!dnsd->urls)
- dnsd->urls = _get_urls();
- if (!dnsd->urls)
- return NULL;
-
- pxPAC *pac = px_pac_new_from_string((char *) px_array_get(dnsd->urls, dnsd->next++));
- if (pac)
- self->found = true;
- return pac;
-}
+ pac* next() {
+ // If we have rewound start the new count
+ if (this->last == "")
+ this->last = _get_fqdn();
-static void
-_rewind(pxWPADModule *s)
-{
- pxDNSDevolutionWPADModule * self = (pxDNSDevolutionWPADModule *) s;
+ // Get the 'next' segment
+ if (this->last.find(".") == string::npos) return NULL;
+ this->last = this->last.substr(this->last.find(".")+1);
- px_array_free(self->urls);
- self->urls = NULL;
- self->next = 0;
- self->__parent__.found = false;
-}
+ // Don't do TLD's
+ if (this->last.find(".") == string::npos) return NULL;
-static void
-_destructor(void *s)
-{
- _rewind((pxWPADModule *) s);
- px_free(s);
-}
+ // Process blacklist
+ for (int i=0 ; blacklist[i] ; i++)
+ if (this->last == blacklist[i])
+ return NULL;
-static void *
-_constructor()
-{
- pxDNSDevolutionWPADModule *self = (pxDNSDevolutionWPADModule*) px_malloc0(sizeof(pxDNSDevolutionWPADModule));
- self->__parent__.next = _next;
- self->__parent__.rewind = _rewind;
- _rewind((pxWPADModule *) self);
- return self;
-}
+ // Try to load
+ try { this->lpac = new pac(url(string("http://wpad.") + this->last + "/wpad.dat")); }
+ catch (parse_error& e) { }
+ catch (io_error& e) { }
-bool
-px_module_load(pxModuleManager *self)
-{
- return px_module_manager_register_module(self, pxWPADModule, _constructor, _destructor);
-}
+ return this->lpac;
+ }
+
+ void rewind() {
+ this->last = "";
+ }
+
+
+private:
+ string last;
+ pac* lpac;
+};
+
+PX_MODULE_LOAD(wpad_module, dnsdevolution, true);
diff --git a/libproxy/modules/xhasclient.cpp b/libproxy/modules/xhasclient.cpp
index 85c563a..af829f4 100644
--- a/libproxy/modules/xhasclient.cpp
+++ b/libproxy/modules/xhasclient.cpp
@@ -1,6 +1,6 @@
/*
*
- *
+ *
Copyright 1989, 1998 The Open Group
Permission to use, copy, modify, distribute, and sell this software and its
@@ -31,54 +31,46 @@ in this Software without prior written authorization from The Open Group.
* Reworked by Nathaniel McCallum, 2007
*/
-#include <stdbool.h>
#include <stdarg.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xmu/WinUtil.h>
-bool
-x_has_client(char *prog, ...)
-{
+bool xhasclient(const char *prog, ...) {
va_list ap;
-
+
// Open display
Display *display = XOpenDisplay(NULL);
if (!display)
return false;
-
+
// For each screen...
- for (int i=0; i < ScreenCount(display); i++)
- {
+ for (int i=0; i < ScreenCount(display); i++) {
Window dummy, *children = NULL;
unsigned int nchildren = 0;
-
+
// Get the root window's children
if (!XQueryTree(display, RootWindow(display, i), &dummy, &dummy, &children, &nchildren))
continue;
-
+
// For each child on the screen...
- for (int j=0; j < nchildren; j++)
- {
+ for (int j=0; j < nchildren; j++) {
// If we can get their client info...
Window client;
- if ((client = XmuClientWindow(display, children[j])) != None)
- {
+ if ((client = XmuClientWindow(display, children[j])) != None) {
int argc;
char **argv;
-
+
// ... and if we can find out their command ...
if (!XGetCommand (display, client, &argv, &argc) || argc == 0)
continue;
-
+
// ... check the commands against our list
va_start(ap, prog);
- for (char *s = prog ; s ; s = va_arg(ap, char *))
- {
+ for (const char *s = prog ; s ; s = va_arg(ap, char *)) {
// We've found a match, return...
- if (!strcmp(argv[0], s))
- {
+ if (!strcmp(argv[0], s)) {
va_end(ap);
XCloseDisplay(display);
return true;
@@ -88,7 +80,7 @@ x_has_client(char *prog, ...)
}
}
}
-
+
// Close the display
XCloseDisplay(display);
return false;