Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, libarchive.org for more info) to build successfully.

js_bbs.cpp 120 KB
Newer Older
1 2 3 4 5 6
/* Synchronet JavaScript "bbs" 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 25 26 27 28 29 30 31 32 33 34

#ifdef JAVASCRIPT

/*****************************/
/* BBS Object Properites */
/*****************************/
enum {
	 BBS_PROP_SYS_STATUS
	,BBS_PROP_STARTUP_OPT
	,BBS_PROP_ANSWER_TIME
	,BBS_PROP_LOGON_TIME
35
	,BBS_PROP_START_TIME
36 37 38 39
	,BBS_PROP_NS_TIME
	,BBS_PROP_LAST_NS_TIME
	,BBS_PROP_ONLINE
	,BBS_PROP_TIMELEFT
40
	,BBS_PROP_EVENT_TIME
41
	,BBS_PROP_EVENT_CODE
42 43

	,BBS_PROP_NODE_NUM
rswindell's avatar
rswindell committed
44 45 46
	,BBS_PROP_NODE_SETTINGS
	,BBS_PROP_NODE_STATUS
	,BBS_PROP_NODE_ERRORS
rswindell's avatar
rswindell committed
47
	,BBS_PROP_NODE_ACTION
rswindell's avatar
rswindell committed
48 49 50 51 52
	,BBS_PROP_NODE_USERON
	,BBS_PROP_NODE_CONNECTION
	,BBS_PROP_NODE_MISC
	,BBS_PROP_NODE_AUX
	,BBS_PROP_NODE_EXTAUX
53 54 55 56 57 58 59 60 61 62 63 64 65 66
	,BBS_PROP_NODE_VAL_USER

	,BBS_PROP_LOGON_ULB
	,BBS_PROP_LOGON_DLB
	,BBS_PROP_LOGON_ULS
	,BBS_PROP_LOGON_DLS
	,BBS_PROP_LOGON_POSTS
	,BBS_PROP_LOGON_EMAILS
	,BBS_PROP_LOGON_FBACKS
	,BBS_PROP_POSTS_READ

	,BBS_PROP_MENU_DIR
	,BBS_PROP_MENU_FILE
	,BBS_PROP_MAIN_CMDS
rswindell's avatar
rswindell committed
67
	,BBS_PROP_FILE_CMDS
68

69 70
	,BBS_PROP_CURGRP
	,BBS_PROP_CURSUB
71
	,BBS_PROP_CURSUB_CODE
72 73
	,BBS_PROP_CURLIB
	,BBS_PROP_CURDIR
74
	,BBS_PROP_CURDIR_CODE
75

76 77
	,BBS_PROP_CONNECTION		/* READ ONLY */
	,BBS_PROP_RLOGIN_NAME
78
	,BBS_PROP_RLOGIN_PASS
79
	,BBS_PROP_RLOGIN_TERM
80
	,BBS_PROP_CLIENT_NAME
81

82 83
	,BBS_PROP_ERRORLEVEL		/* READ ONLY */

84
	/* READ ONLY */
85
	,BBS_PROP_SMB_GROUP
86 87 88 89 90 91 92 93 94
	,BBS_PROP_SMB_GROUP_DESC
	,BBS_PROP_SMB_GROUP_NUM
	,BBS_PROP_SMB_SUB
	,BBS_PROP_SMB_SUB_DESC
	,BBS_PROP_SMB_SUB_CODE
	,BBS_PROP_SMB_SUB_NUM
	,BBS_PROP_SMB_ATTR
	,BBS_PROP_SMB_LAST_MSG
	,BBS_PROP_SMB_TOTAL_MSGS
95 96
	,BBS_PROP_SMB_MSGS
	,BBS_PROP_SMB_CURMSG
97 98 99 100 101 102 103 104 105

	/* READ ONLY */
	,BBS_PROP_MSG_TO
	,BBS_PROP_MSG_TO_EXT
	,BBS_PROP_MSG_TO_NET
	,BBS_PROP_MSG_TO_AGENT
	,BBS_PROP_MSG_FROM
	,BBS_PROP_MSG_FROM_EXT
	,BBS_PROP_MSG_FROM_NET
106
	,BBS_PROP_MSG_FROM_BBSID
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
	,BBS_PROP_MSG_FROM_AGENT
	,BBS_PROP_MSG_REPLYTO
	,BBS_PROP_MSG_REPLYTO_EXT
	,BBS_PROP_MSG_REPLYTO_NET
	,BBS_PROP_MSG_REPLYTO_AGENT
	,BBS_PROP_MSG_SUBJECT
	,BBS_PROP_MSG_DATE
	,BBS_PROP_MSG_TIMEZONE
	,BBS_PROP_MSG_DATE_IMPORTED
	,BBS_PROP_MSG_ATTR
	,BBS_PROP_MSG_AUXATTR
	,BBS_PROP_MSG_NETATTR
	,BBS_PROP_MSG_OFFSET
	,BBS_PROP_MSG_NUMBER
	,BBS_PROP_MSG_EXPIRATION
	,BBS_PROP_MSG_FORWARDED
123
	,BBS_PROP_MSG_THREAD_ID
124
	,BBS_PROP_MSG_THREAD_BACK
125 126
	,BBS_PROP_MSG_THREAD_NEXT
	,BBS_PROP_MSG_THREAD_FIRST
127 128
	,BBS_PROP_MSG_ID
	,BBS_PROP_MSG_REPLY_ID
129
	,BBS_PROP_MSG_DELIVERY_ATTEMPTS
130

131 132
	,BBS_PROP_MSGHDR_TOS

133 134 135 136
	/* READ ONLY */
	,BBS_PROP_BATCH_UPLOAD_TOTAL
	,BBS_PROP_BATCH_DNLOAD_TOTAL

137 138 139 140 141 142 143 144 145 146 147 148 149
	/* READ ONLY */
	,BBS_PROP_FILE_NAME
	,BBS_PROP_FILE_DESC
	,BBS_PROP_FILE_DIR
	,BBS_PROP_FILE_ATTR
	,BBS_PROP_FILE_DATE
	,BBS_PROP_FILE_SIZE
	,BBS_PROP_FILE_CREDITS
	,BBS_PROP_FILE_ULER
	,BBS_PROP_FILE_DATE_ULED
	,BBS_PROP_FILE_DATE_DLED
	,BBS_PROP_FILE_TIMES_DLED

150
	,BBS_PROP_COMMAND_STR
151 152
};

153
#ifdef BUILD_JSDOCS
154
	static const char* bbs_prop_desc[] = {
155 156
	 "system status bitfield (see <tt>SS_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
	,"startup options bitfield (see <tt>BBS_OPT_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
157 158 159 160 161
	,"answer time, in <i>time_t</i> format"
	,"logon time, in <i>time_t</i> format"
	,"time from which user's time left is calculated, in <i>time_t</i> format"
	,"current file new-scan time, in <i>time_t</i> format"
	,"previous file new-scan time, in <i>time_t</i> format"
162
	,"online (see <tt>ON_*</tt> in <tt>sbbsdefs.js</tt> for valid values)"
163
	,"time left (in seconds)"
164
	,"time of next exclusive event (in <i>time_t</i> format), or 0 if none"
165
	,"internal code of next exclusive event"
166

167
	,"current node number"
168
	,"current node settings bitfield (see <tt>NM_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
169 170
	,"current node status value (see <tt>nodedefs.js</tt> for valid values)"
	,"current node error counter"
171
	,"current node action (see <tt>nodedefs.js</tt> for valid values)"
172 173 174 175 176
	,"current node user number (<i>useron</i> value)"
	,"current node connection type (see <tt>nodedefs.js</tt> for valid values)"
	,"current node misc value (see <tt>nodedefs.js</tt> for valid values)"
	,"current node aux value"
	,"current node extended aux (<i>extaux</i>) value"
177
	,"validation feedback user for this node (or 0 for no validation feedback required)"
178

179 180 181 182 183 184 185 186
	,"bytes uploaded during this session"
	,"bytes downloaded during this session"
	,"files uploaded during this session"
	,"files downloaded during this session"
	,"messages posted during this session"
	,"e-mails sent during this session"
	,"feedback messages sent during this session"
	,"messages read during this session"
187 188 189

	,"menu subdirectory (overrides default)"
	,"menu file (overrides default)"
190 191
	,"total main menu commands received from user during this session"
	,"total file menu commands received from user during this session"
192 193 194

	,"current message group"
	,"current message sub-board"
195
	,"current message sub-board internal code"
196 197
	,"current file library"
	,"current file directory"
198
	,"current file directory internal code"
199 200

	,"remote connection type"
201 202
	,"login name given during RLogin negotiation"
	,"password specified during RLogin negotiation"
deuce's avatar
deuce committed
203
	,"terminal specified during RLogin negotiation"
204 205
	,"client name"

206 207
	,"error level returned from last executed external program"

208
	/* READ ONLY */
209 210 211 212 213 214 215 216 217 218 219 220
	,"message group name of message being read"
	,"message group description of message being read"
	,"message group number of message being read"
	,"sub-board name of message being read"
	,"sub-board description of message being read"
	,"sub-board internal code of message being read"
	,"sub-board number of message being read"
	,"message base attributes"
	,"highest message number in message base"
	,"total number of messages in message base"
	,"number of messages loaded from message base"
	,"current message number in message base"
221 222

	/* READ ONLY */
223 224
	,"message recipient name"
	,"message recipient extension"
225
	,"message recipient network address"
226 227 228
	,"message recipient agent type"
	,"message sender name"
	,"message sender extension"
229
	,"message sender network address"
230
	,"message sender BBS ID"
231 232 233
	,"message sender agent type"
	,"message reply-to name"
	,"message reply-to extension"
234
	,"message reply-to network address"
235 236 237 238 239 240
	,"message reply-to agent type"
	,"message subject"
	,"message date/time"
	,"message time zone"
	,"message date/time imported"
	,"message attributes"
241
	,"message auxiliary attributes"
242 243
	,"message network attributes"
	,"message header offset"
244
	,"message number (unique, monotonically incrementing)"
245 246
	,"message expiration"
	,"message forwarded"
247 248
	,"message thread identifier (0 if unknown)"
	,"message thread, back message number"
249
	,"message thread, next message number"
250
	,"message thread, message number of first reply to this message"
251 252 253 254
	,"message identifier"
	,"message replied-to identifier"
	,"message delivery attempt counter"

255 256
	,"message header displayed at top-of-screen"

257 258 259 260 261 262 263 264 265 266 267 268
	,"file name"
	,"file description"
	,"file directory (number)"
	,"file attribute flags"
	,"file date"
	,"file size (in bytes)"
	,"file credit value"
	,"file uploader (user name)"
	,"file upload date"
	,"file last-download date"
	,"file download count"

269 270 271
	,"number of files in batch upload queue"
	,"number of files in batch download queue"

272
	,"current command shell/module <i>command string</i> value"
273
	,NULL
274 275 276
	};
#endif

277
extern JSClass js_bbs_class; // defined later
278
static sbbs_t *js_GetPrivate(JSContext *cx, JSObject *obj)
279
{
280
	return (sbbs_t *)js_GetClassPrivate(cx, obj, &js_bbs_class);
281 282
}

283
static JSBool js_bbs_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
284
{
285
	jsval idval;
286
	char		tmp[128];
287 288
	const char*	p=NULL;
	const char*	nulstr="";
289
	uint32		val=0;
290 291
    jsint       tiny;
	sbbs_t*		sbbs;
deuce's avatar
deuce committed
292
	jsrefcount	rc;
293

294
	if((sbbs=js_GetPrivate(cx, obj))==NULL)
295 296
		return(JS_FALSE);

297 298
    JS_IdToValue(cx, id, &idval);
    tiny = JSVAL_TO_INT(idval);
299 300

	switch(tiny) {
301 302 303 304 305 306 307
		case BBS_PROP_SYS_STATUS:
			val=sbbs->sys_status;
			break;
		case BBS_PROP_STARTUP_OPT:
			val=sbbs->startup->options;
			break;
		case BBS_PROP_ANSWER_TIME:
308
			val=(uint32)sbbs->answertime;
309 310
			break;
		case BBS_PROP_LOGON_TIME:
311
			val=(uint32)sbbs->logontime;
312
			break;
313
		case BBS_PROP_START_TIME:
314
			val=(uint32)sbbs->starttime;
315
			break;
316
		case BBS_PROP_NS_TIME:
317
			val=(uint32)sbbs->ns_time;
318 319
			break;
		case BBS_PROP_LAST_NS_TIME:
320
			val=(uint32)sbbs->last_ns_time;
321
			break;
322 323 324
		case BBS_PROP_ONLINE:
			val=sbbs->online;
			break;
325
		case BBS_PROP_TIMELEFT:
326
			rc=JS_SUSPENDREQUEST(cx);
327
			val=sbbs->gettimeleft(false);
328
			JS_RESUMEREQUEST(cx, rc);
329
			break;
330
		case BBS_PROP_EVENT_TIME:
331
			val=(uint32)sbbs->event_time;
332
			break;
333 334 335
		case BBS_PROP_EVENT_CODE:
			p=sbbs->event_code;
			break;
336 337 338

		case BBS_PROP_NODE_NUM:
			val=sbbs->cfg.node_num;
339
			break;
rswindell's avatar
rswindell committed
340
		case BBS_PROP_NODE_SETTINGS:
341
			val=sbbs->cfg.node_misc;
342
			break;
rswindell's avatar
rswindell committed
343
		case BBS_PROP_NODE_STATUS:
344
			val=sbbs->thisnode.status;
rswindell's avatar
rswindell committed
345 346
			break;
		case BBS_PROP_NODE_ERRORS:
347
			val=sbbs->thisnode.errors;
rswindell's avatar
rswindell committed
348
			break;
rswindell's avatar
rswindell committed
349 350 351
		case BBS_PROP_NODE_ACTION:
			val=sbbs->action;
			break;
rswindell's avatar
rswindell committed
352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
		case BBS_PROP_NODE_USERON:
			val=sbbs->thisnode.useron;
			break;
		case BBS_PROP_NODE_CONNECTION:
			val=sbbs->thisnode.connection;
			break;
		case BBS_PROP_NODE_MISC:
			val=sbbs->thisnode.misc;
			break;
		case BBS_PROP_NODE_AUX:
			val=sbbs->thisnode.aux;
			break;
		case BBS_PROP_NODE_EXTAUX:
			val=sbbs->thisnode.extaux;
			break;

368 369 370 371 372
		case BBS_PROP_NODE_VAL_USER:
			val=sbbs->cfg.node_valuser;
			break;

		case BBS_PROP_LOGON_ULB:
373
			val=(uint32_t)sbbs->logon_ulb;	// TODO: fix for > 4GB!
374 375
			break;
		case BBS_PROP_LOGON_DLB:
376
			val=(uint32_t)sbbs->logon_dlb;	// TODO: fix for > 4GB!
377 378
			break;
		case BBS_PROP_LOGON_ULS:
379
			val=(uint32_t)sbbs->logon_uls;	// TODO: fix for > 4GB!
380 381
			break;
		case BBS_PROP_LOGON_DLS:
382
			val=(uint32_t)sbbs->logon_dls;	// TODO: fix for > 4GB!
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398
			break;
		case BBS_PROP_LOGON_POSTS:
			val=sbbs->logon_posts;
			break;
		case BBS_PROP_LOGON_EMAILS:
			val=sbbs->logon_emails;
			break;
		case BBS_PROP_LOGON_FBACKS:
			val=sbbs->logon_fbacks;
			break;
		case BBS_PROP_POSTS_READ:
			val=sbbs->posts_read;
			break;

		case BBS_PROP_MENU_DIR:
			p=sbbs->menu_dir;
399
			break;
400 401
		case BBS_PROP_MENU_FILE:
			p=sbbs->menu_file;
402
			break;
403 404
		case BBS_PROP_MAIN_CMDS:
			val=sbbs->main_cmds;
405
			break;
rswindell's avatar
rswindell committed
406
		case BBS_PROP_FILE_CMDS:
407
			val=sbbs->xfer_cmds;
408
			break;
409 410 411 412 413 414 415 416

		case BBS_PROP_CURGRP:
			val=sbbs->curgrp;
			break;
		case BBS_PROP_CURSUB:
			if(sbbs->curgrp<sbbs->usrgrps)
				val=sbbs->cursub[sbbs->curgrp];
			break;
417 418 419
		case BBS_PROP_CURSUB_CODE:
			if(sbbs->cursubnum<sbbs->cfg.total_subs)
				p=sbbs->cfg.sub[sbbs->cursubnum]->code;
420 421
			else
				p=nulstr;
422 423
			break;

424 425 426 427 428 429 430
		case BBS_PROP_CURLIB:
			val=sbbs->curlib;
			break;
		case BBS_PROP_CURDIR:
			if(sbbs->curlib<sbbs->usrlibs)
				val=sbbs->curdir[sbbs->curlib];
			break;
431 432 433
		case BBS_PROP_CURDIR_CODE:
			if(sbbs->curdirnum<sbbs->cfg.total_dirs)
				p=sbbs->cfg.dir[sbbs->curdirnum]->code;
434 435
			else
				p=nulstr;
436
			break;
437

438 439
		case BBS_PROP_CONNECTION:
			p=sbbs->connection;
440
			break;
441 442 443
		case BBS_PROP_RLOGIN_NAME:
			p=sbbs->rlogin_name;
			break;
444 445 446
		case BBS_PROP_RLOGIN_PASS:
			p=sbbs->rlogin_pass;
			break;
447 448 449
		case BBS_PROP_RLOGIN_TERM:
			p=sbbs->rlogin_term;
			break;
450 451 452 453
		case BBS_PROP_CLIENT_NAME:
			p=sbbs->client_name;
			break;

454 455 456 457
		case BBS_PROP_ERRORLEVEL:
			val=sbbs->errorlevel;
			break;

458 459
		/* Currently Open Message Base (sbbs.smb) */
		case BBS_PROP_SMB_GROUP:
460
			if(sbbs->smb.subnum==INVALID_SUB || sbbs->smb.subnum>=sbbs->cfg.total_subs)
461 462 463 464 465
				p=nulstr;
			else
				p=sbbs->cfg.grp[sbbs->cfg.sub[sbbs->smb.subnum]->grp]->sname;
			break;
		case BBS_PROP_SMB_GROUP_DESC:
466
			if(sbbs->smb.subnum==INVALID_SUB || sbbs->smb.subnum>=sbbs->cfg.total_subs)
467 468 469 470 471 472 473 474 475 476 477 478 479 480
				p=nulstr;
			else
				p=sbbs->cfg.grp[sbbs->cfg.sub[sbbs->smb.subnum]->grp]->lname;
			break;
		case BBS_PROP_SMB_GROUP_NUM:
			if(sbbs->smb.subnum!=INVALID_SUB && sbbs->smb.subnum<sbbs->cfg.total_subs) {
				uint ugrp;
				for(ugrp=0;ugrp<sbbs->usrgrps;ugrp++)
					if(sbbs->usrgrp[ugrp]==sbbs->cfg.sub[sbbs->smb.subnum]->grp)
						break;
				val=ugrp+1;
			}
			break;
		case BBS_PROP_SMB_SUB:
481
			if(sbbs->smb.subnum==INVALID_SUB || sbbs->smb.subnum>=sbbs->cfg.total_subs)
482 483 484 485 486
				p=nulstr;
			else
				p=sbbs->cfg.sub[sbbs->smb.subnum]->sname;
			break;
		case BBS_PROP_SMB_SUB_DESC:
487
			if(sbbs->smb.subnum==INVALID_SUB || sbbs->smb.subnum>=sbbs->cfg.total_subs)
488 489 490 491 492
				p=nulstr;
			else
				p=sbbs->cfg.sub[sbbs->smb.subnum]->lname;
			break;
		case BBS_PROP_SMB_SUB_CODE:
493
			if(sbbs->smb.subnum==INVALID_SUB || sbbs->smb.subnum>=sbbs->cfg.total_subs)
494 495 496 497 498
				p=nulstr;
			else
				p=sbbs->cfg.sub[sbbs->smb.subnum]->code;
			break;
		case BBS_PROP_SMB_SUB_NUM:
499
			if(sbbs->usrsubs && sbbs->smb.subnum!=INVALID_SUB && sbbs->smb.subnum<sbbs->cfg.total_subs) {
500 501 502 503 504 505 506 507
				uint ugrp;
				for(ugrp=0;ugrp<sbbs->usrgrps;ugrp++)
					if(sbbs->usrgrp[ugrp]==sbbs->cfg.sub[sbbs->smb.subnum]->grp)
						break;
				uint usub;
				for(usub=0;usub<sbbs->usrsubs[ugrp];usub++)
					if(sbbs->usrsub[ugrp][usub]==sbbs->smb.subnum)
						break;
508
				val=usub+1;
509 510 511 512 513 514 515 516 517 518 519
			}
			break;
		case BBS_PROP_SMB_ATTR:
			val=sbbs->smb.status.attr;
			break;
		case BBS_PROP_SMB_LAST_MSG:
			val=sbbs->smb.status.last_msg;
			break;
		case BBS_PROP_SMB_TOTAL_MSGS:
			val=sbbs->smb.status.total_msgs;
			break;
520 521 522 523 524 525
		case BBS_PROP_SMB_MSGS:
			val=sbbs->smb.msgs;
			break;
		case BBS_PROP_SMB_CURMSG:
			val=sbbs->smb.curmsg;
			break;
526 527 528

		/* Currently Displayed Message Header (sbbs.current_msg) */
		case BBS_PROP_MSG_TO:
rswindell's avatar
rswindell committed
529
			if(sbbs->current_msg_to==NULL)
530 531
				p=nulstr;
			else
rswindell's avatar
rswindell committed
532
				p=sbbs->current_msg_to;
533 534
			break;
		case BBS_PROP_MSG_TO_EXT:
535
			if(sbbs->current_msg==NULL || sbbs->current_msg->to_ext==NULL)
536 537 538 539 540
				p=nulstr;
			else
				p=sbbs->current_msg->to_ext;
			break;
		case BBS_PROP_MSG_TO_NET:
541
			if(sbbs->current_msg==NULL || sbbs->current_msg->to_net.type==NET_NONE)
542 543
				p=nulstr;
			else
544
				p=smb_netaddrstr(&sbbs->current_msg->to_net,tmp);
545 546 547 548 549 550
			break;
		case BBS_PROP_MSG_TO_AGENT:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->to_agent;
			break;
		case BBS_PROP_MSG_FROM:
rswindell's avatar
rswindell committed
551
			if(sbbs->current_msg_from==NULL)
552 553
				p=nulstr;
			else
rswindell's avatar
rswindell committed
554
				p=sbbs->current_msg_from;
555 556
			break;
		case BBS_PROP_MSG_FROM_EXT:
557
			if(sbbs->current_msg==NULL || sbbs->current_msg->from_ext==NULL)
558 559 560 561 562
				p=nulstr;
			else
				p=sbbs->current_msg->from_ext;
			break;
		case BBS_PROP_MSG_FROM_NET:
563
			if(sbbs->current_msg==NULL || sbbs->current_msg->from_net.type==NET_NONE)
564 565
				p=nulstr;
			else
566
				p=smb_netaddrstr(&sbbs->current_msg->from_net,tmp);
567
			break;
568 569 570 571 572 573
		case BBS_PROP_MSG_FROM_BBSID:
			if(sbbs->current_msg == NULL || sbbs->current_msg->ftn_bbsid == NULL)
				p = nulstr;
			else // Should we return only the last ID of the QWKnet route here?
				p = sbbs->current_msg->ftn_bbsid;
			break;
574 575 576 577 578
		case BBS_PROP_MSG_FROM_AGENT:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->from_agent;
			break;
		case BBS_PROP_MSG_REPLYTO:
579
			if(sbbs->current_msg==NULL || sbbs->current_msg->replyto==NULL)
580 581 582 583 584
				p=nulstr;
			else
				p=sbbs->current_msg->replyto;
			break;
		case BBS_PROP_MSG_REPLYTO_EXT:
585
			if(sbbs->current_msg==NULL || sbbs->current_msg->replyto_ext==NULL)
586 587 588 589 590
				p=nulstr;
			else
				p=sbbs->current_msg->replyto_ext;
			break;
		case BBS_PROP_MSG_REPLYTO_NET:
591
			if(sbbs->current_msg==NULL || sbbs->current_msg->replyto_net.type==NET_NONE)
592 593
				p=nulstr;
			else
594
				p=smb_netaddrstr(&sbbs->current_msg->replyto_net,tmp);
595 596 597 598 599 600 601
			break;
		case BBS_PROP_MSG_REPLYTO_AGENT:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->replyto_agent;
			break;

		case BBS_PROP_MSG_SUBJECT:
rswindell's avatar
rswindell committed
602
			if(sbbs->current_msg_subj==NULL)
603 604
				p=nulstr;
			else
rswindell's avatar
rswindell committed
605
				p=sbbs->current_msg_subj;
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
			break;
		case BBS_PROP_MSG_DATE:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.when_written.time;
			break;
		case BBS_PROP_MSG_TIMEZONE:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.when_written.zone;
			break;
		case BBS_PROP_MSG_DATE_IMPORTED:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.when_imported.time;
			break;
		case BBS_PROP_MSG_ATTR:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.attr;
			break;
		case BBS_PROP_MSG_AUXATTR:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.auxattr;
			break;
		case BBS_PROP_MSG_NETATTR:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.netattr;
			break;
		case BBS_PROP_MSG_OFFSET:
			if(sbbs->current_msg!=NULL)
633
				val=sbbs->current_msg->idx_offset;
634 635 636 637 638 639 640
			break;
		case BBS_PROP_MSG_NUMBER:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.number;
			break;
		case BBS_PROP_MSG_EXPIRATION:
			if(sbbs->current_msg!=NULL)
641
				val=sbbs->current_msg->expiration;
642 643 644 645 646
			break;
		case BBS_PROP_MSG_FORWARDED:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->forwarded;
			break;
647 648 649 650
		case BBS_PROP_MSG_THREAD_ID:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.thread_id;
			break;
651
		case BBS_PROP_MSG_THREAD_BACK:
652
			if(sbbs->current_msg!=NULL)
653
				val=sbbs->current_msg->hdr.thread_back;
654 655 656 657 658 659 660 661 662 663 664 665 666
			break;
		case BBS_PROP_MSG_THREAD_NEXT:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.thread_next;
			break;
		case BBS_PROP_MSG_THREAD_FIRST:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.thread_first;
			break;
		case BBS_PROP_MSG_DELIVERY_ATTEMPTS:
			if(sbbs->current_msg!=NULL)
				val=sbbs->current_msg->hdr.delivery_attempts;
			break;
667 668 669 670 671 672 673 674 675 676 677 678
		case BBS_PROP_MSG_ID:
			if(sbbs->current_msg==NULL || sbbs->current_msg->id==NULL)
				p=nulstr;
			else
				p=sbbs->current_msg->id;
			break;
		case BBS_PROP_MSG_REPLY_ID:
			if(sbbs->current_msg==NULL || sbbs->current_msg->reply_id==NULL)
				p=nulstr;
			else
				p=sbbs->current_msg->reply_id;
			break;
679 680 681
		case BBS_PROP_MSGHDR_TOS:
			val = sbbs->msghdr_tos;
			break;
682

683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
		/* Currently Displayed File (sbbs.current_file) */
		case BBS_PROP_FILE_NAME:
			if(sbbs->current_file==NULL)
				p=nulstr;
			else
				p=sbbs->current_file->name;
			break;
		case BBS_PROP_FILE_DESC:
			if(sbbs->current_file==NULL)
				p=nulstr;
			else
				p=sbbs->current_file->desc;
			break;
		case BBS_PROP_FILE_ULER:
			if(sbbs->current_file==NULL)
				p=nulstr;
			else
700
				p=sbbs->current_file->from;
701 702 703 704 705
			break;
		case BBS_PROP_FILE_DATE:
			if(sbbs->current_file==NULL)
				p=nulstr;
			else
706
				val=(uint32)sbbs->current_file->time;
707 708 709 710 711
			break;
		case BBS_PROP_FILE_DATE_ULED:
			if(sbbs->current_file==NULL)
				p=nulstr;
			else
712
				val=sbbs->current_file->hdr.when_imported.time;
713 714 715 716 717
			break;
		case BBS_PROP_FILE_DATE_DLED:
			if(sbbs->current_file==NULL)
				p=nulstr;
			else
718
				val=sbbs->current_file->hdr.last_downloaded;
719 720 721 722 723
			break;
		case BBS_PROP_FILE_TIMES_DLED:
			if(sbbs->current_file==NULL)
				p=nulstr;
			else
724
				val=sbbs->current_file->hdr.times_downloaded;
725 726 727 728
			break;
		case BBS_PROP_FILE_SIZE:
			if(sbbs->current_file==NULL)
				p=nulstr;
729 730
			else // TODO: fix for 64-bit file sizes
				val=(uint32)sbbs->current_file->size;
731 732 733 734 735
			break;
		case BBS_PROP_FILE_CREDITS:
			if(sbbs->current_file==NULL)
				p=nulstr;
			else
736
				val=sbbs->current_file->cost;
737 738 739 740 741 742 743 744 745 746 747
			break;
		case BBS_PROP_FILE_DIR:
			if(sbbs->current_file==NULL)
				p=nulstr;
			else
				val=sbbs->current_file->dir;
			break;
		case BBS_PROP_FILE_ATTR:
			if(sbbs->current_file==NULL)
				p=nulstr;
			else
748
				val=sbbs->current_file->hdr.attr;
749 750
			break;

751
		case BBS_PROP_BATCH_UPLOAD_TOTAL:
752
			val = sbbs->batup_total();
753 754
			break;
		case BBS_PROP_BATCH_DNLOAD_TOTAL:
755
			val = sbbs->batdn_total();
756
			break;
757

758 759 760 761
		case BBS_PROP_COMMAND_STR:
			p=sbbs->main_csi.str;
			break;

762 763 764
		default:
			return(JS_TRUE);
	}
765 766 767 768 769 770
	if(p!=NULL) {
		JSString* js_str=JS_NewStringCopyZ(cx, p);
		if(js_str==NULL)
			return(JS_FALSE);
		*vp = STRING_TO_JSVAL(js_str);
	} else
771
		*vp = UINT_TO_JSVAL(val);
772 773 774 775

	return(JS_TRUE);
}

776
static JSBool js_bbs_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict, jsval *vp)
777
{
778
	jsval idval;
rswindell's avatar
rswindell committed
779
	char*		p=NULL;
780
	uint32		val=0;
781
    jsint       tiny;
rswindell's avatar
rswindell committed
782
	JSString*	js_str;
783 784
	sbbs_t*		sbbs;

785
	if((sbbs=js_GetPrivate(cx, obj))==NULL)
786 787
		return(JS_FALSE);

788 789
    JS_IdToValue(cx, id, &idval);
    tiny = JSVAL_TO_INT(idval);
790

791
	if(JSVAL_IS_NUMBER(*vp) || JSVAL_IS_BOOLEAN(*vp)) {
792
		if(!JS_ValueToECMAUint32(cx, *vp, &val))
793 794
			return(JS_FALSE);
	}
rswindell's avatar
rswindell committed
795 796 797
	else if(JSVAL_IS_STRING(*vp)) {
		if((js_str = JS_ValueToString(cx, *vp))==NULL)
			return(JS_FALSE);
deuce's avatar
deuce committed
798
		JSSTRING_TO_MSTRING(cx, js_str, p, NULL);
799
		HANDLE_PENDING(cx, p);
rswindell's avatar
rswindell committed
800
	}
801 802

	switch(tiny) {
803 804 805 806 807 808 809 810 811 812 813 814
		case BBS_PROP_SYS_STATUS:
			sbbs->sys_status=val;
			break;
		case BBS_PROP_STARTUP_OPT:
			sbbs->startup->options=val;
			break;
		case BBS_PROP_ANSWER_TIME:
			sbbs->answertime=val;
			break;
		case BBS_PROP_LOGON_TIME:
			sbbs->logontime=val;
			break;
815 816 817
		case BBS_PROP_START_TIME:
			sbbs->starttime=val;
			break;
818 819 820 821 822 823
		case BBS_PROP_NS_TIME:
			sbbs->ns_time=val;
			break;
		case BBS_PROP_LAST_NS_TIME:
			sbbs->last_ns_time=val;
			break;
824 825 826
		case BBS_PROP_ONLINE:
			sbbs->online=val;
			break;
rswindell's avatar
rswindell committed
827
		case BBS_PROP_NODE_SETTINGS:
828 829
			sbbs->cfg.node_misc=val;
			break;
rswindell's avatar
rswindell committed
830 831 832
		case BBS_PROP_NODE_ACTION:
			sbbs->action=(uchar)val;
			break;
833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852
		case BBS_PROP_NODE_VAL_USER:
			sbbs->cfg.node_valuser=(ushort)val;
			break;
		case BBS_PROP_LOGON_ULB:
			sbbs->logon_ulb=val;
			break;
		case BBS_PROP_LOGON_DLB:
			sbbs->logon_dlb=val;
			break;
		case BBS_PROP_LOGON_ULS:
			sbbs->logon_uls=val;
			break;
		case BBS_PROP_LOGON_DLS:
			sbbs->logon_dls=val;
			break;
		case BBS_PROP_LOGON_POSTS:
			sbbs->logon_posts=val;
			break;
		case BBS_PROP_LOGON_EMAILS:
			sbbs->logon_emails=val;
853
			break;
854 855
		case BBS_PROP_LOGON_FBACKS:
			sbbs->logon_fbacks=val;
856
			break;
857 858
		case BBS_PROP_POSTS_READ:
			sbbs->posts_read=val;
859
			break;
860
		case BBS_PROP_MENU_DIR:
Rob Swindell's avatar
Rob Swindell committed
861 862
			if(p != NULL)
				SAFECOPY(sbbs->menu_dir,p);
863
			break;
864
		case BBS_PROP_MENU_FILE:
Rob Swindell's avatar
Rob Swindell committed
865 866
			if(p != NULL)
				SAFECOPY(sbbs->menu_file,p);
867
			break;
868 869
		case BBS_PROP_MAIN_CMDS:
			sbbs->main_cmds=val;
870
			break;
rswindell's avatar
rswindell committed
871
		case BBS_PROP_FILE_CMDS:
872 873
			sbbs->xfer_cmds=val;
			break;
874 875

		case BBS_PROP_CURGRP:
876 877 878 879 880 881 882 883 884
			if(p!=NULL) {	/* set by name */
				uint i;
				for(i=0;i<sbbs->usrgrps;i++)
					if(!stricmp(sbbs->cfg.grp[sbbs->usrgrp[i]]->sname,p))
						break;
				if(i<sbbs->usrgrps)
					sbbs->curgrp=i;
				break;
			}
885 886 887 888
			if((uint)val<sbbs->cfg.total_grps && (uint)val<sbbs->usrgrps)
				sbbs->curgrp=val;
			break;
		case BBS_PROP_CURSUB:
889
		case BBS_PROP_CURSUB_CODE:
890 891 892 893 894 895
			if(p!=NULL) {	/* set by code */
				for(uint i=0;i<sbbs->usrgrps;i++)
					for(uint j=0;j<sbbs->usrsubs[i];j++)
						if(!stricmp(sbbs->cfg.sub[sbbs->usrsub[i][j]]->code,p)) {
							sbbs->curgrp=i;
							sbbs->cursub[i]=j;
896
							break;
897 898 899
						}
				break;
			}
900 901 902 903
			if(sbbs->curgrp<sbbs->cfg.total_grps && (uint)val<sbbs->usrsubs[sbbs->curgrp])
				sbbs->cursub[sbbs->curgrp]=val;
			break;
		case BBS_PROP_CURLIB:
904 905 906 907 908 909 910 911 912
			if(p!=NULL) {	/* set by name */
				uint i;
				for(i=0;i<sbbs->usrlibs;i++)
					if(!stricmp(sbbs->cfg.lib[sbbs->usrlib[i]]->sname,p))
						break;
				if(i<sbbs->usrlibs)
					sbbs->curlib=i;
				break;
			}
913 914 915 916
			if((uint)val<sbbs->cfg.total_libs && (uint)val<sbbs->usrlibs)
				sbbs->curlib=val;
			break;
		case BBS_PROP_CURDIR:
917
		case BBS_PROP_CURDIR_CODE:
918 919 920 921 922 923
			if(p!=NULL) {	/* set by code */
				for(uint i=0;i<sbbs->usrlibs;i++)
					for(uint j=0;j<sbbs->usrdirs[i];j++)
						if(!stricmp(sbbs->cfg.dir[sbbs->usrdir[i][j]]->code,p)) {
							sbbs->curlib=i;
							sbbs->curdir[i]=j;
924
							break;
925 926 927
						}
				break;
			}
928 929 930 931
			if(sbbs->curlib<sbbs->cfg.total_libs && (uint)val<sbbs->usrdirs[sbbs->curlib])
				sbbs->curdir[sbbs->curlib]=val;
			break;

932
		case BBS_PROP_RLOGIN_NAME:
Rob Swindell's avatar
Rob Swindell committed
933 934
			if(p != NULL)
				SAFECOPY(sbbs->rlogin_name,p);
935
			break;
936
		case BBS_PROP_RLOGIN_PASS:
Rob Swindell's avatar
Rob Swindell committed
937 938
			if(p != NULL)
				SAFECOPY(sbbs->rlogin_pass,p);
939
			break;
940
		case BBS_PROP_RLOGIN_TERM:
Rob Swindell's avatar
Rob Swindell committed
941 942
			if(p != NULL)
				SAFECOPY(sbbs->rlogin_term,p);
943
			break;
944
		case BBS_PROP_CLIENT_NAME:
Rob Swindell's avatar
Rob Swindell committed
945 946
			if(p != NULL)
				SAFECOPY(sbbs->client_name,p);
947
			break;
948

949
		case BBS_PROP_COMMAND_STR:
Rob Swindell's avatar
Rob Swindell committed
950 951
			if(p != NULL)
				sprintf(sbbs->main_csi.str, "%.*s", 1024, p);
952 953
			break;

954
		default:
deuce's avatar
deuce committed
955 956
			if(p)
				free(p);
957 958 959
			return(JS_TRUE);
	}

deuce's avatar
deuce committed
960 961 962
	if(p)
		free(p);

963 964 965 966
	if(sbbs->usrgrps)
		sbbs->cursubnum=sbbs->usrsub[sbbs->curgrp][sbbs->cursub[sbbs->curgrp]];		/* Used for ARS */
	else
		sbbs->cursubnum=INVALID_SUB;
967
	if(sbbs->usrlibs)
968
		sbbs->curdirnum=sbbs->usrdir[sbbs->curlib][sbbs->curdir[sbbs->curlib]];		/* Used for ARS */
969
	else
970 971
		sbbs->curdirnum=INVALID_DIR;

972 973 974
	return(JS_TRUE);
}

975
#define PROP_READONLY JSPROP_ENUMERATE|JSPROP_READONLY
976

977 978 979 980 981 982 983
static jsSyncPropertySpec js_bbs_properties[] = {
/*		 name				,tinyid					,flags				,ver	*/

	{	"sys_status"		,BBS_PROP_SYS_STATUS	,JSPROP_ENUMERATE	,310},
	{	"startup_options"	,BBS_PROP_STARTUP_OPT	,JSPROP_ENUMERATE	,310},
	{	"answer_time"		,BBS_PROP_ANSWER_TIME	,JSPROP_ENUMERATE	,310},
	{	"logon_time"		,BBS_PROP_LOGON_TIME	,JSPROP_ENUMERATE	,310},
984
	{	"start_time"		,BBS_PROP_START_TIME	,JSPROP_ENUMERATE	,314},