From eb677dcd774a460da9349cc3622c5e14317645bd Mon Sep 17 00:00:00 2001 From: npmccallum Date: Sun, 17 Jan 2010 00:49:40 +0000 Subject: make code more c++ish (major rework) git-svn-id: http://libproxy.googlecode.com/svn/trunk@457 c587cffe-e639-0410-9787-d7902ae8ed56 --- libproxy/modules/config_direct.cpp | 62 ----- libproxy/modules/config_envvar.cpp | 101 +++---- libproxy/modules/config_file.cpp | 118 +++----- libproxy/modules/config_gnome.cpp | 411 +++++++++++++--------------- libproxy/modules/config_kde4.cpp | 169 ++++-------- libproxy/modules/config_w32reg.cpp | 194 +++++-------- libproxy/modules/config_wpad.cpp | 51 +--- libproxy/modules/ignore_domain.cpp | 101 +++---- libproxy/modules/ignore_ip.cpp | 320 ++++++++++------------ libproxy/modules/network_networkmanager.cpp | 143 +++++----- libproxy/modules/pacrunner_mozjs.cpp | 232 ++++++---------- libproxy/modules/pacrunner_webkit.cpp | 213 +++++--------- libproxy/modules/pxgconf.cpp | 180 ++++++++++++ libproxy/modules/wpad_dns.cpp | 67 ++--- libproxy/modules/wpad_dnsdevolution.cpp | 199 +++++--------- libproxy/modules/xhasclient.cpp | 36 +-- 16 files changed, 1076 insertions(+), 1521 deletions(-) delete mode 100644 libproxy/modules/config_direct.cpp create mode 100644 libproxy/modules/pxgconf.cpp (limited to 'libproxy/modules') 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 - * - * 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 -#include - -#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 -#include - -#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 + +#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 -#include - -#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(new user_file_config_module); + return mm.register_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 -#include -#include -#include -#include - -#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 // For fileno(), fread(), pclose(), popen(), sscanf() +#include // For select(...) +#include // 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 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(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 -#include -#include -#include +#include // For KStandardDirs +#include "xhasclient.cpp" // For xhasclient(...) -#include "../misc.hpp" -#include "../modules.hpp" #include "../config_file.hpp" - -#include - -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 -#include -#include - -#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 _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 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 manual = _parse_manual(tmp); + delete tmp; + + // First we look for an exact match + if (manual.find(dst.get_scheme()) != map::end) + return manual[dst.get_scheme()]; + + // Next we look for http + else if (manual.find("http") != map::end) + return manual["http"]; + + // Last we look for socks + else if (manual.find("socks") != map::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 -#include +#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 -#include -#include +#include -#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 -#include -#include -#include +#include +#include #ifdef _WIN32 #define _WIN32_WINNT 0x0501 @@ -35,183 +33,161 @@ typedef unsigned short int sa_family_t; #include #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 -#include -#include - -#include "../misc.hpp" -#include "../modules.hpp" +#include "../module_types.hpp" #include #include -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 -#include -#include -#include -#include -#include -#include -#define __USE_BSD -#include - -#include "../misc.hpp" -#include "../modules.hpp" +#include // ? + +#include "../module_types.hpp" +using namespace com::googlecode::libproxy; #include #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 -#include -#include -#ifdef _WIN32 -#define _WIN32_WINNT 0x0501 -#include -#include -#include <../platform/win32/inet.h> -#else -#include -#include -#include -#include -#endif -#define __USE_BSD -#include - -#include "../misc.hpp" -#include "../modules.hpp" +#include "../module_types.hpp" +using namespace com::googlecode::libproxy; #include #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 +#include +#include + +#include +#include +#include + +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 -#include +#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 -#include -#include -#define __USE_BSD -#include - -#ifdef _WIN32 -#include -#else -#include -#endif - -#include "../misc.hpp" -#include "../array.hpp" -#include "../modules.hpp" -#include "../pac.hpp" - -/* The top-level domain blacklist */ +#include + +#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 #include #include #include #include -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; -- cgit v1.2.1