js_system.c 72.9 KB
Newer Older
1 2 3 4 5 6
/* Synchronet JavaScript "system" Object */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
7
 * Copyright Rob Swindell - http://www.synchro.net/copyright.html			*
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *																			*
 * This program is free software; you can redistribute it and/or			*
 * modify it under the terms of the GNU General Public License				*
 * as published by the Free Software Foundation; either version 2			*
 * of the License, or (at your option) any later version.					*
 * See the GNU General Public License for more details: gpl.txt or			*
 * http://www.fsf.org/copyleft/gpl.html										*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

#include "sbbs.h"
23
#include "js_request.h"
24
#include "ver.h"
25
#include "filedat.h"
26 27 28

#ifdef JAVASCRIPT

29 30 31
typedef struct {
	scfg_t* cfg;
	int nodefile;
32
	int nodegets;
33 34 35 36 37
} js_system_private_t;

extern JSClass js_system_class;

/* System Object Properties */
38 39 40
enum {
	 SYS_PROP_NAME
	,SYS_PROP_OP
41
	,SYS_PROP_OP_AVAIL
42 43 44 45 46 47
	,SYS_PROP_ID
	,SYS_PROP_MISC
	,SYS_PROP_INETADDR
	,SYS_PROP_LOCATION
	,SYS_PROP_TIMEZONE
	,SYS_PROP_PWDAYS
rswindell's avatar
rswindell committed
48 49
	,SYS_PROP_MINPWLEN
	,SYS_PROP_MAXPWLEN
50
	,SYS_PROP_DELDAYS
51
	,SYS_PROP_AUTODEL
52

53
	,SYS_PROP_LASTUSER
54 55
	,SYS_PROP_LASTUSERON
	,SYS_PROP_FREEDISKSPACE
56
	,SYS_PROP_FREEDISKSPACEK
57 58 59 60

	,SYS_PROP_NODES
	,SYS_PROP_LASTNODE

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
	,SYS_PROP_NEW_PASS
	,SYS_PROP_NEW_MAGIC
	,SYS_PROP_NEW_LEVEL
	,SYS_PROP_NEW_FLAGS1
	,SYS_PROP_NEW_FLAGS2
	,SYS_PROP_NEW_FLAGS3
	,SYS_PROP_NEW_FLAGS4
	,SYS_PROP_NEW_REST
	,SYS_PROP_NEW_EXEMPT
	,SYS_PROP_NEW_CDT
	,SYS_PROP_NEW_MIN
	,SYS_PROP_NEW_SHELL
	,SYS_PROP_NEW_XEDIT
	,SYS_PROP_NEW_MISC
	,SYS_PROP_NEW_PROT
	,SYS_PROP_NEW_EXPIRE
	,SYS_PROP_NEW_UQ

	,SYS_PROP_EXPIRED_LEVEL
	,SYS_PROP_EXPIRED_FLAGS1
	,SYS_PROP_EXPIRED_FLAGS2
	,SYS_PROP_EXPIRED_FLAGS3
	,SYS_PROP_EXPIRED_FLAGS4
	,SYS_PROP_EXPIRED_REST
	,SYS_PROP_EXPIRED_EXEMPT

87 88 89 90 91 92 93
	/* directories */
	,SYS_PROP_NODE_DIR
	,SYS_PROP_CTRL_DIR
	,SYS_PROP_DATA_DIR
	,SYS_PROP_TEXT_DIR
	,SYS_PROP_TEMP_DIR
	,SYS_PROP_EXEC_DIR
94 95
	,SYS_PROP_MODS_DIR
	,SYS_PROP_LOGS_DIR
rswindell's avatar
rswindell committed
96

97
	/* clock/timer access */
98 99
	,SYS_PROP_CLOCK
	,SYS_PROP_CLOCK_PER_SEC
100
	,SYS_PROP_TIMER
101

102 103
	/* filenames */
	,SYS_PROP_DEVNULL
104
	,SYS_PROP_TEMP_PATH
rswindell's avatar
rswindell committed
105
	,SYS_PROP_CMD_SHELL
106

107
	,SYS_PROP_LOCAL_HOSTNAME
Deucе's avatar
Deucе committed
108 109
	/* last */
	,SYS_PROP_NAME_SERVERS
110 111
};

112
static JSBool js_system_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
113
{
114
	jsval idval;
115
	char		str[128];
116
	char*		p=NULL;
117
    jsint       tiny;
118
	JSString*	js_str;
119
	ulong		val;
deuce's avatar
deuce committed
120
	jsrefcount	rc;
Deucе's avatar
Deucе committed
121 122 123 124
	JSObject *robj;
	jsval jval;
	str_list_t list;
	int i;
125

126 127 128 129
	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
	scfg_t* cfg = sys->cfg;
130

131 132
    JS_IdToValue(cx, id, &idval);
    tiny = JSVAL_TO_INT(idval);
133 134

	switch(tiny) {
135
#ifndef JSDOOR
136
		case SYS_PROP_NAME:
137
	        p=cfg->sys_name;
138 139
			break;
		case SYS_PROP_OP:
140
			p=cfg->sys_op;
141
			break;
142 143 144
		case SYS_PROP_OP_AVAIL:
			*vp=BOOLEAN_TO_JSVAL(sysop_available(cfg));
			break;
145
		case SYS_PROP_ID:
146
			p=cfg->sys_id;
147 148
			break;
		case SYS_PROP_MISC:
149
			*vp=UINT_TO_JSVAL(cfg->sys_misc);
150 151
			break;
		case SYS_PROP_INETADDR:
152
			p=cfg->sys_inetaddr;
153 154
			break;
		case SYS_PROP_LOCATION:
155
			p=cfg->sys_location;
156 157
			break;
		case SYS_PROP_TIMEZONE:
158
			sys_timezone(cfg);
159 160 161 162 163 164 165 166 167 168 169
			*vp = INT_TO_JSVAL(cfg->sys_timezone);
			break;
		case SYS_PROP_NODES:
			*vp = INT_TO_JSVAL(cfg->sys_nodes);
			break;
		case SYS_PROP_LASTNODE:
			*vp = INT_TO_JSVAL(cfg->sys_lastnode);
			break;
		case SYS_PROP_PWDAYS:
			*vp = INT_TO_JSVAL(cfg->sys_pwdays);
			break;
rswindell's avatar
rswindell committed
170
		case SYS_PROP_MINPWLEN:
171
			*vp = INT_TO_JSVAL(cfg->min_pwlen);
rswindell's avatar
rswindell committed
172 173 174 175
			break;
		case SYS_PROP_MAXPWLEN:
			*vp = INT_TO_JSVAL(LEN_PASS);
			break;
176 177 178
		case SYS_PROP_DELDAYS:
			*vp = INT_TO_JSVAL(cfg->sys_deldays);
			break;
179 180 181
		case SYS_PROP_AUTODEL:
			*vp = INT_TO_JSVAL(cfg->sys_autodel);
			break;
182 183 184
		case SYS_PROP_LASTUSER:
			*vp = INT_TO_JSVAL(lastuser(cfg));
			break;
185
		case SYS_PROP_LASTUSERON:
186
			p=lastuseron;
187
			break;
188
#endif
189
		case SYS_PROP_FREEDISKSPACE:
190
		case SYS_PROP_FREEDISKSPACEK:
191
			rc=JS_SUSPENDREQUEST(cx);
192 193 194 195
			if(tiny==SYS_PROP_FREEDISKSPACE)
				val = getfreediskspace(cfg->temp_dir,0);
			else
				val = getfreediskspace(cfg->temp_dir,1024);
196
			JS_RESUMEREQUEST(cx, rc);
197
			*vp=DOUBLE_TO_JSVAL((double)val);
198
			break;
199
#ifndef JSDOOR
200
		case SYS_PROP_NEW_PASS:
201
			p=cfg->new_pass;
202 203
			break;
		case SYS_PROP_NEW_MAGIC:
204
			p=cfg->new_magic;
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
			break;
		case SYS_PROP_NEW_LEVEL:
			*vp = INT_TO_JSVAL(cfg->new_level);
			break;
		case SYS_PROP_NEW_FLAGS1:
			*vp = INT_TO_JSVAL(cfg->new_flags1);
			break;
		case SYS_PROP_NEW_FLAGS2:
			*vp = INT_TO_JSVAL(cfg->new_flags2);
			break;
		case SYS_PROP_NEW_FLAGS3:
			*vp = INT_TO_JSVAL(cfg->new_flags3);
			break;
		case SYS_PROP_NEW_FLAGS4:
			*vp = INT_TO_JSVAL(cfg->new_flags4);
			break;
		case SYS_PROP_NEW_REST:
			*vp = INT_TO_JSVAL(cfg->new_rest);
			break;
		case SYS_PROP_NEW_EXEMPT:
			*vp = INT_TO_JSVAL(cfg->new_exempt);
			break;
		case SYS_PROP_NEW_CDT:
228
			*vp=UINT_TO_JSVAL(cfg->new_cdt);
229 230
			break;
		case SYS_PROP_NEW_MIN:
231
			*vp=UINT_TO_JSVAL(cfg->new_min);
232 233
			break;
		case SYS_PROP_NEW_SHELL:
234 235
			if(cfg->new_shell<cfg->total_shells)
				p=cfg->shell[cfg->new_shell]->code;
236 237
			break;
		case SYS_PROP_NEW_XEDIT:
238
			p=cfg->new_xedit;
239 240
			break;
		case SYS_PROP_NEW_MISC:
241
			*vp=UINT_TO_JSVAL(cfg->new_misc);
242 243 244
			break;
		case SYS_PROP_NEW_PROT:
			sprintf(str,"%c",cfg->new_prot);
245
			p=str;
246 247
			break;
		case SYS_PROP_NEW_EXPIRE:
248
			*vp=UINT_TO_JSVAL(cfg->new_expire);
249 250
			break;
		case SYS_PROP_NEW_UQ:
251
			*vp=UINT_TO_JSVAL(cfg->uq);
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
			break;

		case SYS_PROP_EXPIRED_LEVEL:
			*vp = INT_TO_JSVAL(cfg->expired_level);
			break;
		case SYS_PROP_EXPIRED_FLAGS1:
			*vp = INT_TO_JSVAL(cfg->expired_flags1);
			break;
		case SYS_PROP_EXPIRED_FLAGS2:
			*vp = INT_TO_JSVAL(cfg->expired_flags2);
			break;
		case SYS_PROP_EXPIRED_FLAGS3:
			*vp = INT_TO_JSVAL(cfg->expired_flags3);
			break;
		case SYS_PROP_EXPIRED_FLAGS4:
			*vp = INT_TO_JSVAL(cfg->expired_flags4);
			break;
		case SYS_PROP_EXPIRED_REST:
			*vp = INT_TO_JSVAL(cfg->expired_rest);
			break;
		case SYS_PROP_EXPIRED_EXEMPT:
			*vp = INT_TO_JSVAL(cfg->expired_exempt);
			break;
275
		case SYS_PROP_NODE_DIR:
276
			p=cfg->node_dir;
277
			break;
278
#endif
279
		case SYS_PROP_CTRL_DIR:
280
			p=cfg->ctrl_dir;
281 282
			break;
		case SYS_PROP_DATA_DIR:
283
			p=cfg->data_dir;
284 285
			break;
		case SYS_PROP_TEXT_DIR:
286
			p=cfg->text_dir;
287 288
			break;
		case SYS_PROP_TEMP_DIR:
289
			p=cfg->temp_dir;
290 291
			break;
		case SYS_PROP_EXEC_DIR:
292
			p=cfg->exec_dir;
293
			break;
294 295 296 297 298 299
		case SYS_PROP_MODS_DIR:
			p=cfg->mods_dir;
			break;
		case SYS_PROP_LOGS_DIR:
			p=cfg->logs_dir;
			break;
300 301 302 303

		case SYS_PROP_DEVNULL:
			p=_PATH_DEVNULL;
			break;
304 305 306
		case SYS_PROP_TEMP_PATH:
			p=_PATH_TMP;
			break;
307

rswindell's avatar
rswindell committed
308
		case SYS_PROP_CMD_SHELL:
309
			rc=JS_SUSPENDREQUEST(cx);
rswindell's avatar
rswindell committed
310
			p=os_cmdshell();
311
			JS_RESUMEREQUEST(cx, rc);
rswindell's avatar
rswindell committed
312 313
			break;

314
		case SYS_PROP_CLOCK:
315
			*vp=DOUBLE_TO_JSVAL((double)xp_timer64());
316 317
			break;
		case SYS_PROP_CLOCK_PER_SEC:
318
			*vp=UINT_TO_JSVAL(1000);
319
			break;
320
		case SYS_PROP_TIMER:
321
			*vp=DOUBLE_TO_JSVAL(xp_timer());
322
			break;
323

324
		case SYS_PROP_LOCAL_HOSTNAME:
325
			rc=JS_SUSPENDREQUEST(cx);
326
			gethostname(str,sizeof(str));
327
			JS_RESUMEREQUEST(cx, rc);
328 329
			p=str;
			break;
Deucе's avatar
Deucе committed
330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346
		case SYS_PROP_NAME_SERVERS:
			rc=JS_SUSPENDREQUEST(cx);
			robj = JS_NewArrayObject(cx, 0, NULL);
			if (robj == NULL)
				return JS_FALSE;
			*vp = OBJECT_TO_JSVAL(robj);
			list = getNameServerList();
			if (list != NULL) {
				for (i = 0; list[i]; i++) {
					jval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, list[i]));
					if (!JS_SetElement(cx, robj, i, &jval))
						break;
				}
			}
			freeNameServerList(list);
			JS_RESUMEREQUEST(cx, rc);
			break;
347 348
	}

349 350 351 352 353 354 355
	if(p!=NULL) {	/* string property */
		if((js_str=JS_NewStringCopyZ(cx, p))==NULL)
			return(JS_FALSE);
		*vp = STRING_TO_JSVAL(js_str);
	}

	return(JS_TRUE);
356 357
}

358
static JSBool js_system_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
359
{
360
	jsval idval;
361 362
    jsint       tiny;

363 364 365
	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
366

367 368
    JS_IdToValue(cx, id, &idval);
    tiny = JSVAL_TO_INT(idval);
369

370
#ifndef JSDOOR
371 372
	switch(tiny) {
		case SYS_PROP_MISC:
373
			JS_ValueToECMAUint32(cx, *vp, &sys->cfg->sys_misc);
374
			break;
375 376 377 378 379 380
		case SYS_PROP_OP_AVAIL:
			if(!set_sysop_availability(sys->cfg, JSVAL_TO_BOOLEAN(*vp))) {
				JS_ReportError(cx, "%s: Failed to set sysop availability", __FUNCTION__);
				return JS_FALSE;
			}
			break;
381
	}
382
#endif
383

384
	return JS_TRUE;
385 386 387 388 389
}


#define SYSOBJ_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY

390 391 392
static jsSyncPropertySpec js_system_properties[] = {
/*		 name,						tinyid,				flags,				ver	*/

393
#ifndef JSDOOR
394 395
	{	"name",						SYS_PROP_NAME,		SYSOBJ_FLAGS,		310  },
	{	"operator",					SYS_PROP_OP,		SYSOBJ_FLAGS,		310  },
396
	{	"operator_available",		SYS_PROP_OP_AVAIL,	JSPROP_ENUMERATE,	31801  },
397 398 399 400 401 402 403
	{	"qwk_id",					SYS_PROP_ID,		SYSOBJ_FLAGS,		310  },
	{	"settings",					SYS_PROP_MISC,		JSPROP_ENUMERATE,	310  },
	{	"inetaddr",					SYS_PROP_INETADDR,	JSPROP_READONLY,	310  },	/* alias */
	{	"inet_addr",				SYS_PROP_INETADDR,	SYSOBJ_FLAGS,		311  },
	{	"location",					SYS_PROP_LOCATION,	SYSOBJ_FLAGS,		310  },
	{	"timezone",					SYS_PROP_TIMEZONE,	SYSOBJ_FLAGS,		310  },
	{	"pwdays",					SYS_PROP_PWDAYS,	SYSOBJ_FLAGS,		310  },
rswindell's avatar
rswindell committed
404 405
	{	"min_password_length",		SYS_PROP_MINPWLEN,	SYSOBJ_FLAGS,		31702  },
	{	"max_password_length",		SYS_PROP_MAXPWLEN,	SYSOBJ_FLAGS,		31702  },
406
	{	"deldays",					SYS_PROP_DELDAYS,	SYSOBJ_FLAGS,		310  },
407
	{	"autodel",					SYS_PROP_AUTODEL,	SYSOBJ_FLAGS,		31702  },
408 409 410

	{	"lastuser",					SYS_PROP_LASTUSER		,SYSOBJ_FLAGS,	311  },
	{	"lastuseron",				SYS_PROP_LASTUSERON		,SYSOBJ_FLAGS,	310  },
411
#endif
412 413 414
	{	"freediskspace",			SYS_PROP_FREEDISKSPACE	,SYSOBJ_FLAGS,	310  },
	{	"freediskspacek",			SYS_PROP_FREEDISKSPACEK	,SYSOBJ_FLAGS,	310  },

415
#ifndef JSDOOR
416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
	{	"nodes",					SYS_PROP_NODES,		SYSOBJ_FLAGS,		310  },
	{	"lastnode",					SYS_PROP_LASTNODE,	SYSOBJ_FLAGS,		310  },

	{	"newuser_password",			SYS_PROP_NEW_PASS		,SYSOBJ_FLAGS,	310  },
	{	"newuser_magic_word",		SYS_PROP_NEW_MAGIC		,SYSOBJ_FLAGS,	310  },
	{	"newuser_level",			SYS_PROP_NEW_LEVEL		,SYSOBJ_FLAGS,	310  },
	{	"newuser_flags1",			SYS_PROP_NEW_FLAGS1		,SYSOBJ_FLAGS,	310  },
	{	"newuser_flags2",			SYS_PROP_NEW_FLAGS2		,SYSOBJ_FLAGS,	310  },
	{	"newuser_flags3",			SYS_PROP_NEW_FLAGS3		,SYSOBJ_FLAGS,	310  },
	{	"newuser_flags4",			SYS_PROP_NEW_FLAGS4		,SYSOBJ_FLAGS,	310  },
	{	"newuser_restrictions",		SYS_PROP_NEW_REST		,SYSOBJ_FLAGS,	310  },
	{	"newuser_exemptions",		SYS_PROP_NEW_EXEMPT		,SYSOBJ_FLAGS,	310  },
	{	"newuser_credits",			SYS_PROP_NEW_CDT		,SYSOBJ_FLAGS,	310  },
	{	"newuser_minutes",			SYS_PROP_NEW_MIN		,SYSOBJ_FLAGS,	310  },
	{	"newuser_command_shell",	SYS_PROP_NEW_SHELL		,SYSOBJ_FLAGS,	310  },
	{	"newuser_editor",			SYS_PROP_NEW_XEDIT		,SYSOBJ_FLAGS,	310  },
	{	"newuser_settings",			SYS_PROP_NEW_MISC		,SYSOBJ_FLAGS,	310  },
	{	"newuser_download_protocol",SYS_PROP_NEW_PROT		,SYSOBJ_FLAGS,	310  },
	{	"newuser_expiration_days",	SYS_PROP_NEW_EXPIRE		,SYSOBJ_FLAGS,	310  },
	{	"newuser_questions",		SYS_PROP_NEW_UQ			,SYSOBJ_FLAGS,	310  },

	{	"expired_level",			SYS_PROP_EXPIRED_LEVEL	,SYSOBJ_FLAGS,	310  },
	{	"expired_flags1",			SYS_PROP_EXPIRED_FLAGS1	,SYSOBJ_FLAGS,	310  },
	{	"expired_flags2",			SYS_PROP_EXPIRED_FLAGS2	,SYSOBJ_FLAGS,	310  },
	{	"expired_flags3",			SYS_PROP_EXPIRED_FLAGS3	,SYSOBJ_FLAGS,	310  },
	{	"expired_flags4",			SYS_PROP_EXPIRED_FLAGS4	,SYSOBJ_FLAGS,	310  },
	{	"expired_restrictions",		SYS_PROP_EXPIRED_REST	,SYSOBJ_FLAGS,	310  },
	{	"expired_exemptions",		SYS_PROP_EXPIRED_EXEMPT	,SYSOBJ_FLAGS,	310  },	
444 445

	/* directories */
446
	{	"node_dir",					SYS_PROP_NODE_DIR		,SYSOBJ_FLAGS,	310  },	
447
#endif
448 449 450 451 452 453 454
	{	"ctrl_dir",					SYS_PROP_CTRL_DIR		,SYSOBJ_FLAGS,	310  },	
	{	"data_dir",					SYS_PROP_DATA_DIR		,SYSOBJ_FLAGS,	310  },	
	{	"text_dir",					SYS_PROP_TEXT_DIR		,SYSOBJ_FLAGS,	310  },	
	{	"temp_dir",					SYS_PROP_TEMP_DIR		,SYSOBJ_FLAGS,	310  },	
	{	"exec_dir",					SYS_PROP_EXEC_DIR		,SYSOBJ_FLAGS,	310  },	
	{	"mods_dir",					SYS_PROP_MODS_DIR		,SYSOBJ_FLAGS,	310  },	
	{	"logs_dir",					SYS_PROP_LOGS_DIR		,SYSOBJ_FLAGS,	310  },	
455

456
	/* filenames */
457
	{	"devnull",					SYS_PROP_DEVNULL		,SYSOBJ_FLAGS,	311  },
458
	{	"temp_path",				SYS_PROP_TEMP_PATH		,SYSOBJ_FLAGS,	312	 },
rswindell's avatar
rswindell committed
459
	{	"cmd_shell",				SYS_PROP_CMD_SHELL		,SYSOBJ_FLAGS,	314	 },
460

461
	/* clock access */
462 463
	{	"clock_ticks",				SYS_PROP_CLOCK			,SYSOBJ_FLAGS,	311  },
	{	"clock_ticks_per_second",	SYS_PROP_CLOCK_PER_SEC	,SYSOBJ_FLAGS,	311  },
rswindell's avatar
rswindell committed
464
	{	"timer",					SYS_PROP_TIMER			,SYSOBJ_FLAGS,	314	 },
465

466
	{	"local_host_name",			SYS_PROP_LOCAL_HOSTNAME	,SYSOBJ_FLAGS,	311  },
Deucе's avatar
Deucе committed
467 468
	{	"name_servers",			SYS_PROP_NAME_SERVERS,SYSOBJ_FLAGS,	31802  },
	/* last */
469 470 471
	{0}
};

472
#ifdef BUILD_JSDOCS
473 474 475
static char* sys_prop_desc[] = {
	 "BBS name"
	,"operator name"
476
	,"operator is available for chat"
477
	,"system QWK-ID (for QWK packets)"
478
	,"settings bitfield (see <tt>SYS_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
479
	,"Internet address (host or domain name)"
480
	,"location (city, state)"
481
	,"timezone (use <i>system.zonestr()</i> to get string representation)"
rswindell's avatar
rswindell committed
482 483 484
	,"days between forced user password changes (<tt>0</tt>=<i>never</i>)"
	,"minimum number of characters in user passwords"
	,"maximum number of characters in user passwords"
485 486
	,"days to preserve deleted user records, record will not be reused/overwritten during this period"
	,"days of user inactivity before auto-deletion (<tt>0</tt>=<i>disabled</i>), N/A to P-exempt users"
487

488 489
	,"last user record number in user database (includes deleted and inactive user records)"
	,"name of last user to logoff"
490 491
	,"amount of free disk space (in bytes)"
	,"amount of free disk space (in kilobytes)"
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509

	,"total number of BBS nodes"
	,"last displayable node number"

	,"new user password"
	,"new user magic word"
	,"new user level"
	,"new user flag set #1"
	,"new user flag set #2"
	,"new user flag set #3"
	,"new user flag set #4"
	,"new user restriction flags"
	,"new user exemption flags"
	,"new user credits"
	,"new user extra minutes"
	,"new user command shell"
	,"new user external editor"
	,"new user settings"
510 511 512
	,"new user file transfer protocol (command key)"
	,"new user expiration days"
	,"new user questions bitfield (see <tt>UQ_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
513 514 515 516 517 518 519 520 521 522 523

	,"expired user level"
	,"expired user flag set #1"
	,"expired user flag set #2"
	,"expired user flag set #3"
	,"expired user flag set #4"
	,"expired user restriction flags"
	,"expired user exemption flags"

	/* directories */
	,"node directory"
524
	,"control file directory"
525 526
	,"data file directory"
	,"text file directory"
527
	,"temporary file directory"
528
	,"executable file directory"
529
	,"modified modules directory (optional)"
530
	,"log file directory"
531

532
	/* filenames */
533 534
	,"platform-specific \"null\" device filename"
	,"platform-specific temporary file directory"
rswindell's avatar
rswindell committed
535
	,"platform-specific command processor/shell"
536

537
	/* clock */
538
	,"amount of elapsed time in clock 'ticks'"
539
	,"number of clock ticks per second"
540
	,"high-resolution timer, in seconds (fractional seconds supported)"
541

542
	,"private host name that uniquely identifies this system on the local network"
Deucе's avatar
Deucе committed
543 544
	,"array of nameservers in use by the system"
	/* INSERT new tabled properties here */
545 546

	/* Manually created (non-tabled) properties */
547
	,"public host name that uniquely identifies this system on the Internet (usually the same as <i>system.inet_addr</i>)"
548 549 550 551
	,"socket library version information"
	,"time/date system was brought online (in time_t format)"
	,"Synchronet full version information (e.g. '3.10k Beta Debug')"
	,"date and time compiled"
552 553
	,"Synchronet version number (e.g. '3.10')"
	,"Synchronet revision letter (e.g. 'k')"
554
	,"Synchronet alpha/beta designation (e.g. ' beta')"
555
	,"Synchronet version notice (includes version and platform)"
556 557
	,"Synchronet version number in decimal (e.g. 31301 for v3.13b)"
	,"Synchronet version number in hexadecimal (e.g. 0x31301 for v3.13b)"
558 559
	,"Synchronet Git repository branch name"
	,"Synchronet Git repository commit hash"
560
	,"platform description (e.g. 'Win32', 'Linux', 'FreeBSD')"
561
	,"architecture description (e.g. 'i386', 'i686', 'x86_64')"
562 563 564 565 566
	,"message base library version information"
	,"compiler used to build Synchronet"
	,"Synchronet copyright display"
	,"JavaScript engine version information"
	,"operating system version information"
567
	,"array of FidoNet Technology Network (FTN) addresses associated with this system"
568 569 570 571 572
	,NULL
};
#endif


573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
/* System Stats Propertiess */
enum {
	 SYSSTAT_PROP_LOGONS
	,SYSSTAT_PROP_LTODAY
	,SYSSTAT_PROP_TIMEON
	,SYSSTAT_PROP_TTODAY
	,SYSSTAT_PROP_ULS
	,SYSSTAT_PROP_ULB
	,SYSSTAT_PROP_DLS
	,SYSSTAT_PROP_DLB
	,SYSSTAT_PROP_PTODAY
	,SYSSTAT_PROP_ETODAY
	,SYSSTAT_PROP_FTODAY
	,SYSSTAT_PROP_NUSERS

	,SYSSTAT_PROP_TOTALUSERS
	,SYSSTAT_PROP_TOTALFILES
	,SYSSTAT_PROP_TOTALMSGS
	,SYSSTAT_PROP_TOTALMAIL
	,SYSSTAT_PROP_FEEDBACK
593 594

	,SYSSTAT_PROP_NODE_GETS
rswindell's avatar
rswindell committed
595 596
};

597
#ifndef JSDOOR
598
static JSBool js_sysstats_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
599
{
600
	jsval idval;
601 602 603 604
    jsint       tiny;
	stats_t		stats;
	uint		i;
	ulong		l;
deuce's avatar
deuce committed
605
	jsrefcount	rc;
606

607
	js_system_private_t* sys;
608 609
	if((sys = (js_system_private_t*)JS_GetPrivate(cx,obj))==NULL) {
		JS_ReportError(cx, "JS_GetPrivate failure in %s", __FUNCTION__);
610
		return JS_FALSE;
611
	}
612
	scfg_t* cfg = sys->cfg;
613

614 615
    JS_IdToValue(cx, id, &idval);
    tiny = JSVAL_TO_INT(idval);
616

617 618 619 620 621 622 623
	if(tiny < SYSSTAT_PROP_TOTALUSERS) {
		rc=JS_SUSPENDREQUEST(cx);
		if(!getstats(cfg, 0, &stats)) {
			JS_RESUMEREQUEST(cx, rc);
			JS_ReportError(cx, "getstats failure in %s", __FUNCTION__);
			return JS_FALSE;
		}
624
		JS_RESUMEREQUEST(cx, rc);
deuce's avatar
deuce committed
625
	}
626 627 628

	switch(tiny) {
		case SYSSTAT_PROP_LOGONS:
629
			*vp=UINT_TO_JSVAL(stats.logons);
630 631
			break;
		case SYSSTAT_PROP_LTODAY:
632
			*vp=UINT_TO_JSVAL(stats.ltoday);
633 634
			break;
		case SYSSTAT_PROP_TIMEON:
635
			*vp=UINT_TO_JSVAL(stats.timeon);
636 637
			break;
		case SYSSTAT_PROP_TTODAY:
638
			*vp=UINT_TO_JSVAL(stats.ttoday);
639 640
			break;
		case SYSSTAT_PROP_ULS:
641
			*vp=UINT_TO_JSVAL(stats.uls);
642 643
			break;
		case SYSSTAT_PROP_ULB:
644
			*vp=UINT_TO_JSVAL(stats.ulb);
645 646
			break;
		case SYSSTAT_PROP_DLS:
647
			*vp=UINT_TO_JSVAL(stats.dls);
648 649
			break;
		case SYSSTAT_PROP_DLB:
650
			*vp=UINT_TO_JSVAL(stats.dlb);
651 652
			break;
		case SYSSTAT_PROP_PTODAY:
653
			*vp=UINT_TO_JSVAL(stats.ptoday);
654 655
			break;
		case SYSSTAT_PROP_ETODAY:
656
			*vp=UINT_TO_JSVAL(stats.etoday);
657 658
			break;
		case SYSSTAT_PROP_FTODAY:
659
			*vp=UINT_TO_JSVAL(stats.ftoday);
660 661
			break;
		case SYSSTAT_PROP_NUSERS:
662
			*vp=UINT_TO_JSVAL(stats.nusers);
663 664 665
			break;

		case SYSSTAT_PROP_TOTALUSERS:
666
			rc=JS_SUSPENDREQUEST(cx);
667
			*vp = INT_TO_JSVAL(total_users(cfg));
668
			JS_RESUMEREQUEST(cx, rc);
669 670 671
			break;
		case SYSSTAT_PROP_TOTALMSGS:
			l=0;
672
			rc=JS_SUSPENDREQUEST(cx);
673 674
			for(i=0;i<cfg->total_subs;i++)
				l+=getposts(cfg,i); 
675
			JS_RESUMEREQUEST(cx, rc);
676
			*vp=DOUBLE_TO_JSVAL((double)l); 
677 678 679
			break;
		case SYSSTAT_PROP_TOTALFILES:
			l=0;
680
			rc=JS_SUSPENDREQUEST(cx);
681 682
			for(i=0;i<cfg->total_dirs;i++)
				l+=getfiles(cfg,i);
683
			JS_RESUMEREQUEST(cx, rc);
684
			*vp=DOUBLE_TO_JSVAL((double)l);
685 686
			break;
		case SYSSTAT_PROP_TOTALMAIL:
687
			rc=JS_SUSPENDREQUEST(cx);
688
			*vp = INT_TO_JSVAL(getmail(cfg, /* user: */0, /* Sent: */FALSE, /* SPAM: */FALSE));
689
			JS_RESUMEREQUEST(cx, rc);
690 691
			break;
		case SYSSTAT_PROP_FEEDBACK:
692
			rc=JS_SUSPENDREQUEST(cx);
693
			*vp = INT_TO_JSVAL(getmail(cfg, /* user: */1, /* Sent: */FALSE, /* SPAM: */FALSE));
694
			JS_RESUMEREQUEST(cx, rc);
695
			break;
696 697 698 699

		case SYSSTAT_PROP_NODE_GETS:
			*vp = INT_TO_JSVAL(sys->nodegets);
			break;
700 701 702 703 704 705 706
	}

	return(TRUE);
}

#define SYSSTAT_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY

707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
static jsSyncPropertySpec js_sysstats_properties[] = {
/*		 name,						tinyid,						flags,			ver	*/

	{	"total_logons",				SYSSTAT_PROP_LOGONS,		SYSSTAT_FLAGS,	310 },
	{	"logons_today",				SYSSTAT_PROP_LTODAY,		SYSSTAT_FLAGS,	310 },
	{	"total_timeon",				SYSSTAT_PROP_TIMEON,		SYSSTAT_FLAGS,	310 },
	{	"timeon_today",				SYSSTAT_PROP_TTODAY,		SYSSTAT_FLAGS,	310 },
	{	"total_files",				SYSSTAT_PROP_TOTALFILES,	SYSSTAT_FLAGS,	310 },
	{	"files_uploaded_today",		SYSSTAT_PROP_ULS,			SYSSTAT_FLAGS,	310 },
	{	"bytes_uploaded_today",		SYSSTAT_PROP_ULB,			SYSSTAT_FLAGS,	310 },
	{	"files_downloaded_today",	SYSSTAT_PROP_DLS,			SYSSTAT_FLAGS,	310 },
	{	"bytes_downloaded_today",	SYSSTAT_PROP_DLB,			SYSSTAT_FLAGS,	310 },
	{	"total_messages",			SYSSTAT_PROP_TOTALMSGS,		SYSSTAT_FLAGS,	310 },
	{	"messages_posted_today",	SYSSTAT_PROP_PTODAY,		SYSSTAT_FLAGS,	310 },
	{	"total_email",				SYSSTAT_PROP_TOTALMAIL,		SYSSTAT_FLAGS,	310 },
	{	"email_sent_today",			SYSSTAT_PROP_ETODAY,		SYSSTAT_FLAGS,	310 },
	{	"total_feedback",			SYSSTAT_PROP_FEEDBACK,		SYSSTAT_FLAGS,	310 },
	{	"feedback_sent_today",		SYSSTAT_PROP_FTODAY,		SYSSTAT_FLAGS,	310 },
	{	"total_users",				SYSSTAT_PROP_TOTALUSERS,	SYSSTAT_FLAGS,	310 },
	{	"new_users_today",			SYSSTAT_PROP_NUSERS,		SYSSTAT_FLAGS,	310 },
727
	{	"node_gets",				SYSSTAT_PROP_NODE_GETS,		JSPROP_READONLY, 31702 },
728 729 730
	{0}
};

731
#if !defined(JSDOOR) && defined(BUILD_JSDOCS)
732
static char* sysstat_prop_desc[] = {
733 734 735 736 737 738 739 740 741 742 743 744 745
	 "total logons"
	,"logons today"
	,"total time used"
	,"time used today"
	,"total files in file bases"
	,"files uploaded today"
	,"bytes uploaded today"
	,"files downloaded today"
	,"bytes downloaded today"
	,"total messages in message bases"
	,"messages posted today"
	,"total messages in mail base"
	,"email sent today"
746
	,"total feedback messages waiting"
747
	,"feedback sent today"
748
	,"total user records (does not include deleted or inactive user records)"
749
	,"new users today"
750
	,NULL
751 752 753
};
#endif

754
static JSBool js_sysstats_resolve(JSContext *cx, JSObject *obj, jsid id)
deuce's avatar
deuce committed
755 756
{
	char*			name=NULL;
deuce's avatar
deuce committed
757
	JSBool			ret;
deuce's avatar
deuce committed
758

deuce's avatar
deuce committed
759 760 761 762
	if(id != JSID_VOID && id != JSID_EMPTY) {
		jsval idval;
		
		JS_IdToValue(cx, id, &idval);
deuce's avatar
deuce committed
763 764
		if(JSVAL_IS_STRING(idval)) {
			JSSTRING_TO_MSTRING(cx, JSVAL_TO_STRING(idval), name, NULL);
765
			HANDLE_PENDING(cx, name);
deuce's avatar
deuce committed
766
		}
deuce's avatar
deuce committed
767
	}
deuce's avatar
deuce committed
768

deuce's avatar
deuce committed
769 770 771 772
	ret=js_SyncResolve(cx, obj, name, js_sysstats_properties, NULL, NULL, 0);
	if(name)
		free(name);
	return ret;
deuce's avatar
deuce committed
773 774 775 776
}

static JSBool js_sysstats_enumerate(JSContext *cx, JSObject *obj)
{
deuce's avatar
deuce committed
777
	return(js_sysstats_resolve(cx, obj, JSID_VOID));
deuce's avatar
deuce committed
778
}
779

780 781 782 783 784 785
static JSClass js_sysstats_class = {
     "Stats"				/* name			*/
    ,JSCLASS_HAS_PRIVATE	/* flags		*/
	,JS_PropertyStub		/* addProperty	*/
	,JS_PropertyStub		/* delProperty	*/
	,js_sysstats_get		/* getProperty	*/
786
	,JS_StrictPropertyStub	/* setProperty	*/
deuce's avatar
deuce committed
787 788
	,js_sysstats_enumerate	/* enumerate	*/
	,js_sysstats_resolve	/* resolve		*/
789 790 791 792
	,JS_ConvertStub			/* convert		*/
	,JS_FinalizeStub		/* finalize		*/
};

793
static JSBool
794
js_alias(JSContext *cx, uintN argc, jsval *arglist)
795
{
796 797
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
798
	char*		p;
799
	char		buf[128];
800
	JSString*	js_str;
deuce's avatar
deuce committed
801
	jsrefcount	rc;
802

803 804
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

805 806 807
	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
808 809

	if((js_str=JS_ValueToString(cx, argv[0]))==NULL) {
810
		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
811 812 813
		return(JS_TRUE);
	}

deuce's avatar
deuce committed
814
	JSSTRING_TO_ASTRING(cx, js_str, p, 128, NULL);
deuce's avatar
deuce committed
815
	if(p==NULL) {
816
		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));
817 818 819
		return(JS_TRUE);
	}

820
	rc=JS_SUSPENDREQUEST(cx);
821
	p=alias(sys->cfg,p,buf);
822
	JS_RESUMEREQUEST(cx, rc);
823

824 825
	if((js_str = JS_NewStringCopyZ(cx, p))==NULL)
		return(JS_FALSE);
826

827
	JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
828 829 830 831
	return(JS_TRUE);
}

static JSBool
832
js_username(JSContext *cx, uintN argc, jsval *arglist)
833
{
834 835
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
836 837 838
	int32		val;
	char		buf[128];
	JSString*	js_str;
deuce's avatar
deuce committed
839 840
	char*		cstr;
	jsrefcount	rc;
841

842 843
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

844 845 846
	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
847 848 849 850

	val=0;
	JS_ValueToInt32(cx,argv[0],&val);

851
	rc=JS_SUSPENDREQUEST(cx);
852
	cstr=username(sys->cfg,val,buf);
853
	JS_RESUMEREQUEST(cx, rc);
deuce's avatar
deuce committed
854
	if((js_str = JS_NewStringCopyZ(cx, cstr))==NULL)
855 856
		return(JS_FALSE);

857
	JS_SET_RVAL(cx, arglist, STRING_TO_JSVAL(js_str));
858 859 860
	return(JS_TRUE);
}

861
static JSBool
862
js_matchuser(JSContext *cx, uintN argc, jsval *arglist)
863
{
864 865
	JSObject *obj=JS_THIS_OBJECT(cx, arglist);
	jsval *argv=JS_ARGV(cx, arglist);
866 867
	char*		p;
	JSString*	js_str;
868
	BOOL		sysop_alias=TRUE;
deuce's avatar
deuce committed
869
	jsrefcount	rc;
870

871 872
	JS_SET_RVAL(cx, arglist, JSVAL_VOID);

873 874 875
	js_system_private_t* sys;
	if((sys = (js_system_private_t*)js_GetClassPrivate(cx,obj,&js_system_class))==NULL)
		return JS_FALSE;
876 877

	if((js_str=JS_ValueToString(cx, argv[0]))==NULL) {
878
		JS_SET_RVAL(cx, arglist, INT_TO_JSVAL(0));