2 Unix SMB/CIFS implementation.
4 utility functions for manipulating mpr variables in ejs calls
6 Copyright (C) Andrew Tridgell 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include "lib/appweb/ejs/ejs.h"
25 #include "lib/ldb/include/ldb.h"
28 return a default mpr object
30 struct MprVar mprObject(const char *name)
32 return ejsCreateObj(name && *name?name:"(NULL)", MPR_DEFAULT_HASH_SIZE);
36 find a mpr component, allowing for sub objects, using the '.' convention
38 NTSTATUS mprGetVar(struct MprVar **v, const char *name)
40 const char *p = strchr(name, '.');
44 *v = mprGetProperty(*v, name, NULL);
46 DEBUG(1,("mprGetVar unable to find '%s'\n", name));
47 return NT_STATUS_INVALID_PARAMETER;
51 objname = talloc_strndup(mprMemCtx(), name, p-name);
52 NT_STATUS_HAVE_NO_MEMORY(objname);
53 *v = mprGetProperty(*v, objname, NULL);
54 NT_STATUS_HAVE_NO_MEMORY(*v);
55 status = mprGetVar(v, p+1);
62 set a mpr component, allowing for sub objects, using the '.' convention
63 destroys 'val' after setting
65 NTSTATUS mprSetVar(struct MprVar *v, const char *name, struct MprVar val)
67 const char *p = strchr(name, '.');
72 v2 = mprSetProperty(v, name, &val);
74 DEBUG(1,("mprSetVar unable to set '%s'\n", name));
75 return NT_STATUS_INVALID_PARAMETER_MIX;
80 objname = talloc_strndup(mprMemCtx(), name, p-name);
81 if (objname == NULL) {
82 return NT_STATUS_NO_MEMORY;
84 v2 = mprGetProperty(v, objname, NULL);
86 mprSetVar(v, objname, mprObject(objname));
87 v2 = mprGetProperty(v, objname, NULL);
89 status = mprSetVar(v2, p+1, val);
97 add an indexed array element to a property
99 void mprAddArray(struct MprVar *var, int i, struct MprVar v)
102 mprItoa(i, idx, sizeof(idx));
103 mprSetVar(var, idx, v);
104 mprSetVar(var, "length", mprCreateIntegerVar(i+1));
108 construct a MprVar from a list
110 struct MprVar mprList(const char *name, const char **list)
115 var = mprObject(name);
116 for (i=0;list && list[i];i++) {
117 mprAddArray(&var, i, mprString(list[i]));
120 mprSetVar(&var, "length", mprCreateIntegerVar(i));
126 construct a MprVar from a string, using NULL if needed
128 struct MprVar mprString(const char *s)
131 return mprCreatePtrVar(NULL);
133 return mprCreateStringVar(s, True);
137 construct a string MprVar from a lump of data
139 struct MprVar mprData(const uint8_t *p, size_t length)
142 char *s = talloc_strndup(mprMemCtx(), p, length);
144 return mprCreateUndefinedVar();
152 turn a ldb_message into a ejs object variable
154 static struct MprVar mprLdbMessage(struct ldb_context *ldb, struct ldb_message *msg)
158 /* we force some attributes to always be an array in the
159 returned structure. This makes the scripting easier, as you don't
160 need a special case for the single value case */
161 const char *multivalued[] = { "objectClass", "memberOf", "privilege",
164 var = mprObject(msg->dn);
166 for (i=0;i<msg->num_elements;i++) {
167 struct ldb_message_element *el = &msg->elements[i];
169 const struct ldb_attrib_handler *attr;
172 attr = ldb_attrib_handler(ldb, el->name);
177 if (el->num_values == 1 &&
178 !str_list_check_ci(multivalued, el->name)) {
179 if (attr->ldif_write_fn(ldb, msg, &el->values[0], &v) != 0) {
182 val = mprData(v.data, v.length);
185 val = mprObject(el->name);
186 for (j=0;j<el->num_values;j++) {
187 if (attr->ldif_write_fn(ldb, msg,
188 &el->values[j], &v) != 0) {
191 mprAddArray(&val, j, mprData(v.data, v.length));
194 mprSetVar(&var, el->name, val);
197 /* add the dn if it is not already specified */
198 if (mprGetProperty(&var, "dn", 0) == 0) {
199 mprSetVar(&var, "dn", mprString(msg->dn));
204 return mprCreateUndefinedVar();
209 turn an array of ldb_messages into a ejs object variable
211 struct MprVar mprLdbArray(struct ldb_context *ldb,
212 struct ldb_message **msg, int count, const char *name)
217 res = mprObject(name);
218 for (i=0;i<count;i++) {
219 mprAddArray(&res, i, mprLdbMessage(ldb, msg[i]));
222 mprSetVar(&res, "length", mprCreateIntegerVar(0));
229 turn a MprVar string variable into a const char *
231 const char *mprToString(const struct MprVar *v)
233 if (!mprVarIsString(v->type)) return NULL;
238 turn a MprVar integer variable into an int
240 int mprToInt(const struct MprVar *v)
242 if (!mprVarIsNumber(v->type)) return 0;
243 return mprVarToNumber(v);
247 turn a MprVar object variable into a string list
248 this assumes the object variable consists only of strings
250 const char **mprToList(TALLOC_CTX *mem_ctx, struct MprVar *v)
252 const char **list = NULL;
255 if (v->type != MPR_TYPE_OBJECT ||
256 v->properties == NULL) {
259 for (el=mprGetFirstProperty(v, MPR_ENUM_DATA);
261 el=mprGetNextProperty(v, el, MPR_ENUM_DATA)) {
262 const char *s = mprToString(el);
264 list = str_list_add(list, s);
267 talloc_steal(mem_ctx, list);
273 turn a MprVar object variable into a string list
274 this assumes the object variable is an array of strings
276 const char **mprToArray(TALLOC_CTX *mem_ctx, struct MprVar *v)
278 const char **list = NULL;
282 len = mprGetProperty(v, "length", NULL);
286 length = mprToInt(len);
288 for (i=0;i<length;i++) {
291 mprItoa(i, idx, sizeof(idx));
292 vs = mprGetProperty(v, idx, NULL);
293 if (vs == NULL || vs->type != MPR_TYPE_STRING) {
297 list = str_list_add(list, mprToString(vs));
299 talloc_steal(mem_ctx, list);
304 turn a NTSTATUS into a MprVar object with lots of funky properties
306 struct MprVar mprNTSTATUS(NTSTATUS status)
310 res = mprObject("ntstatus");
312 mprSetVar(&res, "errstr", mprString(nt_errstr(status)));
313 mprSetVar(&res, "v", mprCreateIntegerVar(NT_STATUS_V(status)));
314 mprSetVar(&res, "is_ok", mprCreateBoolVar(NT_STATUS_IS_OK(status)));
315 mprSetVar(&res, "is_err", mprCreateBoolVar(NT_STATUS_IS_ERR(status)));
321 create a data-blob in a mpr variable
323 struct MprVar mprDataBlob(DATA_BLOB blob)
326 struct data_blob *pblob = talloc(mprMemCtx(), struct data_blob);
327 *pblob = data_blob_talloc(pblob, blob.data, blob.length);
329 res = mprObject("DATA_BLOB");
331 mprSetVar(&res, "size", mprCreateIntegerVar(blob.length));
332 mprSetPtrChild(&res, "blob", pblob);
338 return a data blob from a mpr var created using mprDataBlob
340 struct data_blob *mprToDataBlob(struct MprVar *v)
342 return talloc_get_type(mprGetPtr(v, "blob"), struct data_blob);
346 turn a WERROR into a MprVar object with lots of funky properties
348 struct MprVar mprWERROR(WERROR status)
352 res = mprObject("werror");
354 mprSetVar(&res, "errstr", mprString(win_errstr(status)));
355 mprSetVar(&res, "v", mprCreateIntegerVar(W_ERROR_V(status)));
356 mprSetVar(&res, "is_ok", mprCreateBoolVar(W_ERROR_IS_OK(status)));
357 mprSetVar(&res, "is_err", mprCreateBoolVar(!W_ERROR_IS_OK(status)));
364 set a pointer in a existing MprVar
366 void mprSetPtr(struct MprVar *v, const char *propname, const void *p)
368 mprSetVar(v, propname, mprCreatePtrVar(discard_const(p)));
372 set a pointer in a existing MprVar, making it a child of the property
374 void mprSetPtrChild(struct MprVar *v, const char *propname, const void *p)
376 mprSetVar(v, propname, mprCreatePtrVar(discard_const(p)));
377 talloc_steal(mprGetProperty(v, propname, NULL), p);
381 get a pointer from a MprVar
383 void *mprGetPtr(struct MprVar *v, const char *propname)
386 val = mprGetProperty(v, propname, NULL);
390 if (val->type != MPR_TYPE_PTR) {
397 set the return value then free the variable
399 void mpr_Return(int eid, struct MprVar v)
401 ejsSetReturnValue(eid, v);
406 set the return value then free the variable
408 void mpr_ReturnString(int eid, const char *s)
410 mpr_Return(eid, mprString(s));
415 set a C function in a variable
417 void mprSetCFunction(struct MprVar *obj, const char *name, MprCFunction fn)
419 mprSetVar(obj, name, mprCreateCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
423 set a string C function in a variable
425 void mprSetStringCFunction(struct MprVar *obj, const char *name, MprStringCFunction fn)
427 mprSetVar(obj, name, mprCreateStringCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
431 get a pointer in the current object
433 void *mprGetThisPtr(int eid, const char *name)
435 struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
436 return mprGetPtr(this, name);
440 set a pointer as a child of the local object
442 void mprSetThisPtr(int eid, const char *name, void *ptr)
444 struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
445 mprSetPtrChild(this, name, ptr);
449 used by object xxx_init() routines to allow for the caller
450 to supply a pre-existing object to add properties to,
451 or create a new object. This makes inheritance easy
453 struct MprVar *mprInitObject(int eid, const char *name, int argc, struct MprVar **argv)
455 if (argc > 0 && mprVarIsObject(argv[0]->type)) {
458 mpr_Return(eid, mprObject(name));
459 return ejsGetReturnValue(eid);