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