r19051: JSON-RPC server work-in-progress. It's almost working.
[jelmer/samba4-debian.git] / source / scripting / ejs / smbcalls_sys.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    provide access to system functions
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 "scripting/ejs/smbcalls.h"
25 #include "lib/appweb/ejs/ejs.h"
26 #include "lib/ldb/include/ldb.h"
27 #include "system/time.h"
28 #include "system/network.h"
29 #include "lib/socket/netif.h"
30
31 /*
32   return the list of configured network interfaces
33 */
34 static int ejs_sys_interfaces(MprVarHandle eid, int argc, struct MprVar **argv)
35 {
36         int i, count = iface_count();
37         struct MprVar ret = mprArray("interfaces");
38         for (i=0;i<count;i++) {
39                 mprAddArray(&ret, i, mprString(iface_n_ip(i)));
40         }
41         mpr_Return(eid, ret);
42         return 0;       
43 }
44
45 /*
46   return the hostname from gethostname()
47 */
48 static int ejs_sys_hostname(MprVarHandle eid, int argc, struct MprVar **argv)
49 {
50         char name[200];
51         if (gethostname(name, sizeof(name)-1) == -1) {
52                 ejsSetErrorMsg(eid, "gethostname failed - %s", strerror(errno));
53                 return -1;
54         }
55         mpr_Return(eid, mprString(name));
56         return 0;       
57 }
58
59
60 /*
61   return current time as seconds and microseconds
62 */
63 static int ejs_sys_gettimeofday(MprVarHandle eid, int argc, struct MprVar **argv)
64 {
65         struct timeval tv = timeval_current();
66         struct MprVar v = mprObject("timeval");
67         struct MprVar sec = mprCreateIntegerVar(tv.tv_sec);
68         struct MprVar usec = mprCreateIntegerVar(tv.tv_usec);
69
70         mprCreateProperty(&v, "sec", &sec);
71         mprCreateProperty(&v, "usec", &usec);
72         mpr_Return(eid, v);
73         return 0;
74 }
75
76 /*
77   return current time as a 64 bit nttime value
78 */
79 static int ejs_sys_nttime(MprVarHandle eid, int argc, struct MprVar **argv)
80 {
81         struct timeval tv = timeval_current();
82         struct MprVar v = mprCreateNumberVar(timeval_to_nttime(&tv));
83         mpr_Return(eid, v);
84         return 0;
85 }
86
87 /*
88   return time as a 64 bit nttime value from a 32 bit time_t value
89 */
90 static int ejs_sys_unix2nttime(MprVarHandle eid, int argc, struct MprVar **argv)
91 {
92         NTTIME nt;
93         struct MprVar v;
94         if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
95                 ejsSetErrorMsg(eid, "sys_unix2nttime invalid arguments");
96                 return -1;
97         }
98         unix_to_nt_time(&nt, mprVarToNumber(argv[0]));
99         v = mprCreateNumberVar(nt);
100         mpr_Return(eid, v);
101         return 0;
102 }
103
104 /*
105   return the GMT time represented by the struct tm argument, as a time_t value
106 */
107 static int ejs_sys_gmmktime(MprVarHandle eid, int argc, struct MprVar **argv)
108 {
109         struct MprVar *o;
110         struct tm tm;
111         if (argc != 1 || !mprVarIsObject(argv[0]->type)) {
112                 ejsSetErrorMsg(eid, "sys_gmmktime invalid arguments");
113                 return -1;
114         }
115
116         o = argv[0];
117 #define TM_EL(n) tm.n = mprVarToNumber(mprGetProperty(o, #n, NULL))
118         TM_EL(tm_sec);
119         TM_EL(tm_min);
120         TM_EL(tm_hour);
121         TM_EL(tm_mday);
122         TM_EL(tm_mon);
123         TM_EL(tm_year);
124         TM_EL(tm_wday);
125         TM_EL(tm_yday);
126         TM_EL(tm_isdst);
127 #undef TM_EL        
128
129         mpr_Return(eid, mprCreateIntegerVar(mktime(&tm)));
130         return 0;
131 }
132
133 /*
134   return the given time as a gmtime structure
135 */
136 static int ejs_sys_gmtime(MprVarHandle eid, int argc, struct MprVar **argv)
137 {
138         time_t t;
139         struct MprVar ret;
140         struct tm *tm;
141         if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
142                 ejsSetErrorMsg(eid, "sys_gmtime invalid arguments");
143                 return -1;
144         }
145         t = (time_t) mprVarToNumber(argv[0]);
146         tm = gmtime(&t);
147         if (tm == NULL) {
148                 mpr_Return(eid, mprCreateUndefinedVar());
149                 return 0;
150         }
151         ret = mprObject("gmtime");
152 #define TM_EL(n) mprSetVar(&ret, #n, mprCreateIntegerVar(tm->n))
153         TM_EL(tm_sec);
154         TM_EL(tm_min);
155         TM_EL(tm_hour);
156         TM_EL(tm_mday);
157         TM_EL(tm_mon);
158         TM_EL(tm_year);
159         TM_EL(tm_wday);
160         TM_EL(tm_yday);
161         TM_EL(tm_isdst);
162 #undef TM_EL
163
164         mpr_Return(eid, ret);
165         return 0;
166 }
167
168 /*
169   return the given NT time as a gmtime structure
170 */
171 static int ejs_sys_ntgmtime(MprVarHandle eid, int argc, struct MprVar **argv)
172 {
173         time_t t;
174         struct MprVar ret;
175         struct tm *tm;
176         if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
177                 ejsSetErrorMsg(eid, "sys_ntgmtime invalid arguments");
178                 return -1;
179         }
180         t = nt_time_to_unix(mprVarToNumber(argv[0]));
181         tm = gmtime(&t);
182         if (tm == NULL) {
183                 mpr_Return(eid, mprCreateUndefinedVar());
184                 return 0;
185         }
186         ret = mprObject("gmtime");
187 #define TM_EL(n) mprSetVar(&ret, #n, mprCreateIntegerVar(tm->n))
188         TM_EL(tm_sec);
189         TM_EL(tm_min);
190         TM_EL(tm_hour);
191         TM_EL(tm_mday);
192         TM_EL(tm_mon);
193         TM_EL(tm_year);
194         TM_EL(tm_wday);
195         TM_EL(tm_yday);
196         TM_EL(tm_isdst);
197 #undef TM_EL
198
199         mpr_Return(eid, ret);
200         return 0;
201 }
202
203 /*
204   return a ldap time string from a nttime
205 */
206 static int ejs_sys_ldaptime(MprVarHandle eid, int argc, struct MprVar **argv)
207 {
208         char *s;
209         time_t t;
210         if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
211                 ejsSetErrorMsg(eid, "sys_ldaptime invalid arguments");
212                 return -1;
213         }
214         t = nt_time_to_unix(mprVarToNumber(argv[0]));
215         s = ldb_timestring(mprMemCtx(), t);
216         mpr_Return(eid, mprString(s));
217         talloc_free(s);
218         return 0;
219 }
220
221 /*
222   return a http time string from a nttime
223 */
224 static int ejs_sys_httptime(MprVarHandle eid, int argc, struct MprVar **argv)
225 {
226         char *s;
227         time_t t;
228         if (argc != 1 || !mprVarIsNumber(argv[0]->type)) {
229                 ejsSetErrorMsg(eid, "sys_httptime invalid arguments");
230                 return -1;
231         }
232         t = nt_time_to_unix(mprVarToNumber(argv[0]));
233         s = http_timestring(mprMemCtx(), t);
234         mpr_Return(eid, mprString(s));
235         talloc_free(s);
236         return 0;
237 }
238
239 /*
240   unlink a file
241    ok = sys.unlink(fname);
242 */
243 static int ejs_sys_unlink(MprVarHandle eid, int argc, char **argv)
244 {
245         int ret;
246         if (argc != 1) {
247                 ejsSetErrorMsg(eid, "sys_unlink invalid arguments");
248                 return -1;
249         }
250         ret = unlink(argv[0]);
251         mpr_Return(eid, mprCreateBoolVar(ret == 0));
252         return 0;
253 }
254
255 /*
256   load a file as a string
257   usage:
258      string = sys.file_load(filename);
259 */
260 static int ejs_sys_file_load(MprVarHandle eid, int argc, char **argv)
261 {
262         char *s;
263         if (argc != 1) {
264                 ejsSetErrorMsg(eid, "sys_file_load invalid arguments");
265                 return -1;
266         }
267
268         s = file_load(argv[0], NULL, mprMemCtx());
269         mpr_Return(eid, mprString(s));
270         talloc_free(s);
271         return 0;
272 }
273
274 /*
275   save a file from a string
276   usage:
277      ok = sys.file_save(filename, str);
278 */
279 static int ejs_sys_file_save(MprVarHandle eid, int argc, char **argv)
280 {
281         BOOL ret;
282         if (argc != 2) {
283                 ejsSetErrorMsg(eid, "sys_file_save invalid arguments");
284                 return -1;
285         }
286         ret = file_save(argv[0], argv[1], strlen(argv[1]));
287         mpr_Return(eid, mprCreateBoolVar(ret));
288         return 0;
289 }
290
291
292 /*
293   return fields of a stat() call
294 */
295 static struct MprVar mpr_stat(struct stat *st)
296 {
297         struct MprVar ret;
298         ret = mprObject("stat");
299
300 #define ST_EL(n) mprSetVar(&ret, #n, mprCreateNumberVar(st->n))
301         ST_EL(st_dev);
302         ST_EL(st_ino);
303         ST_EL(st_mode);
304         ST_EL(st_nlink);
305         ST_EL(st_uid);
306         ST_EL(st_gid);
307         ST_EL(st_rdev);
308         ST_EL(st_size);
309         ST_EL(st_blksize);
310         ST_EL(st_blocks);
311         ST_EL(st_atime);
312         ST_EL(st_mtime);
313         ST_EL(st_ctime);
314
315         return ret;
316 }
317
318 /*
319   usage:
320       var st = sys.stat(filename);
321   returns an object containing struct stat elements
322 */
323 static int ejs_sys_stat(MprVarHandle eid, int argc, char **argv)
324 {
325         struct stat st;
326         /* validate arguments */
327         if (argc != 1) {
328                 ejsSetErrorMsg(eid, "sys.stat invalid arguments");
329                 return -1;
330         }
331         if (stat(argv[0], &st) != 0) {
332                 mpr_Return(eid, mprCreateUndefinedVar());
333         } else {
334                 mpr_Return(eid, mpr_stat(&st));
335         }
336         return 0;
337 }
338
339 /*
340   usage:
341       var st = sys.lstat(filename);
342   returns an object containing struct stat elements
343 */
344 static int ejs_sys_lstat(MprVarHandle eid, int argc, char **argv)
345 {
346         struct stat st;
347         /* validate arguments */
348         if (argc != 1) {
349                 ejsSetErrorMsg(eid, "sys.stat invalid arguments");
350                 return -1;
351         }
352         if (lstat(argv[0], &st) != 0) {
353                 mpr_Return(eid, mprCreateUndefinedVar());
354         } else {
355                 mpr_Return(eid, mpr_stat(&st));
356         }
357         return 0;
358 }
359
360 /*
361   bitwise AND
362   usage:
363       var z = sys.bitAND(x, 0x70);
364 */
365 static int ejs_sys_bitAND(MprVarHandle eid, int argc, struct MprVar **argv)
366 {
367         int x, y, z;
368
369         if (argc != 2 || 
370             !mprVarIsNumber(argv[0]->type) ||
371             !mprVarIsNumber(argv[1]->type)) {
372                 ejsSetErrorMsg(eid, "bitand invalid arguments");
373                 return -1;
374         }
375         x = mprToInt(argv[0]);
376         y = mprToInt(argv[1]);
377         z = x & y;
378
379         mpr_Return(eid, mprCreateIntegerVar(z));
380         return 0;
381 }
382
383 /*
384   bitwise OR
385   usage:
386       var z = sys.bitOR(x, 0x70);
387 */
388 static int ejs_sys_bitOR(MprVarHandle eid, int argc, struct MprVar **argv)
389 {
390         int x, y, z;
391
392         if (argc != 2 || 
393             !mprVarIsNumber(argv[0]->type) ||
394             !mprVarIsNumber(argv[1]->type)) {
395                 ejsSetErrorMsg(eid, "bitand invalid arguments");
396                 return -1;
397         }
398         x = mprToInt(argv[0]);
399         y = mprToInt(argv[1]);
400         z = x | y;
401
402         mpr_Return(eid, mprCreateIntegerVar(z));
403         return 0;
404 }
405
406 /*
407   initialise sys ejs subsystem
408 */
409 static int ejs_sys_init(MprVarHandle eid, int argc, struct MprVar **argv)
410 {
411         struct MprVar *obj = mprInitObject(eid, "sys", argc, argv);
412
413         mprSetCFunction(obj, "interfaces", ejs_sys_interfaces);
414         mprSetCFunction(obj, "hostname", ejs_sys_hostname);
415         mprSetCFunction(obj, "nttime", ejs_sys_nttime);
416         mprSetCFunction(obj, "gettimeofday", ejs_sys_gettimeofday);
417         mprSetCFunction(obj, "unix2nttime", ejs_sys_unix2nttime);
418         mprSetCFunction(obj, "gmmktime", ejs_sys_gmmktime);
419         mprSetCFunction(obj, "gmtime", ejs_sys_gmtime);
420         mprSetCFunction(obj, "ntgmtime", ejs_sys_ntgmtime);
421         mprSetCFunction(obj, "ldaptime", ejs_sys_ldaptime);
422         mprSetCFunction(obj, "httptime", ejs_sys_httptime);
423         mprSetStringCFunction(obj, "unlink", ejs_sys_unlink);
424         mprSetStringCFunction(obj, "file_load", ejs_sys_file_load);
425         mprSetStringCFunction(obj, "file_save", ejs_sys_file_save);
426         mprSetStringCFunction(obj, "stat", ejs_sys_stat);
427         mprSetStringCFunction(obj, "lstat", ejs_sys_lstat);
428         mprSetCFunction(obj, "bitAND", ejs_sys_bitAND);
429         mprSetCFunction(obj, "bitOR", ejs_sys_bitOR);
430
431         return 0;
432 }
433
434
435 /*
436   setup C functions that be called from ejs
437 */
438 NTSTATUS smb_setup_ejs_system(void)
439 {
440         ejsDefineCFunction(-1, "sys_init", ejs_sys_init, NULL, MPR_VAR_SCRIPT_HANDLE);
441         return NT_STATUS_OK;
442 }