Someone else can do the autoshite magic for it and make PacRunner cope with
building either this or the mozjs one.
---
 src/v8.cc |  304 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 304 insertions(+), 0 deletions(-)
 create mode 100644 src/v8.cc

diff --git a/src/v8.cc b/src/v8.cc
new file mode 100644
index 0000000..1dbaa99
--- /dev/null
+++ b/src/v8.cc
@@ -0,0 +1,304 @@
+/*
+ *
+ *  PACrunner - Proxy configuration daemon
+ *
+ *  Copyright (C) 2010  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include <netdb.h>
+#include <arpa/inet.h>
+#include <linux/if_arp.h>
+
+#include <v8.h>
+#include "javascript.h"
+
+extern "C" {
+#include "pacrunner.h"
+};
+
+struct pacrunner_proxy *current_proxy = NULL;
+v8::Persistent<v8::Context> jsctx;
+v8::Persistent<v8::Function> jsfn;
+guint gc_source = 0;
+
+static gboolean v8_gc(gpointer user_data)
+{
+       v8::Locker lck;
+       return !v8::V8::IdleNotification();
+}
+
+static int getaddr(const char *node, char *host, size_t hostlen)
+{
+       struct sockaddr_in addr;
+       struct ifreq ifr;
+       int sk, err;
+
+       sk = socket(PF_INET, SOCK_DGRAM, 0);
+       if (sk < 0)
+               return -EIO;
+
+       memset(&ifr, 0, sizeof(ifr));
+       strncpy(ifr.ifr_name, node, sizeof(ifr.ifr_name));
+
+       err = ioctl(sk, SIOCGIFADDR, &ifr);
+
+       close(sk);
+
+       if (err < 0)
+               return -EIO;
+
+       memcpy(&addr, &ifr.ifr_addr, sizeof(addr));
+       snprintf(host, hostlen, "%s", inet_ntoa(addr.sin_addr));
+
+       return 0;
+}
+
+static int resolve(const char *node, char *host, size_t hostlen)
+{
+       struct addrinfo *info;
+       int err;
+
+       if (getaddrinfo(node, NULL, NULL, &info) < 0)
+               return -EIO;
+
+       err = getnameinfo(info->ai_addr, info->ai_addrlen,
+                               host, hostlen, NULL, 0, NI_NUMERICHOST);
+
+       freeaddrinfo(info);
+
+       if (err < 0)
+               return -EIO;
+
+       return 0;
+}
+
+static v8::Handle<v8::Value> myipaddress(const v8::Arguments& args)
+{
+       const char *interface;
+       char address[NI_MAXHOST];
+
+       DBG("");
+
+       if (current_proxy == NULL)
+               return v8::ThrowException(v8::String::New("No current proxy"));
+
+       interface = pacrunner_proxy_get_interface(current_proxy);
+       if (interface == NULL)
+               return v8::ThrowException(v8::String::New("Error fetching 
interface"));
+
+       if (getaddr(interface, address, sizeof(address)) < 0)
+               return v8::ThrowException(v8::String::New("Error fetching IP 
address"));
+
+       DBG("address %s", address);
+
+       return v8::String::New(address);
+}
+
+static v8::Handle<v8::Value> dnsresolve(const v8::Arguments& args)
+{
+       char address[NI_MAXHOST];
+       v8::String::Utf8Value host(args[0]);
+
+       if (args.Length() != 1)
+               return v8::ThrowException(v8::String::New("Bad parameters"));
+
+               
+       DBG("host %s", *host);
+
+       if (resolve(*host, address, sizeof(address)) < 0)
+               return v8::ThrowException(v8::String::New("Failed to resolve"));
+
+       DBG("address %s", address);
+
+       return v8::String::New(address);
+}
+
+static void create_object(void)
+{
+       if (!current_proxy)
+               return;
+
+       const char *pac = pacrunner_proxy_get_script(current_proxy);
+       if (!pac) {
+               printf("no script\n");
+               return;
+       }
+       v8::HandleScope handle_scope;
+       v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
+
+       global->Set(v8::String::New("myIpAddress"),
+                   v8::FunctionTemplate::New(myipaddress));
+       global->Set(v8::String::New("dnsResolve"),
+                   v8::FunctionTemplate::New(dnsresolve));
+
+       jsctx = v8::Context::New(NULL, global);
+       v8::Context::Scope context_scope(jsctx);
+
+       v8::TryCatch exc;
+       v8::Handle<v8::Script> script_scr;
+       v8::Handle<v8::Value> result;
+
+       script_scr = v8::Script::Compile(v8::String::New(JAVASCRIPT_ROUTINES));
+       if (script_scr.IsEmpty()) {
+               v8::String::Utf8Value err(exc.Exception());
+               DBG("Javascript failed to compile: %s", *err);
+               jsctx.Dispose();
+               return;
+       }
+       result = script_scr->Run();
+       if (exc.HasCaught()) {
+               v8::String::Utf8Value err(exc.Exception());
+               DBG("Javascript library failed: %s", *err);
+               jsctx.Dispose();
+               return;
+       }
+
+       script_scr = v8::Script::Compile(v8::String::New(pac));
+       if (script_scr.IsEmpty()) {
+               v8::String::Utf8Value err(exc.Exception());
+               DBG("PAC script failed to compile: %s", *err);
+               jsctx.Dispose();
+               return;
+       }
+       result = script_scr->Run();
+       if (exc.HasCaught()) {
+               v8::String::Utf8Value err(exc.Exception());
+               DBG("PAC script failed: %s", *err);
+               jsctx.Dispose();
+               return;
+       }
+
+       v8::Handle<v8::String> fn_name = v8::String::New("FindProxyForURL");
+       v8::Handle<v8::Value> fn_val = jsctx->Global()->Get(fn_name);
+
+       if (!fn_val->IsFunction()) {
+               DBG("FindProxyForUrl is not a function");
+               jsctx.Dispose();
+               return;
+       }
+       
+       jsfn = 
v8::Persistent<v8::Function>::New(v8::Handle<v8::Function>::Cast(fn_val));
+       return;
+}
+
+static void destroy_object(void)
+{
+       if (!jsfn.IsEmpty()) {
+               jsfn.Dispose();
+               jsfn.Clear();
+       }
+       if (!jsctx.IsEmpty()) {
+               jsctx.Dispose();
+               jsctx.Clear();
+       }
+}
+
+int __pacrunner_mozjs_set_proxy(struct pacrunner_proxy *proxy)
+{
+       v8::Locker lck;
+
+       DBG("proxy %p", proxy);
+
+       if (current_proxy != NULL)
+               destroy_object();
+
+       current_proxy = proxy;
+
+       if (current_proxy != NULL)
+               create_object();
+
+       if (!gc_source)
+               gc_source = g_idle_add(v8_gc, NULL);
+
+       return 0;
+}
+
+
+char *__pacrunner_mozjs_execute(const char *url, const char *host)
+{
+       v8::Locker lck;
+
+       DBG("url %s host %s", url, host);
+
+       if (jsctx.IsEmpty() || jsfn.IsEmpty())
+               return NULL;
+
+       v8::HandleScope handle_scope;
+       v8::Context::Scope context_scope(jsctx);
+
+       v8::Handle<v8::Value> args[2] = {
+               v8::String::New(url),
+               v8::String::New(host)
+       };
+
+       v8::Handle<v8::Value> result;
+       v8::TryCatch exc;
+
+       result = jsfn->Call(jsctx->Global(), 2, args);
+       if (exc.HasCaught()) {
+               v8::Handle<v8::Message> msg = exc.Message();
+               int line = msg->GetLineNumber();
+               v8::String::Utf8Value err(msg->Get());
+               DBG("Failed to run FindProxyForUrl(): at line %d: %s",
+                   line, *err);
+               return NULL;
+       }
+       
+       if (!result->IsString()) {
+               DBG("FindProxyForUrl() failed to return a string");
+               return NULL;
+       }
+
+       /* Hrm, how to fix this leak? */
+       char *retval = g_strdup(*v8::String::Utf8Value(result->ToString()));
+
+       if (!gc_source)
+               gc_source = g_idle_add(v8_gc, NULL);
+               
+       return retval;
+}
+
+int __pacrunner_mozjs_init(void)
+{
+       DBG("");
+
+       return 0;
+}
+
+void __pacrunner_mozjs_cleanup(void)
+{
+       DBG("");
+
+       __pacrunner_mozjs_set_proxy(NULL);
+
+       if (gc_source) {
+               g_source_remove(gc_source);
+               gc_source = 0;
+       }
+       while (!v8::V8::IdleNotification())
+               ;
+}
-- 
1.7.3.2



_______________________________________________
connman mailing list
[email protected]
http://lists.connman.net/listinfo/connman

Reply via email to