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:"(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 struct MprVar mprLdbMessage(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 if (el->num_values == 1 &&
170 !str_list_check_ci(multivalued, el->name)) {
171 val = mprData(el->values[0].data, el->values[0].length);
174 val = mprObject(el->name);
175 for (j=0;j<el->num_values;j++) {
177 mprData(el->values[j].data,
178 el->values[j].length));
181 mprSetVar(&var, el->name, val);
184 /* add the dn if it is not already specified */
185 if (mprGetProperty(&var, "dn", 0) == 0) {
186 mprSetVar(&var, "dn", mprString(msg->dn));
194 turn an array of ldb_messages into a ejs object variable
196 struct MprVar mprLdbArray(struct ldb_message **msg, int count, const char *name)
201 res = mprObject(name);
202 for (i=0;i<count;i++) {
203 mprAddArray(&res, i, mprLdbMessage(msg[i]));
206 mprSetVar(&res, "length", mprCreateIntegerVar(0));
213 turn a MprVar string variable into a const char *
215 const char *mprToString(const struct MprVar *v)
217 if (!mprVarIsString(v->type)) return NULL;
222 turn a MprVar integer variable into an int
224 int mprToInt(const struct MprVar *v)
226 if (!mprVarIsNumber(v->type)) return 0;
227 return mprVarToNumber(v);
231 turn a MprVar object variable into a string list
232 this assumes the object variable consists only of strings
234 const char **mprToList(TALLOC_CTX *mem_ctx, struct MprVar *v)
236 const char **list = NULL;
239 if (v->type != MPR_TYPE_OBJECT ||
240 v->properties == NULL) {
243 for (el=mprGetFirstProperty(v, MPR_ENUM_DATA);
245 el=mprGetNextProperty(v, el, MPR_ENUM_DATA)) {
246 const char *s = mprToString(el);
248 list = str_list_add(list, s);
251 talloc_steal(mem_ctx, list);
257 turn a MprVar object variable into a string list
258 this assumes the object variable is an array of strings
260 const char **mprToArray(TALLOC_CTX *mem_ctx, struct MprVar *v)
262 const char **list = NULL;
266 len = mprGetProperty(v, "length", NULL);
270 length = mprToInt(len);
272 for (i=0;i<length;i++) {
275 mprItoa(i, idx, sizeof(idx));
276 vs = mprGetProperty(v, idx, NULL);
277 if (vs == NULL || vs->type != MPR_TYPE_STRING) {
281 list = str_list_add(list, mprToString(vs));
283 talloc_steal(mem_ctx, list);
288 turn a NTSTATUS into a MprVar object with lots of funky properties
290 struct MprVar mprNTSTATUS(NTSTATUS status)
294 res = mprObject("ntstatus");
296 mprSetVar(&res, "errstr", mprString(nt_errstr(status)));
297 mprSetVar(&res, "v", mprCreateIntegerVar(NT_STATUS_V(status)));
298 mprSetVar(&res, "is_ok", mprCreateBoolVar(NT_STATUS_IS_OK(status)));
299 mprSetVar(&res, "is_err", mprCreateBoolVar(NT_STATUS_IS_ERR(status)));
305 turn a WERROR into a MprVar object with lots of funky properties
307 struct MprVar mprWERROR(WERROR status)
311 res = mprObject("werror");
313 mprSetVar(&res, "errstr", mprString(win_errstr(status)));
314 mprSetVar(&res, "v", mprCreateIntegerVar(W_ERROR_V(status)));
315 mprSetVar(&res, "is_ok", mprCreateBoolVar(W_ERROR_IS_OK(status)));
316 mprSetVar(&res, "is_err", mprCreateBoolVar(!W_ERROR_IS_OK(status)));
323 set a pointer in a existing MprVar
325 void mprSetPtr(struct MprVar *v, const char *propname, const void *p)
327 mprSetVar(v, propname, mprCreatePtrVar(discard_const(p)));
331 set a pointer in a existing MprVar, making it a child of the property
333 void mprSetPtrChild(struct MprVar *v, const char *propname, const void *p)
335 mprSetVar(v, propname, mprCreatePtrVar(discard_const(p)));
336 talloc_steal(mprGetProperty(v, propname, NULL), p);
340 get a pointer from a MprVar
342 void *mprGetPtr(struct MprVar *v, const char *propname)
345 val = mprGetProperty(v, propname, NULL);
349 if (val->type != MPR_TYPE_PTR) {
356 set the return value then free the variable
358 void mpr_Return(int eid, struct MprVar v)
360 ejsSetReturnValue(eid, v);
365 set the return value then free the variable
367 void mpr_ReturnString(int eid, const char *s)
369 mpr_Return(eid, mprString(s));
374 set a C function in a variable
376 void mprSetCFunction(struct MprVar *obj, const char *name, MprCFunction fn)
378 mprSetVar(obj, name, mprCreateCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
382 set a string C function in a variable
384 void mprSetStringCFunction(struct MprVar *obj, const char *name, MprStringCFunction fn)
386 mprSetVar(obj, name, mprCreateStringCFunctionVar(fn, obj, MPR_VAR_SCRIPT_HANDLE));
390 get a poiner in the current object
392 void *mprGetThisPtr(int eid, const char *name)
394 struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
395 return mprGetPtr(this, name);
399 set a pointer as a child of the local object
401 void mprSetThisPtr(int eid, const char *name, void *ptr)
403 struct MprVar *this = mprGetProperty(ejsGetLocalObject(eid), "this", 0);
404 mprSetPtrChild(this, name, ptr);
408 used by object xxx_init() routines to allow for the caller
409 to supply a pre-existing object to add properties to,
410 or create a new object. This makes inheritance easy
412 struct MprVar *mprInitObject(int eid, const char *name, int argc, struct MprVar **argv)
414 if (argc > 0 && mprVarIsObject(argv[0]->type)) {
417 mpr_Return(eid, mprObject(name));
418 return ejsGetReturnValue(eid);