Index: /trunk/FACT++/src/InterpreterV8.cc
===================================================================
--- /trunk/FACT++/src/InterpreterV8.cc	(revision 18425)
+++ /trunk/FACT++/src/InterpreterV8.cc	(revision 18426)
@@ -10,4 +10,5 @@
 
 #include <boost/tokenizer.hpp>
+#include <boost/algorithm/string/join.hpp>
 
 #ifdef HAVE_NOVA
@@ -926,4 +927,86 @@
     const Locker lock;
     return handle_scope.Close(Integer::New(WEXITSTATUS(rc)));
+}
+
+// ==========================================================================
+//                                 Curl
+// ==========================================================================
+
+Handle<Value> InterpreterV8::ConstructorCurl(const Arguments &args)
+{
+    if (!args.IsConstructCall())
+        return ThrowException(String::New("Curl must be called as constructor"));
+
+    if (args.Length()!=1 || !args[0]->IsString())
+        return ThrowException(String::New("Constructor must be called with a single string as argument"));
+
+    HandleScope handle_scope;
+
+    Handle<Array> data = Array::New();
+    if (data.IsEmpty())
+        return Undefined();
+
+    Handle<Object> self = args.This();
+
+    self->Set(String::New("url"),  args[0]->ToString(), ReadOnly);
+    self->Set(String::New("data"), data, ReadOnly);
+
+    self->Set(String::New("send"), FunctionTemplate::New(WrapSendCurl)->GetFunction(), ReadOnly);
+
+    return handle_scope.Close(self);
+}
+
+Handle<Value> InterpreterV8::FuncSendCurl(const Arguments& args)
+{
+    HandleScope handle_scope;
+
+    if (args.Length()>1)
+        return ThrowException(String::New("Only one argument allowed."));
+
+    if (args.Length()==1 && !args[0]->IsBoolean())
+        return ThrowException(String::New("Argument must be a boolean."));
+
+    const bool block = args.Length()==0 || args[0]->BooleanValue();
+
+    const Handle<Value> url  = args.This()->Get(String::New("url"));
+    const Handle<Value> data = args.This()->Get(String::New("data"));
+
+    const vector<string> vdata = ValueToArray(data);
+    const string sdata = boost::algorithm::join(vdata, "&");
+
+    const string surl = *String::AsciiValue(url->ToString());
+
+    string cmd = "curl -sSf ";
+    if (!sdata.empty())
+        cmd += "--data '"+sdata+"' ";
+    cmd += "'http://"+surl+"' 2>&1 ";
+
+    FILE *pipe = popen(cmd.c_str(), "r");
+    if (!pipe)
+        return ThrowException(String::New(strerror(errno)));
+
+    if (!block)
+        return Undefined();
+
+    string txt;
+
+    while (!feof(pipe))
+    {
+        char buf[1025];
+        if (fgets(buf, 1024, pipe)==NULL)
+            break;
+        txt += buf;
+    }
+
+    const int rc = pclose(pipe);
+
+    Handle<Object> obj = Object::New();
+
+    obj->Set(String::New("cmd"), String::New(cmd.c_str()));
+    obj->Set(String::New("data"), String::New(txt.c_str()));
+    obj->Set(String::New("rc"), Integer::NewFromUnsigned(WEXITSTATUS(rc)));
+
+    const Locker lock;
+    return handle_scope.Close(obj);
 }
 
@@ -2569,4 +2652,10 @@
 #endif
 
+#ifdef HAVE_CURL
+    Handle<FunctionTemplate> curl = FunctionTemplate::New(ConstructorCurl);
+    mail->SetClassName(String::New("Curl"));
+    global->Set(String::New("Curl"), curl, ReadOnly);
+#endif
+
 #ifdef HAVE_NOVA
     Handle<FunctionTemplate> sky = FunctionTemplate::New(ConstructorSky);
@@ -2805,4 +2894,14 @@
 #endif
 
+#ifdef HAVE_CURL
+    rc.emplace_back("Curl(");
+    rc.emplace_back("new Curl(");
+
+    rc.emplace_back(".url");
+    rc.emplace_back(".user");
+    rc.emplace_back(".data");
+//    rc.emplace_back(".send("); -> MAILX
+#endif
+
 #ifdef HAVE_NOVA
     rc.emplace_back("Sky(");
Index: /trunk/FACT++/src/InterpreterV8.h
===================================================================
--- /trunk/FACT++/src/InterpreterV8.h	(revision 18425)
+++ /trunk/FACT++/src/InterpreterV8.h	(revision 18426)
@@ -81,4 +81,5 @@
     v8::Handle<v8::Value> FuncFile(const v8::Arguments& args);
     v8::Handle<v8::Value> FuncSendMail(const v8::Arguments& args);
+    v8::Handle<v8::Value> FuncSendCurl(const v8::Arguments& args);
     v8::Handle<v8::Value> FuncInclude(const v8::Arguments& args);
     v8::Handle<v8::Value> FuncExit(const v8::Arguments& args);
@@ -105,4 +106,5 @@
 
     static v8::Handle<v8::Value> ConstructorMail(const v8::Arguments &args);
+    static v8::Handle<v8::Value> ConstructorCurl(const v8::Arguments &args);
 
 #ifdef HAVE_NOVA
@@ -131,4 +133,5 @@
     static v8::Handle<v8::Value> WrapFile(const v8::Arguments &args)     { if (This) return This->FuncFile(args);     else return v8::Undefined(); }
     static v8::Handle<v8::Value> WrapSendMail(const v8::Arguments &args) { if (This) return This->FuncSendMail(args); else return v8::Undefined(); }
+    static v8::Handle<v8::Value> WrapSendCurl(const v8::Arguments &args) { if (This) return This->FuncSendCurl(args); else return v8::Undefined(); }
     static v8::Handle<v8::Value> WrapLog(const v8::Arguments &args)      { if (This) return This->FuncLog(args);      else return v8::Undefined(); }
     static v8::Handle<v8::Value> WrapAlarm(const v8::Arguments &args)    { if (This) return This->FuncAlarm(args);    else return v8::Undefined(); }
