summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornpmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56>2008-06-05 20:56:04 +0000
committernpmccallum <npmccallum@c587cffe-e639-0410-9787-d7902ae8ed56>2008-06-05 20:56:04 +0000
commit9a401f3d7392134859a809905b11b7bcfaeea50b (patch)
treef34c169d4e4f43546bd4404af8c69be09e30ea55
parent197ba7edc0ce6f6758b198821a9c6bf7c1fd1932 (diff)
downloadlibproxy-git-libproxy-0.2.3.tar.gz
The real 0.2.3 releaselibproxy-0.2.3
-rw-r--r--ChangeLog7
-rw-r--r--Makefile.am5
-rw-r--r--configure.ac41
-rw-r--r--libproxy-1.0.pc.in10
-rw-r--r--src/bin/proxy.c26
-rw-r--r--src/lib/Makefile.am18
-rw-r--r--src/lib/array.c138
-rw-r--r--src/lib/array.h39
-rw-r--r--src/lib/config_file.c158
-rw-r--r--src/lib/config_file.h2
-rw-r--r--src/lib/dhcp.c (renamed from src/lib/wpad_dhcp.c)2
-rw-r--r--src/lib/dhcp.h (renamed from src/lib/wpad_dhcp.h)0
-rw-r--r--src/lib/dns.c (renamed from src/lib/wpad_dns.c)42
-rw-r--r--src/lib/dns.h (renamed from src/lib/wpad_dns.h)0
-rw-r--r--src/lib/misc.c24
-rw-r--r--src/lib/misc.h2
-rw-r--r--src/lib/pac.c34
-rw-r--r--src/lib/proxy.h2
-rw-r--r--src/lib/proxy_factory.c402
-rw-r--r--src/lib/proxy_factory.h20
-rw-r--r--src/lib/slp.c (renamed from src/lib/wpad_slp.c)2
-rw-r--r--src/lib/slp.h (renamed from src/lib/wpad_slp.h)0
-rw-r--r--src/lib/strdict.c122
-rw-r--r--src/lib/strdict.h35
-rw-r--r--src/lib/url.c46
-rw-r--r--src/lib/url.h2
-rw-r--r--src/lib/wpad.c5
-rw-r--r--src/lib/wpad.h6
-rw-r--r--src/plugins/Makefile.am10
-rw-r--r--src/plugins/mozjs.c189
-rw-r--r--src/plugins/networkmanager.c4
-rw-r--r--src/plugins/webkit.c209
32 files changed, 893 insertions, 709 deletions
diff --git a/ChangeLog b/ChangeLog
index 4ae5589..b4e9d0f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Thu Jun 05 17:05:12 2008 Nathaniel McCallum <nathaniel@natemccallum.com>
+ * === Released 0.2.3 ===
+ * New plugin: webkit (JavaScript)
+ * Massive speed improvements in all javascript plugins
+ * Bug fixes
+ * Memory leak fixes
+ * pkgconfig support
Wed Jan 09 04:18:45 2008 Jeff Schroeder <jeffschroeder@computer.org>
* === Released 0.2.2 ===
* Python bindings fix
diff --git a/Makefile.am b/Makefile.am
index af437a6..42ca864 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1 +1,6 @@
SUBDIRS = src
+
+EXTRA_DIST = libproxy-1.0.pc.in
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libproxy-1.0.pc
diff --git a/configure.ac b/configure.ac
index 36ad1e7..9b425b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
AC_PREREQ(2.61)
-AC_INIT([libproxy],[0.2.2],[nathaniel@natemccallum.com])
+AC_INIT([libproxy],[0.2.3],[nathaniel@natemccallum.com])
AC_CONFIG_SRCDIR([src/lib/proxy_factory.c])
AM_INIT_AUTOMAKE
@@ -11,16 +11,14 @@ AC_PROG_LIBTOOL
AC_PROG_LN_S
AC_PROG_MAKE_SET
-### Check for pthread
-AC_CHECK_HEADERS(pthread.h)
-AC_CHECK_FUNCS(pthread_mutex_init)
-
### Checks for libraries for plugins.
PKG_CHECK_MODULES(x11, x11, have_x11=yes, have_x11=no)
PKG_CHECK_MODULES(xmu, xmu, have_xmu=yes, have_xmu=no)
PKG_CHECK_MODULES(gconf, gconf-2.0, have_gconf=yes, have_gconf=no)
+PKG_CHECK_MODULES(webkit, webkit-1.0, have_webkit=yes, have_webkit=no)
PKG_CHECK_MODULES(mozjs, xulrunner-js, have_mozjs=yes,
- [PKG_CHECK_MODULES(mozjs, firefox-js, have_mozjs=yes, have_mozjs=no)])
+ [PKG_CHECK_MODULES(mozjs, firefox-js, have_mozjs=yes,
+ [PKG_CHECK_MODULES(mozjs, mozilla-js, have_mozjs=yes, have_mozjs=no)])])
PKG_CHECK_MODULES(NetworkManager, NetworkManager,
have_networkmanager=yes, have_networkmanager=no)
@@ -88,6 +86,27 @@ else
fi
AM_CONDITIONAL([WITH_KDE], [test x$with_kde = xyes])
+# WebKit Javascript
+AC_ARG_WITH([webkit],
+ [AS_HELP_STRING([--with-webkit],
+ [build WebKit JavaScriptCore PAC runner plugin @<:@automatic@:>@])],
+ [],
+ [test x$have_webkit == xyes && with_webkit=yes])
+if test x$with_webkit = xyes; then
+ if test x$have_webkit == xyes; then
+ WEBKIT_CFLAGS="$webkit_CFLAGS"
+ WEBKIT_LIBS="$webkit_LIBS"
+ AC_SUBST(WEBKIT_CFLAGS)
+ AC_SUBST(WEBKIT_LIBS)
+ else
+ echo "WebKit JavaScriptCore plugin requires: WebKit!"
+ exit 1
+ fi
+else
+ with_webkit=no
+fi
+AM_CONDITIONAL([WITH_WEBKIT], [test x$with_webkit = xyes])
+
# Mozilla Javascript
AC_ARG_WITH([mozjs],
[AS_HELP_STRING([--with-mozjs],
@@ -157,15 +176,16 @@ AC_C_CONST
AC_TYPE_SIZE_T
PLUGINDIR=$libdir/$PACKAGE_NAME/$PACKAGE_VERSION/plugins
AC_SUBST(PLUGINDIR)
-CFLAGS="-std=c99 $CFLAGS -DPLUGINDIR=\\\"$PLUGINDIR\\\" -DSYSCONFDIR=\\\"$sysconfdir\\\" -D_POSIX_C_SOURCE=1"
+CFLAGS="-g -std=c99 $CFLAGS -DPLUGINDIR=\\\"$PLUGINDIR\\\" -DSYSCONFDIR=\\\"$sysconfdir\\\" -D_POSIX_C_SOURCE=1"
### Checks for library functions.
AC_FUNC_MALLOC
#AC_CHECK_FUNCS([gethostbyname gethostname memset socket strdup strstr])
-AC_CONFIG_FILES([Makefile src/Makefile src/lib/Makefile src/plugins/Makefile
- src/bin/Makefile src/bindings/Makefile src/bindings/python/Makefile
- src/bindings/java/Makefile src/bindings/dotnet/Makefile])
+AC_CONFIG_FILES([libproxy-1.0.pc Makefile src/Makefile src/lib/Makefile
+ src/plugins/Makefile src/bin/Makefile src/bindings/Makefile
+ src/bindings/python/Makefile src/bindings/java/Makefile
+ src/bindings/dotnet/Makefile])
AC_OUTPUT
### Print build summary
@@ -176,6 +196,7 @@ echo -e "\t\tenvvar : $with_envvar"
echo -e "\t\tfile : $with_file"
echo -e "\t\tgnome : $with_gnome"
echo -e "\t\tkde : $with_kde"
+echo -e "\t\twebkit : $with_webkit"
echo -e "\t\tmozjs : $with_mozjs"
echo -e "\t\tnetworkmanager : $with_networkmanager"
echo
diff --git a/libproxy-1.0.pc.in b/libproxy-1.0.pc.in
new file mode 100644
index 0000000..3ba0a67
--- /dev/null
+++ b/libproxy-1.0.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libproxy
+Description: Proxy Configuration Library
+Version: @VERSION@
+Libs: -L${libdir} -lproxy
+Cflags: -I${includedir}
diff --git a/src/bin/proxy.c b/src/bin/proxy.c
index 225948f..4fd6681 100644
--- a/src/bin/proxy.c
+++ b/src/bin/proxy.c
@@ -23,7 +23,7 @@
#include <unistd.h>
#include <string.h>
-/* Import libproxy API */
+// Import libproxy API
#include <proxy.h>
#define STDIN fileno(stdin)
@@ -36,20 +36,20 @@
static char *
readline(int fd)
{
- /* Verify we have an open socket */
+ // Verify we have an open socket
if (fd < 0) return NULL;
- /* For each character received add it to the buffer unless it is a newline */
+ // For each character received add it to the buffer unless it is a newline
char *buffer = NULL;
for (int i=1; i > 0 ; i++)
{
char c;
- /* Receive a single character, check for newline or EOF */
+ // Receive a single character, check for newline or EOF
if (read(fd, &c, 1) != 1) return buffer;
if (c == '\n') return buffer ? buffer : strdup("");
- /* Allocate new buffer if we need */
+ // Allocate new buffer if we need
if (i % 1024 == 1)
{
char *tmp = buffer;
@@ -58,7 +58,7 @@ readline(int fd)
if (tmp) { strcpy(buffer, tmp); free(tmp); }
}
- /* Add new character */
+ // Add new character
buffer[i-1] = c;
}
return buffer;
@@ -67,7 +67,7 @@ readline(int fd)
int
main(int argc, char **argv)
{
- /* Create the proxy factory object */
+ // Create the proxy factory object
pxProxyFactory *pf = px_proxy_factory_new();
if (!pf)
{
@@ -75,14 +75,12 @@ main(int argc, char **argv)
return 1;
}
- /* For each URL we read on STDIN, get the proxies to use */
+ // For each URL we read on STDIN, get the proxies to use
for (char *url = NULL ; url = readline(STDIN) ; free(url))
{
- /*
- * Get an array of proxies to use. These should be used
- * in the order returned. Only move on to the next proxy
- * if the first one fails (etc).
- */
+ // Get an array of proxies to use. These should be used
+ // in the order returned. Only move on to the next proxy
+ // if the first one fails (etc).
char **proxies = px_proxy_factory_get_proxies(pf, url);
for (int i = 0 ; proxies[i] ; i++)
{
@@ -96,7 +94,7 @@ main(int argc, char **argv)
free(proxies);
}
- /* Destantiate the proxy factory object */
+ // Destantiate the proxy factory object
px_proxy_factory_free(pf);
return 0;
}
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 31a4297..f320af6 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -1,20 +1,8 @@
lib_LTLIBRARIES = libproxy.la
-libproxy_la_SOURCES = \
- array.c array.h \
- config_file.c config_file.h \
- misc.c misc.h \
- pac.c pac.h \
- proxy_factory.c proxy_factory.h \
- strdict.c strdict.h \
- url.c url.h \
- wpad.c wpad.h \
- wpad_dhcp.c wpad_dhcp.h \
- wpad_dns.c wpad_dns.h \
- wpad_slp.c wpad_slp.h \
- proxy.h
-
+libproxy_la_SOURCES = misc.c url.c pac.c dhcp.c dns.c slp.c wpad.c proxy_factory.c config_file.c \
+ misc.h url.h pac.h dhcp.h dns.h slp.h wpad.h proxy_factory.h proxy.h config_file.h
libproxy_la_CFLAGS = -Wall
-libproxy_la_LDFLAGS = -lpthread
+libproxy_la_LDFLAGS = -lm
include_HEADERS = proxy.h
diff --git a/src/lib/array.c b/src/lib/array.c
deleted file mode 100644
index 5441d9e..0000000
--- a/src/lib/array.c
+++ /dev/null
@@ -1,138 +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 <stdint.h>
-#include <string.h>
-
-#include "misc.h"
-#include "array.h"
-
-struct _pxArray {
- pxArrayItemsEqual equals;
- pxArrayItemCallback free;
- bool unique;
- bool replace;
- unsigned int length;
- void **data;
-};
-
-static bool
-identity(void *a, void *b)
-{
- return (a == b);
-}
-
-static void
-nothing(void *a)
-{
- return;
-}
-
-pxArray *
-px_array_new(pxArrayItemsEqual equals, pxArrayItemCallback free, bool unique, bool replace)
-{
- pxArray *self = px_malloc0(sizeof(pxArray));
- self->equals = equals ? equals : &identity;
- self->free = free ? free : &nothing;
- self->unique = unique;
- self->replace = replace;
- self->length = 0;
- self->data = px_malloc0(sizeof(void *));
- return self;
-}
-
-bool
-px_array_add(pxArray *self, void *item)
-{
- /* Verify some basic stuff */
- if (!self || !item) return false;
-
- /* If we are a unique array and a dup is found, either bail or replace the item */
- if (self->unique && px_array_find(self, item) >= 0)
- {
- if (!self->replace)
- return false;
-
- self->free(self->data[px_array_find(self, item)]);
- self->data[px_array_find(self, item)] = item;
- return true;
- }
-
- self->length++;
- void **data = px_malloc0(sizeof(void *) * (self->length + 1));
- memcpy(data, self->data, sizeof(void *) * self->length);
- data[self->length] = item;
- px_free(self->data);
- self->data = data;
- return true;
-}
-
-bool
-px_array_del(pxArray *self, const void *item)
-{
- unsigned int index = px_array_find(self, item);
- if (index < 0) return false;
-
- /* Free the old one and shift elements down */
- self->free(self->data[index]);
- memmove(self->data+index,
- self->data+index+1,
- sizeof(void *) * (self->length - index));
-
- return true;
-}
-
-void
-px_array_foreach(pxArray *self, pxArrayItemCallbackWithArg cb, void *arg)
-{
- for (int i=0 ; self->data[i] ; i++)
- cb(self->data[i], arg);
-}
-
-int
-px_array_find(pxArray *self, const void *item)
-{
- if (!self || !item) return -1;
-
- for (int i=0 ; self->data[i] ; i++)
- if (self->equals(self->data[i], (void *) item))
- return i;
-
- return -1;
-}
-
-const void *
-px_array_get(pxArray *self, int index)
-{
- if (!self) return NULL;
- if (index < 0) index = self->length + index;
- if (index < 0) return NULL;
-
- return self->data[index];
-}
-
-void
-px_array_free(pxArray *self)
-{
- if (!self) return;
-
- for (int i=0 ; self->data[i] ; i++)
- self->free(self->data[i]);
- px_free(self);
-}
diff --git a/src/lib/array.h b/src/lib/array.h
deleted file mode 100644
index acd5b9e..0000000
--- a/src/lib/array.h
+++ /dev/null
@@ -1,39 +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 <stdbool.h>
-
-typedef bool (*pxArrayItemsEqual)(void *, void *);
-typedef void (*pxArrayItemCallback)(void *);
-typedef void (*pxArrayItemCallbackWithArg)(void *, void *);
-typedef struct _pxArray pxArray;
-
-pxArray *px_array_new(pxArrayItemsEqual equals, pxArrayItemCallback free, bool unique, bool replace);
-
-bool px_array_add(pxArray *self, void *item);
-
-bool px_array_del(pxArray *self, const void *item);
-
-void px_array_foreach(pxArray *self, pxArrayItemCallbackWithArg cb, void *arg);
-
-int px_array_find(pxArray *self, const void *item);
-
-const void *px_array_get(pxArray *self, int index);
-
-void px_array_free(pxArray *self);
diff --git a/src/lib/config_file.c b/src/lib/config_file.c
index 8e32cab..69f5fec 100644
--- a/src/lib/config_file.c
+++ b/src/lib/config_file.c
@@ -24,64 +24,130 @@
#include <string.h>
#include "misc.h"
-#include "strdict.h"
#include "config_file.h"
+struct _pxConfigFileSection {
+ char *name;
+ char **keys;
+ char **vals;
+};
+typedef struct _pxConfigFileSection pxConfigFileSection;
+
struct _pxConfigFile {
- char *filename;
- time_t mtime;
- pxStrDict *sections;
+ char *filename;
+ time_t mtime;
+ pxConfigFileSection **sections;
};
pxConfigFile *
px_config_file_new(char *filename)
{
- /* Open the file and stat it */
+ // Open the file and stat it
struct stat st;
int fd = open(filename, O_RDONLY);
if (fd < 0) return NULL;
fstat(fd, &st);
- /* Allocate our structure; get mtime and filename */
+ // Allocate our structure; get mtime and filename
pxConfigFile *self = px_malloc0(sizeof(pxConfigFile));
- self->filename = px_strdup(filename);
self->mtime = st.st_mtime;
- self->sections = px_strdict_new((void *) px_strdict_free);
+ self->filename = px_strdup(filename);
- /* Add one section (PX_CONFIG_FILE_DEFAULT_SECTION) */
- px_strdict_set(self->sections, PX_CONFIG_FILE_DEFAULT_SECTION, px_strdict_new(free));
- pxStrDict *current = (pxStrDict *) px_strdict_get(self->sections, PX_CONFIG_FILE_DEFAULT_SECTION);
+ // Add one section (PX_CONFIG_FILE_DEFAULT_SECTION)
+ self->sections = px_malloc0(sizeof(pxConfigFileSection *) * 2);
+ self->sections[0] = px_malloc0(sizeof(pxConfigFileSection));
+ self->sections[0]->name = px_strdup(PX_CONFIG_FILE_DEFAULT_SECTION);
+ pxConfigFileSection *current = self->sections[0];
- /* Parse our file */
+ // Parse our file
for (char *line=NULL ; (line = px_readline(fd)) ; px_free(line))
{
- /* Strip */
+ // Strip
char *tmp = px_strstrip(line);
px_free(line); line = tmp;
- /* Check for comment and/or empty line */
+ // Check for comment and/or empty line
if (*line == '#' || !strcmp(line, "")) continue;
- /* If we have a new section */
+ // If we have a new section
if (*line == '[' || line[strlen(line)-1] == ']')
{
- /* Get just the section name */
+ // Get just the section name
memmove(line, line+1, strlen(line)-1);
line[strlen(line)-2] = '\0';
- if (px_strdict_get(self->sections, line))
- current = (pxStrDict *) px_strdict_get(self->sections, line);
- else
- px_strdict_set(self->sections, line, px_strdict_new(free));
+ // Check for each section...
+ for (int i=0 ; self->sections[i] ; i++)
+ {
+ // If we found the section already, set it as current and move on
+ if (!strcmp(self->sections[i]->name, line))
+ {
+ current = self->sections[i];
+ break;
+ }
+
+ // If the section wasn't found, add a new section
+ if (!self->sections[i+1])
+ {
+ // Create new section
+ current = px_malloc0(sizeof(pxConfigFileSection));
+ current->name = px_strdup(line);
+
+ // Add section to the end
+ pxConfigFileSection **sections = self->sections;
+ self->sections = px_malloc0(sizeof(pxConfigFileSection *) * (i+3));
+ memcpy(self->sections, sections, sizeof(pxConfigFileSection) * (i+1));
+ self->sections[i+1] = current;
+ px_free(sections);
+
+ break;
+ }
+ }
+ continue;
}
- /* If this is a key/val line, get the key/val. */
- else if ((tmp = strchr(line, '=')) && tmp[1])
+ // If this is a key/val line, get the key/val.
+ if ((tmp = strchr(line, '=')) && tmp[1])
{
- *tmp = '\0';
- char *key = px_strstrip(line);
- px_strdict_set(current, key, px_strstrip(tmp+1));
- px_free(key);
+ // If this is our first key/val, create a new array
+ if (!current->keys || !current->vals)
+ {
+ // Add key
+ current->keys = px_malloc0(sizeof(char *) * 2);
+ current->keys[0] = px_strndup(line, tmp - line);
+ current->keys[1] = NULL;
+
+ // Add val
+ current->vals = px_malloc0(sizeof(char *) * 2);
+ current->vals[0] = px_strdup(tmp+1);
+ current->vals[1] = NULL;
+ }
+
+ // If this is not our first key/val, tack it on the end
+ else
+ {
+ for (int i=0 ; current->keys[i] ; i++)
+ {
+ if (!current->keys[i+1])
+ {
+ // Add val
+ char **vals = px_malloc0(sizeof(char *) * (i+3));
+ memcpy(vals, current->vals, sizeof(char *) * (i+1));
+ vals[i+1] = px_strstrip(tmp+1);
+ px_free(current->vals); current->vals = vals;
+
+ // Add key
+ *tmp = '\0';
+ char **keys = px_malloc0(sizeof(char *) * (i+3));
+ memcpy(keys, current->keys, sizeof(char *) * (i+1));
+ keys[i+1] = px_strstrip(line);
+ px_free(current->keys); current->keys = keys;
+
+ break;
+ }
+ }
+ }
+ continue;
}
}
@@ -96,10 +162,39 @@ px_config_file_is_stale(pxConfigFile *self)
return (!stat(self->filename, &st) && st.st_mtime > self->mtime);
}
+char **
+px_config_file_get_sections(pxConfigFile *self)
+{
+ int count;
+ for (count=0 ; self->sections[count] ; count++);
+ char **output = px_malloc0(sizeof(char *) * ++count);
+ for (count=0 ; self->sections[count] ; count++)
+ output[count] = px_strdup(self->sections[count]->name);
+ return output;
+}
+
+char **
+px_config_file_get_keys(pxConfigFile *self, char *section)
+{
+ for (int i=0 ; self->sections[i] ; i++)
+ {
+ if (!strcmp(self->sections[i]->name, section))
+ return px_strdupv((const char **) self->sections[i]->keys);
+ }
+
+ return NULL;
+}
+
char *
px_config_file_get_value(pxConfigFile *self, char *section, char *key)
{
- return px_strdup(px_strdict_get((pxStrDict *) px_strdict_get(self->sections, section), key));
+ for (int i=0 ; self->sections[i] ; i++)
+ if (!strcmp(self->sections[i]->name, section))
+ for (int j=0 ; self->sections[i]->keys && self->sections[i]->keys[j] ; j++)
+ if (!strcmp(self->sections[i]->keys[j], key))
+ return px_strdup(self->sections[i]->vals[j]);
+
+ return NULL;
}
void
@@ -107,7 +202,14 @@ px_config_file_free(pxConfigFile *self)
{
if (!self) return;
- px_strdict_free(self->sections);
+ for (int i=0 ; self->sections && self->sections[i] ; i++)
+ {
+ px_free(self->sections[i]->name);
+ px_strfreev(self->sections[i]->keys);
+ px_strfreev(self->sections[i]->vals);
+ px_free(self->sections[i]);
+ }
+ px_free(self->sections);
px_free(self->filename);
px_free(self);
}
diff --git a/src/lib/config_file.h b/src/lib/config_file.h
index 5aa9826..938d203 100644
--- a/src/lib/config_file.h
+++ b/src/lib/config_file.h
@@ -28,6 +28,8 @@ typedef struct _pxConfigFile pxConfigFile;
pxConfigFile *px_config_file_new (char *filename);
bool px_config_file_is_stale (pxConfigFile *self);
+char **px_config_file_get_sections(pxConfigFile *self);
+char **px_config_file_get_keys (pxConfigFile *self, char *section);
char *px_config_file_get_value (pxConfigFile *self, char *section, char *key);
void px_config_file_free (pxConfigFile *self);
diff --git a/src/lib/wpad_dhcp.c b/src/lib/dhcp.c
index 9d613f8..1afe13d 100644
--- a/src/lib/wpad_dhcp.c
+++ b/src/lib/dhcp.c
@@ -20,7 +20,7 @@
#include <stdlib.h>
#include "pac.h"
-#include "wpad_dhcp.h"
+#include "dhcp.h"
struct _pxDHCP { };
diff --git a/src/lib/wpad_dhcp.h b/src/lib/dhcp.h
index 2e83e67..2e83e67 100644
--- a/src/lib/wpad_dhcp.h
+++ b/src/lib/dhcp.h
diff --git a/src/lib/wpad_dns.c b/src/lib/dns.c
index 8bf4576..6861fdc 100644
--- a/src/lib/wpad_dns.c
+++ b/src/lib/dns.c
@@ -26,7 +26,7 @@
#include "misc.h"
#include "pac.h"
-#include "wpad_dns.h"
+#include "dns.h"
struct _pxDNS {
pxURL **urls;
@@ -34,13 +34,13 @@ struct _pxDNS {
char *domain;
};
-/* The top-level domain blacklist */
+// The top-level domain blacklist
static char *tld[] = {
- /* General top-level domains */
+ // 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 */
+ // 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",
@@ -63,23 +63,23 @@ static char *tld[] = {
"uy", "uz", "va", "vc", "ve", "vg", "vi", "vn", "vu", "wf", "ws", "ye",
"yt", "yu", "za", "zm", "zw",
- /* Other domains to blacklist */
+ // Other domains to blacklist
"co.uk", "com.au",
- /* Terminator */
+ // Terminator
NULL
};
static char *
get_domain_name()
{
- /* Get the hostname */
+ // Get the hostname
char *hostname = px_malloc0(128);
for (int i = 0 ; gethostname(hostname, (i + 1) * 128) && errno == ENAMETOOLONG ; )
hostname = px_malloc0((++i + 1) * 128);
- /* Lookup the hostname */
- /* TODO: Make this whole process not suck */
+ // Lookup the hostname
+ // TODO: Make this whole process not suck
struct hostent *host_info = gethostbyname(hostname);
if (host_info)
{
@@ -87,7 +87,7 @@ get_domain_name()
hostname = px_strdup(host_info->h_name);
}
- /* Get domain portion */
+ // Get domain portion
if (!strchr(hostname, '.')) return NULL;
if (!strcmp(".", strchr(hostname, '.'))) return NULL;
char *tmp = px_strdup(strchr(hostname, '.') + 1);
@@ -107,29 +107,29 @@ get_urls(const char *domain)
return urls;
}
- /* Split up the domain */
+ // Split up the domain
char **domainv = px_strsplit(domain, ".");
if (!domainv) return NULL;
- /* Count the number of domain blocks */
+ // Count the number of domain blocks
int count = 0;
for (int i=0 ; *(domainv + i) ; i++)
count++;
- /* Allocate our URL array */
+ // Allocate our URL array
urls = px_malloc0(sizeof(pxURL *) * (count + 2));
- /* Create the URLs */
+ // Create the URLs
urls[0] = px_url_new("http://wpad/wpad.dat");
char *url = px_malloc0(strlen("http://wpad./wpad.dat") + strlen(domain) + 1);
for (int i=0, j=1 ; domainv[i] ; i++) {
- /* Check the domain against the blacklist */
+ // Check the domain against the blacklist
char *tmp = px_strjoin((const char **) (domainv + i), ".");
for (int k=0; tld[k] ; k++)
if (!strcmp(tmp, tld[k])) { px_free(tmp); tmp = NULL; break; }
if (!tmp) continue;
- /* Create the URL */
+ // Create the URL
sprintf(url, "http://wpad.%s/wpad.dat", tmp);
px_free(tmp); tmp = NULL;
urls[j] = px_url_new(url);
@@ -176,25 +176,25 @@ px_dns_next(pxDNS *self)
if (!self->urls) {
char *domain;
- /* Reset the counter */
+ // Reset the counter
self->next = 0;
- /* Get the domain name */
+ // Get the domain name
if (self->domain)
domain = px_strdup(self->domain);
else
domain = get_domain_name();
- /* Get the URLs */
+ // Get the URLs
self->urls = get_urls(domain);
px_free(domain);
- /* Make sure we have more than one URL */
+ // Make sure we have more than one URL
if (!self->urls || !self->urls[0])
return NULL;
}
- /* Try to find a PAC at each URL */
+ // Try to find a PAC at each URL
for (pxPAC *pac = NULL ; self->urls[self->next] ; )
if ((pac = px_pac_new(self->urls[self->next++])))
return pac;
diff --git a/src/lib/wpad_dns.h b/src/lib/dns.h
index f3deac7..f3deac7 100644
--- a/src/lib/wpad_dns.h
+++ b/src/lib/dns.h
diff --git a/src/lib/misc.c b/src/lib/misc.c
index 358d1c0..40f7886 100644
--- a/src/lib/misc.c
+++ b/src/lib/misc.c
@@ -110,13 +110,13 @@ px_strcat(const char *s, ...)
{
va_list args;
- /* Count the number of characters to concatentate */
+ // Count the number of characters to concatentate
va_start(args, s);
int count = strlen(s);
for (char *tmp = NULL ; (tmp = va_arg(args, char *)) ; count += strlen(tmp));
va_end(args);
- /* Build our output string */
+ // Build our output string
char *output = px_malloc0(count + 1);
strcat(output, s);
va_start(args, s);
@@ -139,13 +139,13 @@ px_strjoin(const char **strv, const char *delimiter)
if (!strv) return NULL;
if (!delimiter) return NULL;
- /* Count up the length we need */
+ // Count up the length we need
size_t length = 0;
for (int i=0 ; strv[i]; i++)
length += strlen(strv[i]) + strlen(delimiter);
if (!length) return NULL;
- /* Do the join */
+ // Do the join
char *str = px_malloc0(length);
for (int i=0 ; strv[i]; i++)
{
@@ -164,15 +164,15 @@ px_strjoin(const char **strv, const char *delimiter)
char **
px_strsplit(const char *string, const char *delimiter)
{
- /* Count how many times the delimiter appears */
+ // Count how many times the delimiter appears
int count = 1;
for (const char *tmp = string ; (tmp = strstr(tmp, delimiter)) ; tmp += strlen(delimiter))
count++;
- /* Allocate the vector */
+ // Allocate the vector
char **strv = px_malloc0(sizeof(char *) * (count + 1));
- /* Fill the vector */
+ // Fill the vector
const char *last = string;
for (int i=0 ; i < count ; i++)
{
@@ -210,20 +210,20 @@ px_strfreev(char **strv)
char *
px_readline(int fd)
{
- /* Verify we have an open socket */
+ // Verify we have an open socket
if (fd < 0) return NULL;
- /* For each character received add it to the buffer unless it is a newline */
+ // For each character received add it to the buffer unless it is a newline
char *buffer = NULL;
for (int i=1; i > 0 ; i++)
{
char c;
- /* Receive a single character, check for newline or EOF */
+ // Receive a single character, check for newline or EOF
if (read(fd, &c, 1) != 1) return buffer;
if (c == '\n') return buffer ? buffer : px_strdup("");
- /* Allocate new buffer if we need */
+ // Allocate new buffer if we need
if (i % 1024 == 1)
{
char *tmp = buffer;
@@ -231,7 +231,7 @@ px_readline(int fd)
if (tmp) { strcpy(buffer, tmp); px_free(tmp); }
}
- /* Add new character */
+ // Add new character
buffer[i-1] = c;
}
return buffer;
diff --git a/src/lib/misc.h b/src/lib/misc.h
index b1e45e6..bee77ac 100644
--- a/src/lib/misc.h
+++ b/src/lib/misc.h
@@ -20,7 +20,7 @@
#ifndef MISC_H_
#define MISC_H_
-#include <stdlib.h> /* For type size_t */
+#include <stdlib.h> // For type size_t
/**
* Allocates memory and always returns valid memory.
diff --git a/src/lib/pac.c b/src/lib/pac.c
index ca32ede..9403d39 100644
--- a/src/lib/pac.c
+++ b/src/lib/pac.c
@@ -70,13 +70,13 @@ px_pac_new(pxURL *url)
{
if (!url) return NULL;
- /* Allocate the object */
+ // Allocate the object
pxPAC *self = px_malloc0(sizeof(pxPAC));
- /* Copy the given URL */
- self->url = px_url_new(px_url_to_string(url)); /* Always returns valid value */
+ // Copy the given URL
+ self->url = px_url_new(px_url_to_string(url)); // Always returns valid value
- /* Make sure we have a real pxPAC */
+ // Make sure we have a real pxPAC
if (!px_pac_reload(self)) { px_pac_free(self); return NULL; }
return self;
@@ -90,13 +90,13 @@ px_pac_new(pxURL *url)
pxPAC *
px_pac_new_from_string(char *url)
{
- /* Create temporary URL */
+ // Create temporary URL
pxURL *tmpurl = px_url_new(url);
if (!tmpurl) return NULL;
- /* Create pac */
+ // Create pac
pxPAC *self = px_pac_new(tmpurl);
- px_url_free(tmpurl); /* Free no longer used URL */
+ px_url_free(tmpurl); // Free no longer used URL
if (!self) return NULL;
return self;
}
@@ -124,33 +124,33 @@ px_pac_reload(pxPAC *self)
bool correct_mime_type;
unsigned long int content_length = 0;
- /* Get the pxPAC */
+ // Get the pxPAC
sock = px_url_get(self->url, headers);
if (sock < 0) return false;
- /* Verify status line */
+ // Verify status line
line = px_readline(sock);
if (!line) goto error;
- if (strncmp(line, "HTTP", strlen("HTTP"))) goto error; /* Check valid HTTP response */
- if (!strchr(line, ' ') || atoi(strchr(line, ' ') + 1) != 200) goto error; /* Check status code */
+ if (strncmp(line, "HTTP", strlen("HTTP"))) goto error; // Check valid HTTP response
+ if (!strchr(line, ' ') || atoi(strchr(line, ' ') + 1) != 200) goto error; // Check status code
- /* Check for correct mime type and content length */
+ // Check for correct mime type and content length
while (strcmp(line, "\r")) {
- /* Check for content type */
+ // Check for content type
if (strstr(line, "Content-Type: ") == line && strstr(line, PAC_MIME_TYPE))
correct_mime_type = true;
- /* Check for content length */
+ // Check for content length
else if (strstr(line, "Content-Length: ") == line)
content_length = atoi(line + strlen("Content-Length: "));
- /* Get new line */
+ // Get new line
px_free(line);
line = px_readline(sock);
if (!line) goto error;
}
- /* Get content */
+ // Get content
if (!content_length || !correct_mime_type) goto error;
px_free(line); line = NULL;
px_free(self->cache);
@@ -158,7 +158,7 @@ px_pac_reload(pxPAC *self)
for (int recvd=0 ; recvd != content_length ; )
recvd += recv(sock, self->cache + recvd, content_length - recvd, 0);
- /* Clean up */
+ // Clean up
close(sock);
return true;
diff --git a/src/lib/proxy.h b/src/lib/proxy.h
index 3257e8a..9dc9f66 100644
--- a/src/lib/proxy.h
+++ b/src/lib/proxy.h
@@ -35,8 +35,6 @@ pxProxyFactory *px_proxy_factory_new();
* A NULL-terminated array of proxy strings is returned.
* If the first proxy fails, the second should be tried, etc...
* Don't forget to free the strings/array when you are done.
- * In all cases, at least one entry in the array will be returned.
- * There are no error conditions.
*
* The format of the returned proxy strings are as follows:
* - http://proxy:port
diff --git a/src/lib/proxy_factory.c b/src/lib/proxy_factory.c
index 1376563..5591c9c 100644
--- a/src/lib/proxy_factory.c
+++ b/src/lib/proxy_factory.c
@@ -34,8 +34,6 @@
#include "proxy_factory.h"
#include "wpad.h"
#include "config_file.h"
-#include "array.h"
-#include "strdict.h"
#define DEFAULT_CONFIG_ORDER "USER,SESSION,SYSTEM"
@@ -46,19 +44,25 @@ struct _pxProxyFactoryConfig {
};
typedef struct _pxProxyFactoryConfig pxProxyFactoryConfig;
+struct _pxKeyVal {
+ char *key;
+ void *value;
+};
+typedef struct _pxKeyVal pxKeyVal;
+
struct _pxProxyFactory {
- pthread_mutex_t mutex;
- pxArray *plugins;
- pxProxyFactoryConfig **configs;
- pxStrDict *misc;
- pxArray *on_get_proxies;
- pxPACRunnerCallback pac_runner;
- pxPAC *pac;
- pxWPAD *wpad;
- pxConfigFile *cf;
+ pthread_mutex_t mutex;
+ void **plugins;
+ pxProxyFactoryConfig **configs;
+ pxKeyVal **misc;
+ pxProxyFactoryVoidCallback *on_get_proxy;
+ pxPACRunnerCallback pac_runner;
+ pxPAC *pac;
+ pxWPAD *wpad;
+ pxConfigFile *cf;
};
-/* Convert the PAC formatted response into our proxy URL array response */
+// Convert the PAC formatted response into our proxy URL array response
static char **
_format_pac_response(char *response)
{
@@ -107,7 +111,7 @@ _sockaddr_equals(const struct sockaddr *ip_a, const struct sockaddr *ip_b, const
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 */
+ // Setup the arrays
uint8_t bytes = 0, *a_data = NULL, *b_data = NULL, *nm_data = NULL;
if (ip_a->sa_family == AF_INET)
{
@@ -142,26 +146,26 @@ _sockaddr_from_string(const char *ip, int len)
if (!ip) return NULL;
struct sockaddr *result = NULL;
- /* Copy the string */
+ // Copy the string
if (len >= 0)
ip = px_strndup(ip, len);
else
ip = px_strdup(ip);
- /* Try to parse IPv4 */
+ // Try to parse IPv4
result = px_malloc0(sizeof(struct sockaddr_in));
result->sa_family = AF_INET;
if (inet_pton(AF_INET, ip, &((struct sockaddr_in *) result)->sin_addr) > 0)
goto out;
- /* Try to parse IPv6 */
+ // Try to parse IPv6
px_free(result);
result = px_malloc0(sizeof(struct sockaddr_in6));
result->sa_family = AF_INET6;
if (inet_pton(AF_INET6, ip, &((struct sockaddr_in6 *) result)->sin6_addr) > 0)
goto out;
- /* No address found */
+ // No address found
px_free(result);
result = NULL;
out:
@@ -172,7 +176,7 @@ _sockaddr_from_string(const char *ip, int len)
static struct sockaddr *
_sockaddr_from_cidr(int af, int cidr)
{
- /* TODO: Support CIDR notation */
+ // TODO: Support CIDR notation
return NULL;
}
@@ -186,25 +190,21 @@ _ip_ignore(pxURL *url, char *ignore)
const struct sockaddr *dst_ip = px_url_get_ip_no_dns(url);
struct sockaddr *ign_ip = NULL, *net_ip = NULL;
- /*
- * IPv4
- * IPv6
- */
+ // IPv4
+ // IPv6
if ((ign_ip = _sockaddr_from_string(ignore, -1)))
goto out;
- /*
- * IPv4/CIDR
- * IPv4/IPv4
- * IPv6/CIDR
- * IPv6/IPv6
- */
+ // 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 CIDR notation was used, get the netmask
if (ign_ip && !net_ip)
{
uint32_t cidr = 0;
@@ -221,15 +221,13 @@ _ip_ignore(pxURL *url, char *ignore)
net_ip = NULL;
}
- /*
- * IPv4:port
- * [IPv6]:port
- */
+ // 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 */
+ // 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;
@@ -251,11 +249,11 @@ _domain_ignore(pxURL *url, char *ignore)
if (!url || !ignore)
return false;
- /* Get our URL's hostname and 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 */
+ // Get our ignore pattern's hostname and port
char *ihost = px_strdup(ignore);
int iport = 0;
if (strchr(ihost, ':'))
@@ -267,49 +265,33 @@ _domain_ignore(pxURL *url, char *ignore)
iport = 0;
}
- /* Hostname match (domain.com or domain.com:80) */
+ // 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) */
+ // Endswith (.domain.com or .domain.com:80)
if (ihost[0] == '.' && _endswith(host, ihost))
if (!iport || port == iport)
goto match;
- /* Glob (*.domain.com or *.domain.com:80) */
+ // Glob (*.domain.com or *.domain.com:80)
if (ihost[0] == '*' && _endswith(host, ihost+1))
if (!iport || port == iport)
goto match;
- /* No match was found */
+ // No match was found
px_free(host);
px_free(ihost);
return false;
- /* A match was found */
+ // A match was found
match:
px_free(host);
px_free(ihost);
return true;
}
-static void
-destantiate_plugins(void *item, void *self)
-{
- /* Call the destantiation hook */
- pxProxyFactoryVoidCallback destantiate;
- destantiate = dlsym(item, "on_proxy_factory_destantiate");
- if (destantiate)
- destantiate(self);
-}
-
-static void
-call_on_proxy_factory_get_proxies(void *item, void *self)
-{
- ((pxProxyFactoryVoidCallback) item)(self);
-}
-
/**
* Creates a new pxProxyFactory instance.
*
@@ -319,33 +301,44 @@ pxProxyFactory *
px_proxy_factory_new ()
{
pxProxyFactory *self = px_malloc0(sizeof(pxProxyFactory));
+ unsigned int i;
+
+ // Create the mutex
pthread_mutex_init(&self->mutex, NULL);
- self->plugins = px_array_new(NULL, (void *) dlclose, true, false);
- self->misc = px_strdict_new(NULL);
- self->on_get_proxies = px_array_new(NULL, NULL, true, false);
- /* Open the plugin dir */
+ // Open the plugin dir
DIR *plugindir = opendir(PLUGINDIR);
if (!plugindir) return self;
- /* For each plugin... */
+ // Count the number of plugins
+ for (i=0 ; readdir(plugindir) ; i++);
+ self->plugins = (void **) px_malloc0(sizeof(void *) * (i + 1));
+ rewinddir(plugindir);
+
+ // For each plugin...
struct dirent *ent;
- for (int i=0 ; (ent = readdir(plugindir)) ; i++)
+ for (i=0 ; (ent = readdir(plugindir)) ; i++)
{
- /* Load the plugin */
+ // Load the plugin
char *tmp = px_strcat(PLUGINDIR, "/", ent->d_name, NULL);
- void *plugin = dlopen(tmp, RTLD_NOW | RTLD_LOCAL);
+ self->plugins[i] = dlopen(tmp, RTLD_NOW | RTLD_LOCAL);
px_free(tmp);
- if (!plugin)
+ if (!(self->plugins[i]))
+ {
+ dlerror();
+ i--;
continue;
+ }
- /* Call the instantiation hook */
+ // Call the instantiation hook
pxProxyFactoryBoolCallback instantiate;
- instantiate = dlsym(plugin, "on_proxy_factory_instantiate");
+ instantiate = dlsym(self->plugins[i], "on_proxy_factory_instantiate");
if (instantiate && !instantiate(self))
- dlclose(plugin);
- else if (instantiate)
- px_array_add(self->plugins, plugin);
+ {
+ dlclose(self->plugins[i]);
+ self->plugins[i--] = NULL;
+ continue;
+ }
}
closedir(plugindir);
@@ -358,29 +351,27 @@ px_proxy_factory_config_add(pxProxyFactory *self, const char *name, pxConfigCate
int count;
pxProxyFactoryConfig **tmp;
- /* Verify some basic stuff */
+ // Verify some basic stuff
if (!self) return false;
if (!callback) return false;
if (!name || !strcmp(name, "")) return false;
- /* Allocate an empty config array if there is none */
+ // Allocate an empty config array if there is none
if (!self->configs) self->configs = px_malloc0(sizeof(pxProxyFactoryConfig *));
- /*
- * Make sure that 'name' is unique
- * Also, get a count of how many configs we have
- */
+ // Make sure that 'name' is unique
+ // Also, get a count of how many configs we have
for (count=0 ; self->configs[count] ; count++)
if (!strcmp(self->configs[count]->name, name))
return false;
- /* Allocate new array, copy old values into it and free old array */
+ // Allocate new array, copy old values into it and free old array
tmp = px_malloc0(sizeof(pxProxyFactoryConfig *) * (count + 2));
memcpy(tmp, self->configs, sizeof(pxProxyFactoryConfig *) * count);
px_free(self->configs);
self->configs = tmp;
- /* Add the new callback to the end */
+ // Add the new callback to the end
self->configs[count] = px_malloc0(sizeof(pxProxyFactoryConfig));
self->configs[count]->category = category;
self->configs[count]->name = px_strdup(name);
@@ -394,12 +385,12 @@ px_proxy_factory_config_del(pxProxyFactory *self, const char *name)
{
int i,j;
- /* Verify some basic stuff */
+ // Verify some basic stuff
if (!self) return false;
if (!name || !strcmp(name, "")) return false;
if (!self->configs) return false;
- /* Remove and shift all configs down (if found) */
+ // Remove and shift all configs down (if found)
for (i=0,j=0 ; self->configs[j]; i++,j++)
{
if (i != j)
@@ -411,7 +402,7 @@ px_proxy_factory_config_del(pxProxyFactory *self, const char *name)
}
}
- /* If we have an empty array, free it */
+ // If we have an empty array, free it
if (!self->configs[0])
{
px_free(self->configs);
@@ -424,21 +415,83 @@ px_proxy_factory_config_del(pxProxyFactory *self, const char *name)
bool
px_proxy_factory_misc_set(pxProxyFactory *self, const char *key, const void *value)
{
- /* Verify some basic stuff */
- if (!self) return false;
- if (!key || !strcmp(key, "")) return false;
-
- return px_strdict_set(self->misc, key, (void *) value);
+ int count;
+ pxKeyVal **tmp;
+
+ // Verify some basic stuff
+ if (!self) return false;
+ if (!key || !strcmp(key, "")) return false;
+
+ // Allocate an empty config array if there is none
+ if (!self->misc) self->misc = px_malloc0(sizeof(pxKeyVal *));
+
+ // Count the number of values
+ for (count=0 ; self->misc[count] ; count++);
+
+ // Unset value
+ if (!value)
+ {
+ // Remove the keyval, shifting downward
+ for (int i=0,j=0 ; self->misc[i] ; i++, j++)
+ {
+ // If the key is found, remove it
+ if (!strcmp(key, self->misc[i]->key))
+ {
+ px_free(self->misc[i]->key);
+ px_free(self->misc[i]);
+ self->misc[i] = NULL;
+ count--;
+ j--;
+ }
+
+ // Shift down
+ if (i > 0 && j > 0)
+ self->misc[j] = self->misc[i];
+ }
+
+ // Resize array
+ tmp = px_malloc0(sizeof(pxKeyVal *) * (count + 1));
+ memcpy(tmp, self->misc, sizeof(pxKeyVal *) * count);
+ px_free(self->misc);
+ self->misc = tmp;
+ return true;
+ }
+
+ // Attempt to update the value within the array
+ for (int i=0 ; self->misc[i] ; i++)
+ {
+ if (!strcmp(key, self->misc[i]->key))
+ {
+ self->misc[i]->value = (void *) value;
+ return true;
+ }
+ }
+
+ // The key was not found in the array, so add it
+ tmp = px_malloc0(sizeof(pxKeyVal *) * (count + 2));
+ memcpy(tmp, self->misc, sizeof(pxKeyVal *) * count);
+ tmp[count] = px_malloc0(sizeof(pxKeyVal));
+ tmp[count]->key = px_strdup(key);
+ tmp[count]->value = (void *) value;
+ px_free(self->misc);
+ self->misc = tmp;
+ return true;
}
void *
px_proxy_factory_misc_get(pxProxyFactory *self, const char *key)
{
- /* Verify some basic stuff */
+ // Verify some basic stuff
if (!self) return NULL;
if (!key || !strcmp(key, "")) return NULL;
+ if (!self->misc) return NULL;
+
+ // Find the value listed
+ for (int i=0 ; self->misc[i] ; i++)
+ if (!strcmp(key, self->misc[i]->key))
+ return self->misc[i]->value;
- return (void *) px_strdict_get(self->misc, key);
+ return NULL;
}
/**
@@ -446,9 +499,6 @@ px_proxy_factory_misc_get(pxProxyFactory *self, const char *key)
*
* A NULL-terminated array of proxy strings is returned.
* If the first proxy fails, the second should be tried, etc...
- * Don't forget to free the strings/array when you are done.
- * In all cases, at least one entry in the array will be returned.
- * There are no error conditions.
*
* The format of the returned proxy strings are as follows:
* - http://proxy:port
@@ -465,47 +515,48 @@ px_proxy_factory_get_proxies (pxProxyFactory *self, char *url)
char **response = px_strsplit("direct://", ";");
char *tmp = NULL, *order = NULL, **orderv = NULL;
- /* Verify some basic stuff */
+ // Verify some basic stuff
if (!self) goto do_return;
if (!url || !strcmp(url, "")) goto do_return;
if (!realurl) goto do_return;
- /* Lock mutex */
+ // Lock mutex
pthread_mutex_lock(&self->mutex);
- /* Call the events */
- px_array_foreach(self->on_get_proxies, call_on_proxy_factory_get_proxies, self);
+ // Call the events
+ for (int i=0 ; self->on_get_proxy && self->on_get_proxy[i] ; i++)
+ self->on_get_proxy[i](self);
- /* If our config file is stale, close it */
+ // If our config file is stale, close it
if (self->cf && px_config_file_is_stale(self->cf))
{
px_config_file_free(self->cf);
self->cf = NULL;
}
- /* Try to open our config file if we don't have one */
+ // Try to open our config file if we don't have one
if (!self->cf)
self->cf = px_config_file_new(SYSCONFDIR "/proxy.conf");
- /* If we have a config file, load the order from it */
+ // If we have a config file, load the order from it
if (self->cf)
tmp = px_config_file_get_value(self->cf, PX_CONFIG_FILE_DEFAULT_SECTION, "config_order");
- /* Attempt to get info from the environment */
+ // Attempt to get info from the environment
order = getenv("PX_CONFIG_ORDER");
- /* Create the config order */
+ // Create the config order
order = px_strcat(tmp ? tmp : "", ",", order ? order : "", ",", DEFAULT_CONFIG_ORDER, NULL);
px_free(tmp); tmp = NULL;
- /* Create the config plugin order vector */
+ // Create the config plugin order vector
orderv = px_strsplit(order, ",");
px_free(order);
- /* Get the config by searching the config order */
+ // Get the config by searching the config order
for (int i=0 ; orderv[i] && !config ; i++)
{
- /* Get the category (if applicable) */
+ // Get the category (if applicable)
pxConfigCategory category;
if (!strcmp(orderv[i], "USER"))
category = PX_CONFIG_CATEGORY_USER;
@@ -526,11 +577,11 @@ px_proxy_factory_get_proxies (pxProxyFactory *self, char *url)
}
px_strfreev(orderv);
- /* No config was found via search order, call all plugins */
+ // No config was found via search order, call all plugins
for (int i=0 ; self->configs && self->configs[i] && !config ; i++)
config = self->configs[i]->callback(self);
- /* No plugin returned a valid config, fall back to 'wpad://' */
+ // No plugin returned a valid config, fall back to 'wpad://'
if (!config)
{
fprintf(stderr, "*** Unable to locate valid config! Falling back to auto-detection...\n");
@@ -539,7 +590,7 @@ px_proxy_factory_get_proxies (pxProxyFactory *self, char *url)
config->ignore = px_strdup("");
}
- /* If the config plugin returned an invalid config type or malformed URL, fall back to 'wpad://' */
+ // If the config plugin returned an invalid config type or malformed URL, fall back to 'wpad://'
if (!(!strncmp(config->url, "http://", 7) ||
!strncmp(config->url, "socks://", 8) ||
!strncmp(config->url, "pac+", 4) ||
@@ -564,7 +615,7 @@ px_proxy_factory_get_proxies (pxProxyFactory *self, char *url)
config->url = px_strdup("wpad://");
}
- /* Check our ignore patterns */
+ // Check our ignore patterns
char **ignores = px_strsplit(config->ignore, ",");
for (int i=0 ; ignores[i] ; i++)
{
@@ -576,10 +627,10 @@ px_proxy_factory_get_proxies (pxProxyFactory *self, char *url)
}
px_strfreev(ignores);
- /* If we have a wpad config */
+ // If we have a wpad config
if (!strcmp(config->url, "wpad://"))
{
- /* Get the WPAD object if needed */
+ // Get the WPAD object if needed
if (!self->wpad)
{
if (self->pac) px_pac_free(self->pac);
@@ -592,46 +643,45 @@ px_proxy_factory_get_proxies (pxProxyFactory *self, char *url)
}
}
- /*
- * If we have no PAC, get one
- * If getting the PAC fails, but the WPAD cycle worked, restart the cycle
- */
+ // If we have no PAC, get one
+ // If getting the PAC fails, but the WPAD cycle worked, restart the cycle
if (!self->pac && !(self->pac = px_wpad_next(self->wpad)) && px_wpad_pac_found(self->wpad))
{
px_wpad_rewind(self->wpad);
self->pac = px_wpad_next(self->wpad);
}
- /* If the WPAD cycle failed, fall back to direct */
+ // If the WPAD cycle failed, fall back to direct
if (!self->pac)
{
fprintf(stderr, "*** Unable to locate PAC! Falling back to direct...\n");
goto do_return;
}
- /* Run the PAC */
+ // Run the PAC
if (self->pac_runner)
{
px_strfreev(response);
response = _format_pac_response(self->pac_runner(self, self->pac, realurl));
}
- /* No PAC runner found, fall back to direct */
+ // No PAC runner found, fall back to direct
else
fprintf(stderr, "*** PAC found, but no active PAC runner! Falling back to direct...\n");
}
- /* If we have a PAC config */
+ // If we have a PAC config
else if (!strncmp(config->url, "pac+", 4))
{
- /* Clear WPAD to indicate that this is a non-WPAD PAC */
+ // Clear WPAD to indicate that this is a non-WPAD PAC
if (self->wpad)
{
px_wpad_free(self->wpad);
self->wpad = NULL;
}
- /* If a PAC already exists, but came from a different URL than the one specified, remove it */
+ // If a PAC alread exists, but comes from a different URL than the one
+ // specified, remove it
if (self->pac)
{
pxURL *urltmp = px_url_new(config->url + 4);
@@ -648,14 +698,14 @@ px_proxy_factory_get_proxies (pxProxyFactory *self, char *url)
px_url_free(urltmp);
}
- /* Try to load the PAC if it is not already loaded */
+ // Try to load the PAC if it is not already loaded
if (!self->pac && !(self->pac = px_pac_new_from_string(config->url + 4)))
{
fprintf(stderr, "*** Invalid PAC URL! Falling back to direct...\n");
goto do_return;
}
- /* Run the PAC */
+ // Run the PAC
if (self->pac_runner)
{
px_strfreev(response);
@@ -665,7 +715,7 @@ px_proxy_factory_get_proxies (pxProxyFactory *self, char *url)
fprintf(stderr, "*** PAC found, but no active PAC runner! Falling back to direct...\n");
}
- /* If we have a manual config (http://..., socks://...) */
+ // If we have a manual config (http://..., socks://...)
else if (!strncmp(config->url, "http://", 7) || !strncmp(config->url, "socks://", 8))
{
if (self->wpad) { px_wpad_free(self->wpad); self->wpad = NULL; }
@@ -674,7 +724,7 @@ px_proxy_factory_get_proxies (pxProxyFactory *self, char *url)
response = px_strsplit(config->url, ";");
}
- /* Actually return, freeing misc stuff */
+ // Actually return, freeing misc stuff
do_return:
if (config) { px_free(config->url); px_free(config->ignore); px_free(config); }
if (realurl) px_url_free(realurl);
@@ -683,15 +733,60 @@ px_proxy_factory_get_proxies (pxProxyFactory *self, char *url)
}
bool
-px_proxy_factory_on_get_proxies_add (pxProxyFactory *self, pxProxyFactoryVoidCallback callback)
+px_proxy_factory_on_get_proxy_add (pxProxyFactory *self, pxProxyFactoryVoidCallback callback)
{
- return self ? px_array_add(self->on_get_proxies, callback) : false;
+ int count;
+ pxProxyFactoryVoidCallback *tmp;
+
+ // Verify some basic stuff
+ if (!self) return false;
+ if (!callback) return false;
+
+ // Allocate an empty config array if there is none
+ if (!self->on_get_proxy) self->on_get_proxy = px_malloc0(sizeof(pxProxyFactoryVoidCallback));
+
+ // Get a count of how many callbacks we have
+ for (count=0 ; self->on_get_proxy[count] ; count++);
+
+ // Allocate new array, copy old values into it and free old array
+ tmp = px_malloc0(sizeof(pxProxyFactoryVoidCallback) * (count + 2));
+ memcpy(tmp, self->on_get_proxy, sizeof(pxProxyFactoryVoidCallback) * count);
+ px_free(self->on_get_proxy);
+ self->on_get_proxy = tmp;
+
+ // Add the new callback to the end
+ self->on_get_proxy[count] = callback;
+
+ return true;
}
bool
-px_proxy_factory_on_get_proxies_del (pxProxyFactory *self, pxProxyFactoryVoidCallback callback)
+px_proxy_factory_on_get_proxy_del (pxProxyFactory *self, pxProxyFactoryVoidCallback callback)
{
- return self ? px_array_del(self->on_get_proxies, callback) : false;
+ int i,j;
+
+ // Verify some basic stuff
+ if (!self) return false;
+ if (!callback) return false;
+ if (!self->on_get_proxy) return false;
+
+ // Remove and shift all callbacks down (if found)
+ for (i=0,j=0 ; self->on_get_proxy[j]; i++,j++)
+ {
+ if (i != j)
+ self->on_get_proxy[j] = self->on_get_proxy[i];
+ else if (self->on_get_proxy[i] == callback)
+ self->on_get_proxy[j--] = NULL;
+ }
+
+ // If we have an empty array, free it
+ if (!self->on_get_proxy[0])
+ {
+ px_free(self->on_get_proxy);
+ self->on_get_proxy = NULL;
+ }
+
+ return i != j ? true : false;
}
bool
@@ -706,10 +801,17 @@ px_proxy_factory_pac_runner_set (pxProxyFactory *self, pxPACRunnerCallback callb
void
px_proxy_factory_network_changed(pxProxyFactory *self)
{
- px_wpad_free(self->wpad);
- px_pac_free(self->pac);
- self->wpad = NULL;
- self->pac = NULL;
+ if (self->wpad)
+ {
+ px_wpad_free(self->wpad);
+ self->wpad = NULL;
+ }
+
+ if (self->pac)
+ {
+ px_pac_free(self->pac);
+ self->pac = NULL;
+ }
}
/**
@@ -718,18 +820,42 @@ px_proxy_factory_network_changed(pxProxyFactory *self)
void
px_proxy_factory_free (pxProxyFactory *self)
{
+ unsigned int i;
+
if (!self) return;
pthread_mutex_lock(&self->mutex);
- /* Free the plugins */
- px_array_foreach(self->plugins, destantiate_plugins, self);
- px_array_free(self->plugins);
+ // Free the plugins
+ if (self->plugins)
+ {
+ for (i=0 ; self->plugins[i] ; i++)
+ {
+ // Call the destantiation hook
+ pxProxyFactoryVoidCallback destantiate;
+ destantiate = dlsym(self->plugins[i], "on_proxy_factory_destantiate");
+ if (destantiate)
+ destantiate(self);
+
+ // Unload the plugin
+ dlclose(self->plugins[i]);
+ self->plugins[i] = NULL;
+ }
+ px_free(self->plugins);
+ }
- /* Free misc */
- px_strdict_free(self->misc);
+ // Free misc
+ if (self->misc)
+ {
+ for (i=0 ; self->misc[i] ; i++)
+ {
+ px_free(self->misc[i]->key);
+ px_free(self->misc[i]);
+ }
+ px_free(self->misc);
+ }
- /* Free everything else */
+ // Free everything else
px_pac_free(self->pac);
px_wpad_free(self->wpad);
px_config_file_free(self->cf);
diff --git a/src/lib/proxy_factory.h b/src/lib/proxy_factory.h
index c73dad7..57ee186 100644
--- a/src/lib/proxy_factory.h
+++ b/src/lib/proxy_factory.h
@@ -35,15 +35,13 @@ enum _pxConfigCategory {
};
typedef enum _pxConfigCategory pxConfigCategory;
-/*
- * URLs look like this:
- * http://host:port
- * socks://host:port
- * pac+http://pac_host:port/path/to/pac
- * wpad://
- * direct://
- */
- /* TODO: ignore syntax TBD */
+// URLs look like this:
+// http://host:port
+// socks://host:port
+// pac+http://pac_host:port/path/to/pac
+// wpad://
+// direct://
+// TODO: ignore syntax TBD
struct _pxConfig {
char *url;
char *ignore;
@@ -68,8 +66,8 @@ bool px_proxy_factory_config_del (pxProxyFactory *self, const c
bool px_proxy_factory_misc_set (pxProxyFactory *self, const char *key, const void *value);
void *px_proxy_factory_misc_get (pxProxyFactory *self, const char *key);
void px_proxy_factory_network_changed (pxProxyFactory *self);
-bool px_proxy_factory_on_get_proxies_add(pxProxyFactory *self, pxProxyFactoryVoidCallback callback);
-bool px_proxy_factory_on_get_proxies_del(pxProxyFactory *self, pxProxyFactoryVoidCallback callback);
+bool px_proxy_factory_on_get_proxy_add(pxProxyFactory *self, pxProxyFactoryVoidCallback callback);
+bool px_proxy_factory_on_get_proxy_del(pxProxyFactory *self, pxProxyFactoryVoidCallback callback);
bool px_proxy_factory_pac_runner_set (pxProxyFactory *self, pxPACRunnerCallback callback);
#endif /*PROXY_FACTORY_H_*/
diff --git a/src/lib/wpad_slp.c b/src/lib/slp.c
index 7251ce4..1e65013 100644
--- a/src/lib/wpad_slp.c
+++ b/src/lib/slp.c
@@ -20,7 +20,7 @@
#include <stdlib.h>
#include "pac.h"
-#include "wpad_slp.h"
+#include "slp.h"
struct _pxSLP { };
diff --git a/src/lib/wpad_slp.h b/src/lib/slp.h
index 9f3b5bf..9f3b5bf 100644
--- a/src/lib/wpad_slp.h
+++ b/src/lib/slp.h
diff --git a/src/lib/strdict.c b/src/lib/strdict.c
deleted file mode 100644
index 3157e65..0000000
--- a/src/lib/strdict.c
+++ /dev/null
@@ -1,122 +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 <stdint.h>
-#include <string.h>
-
-#include "misc.h"
-#include "array.h"
-#include "strdict.h"
-
-struct _pxStrDict {
- pxStrDictItemCallback free;
- pxArray *data;
-};
-
-static bool
-dict_equals(void *a, void *b)
-{
- if (!a || !b) return false;
- void **aa = (void **) a;
- void **bb = (void **) b;
- return (!strcmp((char *) *aa, (char *) *bb));
-}
-
-static void
-dict_free(void *item)
-{
- char *key = (char *) ((void **) item)[0];
- void **realitem = ((void **) item)[1];
- pxStrDictItemCallback do_free = ((void **) item)[2];
-
- do_free(realitem);
- px_free(key);
- px_free(item);
-}
-
-static void
-dict_foreach(void *item, void *misc)
-{
- pxStrDictForeachCallback foreach = ((void **) misc)[0];
- char *key = ((void **) item)[0];
- void *val = ((void **) item)[1];
- void *arg = ((void **) misc)[1];
- foreach(key, val, arg);
-}
-
-static void
-do_nothing(void *item)
-{
-}
-
-pxStrDict *px_strdict_new(pxStrDictItemCallback free)
-{
- pxStrDict *self = px_malloc0(sizeof(pxStrDict));
- self->free = free ? free : do_nothing;
- self->data = px_array_new(dict_equals, dict_free, true, false);
- return self;
-}
-
-bool
-px_strdict_set(pxStrDict *self, const char *key, void *value)
-{
- if (!self || !key) return false;
-
- /* We are unseting the value */
- if (!value)
- {
- void *item[3] = { (void *) key, value, self->free };
- return px_array_del(self->data, item);
- }
-
- void **item = px_malloc0(sizeof(void *) * 3);
- item[0] = px_strdup(key);
- item[1] = value;
- item[2] = self->free;
-
- if (px_array_add(self->data, item))
- return true;
-
- px_free(*item);
- px_free(item);
- return false;
-}
-
-const void *
-px_strdict_get(pxStrDict *self, const char *key)
-{
- void *v[3] = { (void *) key, NULL, NULL };
- int i = px_array_find(self->data, v);
- if (i < 0) return NULL;
- return px_array_get(self->data, i);
-}
-
-void
-px_strdict_foreach(pxStrDict *self, pxStrDictForeachCallback *cb, void *arg)
-{
- void *v[2] = { cb, arg };
- px_array_foreach(self->data, dict_foreach, v);
-}
-
-void
-px_strdict_free(pxStrDict *self)
-{
- px_array_free(self->data);
- px_free(self);
-}
diff --git a/src/lib/strdict.h b/src/lib/strdict.h
deleted file mode 100644
index 9a7dc1a..0000000
--- a/src/lib/strdict.h
+++ /dev/null
@@ -1,35 +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 <stdbool.h>
-
-typedef void (*pxStrDictItemCallback)(void *);
-typedef void (*pxStrDictForeachCallback)(const char *, void *, void *);
-
-typedef struct _pxStrDict pxStrDict;
-
-pxStrDict *px_strdict_new(pxStrDictItemCallback free);
-
-bool px_strdict_set(pxStrDict *self, const char *key, void *value);
-
-const void *px_strdict_get(pxStrDict *self, const char *key);
-
-void px_strdict_foreach(pxStrDict *self, pxStrDictForeachCallback *cb, void *arg);
-
-void px_strdict_free(pxStrDict *self);
diff --git a/src/lib/url.c b/src/lib/url.c
index ba156e4..3eb0e35 100644
--- a/src/lib/url.c
+++ b/src/lib/url.c
@@ -87,10 +87,10 @@ px_url_get(pxURL *self, const char **headers)
char *joined_headers = NULL;
int sock = -1;
- /* DNS lookup of host */
+ // DNS lookup of host
if (!px_url_get_ips(self)) goto error;
- /* Iterate through each pxIP trying to make a connection */
+ // Iterate through each pxIP trying to make a connection
for (int i = 0 ; self->ips && self->ips[i] && sock < 0 ; i++)
{
sock = socket(self->ips[i]->sa_family, SOCK_STREAM, 0);
@@ -108,7 +108,7 @@ px_url_get(pxURL *self, const char **headers)
}
if (sock < 0) goto error;
- /* Merge optional headers */
+ // Merge optional headers
if (headers)
{
joined_headers = px_strjoin(headers, "\r\n");
@@ -117,17 +117,17 @@ px_url_get(pxURL *self, const char **headers)
else
joined_headers = px_strdup("");
- /* Create request header */
+ // Create request header
request = px_strcat("GET ", px_url_get_path(self),
" HTTP/1.1\r\nHost: ", px_url_get_host(self),
"\r\n", joined_headers, "\r\n\r\n", NULL);
px_free(joined_headers);
- /* Send HTTP request */
+ // Send HTTP request
if (send(sock, request, strlen(request), 0) != strlen(request)) goto error;
px_free(request); request = NULL;
- /* Return the socket, which is ready for reading the response */
+ // Return the socket, which is ready for reading the response
return sock;
error:
@@ -166,12 +166,12 @@ px_url_get_ip_no_dns(pxURL *self)
{
if (!self) return NULL;
- /* Check the cache */
+ // Check the cache
if (self->ips && self->ips[0])
return (const struct sockaddr *) self->ips[0];
px_free(self->ips);
- /* Try for IPv4 first */
+ // Try for IPv4 first
struct sockaddr *ip = px_malloc0(sizeof(struct sockaddr_in));
if (inet_pton(AF_INET, px_url_get_host(self), &((struct sockaddr_in *) ip)->sin_addr) > 0)
{
@@ -182,7 +182,7 @@ px_url_get_ip_no_dns(pxURL *self)
}
px_free(ip);
- /* Try for IPv6 next */
+ // Try for IPv6 next
ip = px_malloc0(sizeof(struct sockaddr_in6));
if (inet_pton(AF_INET6, px_url_get_host(self), &((struct sockaddr_in6 *) ip)->sin6_addr) > 0)
{
@@ -193,7 +193,7 @@ px_url_get_ip_no_dns(pxURL *self)
}
px_free(ip);
- /* The hostname was not an IP address */
+ // The hostname was not an IP address
return NULL;
}
@@ -206,24 +206,24 @@ px_url_get_ips(pxURL *self)
{
if (!self) return NULL;
- /* Check the cache */
+ // Check the cache
if (self->ips) return (const struct sockaddr **) self->ips;
- /* Check without DNS first */
+ // Check without DNS first
if (px_url_get_ip_no_dns(self)) return (const struct sockaddr **) self->ips;
- /* Check DNS for IPs */
+ // Check DNS for IPs
struct addrinfo *info;
if (!getaddrinfo(px_url_get_host(self), NULL, NULL, &info))
{
struct addrinfo *first = info;
int count;
- /* Count how many IPs we got back */
+ // Count how many IPs we got back
for (count=0 ; info ; info = info->ai_next)
count++;
- /* Copy the sockaddr's into self->ips */
+ // Copy the sockaddr's into self->ips
info = first;
self->ips = px_malloc0(sizeof(struct sockaddr *) * ++count);
for (int i=0 ; info ; info = info->ai_next)
@@ -246,7 +246,7 @@ px_url_get_ips(pxURL *self)
return (const struct sockaddr **) self->ips;
}
- /* No addresses found */
+ // No addresses found
return NULL;
}
@@ -287,24 +287,24 @@ px_url_get_scheme(pxURL *self)
pxURL *
px_url_new(const char *url)
{
- /* Allocate pxURL */
+ // Allocate pxURL
pxURL *self = px_malloc0(sizeof(pxURL));
- /* Get scheme */
+ // Get scheme
if (!strstr(url, "://")) goto error;
self->scheme = px_strndup(url, strstr(url, "://") - url);
- /* Get host */
+ // Get host
self->host = px_strdup(strstr(url, "://") + strlen("://"));
- /* Get path */
+ // Get path
self->path = px_strdup(strchr(self->host, '/'));
if (self->path)
self->host[strlen(self->host) - strlen(self->path)] = 0;
else
self->path = px_strdup("");
- /* Get the port */
+ // Get the port
bool port_specified = false;
if (strchr(self->host, ':')) {
if (!atoi(strchr(self->host, ':')+1)) goto error;
@@ -315,10 +315,10 @@ px_url_new(const char *url)
else
self->port = px_url_get_default_port(self);
- /* Make sure we have a real host */
+ // Make sure we have a real host
if (!strcmp(self->host, "")) goto error;
- /* Verify by re-assembly */
+ // Verify by re-assembly
self->url = px_malloc0(strlen(url) + 1);
if (!port_specified)
snprintf(self->url, strlen(url) + 1, "%s://%s%s", self->scheme, self->host, self->path);
diff --git a/src/lib/url.h b/src/lib/url.h
index bf2fd68..3e1b667 100644
--- a/src/lib/url.h
+++ b/src/lib/url.h
@@ -20,7 +20,7 @@
#ifndef URL_H_
#define URL_H_
-#include "stdbool.h" /* For type bool */
+#include "stdbool.h" // For type bool
/**
* WPAD object. All fields are private.
diff --git a/src/lib/wpad.c b/src/lib/wpad.c
index 7c18ef4..65fffad 100644
--- a/src/lib/wpad.c
+++ b/src/lib/wpad.c
@@ -18,6 +18,9 @@
******************************************************************************/
#include "misc.h"
+#include "dhcp.h"
+#include "dns.h"
+#include "slp.h"
#include "wpad.h"
struct _pxWPAD {
@@ -71,7 +74,7 @@ px_wpad_next(pxWPAD *self)
{
if (!self) return NULL;
- /* Check all the detectors for a PAC */
+ // Check all the detectors for a PAC
pxPAC *pac = NULL;
if (!(pac = px_dhcp_next(self->dhcp)))
if (!(pac = px_slp_next(self->slp)))
diff --git a/src/lib/wpad.h b/src/lib/wpad.h
index 3e6d8bb..411b0de 100644
--- a/src/lib/wpad.h
+++ b/src/lib/wpad.h
@@ -21,9 +21,9 @@
#define WPAD_H_
#include "pac.h"
-#include "wpad_dhcp.h"
-#include "wpad_dns.h"
-#include "wpad_slp.h"
+#include "dhcp.h"
+#include "dns.h"
+#include "slp.h"
/**
* WPAD object. All fields are private.
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 5e5d18c..9a561ea 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -14,6 +14,9 @@ endif
if WITH_KDE
plugin_LTLIBRARIES += kde.la
endif
+if WITH_WEBKIT
+plugin_LTLIBRARIES += webkit.la
+endif
if WITH_MOZJS
plugin_LTLIBRARIES += mozjs.la
endif
@@ -45,6 +48,13 @@ kde_la_CFLAGS = -I$(top_srcdir)/src/lib @KDE_CFLAGS@
kde_la_LIBADD = ../lib/libproxy.la
kde_la_LDFLAGS = -module -avoid-version @KDE_LIBS@
+# WebKit (JavaScriptCore) based PAC runner
+webkit_la_SOURCES = webkit.c
+webkit_la_CFLAGS = -I$(top_srcdir)/src/lib @WEBKIT_CFLAGS@
+webkit_la_LIBADD = ../lib/libproxy.la
+webkit_la_LDFLAGS = -module -avoid-version @WEBKIT_LIBS@
+nodist_webkit_la_SOURCES = pacutils.h
+
# Mozilla (Spidermonkey) based PAC runner
mozjs_la_SOURCES = mozjs.c
mozjs_la_CFLAGS = -I$(top_srcdir)/src/lib @MOZJS_CFLAGS@
diff --git a/src/plugins/mozjs.c b/src/plugins/mozjs.c
index 5f89672..88c8180 100644
--- a/src/plugins/mozjs.c
+++ b/src/plugins/mozjs.c
@@ -36,38 +36,34 @@ static JSBool dnsResolve(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
// Get hostname argument
char *tmp = px_strdup(JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
+ // Set the default return value
+ *rval = JSVAL_NULL;
+
// Look it up
- struct addrinfo *info;
+ struct addrinfo *info = NULL;
if (getaddrinfo(tmp, NULL, NULL, &info))
- goto error;
+ goto out;
+
+ // Allocate the IP address
px_free(tmp);
+ tmp = px_malloc0(INET6_ADDRSTRLEN+1);
- // Try for IPv4
- tmp = px_malloc0(INET_ADDRSTRLEN+1);
- if (inet_ntop(info->ai_family,
+ // Try for IPv4 and IPv6
+ if (!inet_ntop(info->ai_family,
&((struct sockaddr_in *) info->ai_addr)->sin_addr,
tmp, INET_ADDRSTRLEN+1) > 0)
- {
- JSString *ip = JS_NewString(cx, tmp, strlen(tmp));
- *rval = STRING_TO_JSVAL(ip);
- return true;
- }
-
- // Try for IPv6
- px_free(tmp);
- tmp = px_malloc0(INET6_ADDRSTRLEN+1);
- if (inet_ntop(info->ai_family,
- &((struct sockaddr_in6 *) info->ai_addr)->sin6_addr,
- tmp, INET6_ADDRSTRLEN+1) > 0)
- {
- JSString *ip = JS_NewString(cx, tmp, strlen(tmp));
- *rval = STRING_TO_JSVAL(ip);
- return true;
- }
+ if (!inet_ntop(info->ai_family,
+ &((struct sockaddr_in6 *) info->ai_addr)->sin6_addr,
+ tmp, INET6_ADDRSTRLEN+1) > 0)
+ goto out;
+
+ // We succeeded
+ *rval = STRING_TO_JSVAL(JS_NewString(cx, tmp, strlen(tmp)));
+ tmp = NULL;
- error:
+ out:
+ if (info) freeaddrinfo(info);
px_free(tmp);
- *rval = JSVAL_NULL;
return true;
}
@@ -83,72 +79,115 @@ static JSBool myIpAddress(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
return true;
}
+typedef struct {
+ JSRuntime *run;
+ JSContext *ctx;
+ JSClass *cls;
+ char *pac;
+} ctxStore;
+
+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 = px_malloc0(sizeof(ctxStore));
+
+ // Setup Javascript global class
+ self->cls = 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;
+}
+
char *mozjs_pacrunner(pxProxyFactory *self, pxPAC *pac, pxURL *url)
{
- JSRuntime *runtime = NULL;
- JSContext *context = NULL;
- JSObject *global = NULL;
- jsval rval;
- char *answer = 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;
-
- // Setup Javascript global class
- JSClass *global_class = px_malloc0(sizeof(JSClass));
- global_class->name = "global";
- global_class->flags = 0;
- global_class->addProperty = JS_PropertyStub;
- global_class->delProperty = JS_PropertyStub;
- global_class->getProperty = JS_PropertyStub;
- global_class->setProperty = JS_PropertyStub;
- global_class->enumerate = JS_EnumerateStub;
- global_class->resolve = JS_ResolveStub;
- global_class->convert = JS_ConvertStub;
- global_class->finalize = JS_FinalizeStub;
-
- // Initialize Javascript runtime environment
- if (!(runtime = JS_NewRuntime(1024 * 1024))) goto out;
- if (!(context = JS_NewContext(runtime, 1024 * 1024))) goto out;
- if (!(global = JS_NewObject(context, global_class, NULL, NULL))) goto out;
- JS_InitStandardClasses(context, global);
-
- // Define Javascript functions
- JS_DefineFunction(context, global, "dnsResolve", dnsResolve, 1, 0);
- JS_DefineFunction(context, global, "myIpAddress", myIpAddress, 0, 0);
- JS_EvaluateScript(context, global, JAVASCRIPT_ROUTINES,
- strlen(JAVASCRIPT_ROUTINES), "pacutils.js", 0, &rval);
-
- // Add PAC to the environment
- JS_EvaluateScript(context, JS_GetGlobalObject(context),
- px_pac_to_string(pac), strlen(px_pac_to_string(pac)),
- px_url_to_string((pxURL *) px_pac_get_url(pac)), 0, &rval);
+
+ // Get the cached context
+ ctxStore *ctxs = px_proxy_factory_misc_get(self, "mozjs");
+
+ // 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;
+ }
+
+ // If no context exists (or if the pac was changed), create one
+ if (!ctxs)
+ {
+ if ((ctxs = ctxs_new(pac)))
+ px_proxy_factory_misc_set(self, "mozjs", ctxs);
+ else
+ return NULL;
+ }
// 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 val[2] = {
- STRING_TO_JSVAL(JS_NewString(context, tmpurl, strlen(tmpurl))),
- STRING_TO_JSVAL(JS_NewString(context, tmphost, strlen(tmphost)))
+ 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())
- JSBool result = JS_CallFunctionName(context, JS_GetGlobalObject(context),
- "FindProxyForURL", 2, val, &rval);
- if (!result) goto out;
- answer = px_strdup(JS_GetStringBytes(JS_ValueToString(context, rval)));
+ 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);
- answer = NULL;
+ return NULL;
}
-
- out:
- if (context) JS_DestroyContext(context);
- if (runtime) JS_DestroyRuntime(runtime);
- px_free(global_class);
- return answer;
+ return answer;
}
bool on_proxy_factory_instantiate(pxProxyFactory *self)
@@ -159,4 +198,6 @@ bool on_proxy_factory_instantiate(pxProxyFactory *self)
void on_proxy_factory_destantiate(pxProxyFactory *self)
{
px_proxy_factory_pac_runner_set(self, NULL);
+ ctxs_free(px_proxy_factory_misc_get(self, "mozjs"));
+ px_proxy_factory_misc_set(self, "mozjs", NULL);
}
diff --git a/src/plugins/networkmanager.c b/src/plugins/networkmanager.c
index fca92d6..e7c8360 100644
--- a/src/plugins/networkmanager.c
+++ b/src/plugins/networkmanager.c
@@ -84,13 +84,13 @@ nm_on_get_proxy(pxProxyFactory *self)
bool
on_proxy_factory_instantiate(pxProxyFactory *self)
{
- px_proxy_factory_on_get_proxies_add(self, nm_on_get_proxy);
+ px_proxy_factory_on_get_proxy_add(self, nm_on_get_proxy);
}
void
on_proxy_factory_destantiate(pxProxyFactory *self)
{
- px_proxy_factory_on_get_proxies_del(self, nm_on_get_proxy);
+ px_proxy_factory_on_get_proxy_del(self, nm_on_get_proxy);
DBusConnection *conn = px_proxy_factory_misc_get(self, "networkmanager");
if (conn)
{
diff --git a/src/plugins/webkit.c b/src/plugins/webkit.c
new file mode 100644
index 0000000..859c618
--- /dev/null
+++ b/src/plugins/webkit.c
@@ -0,0 +1,209 @@
+/*******************************************************************************
+ * 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 <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+#define __USE_BSD
+#include <unistd.h>
+
+#include <misc.h>
+#include <proxy_factory.h>
+
+#include <JavaScriptCore/JavaScript.h>
+#include "pacutils.h"
+
+static char *jstr2str(JSStringRef str, bool release)
+{
+ char *tmp = px_malloc0(JSStringGetMaximumUTF8CStringSize(str)+1);
+ JSStringGetUTF8CString(str, tmp, JSStringGetMaximumUTF8CStringSize(str)+1);
+ if (release) JSStringRelease(str);
+ return tmp;
+}
+
+static JSValueRef dnsResolve(JSContextRef ctx, JSObjectRef func, JSObjectRef self, size_t argc, const JSValueRef argv[], JSValueRef* exception)
+{
+ if (argc != 1) return NULL;
+ if (!JSValueIsString(ctx, argv[0])) return NULL;
+
+ // Get hostname argument
+ char *tmp = jstr2str(JSValueToStringCopy(ctx, argv[0], NULL), true);
+
+ // Look it up
+ struct addrinfo *info;
+ if (getaddrinfo(tmp, NULL, NULL, &info))
+ return NULL;
+ px_free(tmp);
+
+ // Try for IPv4
+ tmp = px_malloc0(INET6_ADDRSTRLEN+1);
+ if (!inet_ntop(info->ai_family,
+ &((struct sockaddr_in *) info->ai_addr)->sin_addr,
+ tmp, INET_ADDRSTRLEN+1) > 0)
+ // Try for IPv6
+ if (!inet_ntop(info->ai_family,
+ &((struct sockaddr_in6 *) info->ai_addr)->sin6_addr,
+ tmp, INET6_ADDRSTRLEN+1) > 0)
+ {
+ freeaddrinfo(info);
+ px_free(tmp);
+ return NULL;
+ }
+ freeaddrinfo(info);
+
+ // Create the return value
+ JSStringRef str = JSStringCreateWithUTF8CString(tmp);
+ JSValueRef ret = JSValueMakeString(ctx, str);
+ JSStringRelease(str);
+ px_free(tmp);
+
+ return ret;
+}
+
+static JSValueRef myIpAddress(JSContextRef ctx, JSObjectRef func, JSObjectRef self, size_t argc, const JSValueRef argv[], JSValueRef* exception)
+{
+ char hostname[1024];
+ if (!gethostname(hostname, 1023)) {
+ JSStringRef str = JSStringCreateWithUTF8CString(hostname);
+ JSValueRef val = JSValueMakeString(ctx, str);
+ JSStringRelease(str);
+ JSValueRef ip = dnsResolve(ctx, func, self, 1, &val, NULL);
+ return ip;
+ }
+ return NULL;
+}
+
+typedef struct {
+ JSGlobalContextRef ctx;
+ char *pac;
+} ctxStore;
+
+static void ctxs_free(ctxStore *self)
+{
+ if (!self) return;
+ JSGlobalContextRelease(self->ctx);
+ JSGarbageCollect(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 = 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);
+
+ // 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);
+
+ // 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);
+
+ return self;
+
+error:
+ if (str) JSStringRelease(str);
+ ctxs_free(self);
+ return NULL;
+}
+
+char *webkit_pacrunner(pxProxyFactory *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 = px_proxy_factory_misc_get(self, "webkit");
+
+ // 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;
+ }
+
+ // If no context exists (or if the pac was changed), create one
+ if (!ctxs)
+ {
+ if ((ctxs = ctxs_new(pac)))
+ px_proxy_factory_misc_set(self, "webkit", ctxs);
+ else
+ return NULL;
+ }
+
+ // 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);
+
+ // Convert the return value to a string
+ return jstr2str(JSValueToStringCopy(ctxs->ctx, val, NULL), true);
+
+error:
+ if (str) JSStringRelease(str);
+ ctxs_free(ctxs);
+ return tmp;
+}
+
+bool on_proxy_factory_instantiate(pxProxyFactory *self)
+{
+ return px_proxy_factory_pac_runner_set(self, webkit_pacrunner);
+}
+
+void on_proxy_factory_destantiate(pxProxyFactory *self)
+{
+ px_proxy_factory_pac_runner_set(self, NULL);
+ ctxs_free(px_proxy_factory_misc_get(self, "webkit"));
+ px_proxy_factory_misc_set(self, "webkit", NULL);
+}