r8215: switched the pull side of the ejs generator over to the recursive LEVELS based...
[jra/samba/.git] / source4 / scripting / ejs / ejsrpc.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    provide interfaces to rpc calls from ejs scripts
5
6    Copyright (C) Andrew Tridgell 2005
7    
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.
12    
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.
17    
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.
21 */
22
23 #include "includes.h"
24 #include "lib/ejs/ejs.h"
25 #include "scripting/ejs/ejsrpc.h"
26
27 NTSTATUS ejs_pull_rpc(int eid, const char *callname, 
28                       struct MprVar *v, void *ptr, ejs_pull_function_t ejs_pull)
29 {
30         struct ejs_rpc *ejs = talloc(ptr, struct ejs_rpc);      
31         NT_STATUS_HAVE_NO_MEMORY(ejs);
32         ejs->eid = eid;
33         ejs->callname = callname;
34         return ejs_pull(ejs, v, ptr);
35 }
36
37
38 NTSTATUS ejs_push_rpc(int eid, const char *callname, 
39                       struct MprVar *v, const void *ptr, ejs_push_function_t ejs_push)
40 {
41         struct ejs_rpc *ejs = talloc(ptr, struct ejs_rpc);
42         NT_STATUS_HAVE_NO_MEMORY(ejs);
43         ejs->eid = eid;
44         ejs->callname = callname;
45         return ejs_push(ejs, v, ptr);
46 }
47
48 /*
49   set the switch var to be used by the next union switch
50 */
51 void ejs_set_switch(struct ejs_rpc *ejs, uint32_t switch_var)
52 {
53         ejs->switch_var = switch_var;
54 }
55
56 /*
57   panic in the ejs wrapper code
58  */
59 NTSTATUS ejs_panic(struct ejs_rpc *ejs, const char *why)
60 {
61         ejsSetErrorMsg(ejs->eid, "rpc_call '%s' failed - %s", ejs->callname, why);
62         return NT_STATUS_INTERNAL_ERROR;
63 }
64
65 /*
66   find a mpr component, allowing for sub objects, using the '.' convention
67 */
68 static struct MprVar *mprGetVar(struct MprVar *v, const char *name)
69 {
70         const char *p = strchr(name, '.');
71         char *objname;
72         struct MprVar *v2;
73         if (p == NULL) {
74                 return mprGetProperty(v, name, NULL);
75         }
76         objname = talloc_strndup(mprMemCtx(), name, p-name);
77         if (objname == NULL) {
78                 return NULL;
79         }
80         v2 = mprGetProperty(v, objname, NULL);
81         if (v2 == NULL) {
82                 talloc_free(objname);
83                 return NULL;
84         }
85         v2 = mprGetVar(v2, p+1);
86         talloc_free(objname);
87         return v2;
88 }
89
90
91 /*
92   set a mpr component, allowing for sub objects, using the '.' convention
93 */
94 static NTSTATUS mprSetVar(struct MprVar *v, const char *name, struct MprVar val)
95 {
96         const char *p = strchr(name, '.');
97         char *objname;
98         struct MprVar *v2;
99         NTSTATUS status;
100         if (p == NULL) {
101                 v2 = mprSetProperty(v, name, &val);
102                 if (v2 == NULL) {
103                         return NT_STATUS_INVALID_PARAMETER_MIX;
104                 }
105                 return NT_STATUS_OK;
106         }
107         objname = talloc_strndup(mprMemCtx(), name, p-name);
108         if (objname == NULL) {
109                 return NT_STATUS_NO_MEMORY;
110         }
111         v2 = mprGetProperty(v, objname, NULL);
112         if (v2 == NULL) {
113                 struct MprVar val2 = mprCreateObjVar(objname, MPR_DEFAULT_HASH_SIZE);
114                 v2 = mprCreateProperty(v, objname, &val2);
115         }
116         status = mprSetVar(v2, p+1, val);
117         talloc_free(objname);
118         return status;
119 }
120
121
122 /*
123   start the ejs pull process for a structure
124 */
125 NTSTATUS ejs_pull_struct_start(struct ejs_rpc *ejs, struct MprVar **v, const char *name)
126 {
127         *v = mprGetProperty(*v, name, NULL);
128         if (*v == NULL) {
129                 return NT_STATUS_INVALID_PARAMETER;
130         }
131         return NT_STATUS_OK;
132 }
133
134
135 /*
136   start the ejs push process for a structure
137 */
138 NTSTATUS ejs_push_struct_start(struct ejs_rpc *ejs, struct MprVar **v, const char *name)
139 {
140         struct MprVar s = mprCreateObjVar(name, MPR_DEFAULT_HASH_SIZE);
141         *v = mprSetProperty(*v, name, &s);
142         if (*v == NULL) {
143                 return NT_STATUS_INVALID_PARAMETER;
144         }
145         return NT_STATUS_OK;
146 }
147
148 /*
149   pull a uint8 from a mpr variable to a C element
150 */
151 NTSTATUS ejs_pull_uint8(struct ejs_rpc *ejs, 
152                         struct MprVar *v, const char *name, uint8_t *r)
153 {
154         struct MprVar *var;
155         var = mprGetVar(v, name);
156         if (var == NULL) {
157                 return NT_STATUS_INVALID_PARAMETER_MIX;
158         }
159         *r = mprVarToInteger(var);
160         return NT_STATUS_OK;
161         
162 }
163
164 NTSTATUS ejs_push_uint8(struct ejs_rpc *ejs, 
165                         struct MprVar *v, const char *name, const uint8_t *r)
166 {
167         return mprSetVar(v, name, mprCreateIntegerVar(*r));
168 }
169
170 /*
171   pull a uint16 from a mpr variable to a C element
172 */
173 NTSTATUS ejs_pull_uint16(struct ejs_rpc *ejs, 
174                          struct MprVar *v, const char *name, uint16_t *r)
175 {
176         struct MprVar *var;
177         var = mprGetVar(v, name);
178         if (var == NULL) {
179                 return NT_STATUS_INVALID_PARAMETER_MIX;
180         }
181         *r = mprVarToInteger(var);
182         return NT_STATUS_OK;
183         
184 }
185
186 NTSTATUS ejs_push_uint16(struct ejs_rpc *ejs, 
187                          struct MprVar *v, const char *name, const uint16_t *r)
188 {
189         return mprSetVar(v, name, mprCreateIntegerVar(*r));
190 }
191
192 /*
193   pull a uint32 from a mpr variable to a C element
194 */
195 NTSTATUS ejs_pull_uint32(struct ejs_rpc *ejs, 
196                          struct MprVar *v, const char *name, uint32_t *r)
197 {
198         struct MprVar *var;
199         var = mprGetVar(v, name);
200         if (var == NULL) {
201                 return NT_STATUS_INVALID_PARAMETER_MIX;
202         }
203         *r = mprVarToInteger(var);
204         return NT_STATUS_OK;
205 }
206
207 NTSTATUS ejs_push_uint32(struct ejs_rpc *ejs, 
208                          struct MprVar *v, const char *name, const uint32_t *r)
209 {
210         return mprSetVar(v, name, mprCreateIntegerVar(*r));
211 }
212
213 NTSTATUS ejs_pull_hyper(struct ejs_rpc *ejs, 
214                         struct MprVar *v, const char *name, uint64_t *r)
215 {
216         struct MprVar *var;
217         var = mprGetVar(v, name);
218         if (var == NULL) {
219                 return NT_STATUS_INVALID_PARAMETER_MIX;
220         }
221         *r = mprVarToInteger(var);
222         return NT_STATUS_OK;
223 }
224
225 NTSTATUS ejs_push_hyper(struct ejs_rpc *ejs, 
226                         struct MprVar *v, const char *name, const uint64_t *r)
227 {
228         return mprSetVar(v, name, mprCreateIntegerVar(*r));
229 }
230
231
232 /*
233   pull a enum from a mpr variable to a C element
234   a enum is just treating as an unsigned integer at this level
235 */
236 NTSTATUS ejs_pull_enum(struct ejs_rpc *ejs, 
237                        struct MprVar *v, const char *name, unsigned *r)
238 {
239         struct MprVar *var;
240         var = mprGetVar(v, name);
241         if (var == NULL) {
242                 return NT_STATUS_INVALID_PARAMETER_MIX;
243         }
244         *r = mprVarToInteger(var);
245         return NT_STATUS_OK;
246         
247 }
248
249 NTSTATUS ejs_push_enum(struct ejs_rpc *ejs, 
250                        struct MprVar *v, const char *name, const unsigned *r)
251 {
252         return mprSetVar(v, name, mprCreateIntegerVar(*r));
253 }
254
255
256 /*
257   pull a string
258 */
259 NTSTATUS ejs_pull_string(struct ejs_rpc *ejs, 
260                          struct MprVar *v, const char *name, char **s)
261 {
262         struct MprVar *var;
263         var = mprGetVar(v, name);
264         if (var == NULL) {
265                 return NT_STATUS_INVALID_PARAMETER_MIX;
266         }
267         *s = mprToString(var);
268         return NT_STATUS_OK;
269 }
270
271 /*
272   push a string
273 */
274 NTSTATUS ejs_push_string(struct ejs_rpc *ejs, 
275                          struct MprVar *v, const char *name, const char *s)
276 {
277         return mprSetVar(v, name, mprCreateStringVar(s, True));
278 }