test setinfo FULL_EA_INFORMATION in gentest
[gd/samba/.git] / source4 / scripting / ejs / mprutil.c
index 30dec22af1f15bdc81f3d3af79c824cb03e308cc..9143947fb846deec53baf13476f4a206db549456 100644 (file)
@@ -7,7 +7,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-#include "lib/ejs/ejs.h"
+#include "lib/appweb/ejs/ejs.h"
 #include "lib/ldb/include/ldb.h"
+#include "scripting/ejs/smbcalls.h"
 
 /*
   return a default mpr object
 */
 struct MprVar mprObject(const char *name)
 {
-       return ejsCreateObj(name?name:"(NULL)", MPR_DEFAULT_HASH_SIZE);
+       return ejsCreateObj(name && *name?name:"(NULL)", MPR_DEFAULT_HASH_SIZE);
+}
+
+/*
+  return a empty mpr array
+*/
+struct MprVar mprArray(const char *name)
+{
+       return ejsCreateArray(name && *name?name:"(NULL)", 0);
 }
 
 /*
@@ -101,7 +109,6 @@ struct MprVar mprObject(const char *name)
        char idx[16];
        mprItoa(i, idx, sizeof(idx));
        mprSetVar(var, idx, v);
-       mprSetVar(var, "length", mprCreateIntegerVar(i+1));
 }
 
 /*
@@ -112,13 +119,10 @@ struct MprVar mprList(const char *name, const char **list)
        struct MprVar var;
        int i;
 
-       var = mprObject(name);
+       var = mprArray(name);
        for (i=0;list && list[i];i++) {
                mprAddArray(&var, i, mprString(list[i]));
        }
-       if (i==0) {
-               mprSetVar(&var, "length", mprCreateIntegerVar(i));
-       }
        return var;
 }
 
@@ -130,7 +134,7 @@ struct MprVar mprString(const char *s)
        if (s == NULL) {
                return mprCreatePtrVar(NULL);
        }
-       return mprCreateStringVar(s, True);
+       return mprCreateStringVar(s, true);
 }
 
 /*
@@ -139,7 +143,7 @@ struct MprVar mprString(const char *s)
 struct MprVar mprData(const uint8_t *p, size_t length)
 {
        struct MprVar var;
-       char *s = talloc_strndup(mprMemCtx(), p, length);
+       char *s = talloc_strndup(mprMemCtx(), (const char *)p, length);
        if (s == NULL) {
                return mprCreateUndefinedVar();
        }
@@ -151,7 +155,7 @@ struct MprVar mprData(const uint8_t *p, size_t length)
 /*
   turn a ldb_message into a ejs object variable
 */
-struct MprVar mprLdbMessage(struct ldb_message *msg)
+static struct MprVar mprLdbMessage(struct ldb_context *ldb, struct ldb_message *msg)
 {
        struct MprVar var;
        int i;
@@ -161,21 +165,46 @@ struct MprVar mprLdbMessage(struct ldb_message *msg)
        const char *multivalued[] = { "objectClass", "memberOf", "privilege", 
                                            "member", NULL };
 
-       var = mprObject(msg->dn);
+       var = mprObject(ldb_dn_alloc_linearized(msg, msg->dn));
 
        for (i=0;i<msg->num_elements;i++) {
                struct ldb_message_element *el = &msg->elements[i];
                struct MprVar val;
+               const struct ldb_schema_attribute *a;
+               struct ldb_val v;
+
+               a = ldb_schema_attribute_by_name(ldb, el->name);
+               if (a == NULL) {
+                       goto failed;
+               }
+
                if (el->num_values == 1 &&
                    !str_list_check_ci(multivalued, el->name)) {
-                       val = mprData(el->values[0].data, el->values[0].length);
+                       if (a->syntax->ldif_write_fn(ldb, msg, &el->values[0], &v) != 0) {
+                               goto failed;
+                       }
+                       /* FIXME: nasty hack, remove me when ejs will support
+                        * arbitrary string and does not truncate on \0 */
+                       if (strlen((char *)v.data) != v.length) {
+                               val = mprDataBlob(v);
+                       } else {
+                               val = mprData(v.data, v.length);
+                       }
                } else {
                        int j;
-                       val = mprObject(el->name);
+                       val = mprArray(el->name);
                        for (j=0;j<el->num_values;j++) {
-                               mprAddArray(&val, j, 
-                                           mprData(el->values[j].data, 
-                                                   el->values[j].length));
+                               if (a->syntax->ldif_write_fn(ldb, msg, 
+                                                            &el->values[j], &v) != 0) {
+                                       goto failed;
+                               }
+                               /* FIXME: nasty hack, remove me when ejs will support
+                                * arbitrary string and does not truncate on \0 */
+                               if (strlen((char *)v.data) != v.length) {
+                                       mprAddArray(&val, j, mprDataBlob(v));
+                               } else {
+                                       mprAddArray(&val, j, mprData(v.data, v.length));
+                               }
                        }
                }
                mprSetVar(&var, el->name, val);
@@ -183,34 +212,53 @@ struct MprVar mprLdbMessage(struct ldb_message *msg)
 
        /* add the dn if it is not already specified */
        if (mprGetProperty(&var, "dn", 0) == 0) {
-               mprSetVar(&var, "dn", mprString(msg->dn));
+               mprSetVar(&var, "dn", mprString(ldb_dn_alloc_linearized(msg, msg->dn)));
        }
        
        return var;             
+failed:
+       return mprCreateUndefinedVar();
 }
 
 
 /*
-  turn an array of ldb_messages into a ejs object variable
+  build a MprVar result object for ldb operations with lots of funky properties
 */
-struct MprVar mprLdbArray(struct ldb_message **msg, int count, const char *name)
+struct MprVar mprLdbResult(struct ldb_context *ldb, int err, struct ldb_result *result)
 {
-       struct MprVar res;
-       int i;
+       struct MprVar ret;
+       struct MprVar ary;
+
+       ret = mprObject("ldbret");
+
+       mprSetVar(&ret, "error", mprCreateIntegerVar(err));
+       mprSetVar(&ret, "errstr", mprString(ldb_errstring(ldb)));
+
+       ary = mprArray("ldb_message");
+       if (result) {
+               int i;
 
-       res = mprObject(name);
-       for (i=0;i<count;i++) {
-               mprAddArray(&res, i, mprLdbMessage(msg[i]));
+               for (i = 0; i < result->count; i++) {
+                       mprAddArray(&ary, i, mprLdbMessage(ldb, result->msgs[i]));
+               }
        }
-       return res;
+
+       mprSetVar(&ret, "msgs", ary);
+
+       /* TODO: add referrals, exteded ops, and controls */
+
+       return ret;
 }
 
 
 /*
   turn a MprVar string variable into a const char *
  */
-const char *mprToString(const struct MprVar *v)
+const char *mprToString(struct MprVar *v)
 {
+       if (v->trigger) {
+               mprReadProperty(v, 0);
+       }
        if (!mprVarIsString(v->type)) return NULL;
        return v->string;
 }
@@ -218,8 +266,11 @@ const char *mprToString(const struct MprVar *v)
 /*
   turn a MprVar integer variable into an int
  */
-int mprToInt(const struct MprVar *v)
+int mprToInt(struct MprVar *v)
 {
+       if (v->trigger) {
+               mprReadProperty(v, 0);
+       }
        if (!mprVarIsNumber(v->type)) return 0;
        return mprVarToNumber(v);
 }
@@ -298,6 +349,31 @@ struct MprVar mprNTSTATUS(NTSTATUS status)
        return res;
 }
 
+/*
+  create a data-blob in a mpr variable
+*/
+struct MprVar mprDataBlob(DATA_BLOB blob)
+{
+       struct MprVar res;
+       struct datablob *pblob = talloc(mprMemCtx(), struct datablob);
+       *pblob = data_blob_talloc(pblob, blob.data, blob.length);
+
+       res = mprObject("DATA_BLOB");
+
+       mprSetVar(&res, "size", mprCreateIntegerVar(blob.length));
+       mprSetPtrChild(&res, "blob", pblob);
+
+       return res;
+}
+
+/*
+  return a data blob from a mpr var created using mprDataBlob
+*/
+struct datablob *mprToDataBlob(struct MprVar *v)
+{
+       return talloc_get_type(mprGetPtr(v, "blob"), struct datablob);
+}
+
 /*
   turn a WERROR into a MprVar object with lots of funky properties
 */
@@ -325,12 +401,14 @@ void mprSetPtr(struct MprVar *v, const char *propname, const void *p)
 }
 
 /*
-  set a pointer in a existing MprVar, making it a child of the property
+  set a pointer in a existing MprVar, freeing it when the property goes away
 */
 void mprSetPtrChild(struct MprVar *v, const char *propname, const void *p)
 {
        mprSetVar(v, propname, mprCreatePtrVar(discard_const(p)));
-       talloc_steal(mprGetProperty(v, propname, NULL), p);
+       v = mprGetProperty(v, propname, NULL);
+       v->allocatedData = 1;
+       talloc_steal(mprMemCtx(), p);
 }
 
 /*
@@ -367,3 +445,50 @@ void mpr_ReturnString(int eid, const char *s)
 }
 
 
+/*
+  set a C function in a variable
+*/
+ void mprSetCFunction(struct MprVar *obj, const char *name, MprCFunction fn)
+{
+       mprSetVar(obj, name, mprCreateCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
+}
+
+/*
+  set a string C function in a variable
+*/
+ void mprSetStringCFunction(struct MprVar *obj, const char *name, MprStringCFunction fn)
+{
+       mprSetVar(obj, name, mprCreateStringCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
+}
+
+/*
+  get a pointer in the current object
+*/
+void *mprGetThisPtr(int eid, const char *name)
+{
+       struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
+       return mprGetPtr(this, name);
+}
+
+/*
+  set a pointer as a child of the local object
+*/
+void mprSetThisPtr(int eid, const char *name, void *ptr)
+{
+       struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
+       mprSetPtrChild(this, name, ptr);
+}
+
+/*
+  used by object xxx_init() routines to allow for the caller
+  to supply a pre-existing object to add properties to,
+  or create a new object. This makes inheritance easy
+*/
+struct MprVar *mprInitObject(int eid, const char *name, int argc, struct MprVar **argv)
+{
+       if (argc > 0 && mprVarIsObject(argv[0]->type)) {
+               return argv[0];
+       }
+       mpr_Return(eid, mprObject(name));
+       return ejsGetReturnValue(eid);
+}