exec.cpp 46.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/* exec.cpp */

/* Synchronet command shell/module interpretter */

/* $Id$ */

/****************************************************************************
 * @format.tab-size 4		(Plain Text/Source Code File Header)			*
 * @format.use-tabs true	(see http://www.synchro.net/ptsc_hdr.html)		*
 *																			*
11
 * Copyright 2003 Rob Swindell - http://www.synchro.net/copyright.html		*
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
 *																			*
 * 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										*
 *																			*
 * Anonymous FTP access to the most recent released source is available at	*
 * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net	*
 *																			*
 * Anonymous CVS access to the development source and modification history	*
 * is available at cvs.synchro.net:/cvsroot/sbbs, example:					*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login			*
 *     (just hit return, no password is necessary)							*
 * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src		*
 *																			*
 * For Synchronet coding style and modification guidelines, see				*
 * http://www.synchro.net/source.html										*
 *																			*
 * You are encouraged to submit any modifications (preferably in Unix diff	*
 * format) via e-mail to mods@synchro.net									*
 *																			*
 * Note: If this box doesn't appear square, then you need to fix your tabs.	*
 ****************************************************************************/

#include "sbbs.h"
#include "cmdshell.h"

char ** sbbs_t::getstrvar(csi_t *bin, long name)
{
	uint i;

	if(sysvar_pi>=MAX_SYSVARS) sysvar_pi=0;
	switch(name) {
		case 0:
			return((char **)&(bin->str));
		case 0x490873f1:
			sysvar_p[sysvar_pi]=(char*)useron.alias;
			break;
		case 0x5de44e8b:
			sysvar_p[sysvar_pi]=(char*)useron.name;
			break;
		case 0x979ef1de:
			sysvar_p[sysvar_pi]=(char*)useron.handle;
			break;
		case 0xc8cd5fb7:
			sysvar_p[sysvar_pi]=(char*)useron.comp;
			break;
		case 0xcc7aca99:
			sysvar_p[sysvar_pi]=(char*)useron.note;
			break;
		case 0xa842c43b:
			sysvar_p[sysvar_pi]=(char*)useron.address;
			break;
		case 0x4ee1ff3a:
			sysvar_p[sysvar_pi]=(char*)useron.location;
			break;
		case 0xf000aa78:
			sysvar_p[sysvar_pi]=(char*)useron.zipcode;
			break;
		case 0xcdb7e4a9:
			sysvar_p[sysvar_pi]=(char*)useron.pass;
			break;
		case 0x94d59a7a:
			sysvar_p[sysvar_pi]=(char*)useron.birth;
			break;
		case 0xec2b8fb8:
			sysvar_p[sysvar_pi]=(char*)useron.phone;
			break;
		case 0x08f65a2a:
			sysvar_p[sysvar_pi]=(char*)useron.modem;
			break;
		case 0xc7e0e8ce:
			sysvar_p[sysvar_pi]=(char*)useron.netmail;
			break;
		case 0xd3606303:
			sysvar_p[sysvar_pi]=(char*)useron.tmpext;
			break;
		case 0x3178f9d6:
			sysvar_p[sysvar_pi]=(char*)useron.comment;
			break;

		case 0x41239e21:
			sysvar_p[sysvar_pi]=(char*)connection;
			break;
		case 0x90fc82b4:
			sysvar_p[sysvar_pi]=(char*)cid;
			break;
		case 0x15755030:
			return((char **)&comspec);
103
104
105
		case 0x5E049062:
			sysvar_p[sysvar_pi]=question;
			break;
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429

		case 0xf19cd046:
			sysvar_p[sysvar_pi]=(char*)wordwrap;
			break;

		default:
			if(bin->str_var && bin->str_var_name)
				for(i=0;i<bin->str_vars;i++)
					if(bin->str_var_name[i]==name)
						return((char **)&(bin->str_var[i]));
			if(global_str_var && global_str_var_name)
				for(i=0;i<global_str_vars;i++)
					if(global_str_var_name[i]==name)
						return(&(global_str_var[i]));
			return(NULL); }

	return((char **)&sysvar_p[sysvar_pi++]);
}

long * sbbs_t::getintvar(csi_t *bin, long name)
{
	uint i;

	if(sysvar_li>=MAX_SYSVARS) sysvar_li=0;
	switch(name) {
		case 0:
			sysvar_l[sysvar_li]=strtol((char*)bin->str,0,0);
			break;
		case 0x908ece53:
			sysvar_l[sysvar_li]=useron.number;
			break;
		case 0xdcedf626:
			sysvar_l[sysvar_li]=useron.uls;
			break;
		case 0xc1093f61:
			sysvar_l[sysvar_li]=useron.dls;
			break;
		case 0x2039a29f:
			sysvar_l[sysvar_li]=useron.posts;
			break;
		case 0x4a9f3955:
			sysvar_l[sysvar_li]=useron.emails;
			break;
		case 0x0c8dcf3b:
			sysvar_l[sysvar_li]=useron.fbacks;
			break;
		case 0x9a13bf95:
			sysvar_l[sysvar_li]=useron.etoday;
			break;
		case 0xc9082cbd:
			sysvar_l[sysvar_li]=useron.ptoday;
			break;
		case 0x7c72376d:
			sysvar_l[sysvar_li]=useron.timeon;
			break;
		case 0xac72c50b:
			sysvar_l[sysvar_li]=useron.textra;
			break;
		case 0x04807a11:
			sysvar_l[sysvar_li]=useron.logons;
			break;
		case 0x52996eab:
			sysvar_l[sysvar_li]=useron.ttoday;
			break;
		case 0x098bdfcb:
			sysvar_l[sysvar_li]=useron.tlast;
			break;
		case 0xbd1cee5d:
			sysvar_l[sysvar_li]=useron.ltoday;
			break;
		case 0x07954570:
			sysvar_l[sysvar_li]=useron.xedit;
			break;
		case 0xedf6aa98:
			sysvar_l[sysvar_li]=useron.shell;
			break;
		case 0x328ed476:
			sysvar_l[sysvar_li]=useron.level;
			break;
		case 0x9e70e855:
			sysvar_l[sysvar_li]=useron.sex;
			break;
		case 0x094cc42c:
			sysvar_l[sysvar_li]=useron.rows;
			break;
		case 0xabc4317e:
			sysvar_l[sysvar_li]=useron.prot;
			break;
		case 0x7dd9aac0:
			sysvar_l[sysvar_li]=useron.leech;
			break;
		case 0x7c602a37:
			return((long *)&useron.misc);
		case 0x61be0d36:
			return((long *)&useron.qwk);
		case 0x665ac227:
			return((long *)&useron.chat);
		case 0x951341ab:
			return((long *)&useron.flags1);
		case 0x0c1a1011:
			return((long *)&useron.flags2);
		case 0x7b1d2087:
			return((long *)&useron.flags3);
		case 0xe579b524:
			return((long *)&useron.flags4);
		case 0x12e7d6d2:
			return((long *)&useron.exempt);
		case 0xfed3115d:
			return((long *)&useron.rest);
		case 0xb65dd6d4:
			return((long *)&useron.ulb);
		case 0xabb91f93:
			return((long *)&useron.dlb);
		case 0x92fb364f:
			return((long *)&useron.cdt);
		case 0xd0a99c72:
			return((long *)&useron.min);
		case 0xd7ae3022:
			return((long *)&useron.freecdt);
		case 0x1ef214ef:
			return((long *)&useron.firston);
		case 0x0ea515b1:
			return((long *)&useron.laston);
		case 0x2aaf9bd3:
			return((long *)&useron.expire);
		case 0x89c91dc8:
			return((long *)&useron.pwmod);
		case 0x5b0d0c54:
			return((long *)&useron.ns_time);

		case 0xae256560:
			return((long *)&cur_rate);
		case 0x2b3c257f:
			return((long *)&cur_cps);
		case 0x1c4455ee:
			return((long *)&dte_rate);
		case 0x7fbf958e:
			return((long *)&lncntr);
		case 0x5c1c1500:
			return((long *)&tos);
		case 0x613b690e:
			return((long *)&rows);
		case 0x205ace36:
			return((long *)&autoterm);
		case 0x7d0ed0d1:
			return((long *)&console);
		case 0xbf31a280:
			return((long *)&answertime);
		case 0x83aa2a6a:
			return((long *)&logontime);
		case 0xb50cb889:
			return((long *)&ns_time);
		case 0xae92d249:
			return((long *)&last_ns_time);
		case 0x97f99eef:
			return((long *)&online);
		case 0x381d3c2a:
			return((long *)&sys_status);
		case 0x7e29c819:
			return((long *)&cfg.sys_misc);
		case 0x11c83294:
			return((long *)&cfg.sys_psnum);
		case 0x02408dc5:
			sysvar_l[sysvar_li]=cfg.sys_timezone;
			break;
		case 0x78afeaf1:
			sysvar_l[sysvar_li]=cfg.sys_pwdays;
			break;
		case 0xd859385f:
			sysvar_l[sysvar_li]=cfg.sys_deldays;
			break;
		case 0x6392dc62:
			sysvar_l[sysvar_li]=cfg.sys_autodel;
			break;
		case 0x698d59b4:
			sysvar_l[sysvar_li]=cfg.sys_nodes;
			break;
		case 0x6fb1c46e:
			sysvar_l[sysvar_li]=cfg.sys_exp_warn;
			break;
		case 0xdf391ca7:
			sysvar_l[sysvar_li]=cfg.sys_lastnode;
			break;
		case 0xdd982780:
			sysvar_l[sysvar_li]=cfg.sys_autonode;
			break;
		case 0xf53db6c7:
			sysvar_l[sysvar_li]=cfg.node_scrnlen;
			break;
		case 0xa1f0fcb7:
			sysvar_l[sysvar_li]=cfg.node_scrnblank;
			break;
		case 0x709c07da:
			return((long *)&cfg.node_misc);
		case 0xb17e7914:
			sysvar_l[sysvar_li]=cfg.node_valuser;
			break;
		case 0xadae168a:
			sysvar_l[sysvar_li]=cfg.node_ivt;
			break;
		case 0x2aa89801:
			sysvar_l[sysvar_li]=cfg.node_swap;
			break;
		case 0x4f02623a:
			sysvar_l[sysvar_li]=cfg.node_minbps;
			break;
		case 0xe7a7fb07:
			sysvar_l[sysvar_li]=cfg.node_num;
			break;
		case 0x6c8e350a:
			sysvar_l[sysvar_li]=cfg.new_level;
			break;
		case 0xccfe7c5d:
			return((long *)&cfg.new_flags1);
		case 0x55f72de7:
			return((long *)&cfg.new_flags2);
		case 0x22f01d71:
			return((long *)&cfg.new_flags3);
		case 0xbc9488d2:
			return((long *)&cfg.new_flags4);
		case 0x4b0aeb24:
			return((long *)&cfg.new_exempt);
		case 0x20cb6325:
			return((long *)&cfg.new_rest);
		case 0x31178ba2:
			return((long *)&cfg.new_cdt);
		case 0x7345219f:
			return((long *)&cfg.new_min);
		case 0xb3f64be4:
			sysvar_l[sysvar_li]=cfg.new_shell;
			break;
		case 0xa278584f:
			return((long *)&cfg.new_misc);
		case 0x7342a625:
			sysvar_l[sysvar_li]=cfg.new_expire;
			break;
		case 0x75dc4306:
			sysvar_l[sysvar_li]=cfg.new_prot;
			break;
		case 0xfb394e27:
			sysvar_l[sysvar_li]=cfg.expired_level;
			break;
		case 0x89b69753:
			return((long *)&cfg.expired_flags1);
		case 0x10bfc6e9:
			return((long *)&cfg.expired_flags2);
		case 0x67b8f67f:
			return((long *)&cfg.expired_flags3);
		case 0xf9dc63dc:
			return((long *)&cfg.expired_flags4);
		case 0x0e42002a:
			return((long *)&cfg.expired_exempt);
		case 0x4569c62e:
			return((long *)&cfg.expired_rest);
		case 0xfcf3542e:
			sysvar_l[sysvar_li]=cfg.min_dspace;
			break;
		case 0xcf9ce02c:
			sysvar_l[sysvar_li]=cfg.cdt_min_value;
			break;
		case 0xfcb5b274:
			return((long *)&cfg.cdt_per_dollar);
		case 0x4db200d2:
			sysvar_l[sysvar_li]=cfg.leech_pct;
			break;
		case 0x9a7d9cca:
			sysvar_l[sysvar_li]=cfg.leech_sec;
			break;
		case 0x396b7167:
			return((long *)&cfg.netmail_cost);
		case 0x5eeaff21:
			sysvar_l[sysvar_li]=cfg.netmail_misc;
			break;
		case 0x82d9484e:
			return((long *)&cfg.inetmail_cost);
		case 0xe558c608:
			return((long *)&cfg.inetmail_misc);

		case 0xc6e8539d:
			return((long *)&logon_ulb);
		case 0xdb0c9ada:
			return((long *)&logon_dlb);
		case 0xac58736f:
			return((long *)&logon_uls);
		case 0xb1bcba28:
			return((long *)&logon_dls);
		case 0x9c5051c9:
			return((long *)&logon_posts);
		case 0xc82ba467:
			return((long *)&logon_emails);
		case 0x8e395209:
			return((long *)&logon_fbacks);
		case 0x8b12ba9d:
			return((long *)&posts_read);
		case 0xe51c1956:
			sysvar_l[sysvar_li]=(ulong)logfile_fp;
			break;
		case 0x5a22d4bd:
			sysvar_l[sysvar_li]=(ulong)nodefile_fp;
			break;
		case 0x3a37c26b:
			sysvar_l[sysvar_li]=(ulong)node_ext_fp;
			break;

		case 0xeb6c9c73:
			sysvar_l[sysvar_li]=errorlevel;
			break;

		case 0x5aaccfc5:
			sysvar_l[sysvar_li]=errno;
			break;

		case 0x057e4cd4:
			sysvar_l[sysvar_li]=timeleft;
			break;

		case 0x1e5052a7:
			return((long *)&cfg.max_minutes);
		case 0xedc643f1:
			return((long *)&cfg.max_qwkmsgs);

		case 0x430178ec:
			return((long *)&cfg.uq);

430
431
432
433
434
435
436
		case 0x455CB929:
			return(&bin->ftp_mode);

		case 0x2105D2B9:
			return(&bin->socket_error);

		case 0xA0023A2E:
437
			return((long *)&startup->options);
438
439
440
441
442

		case 0x16E2585F:
			sysvar_l[sysvar_li]=client_socket;
			break;

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
		default:
			if(bin->int_var && bin->int_var_name)
				for(i=0;i<bin->int_vars;i++)
					if(bin->int_var_name[i]==name)
						return(&bin->int_var[i]);
			if(global_int_var && global_int_var_name)
				for(i=0;i<global_int_vars;i++)
					if(global_int_var_name[i]==name)
						return(&global_int_var[i]);
			return(NULL); }

	return(&sysvar_l[sysvar_li++]);
}

void sbbs_t::clearvars(csi_t *bin)
{
	bin->str_vars=0;
	bin->str_var=NULL;
	bin->str_var_name=NULL;
	bin->int_vars=0;
	bin->int_var=NULL;
	bin->int_var_name=NULL;
	bin->files=0;
466
467
	bin->loops=0;
	bin->sockets=0;
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
	bin->retval=0;
}

void sbbs_t::freevars(csi_t *bin)
{
	uint i;

	if(bin->str_var) {
		for(i=0;i<bin->str_vars;i++)
			if(bin->str_var[i])
				FREE(bin->str_var[i]);
		FREE(bin->str_var); 
	}
	if(bin->int_var)
		FREE(bin->int_var);
	if(bin->str_var_name)
		FREE(bin->str_var_name);
	if(bin->int_var_name)
		FREE(bin->int_var_name);
	for(i=0;i<bin->files;i++) {
		if(bin->file[i]) {
			fclose((FILE *)bin->file[i]);
			bin->file[i]=0; 
		}
	}
493
494
495
496
497
498
	for(i=0;i<bin->sockets;i++) {
		if(bin->socket[i]) {
			close_socket((SOCKET)bin->socket[i]);
			bin->socket[i]=0; 
		}
	}
499
500
501
502
503
504
505
506
507
}

/****************************************************************************/
/* Copies a new value (str) into the string variable pointed to by p		*/
/* re-allocating if necessary												*/
/****************************************************************************/
char * sbbs_t::copystrvar(csi_t *csi, char *p, char *str)
{
	char *np;	/* New pointer after realloc */
508
	int i=0;
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524

	if(p!=csi->str) {
		if(p)
			for(i=0;i<MAX_SYSVARS;i++)
				if(p==sysvar_p[i])
					break;
		if(!p || i==MAX_SYSVARS) {		/* Not system variable */
			if((np=(char*)REALLOC(p,strlen(str)+1))==NULL)
				errormsg(WHERE,ERR_ALLOC,"variable",strlen(str)+1);
			else
				p=np; } }
	if(p)
		strcpy(p,str);
	return(p);
}

rswindell's avatar
rswindell committed
525
#ifdef JAVASCRIPT
526

527
528
529
530
531
532
533
534
static JSBool
js_BranchCallback(JSContext *cx, JSScript *script)
{
	sbbs_t*		sbbs;

	if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL)
		return(JS_FALSE);

535
	sbbs->js_branch.counter++;
536

537
538
539
	/* Terminated? */
	if(sbbs->terminated) {
		JS_ReportError(cx,"Terminated");
540
		sbbs->js_branch.counter=0;
541
542
543
		return(JS_FALSE);
	}
	/* Infinite loop? */
544
545
546
	if(sbbs->js_branch.limit && sbbs->js_branch.counter>sbbs->js_branch.limit) {
		JS_ReportError(cx,"Infinite loop (%lu branches) detected",sbbs->js_branch.counter);
		sbbs->js_branch.counter=0;
547
548
549
		return(JS_FALSE);
	}
	/* Give up timeslices every once in a while */
550
	if(sbbs->js_branch.yield_freq && (sbbs->js_branch.counter%sbbs->js_branch.yield_freq)==0)
551
		YIELD();
552

553
	if(sbbs->js_branch.gc_freq && (sbbs->js_branch.counter%sbbs->js_branch.gc_freq)==0)
554
555
		JS_MaybeGC(cx);

556
557
558
    return(JS_TRUE);
}

559
560
561
562
563
564
565
static const char* js_ext(const char* fname)
{
	if(strchr(fname,'.')==NULL)
		return(".js");
	return("");
}

566
long sbbs_t::js_execfile(const char *cmd)
rswindell's avatar
rswindell committed
567
{
568
569
570
571
572
	char*		p;
	char*		args=NULL;
	char*		fname;
	int			argc=0;
	char		cmdline[MAX_PATH+1];
rswindell's avatar
rswindell committed
573
	char		path[MAX_PATH+1];
574
575
	JSObject*	js_scope=NULL;
	JSScript*	js_script=NULL;
rswindell's avatar
rswindell committed
576
	jsval		rval;
577
	int32		result=0;
rswindell's avatar
rswindell committed
578
	
579
580
581
582
583
584
	if(js_cx==NULL) {
		errormsg(WHERE,ERR_CHK,"JavaScript support",0);
		errormsg(WHERE,ERR_EXEC,cmd,0);
		return(-1);
	}

585
	SAFECOPY(cmdline,cmd);
586
587
588
589
590
591
592
	p=strchr(cmdline,' ');
	if(p!=NULL) {
		*p=0;
		args=p+1;
	}
	fname=cmdline;

593
	if(strcspn(fname,"/\\")==strlen(fname)) {
594
		sprintf(path,"%s%s%s",cfg.mods_dir,fname,js_ext(fname));
595
		if(cfg.mods_dir[0]==0 || !fexistcase(path))
596
			sprintf(path,"%s%s%s",cfg.exec_dir,fname,js_ext(fname));
597
	} else
598
		sprintf(path,"%s%s",fname,js_ext(fname));
rswindell's avatar
rswindell committed
599

600
	if(!fexistcase(path)) {
rswindell's avatar
rswindell committed
601
602
603
604
		errormsg(WHERE,ERR_OPEN,path,O_RDONLY);
		return(-1); 
	}

605
	js_scope=JS_NewObject(js_cx, NULL, NULL, js_glob);
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629

	if(js_scope!=NULL) {

		JSObject* argv=JS_NewArrayObject(js_cx, 0, NULL);

		if(args!=NULL && argv!=NULL) {
			while(*args) {
				p=strchr(args,' ');
				if(p!=NULL)
					*p=0;
				while(*args && *args==' ') args++; /* Skip spaces */
				JSString* arg = JS_NewStringCopyZ(js_cx, args);
				if(arg==NULL)
					break;
				jsval val=STRING_TO_JSVAL(arg);
				if(!JS_SetElement(js_cx, argv, argc, &val))
					break;
				argc++;
				if(p==NULL)	/* last arg */
					break;
				args+=(strlen(args)+1);
			}
		}
		JS_DefineProperty(js_cx, js_scope, "argv", OBJECT_TO_JSVAL(argv)
630
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
631
		JS_DefineProperty(js_cx, js_scope, "argc", INT_TO_JSVAL(argc)
632
			,NULL,NULL,JSPROP_READONLY|JSPROP_ENUMERATE);
633

634
635
		JS_ClearPendingException(js_cx);

636
637
		js_script=JS_CompileFile(js_cx, js_scope, path);
	}
638

639
	if(js_scope==NULL || js_script==NULL) {
rswindell's avatar
rswindell committed
640
641
642
643
		errormsg(WHERE,ERR_EXEC,path,0);
		return(-1);
	}

644
	js_branch.counter=0;	// Reset loop counter
645

646
647
	JS_SetBranchCallback(js_cx, js_BranchCallback);

648
	JS_ExecuteScript(js_cx, js_scope, js_script, &rval);
rswindell's avatar
rswindell committed
649

650
651
	JS_GetProperty(js_cx, js_glob, "exit_code", &rval);

rswindell's avatar
rswindell committed
652
653
	JS_DestroyScript(js_cx, js_script);

654
655
	JS_ClearScope(js_cx, js_scope);

656
657
	JS_GC(js_cx);

658
659
660
661
	if(rval!=JSVAL_VOID)
		JS_ValueToInt32(js_cx,rval,&result);
		
	return(result);
rswindell's avatar
rswindell committed
662
663
664
}
#endif

665
666
667

long sbbs_t::exec_bin(char *mod, csi_t *csi)
{
rswindell's avatar
rswindell committed
668
    char    str[MAX_PATH+1];
669
	char	modname[MAX_PATH+1];
670
671
672
	int 	file;
    csi_t   bin;

rswindell's avatar
rswindell committed
673
#ifdef JAVASCRIPT
674
	if(cfg.mods_dir[0]) {
675
		sprintf(str,"%s%s.js",cfg.mods_dir,mod);
676
		if(fexistcase(str)) 
677
678
			return(js_execfile(str));
	}
679
	sprintf(str,"%s%s.js",cfg.exec_dir,mod);
680
	if(fexistcase(str)) 
rswindell's avatar
rswindell committed
681
682
683
		return(js_execfile(str));
#endif

684
685
686
	memcpy(&bin,csi,sizeof(csi_t));
	clearvars(&bin);

687
688
689
690
691
	SAFECOPY(modname,mod);
	if(!strchr(modname,'.'))
		strcat(modname,".bin");

	sprintf(str,"%s%s",cfg.mods_dir,modname);
692
	if(cfg.mods_dir[0]==0 || !fexistcase(str)) {
693
		sprintf(str,"%s%s",cfg.exec_dir,modname);
694
695
		fexistcase(str);
	}
696
697
	if((file=nopen(str,O_RDONLY))==-1) {
		errormsg(WHERE,ERR_OPEN,str,O_RDONLY);
698
699
		return(-1); 
	}
700
701
702
703
704

	bin.length=filelength(file);
	if((bin.cs=(uchar *)MALLOC(bin.length))==NULL) {
		close(file);
		errormsg(WHERE,ERR_ALLOC,str,bin.length);
705
706
		return(-1); 
	}
707
708
709
710
	if(lread(file,bin.cs,bin.length)!=bin.length) {
		close(file);
		errormsg(WHERE,ERR_READ,str,bin.length);
		FREE(bin.cs);
711
712
		return(-1); 
	}
713
714
715
716
717
718
719
720
721
722
723
	close(file);

	bin.ip=bin.cs;
	bin.rets=0;
	bin.cmdrets=0;
	bin.misc=0;

	while(exec(&bin)==0)
		if(!(bin.misc&CS_OFFLINE_EXEC)) {
			checkline();
			if(!online)
724
725
				break; 
		}
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803

	freevars(&bin);
	FREE(bin.cs);
	csi->logic=bin.logic;
	return(bin.retval);
}

/****************************************************************************/
/* Skcsi->ip to a specific instruction                                           */
/****************************************************************************/
void sbbs_t::skipto(csi_t *csi, uchar inst)
{
	int i,j;

	while(csi->ip<csi->cs+csi->length && ((inst&0x80) || *csi->ip!=inst)) {

		if(*csi->ip==CS_IF_TRUE || *csi->ip==CS_IF_FALSE
			|| (*csi->ip>=CS_IF_GREATER && *csi->ip<=CS_IF_LESS_OR_EQUAL)) {
			csi->ip++;
			skipto(csi,CS_ENDIF);
			csi->ip++;
			continue; }

		if(inst==CS_ELSEORENDIF
			&& (*csi->ip==CS_ELSE || *csi->ip==CS_ENDIF))
			break;

		if(inst==CS_NEXTCASE
			&& (*csi->ip==CS_CASE || *csi->ip==CS_DEFAULT
				|| *csi->ip==CS_END_SWITCH))
			break;

		if(*csi->ip==CS_SWITCH) {
			csi->ip++;
			csi->ip+=4; /* Skip variable name */
			skipto(csi,CS_END_SWITCH);
			csi->ip++;
			continue; }

		if(*csi->ip==CS_CASE) {
			csi->ip++;
			csi->ip+=4; /* Skip value */
			skipto(csi,CS_NEXTCASE);
			continue; }

		if(*csi->ip==CS_CMDKEY || *csi->ip==CS_CMDCHAR) {
			csi->ip+=2;
			skipto(csi,CS_END_CMD);
			csi->ip++;
			continue; }
		if(*csi->ip==CS_CMDSTR || *csi->ip==CS_CMDKEYS) {
			csi->ip++;              /* skip inst */
			while(*(csi->ip++));    /* skip string */
			skipto(csi,CS_END_CMD);
			csi->ip++;
			continue; }

		if(*csi->ip>=CS_FUNCTIONS) {
			csi->ip++;
			continue; }

		if(*csi->ip>=CS_MISC) {
			switch(*csi->ip) {
				case CS_VAR_INSTRUCTION:
					csi->ip++;
					switch(*(csi->ip++)) {
						case SHOW_VARS:
							continue;
						case PRINT_VAR:
						case DEFINE_STR_VAR:
						case DEFINE_INT_VAR:
						case DEFINE_GLOBAL_STR_VAR:
						case DEFINE_GLOBAL_INT_VAR:
						case TIME_INT_VAR:
						case STRUPR_VAR:
						case STRLWR_VAR:
						case TRUNCSP_STR_VAR:
						case CHKFILE_VAR:
804
						case COPY_CHAR:
805
806
807
808
809
810
811
812
813
814
815
						case STRIP_CTRL_STR_VAR:
							csi->ip+=4; /* Skip variable name */
							continue;
						case GETSTR_VAR:
						case GETNAME_VAR:
						case GETLINE_VAR:
						case GETSTRUPR_VAR:
						case SHIFT_STR_VAR:
						case SEND_FILE_VIA_VAR:
						case RECEIVE_FILE_VIA_VAR:
						case COMPARE_FIRST_CHAR:
816
817
						case SHIFT_TO_FIRST_CHAR:
						case SHIFT_TO_LAST_CHAR:
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
							csi->ip+=4; /* Skip variable name */
							csi->ip++;	/* Skip char */
							continue;
						case PRINTTAIL_VAR_MODE:
							csi->ip++;	/* Skip length */
						case PRINTFILE_VAR_MODE:
						case GETNUM_VAR:
							csi->ip+=4; /* Skip variable name */
							csi->ip+=2;  /* Skip max num */
							continue;
						case STRNCMP_VAR:
							csi->ip++;	/* Skip length */
						case SET_STR_VAR:
						case COMPARE_STR_VAR:
						case CAT_STR_VAR:
						case STRSTR_VAR:
						case TELNET_GATE_STR:
							csi->ip+=4; /* Skip variable name */
							while(*(csi->ip++));	/* skip string */
							continue;
						case FORMAT_TIME_STR:
							csi->ip+=4; /* Skip destination variable */
							while(*(csi->ip++));	/* Skip string */
							csi->ip+=4; /* Skip int variable */
							continue;
						case FORMAT_STR_VAR:	/* SPRINTF */
							csi->ip+=4; /* Skip destination variable */
						case VAR_PRINTF:
rswindell's avatar
rswindell committed
846
						case VAR_PRINTF_LOCAL:
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
							while(*(csi->ip++));	/* Skip string */
							j=*(csi->ip++); /* Skip number of arguments */
							for(i=0;i<j;i++)
								csi->ip+=4; /* Skip arguments */
							continue;
						case SEND_FILE_VIA:
						case RECEIVE_FILE_VIA:
							csi->ip++;				/* Skip prot */
							while(*(csi->ip++));	/* Skip filepath */
							continue;
						case GETSTR_MODE:
						case STRNCMP_VARS:
							csi->ip++;	/* Skip length */
						default:
							csi->ip+=8; /* Skip two variable names or var & val */
							continue; }

				case CS_FIO_FUNCTION:
					csi->ip++;
					switch(*(csi->ip++)) {
						case FIO_OPEN:
							csi->ip+=4; 			/* File handle */
							csi->ip+=2; 			/* Access */
							while(*(csi->ip++));	/* path/filename */
							continue;
						case FIO_CLOSE:
						case FIO_FLUSH:
						case FIO_EOF:
						case REMOVE_FILE:
						case REMOVE_DIR:
						case CHANGE_DIR:
						case MAKE_DIR:
						case REWIND_DIR:
						case CLOSE_DIR:
							csi->ip+=4; 			/* File handle */
							continue;
						case FIO_SET_ETX:
							csi->ip++;
							continue;
						case FIO_PRINTF:
							csi->ip+=4; 			/* File handle */
							while(*(csi->ip++));	/* String */
							j=*(csi->ip++); 		/* Number of arguments */
							for(i=0;i<j;i++)
								csi->ip+=4; 		/* Arguments */
							continue;
						case FIO_READ:
						case FIO_WRITE:
						case FIO_SEEK:
						case FIO_SEEK_VAR:
						case FIO_OPEN_VAR:
							csi->ip+=4; 			/* File handle */
							csi->ip+=4; 			/* Variable */
							csi->ip+=2; 			/* Length/access */
							continue;
						case FIO_READ_VAR:
						case FIO_WRITE_VAR:
							csi->ip+=4; 			/* File handle */
							csi->ip+=4; 			/* Buf Variable */
							csi->ip+=4; 			/* Length Variable */
							continue;
						default:
							csi->ip+=4;             /* File handle */
							csi->ip+=4;             /* Variable */
							continue; }

913
914
915
916
917
918
919
920
921
922
923
924
925
				case CS_NET_FUNCTION:
					csi->ip++;
					switch(*(csi->ip++)) {
						case CS_SOCKET_CONNECT:
							csi->ip+=4;				/* socket */
							csi->ip+=4;				/* address */
							csi->ip+=2;				/* port */
							continue;
						case CS_SOCKET_NREAD:
							csi->ip+=4;				/* socket */
							csi->ip+=4;				/* intvar */
							continue;
						case CS_SOCKET_READ:
926
						case CS_SOCKET_READLINE:
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
						case CS_SOCKET_PEEK:
							csi->ip+=4;				/* socket */
							csi->ip+=4;				/* buffer */
							csi->ip+=2;				/* length */
							continue;
						case CS_SOCKET_WRITE:
							csi->ip+=4;				/* socket */
							csi->ip+=4;				/* strvar */
							continue;

						case CS_FTP_LOGIN:
						case CS_FTP_GET:
						case CS_FTP_PUT:
						case CS_FTP_RENAME:
							csi->ip+=4;				/* socket */
							csi->ip+=4;				/* username/path */
							csi->ip+=4;				/* password/path */
							continue;
						case CS_FTP_DIR:
						case CS_FTP_CWD:
						case CS_FTP_DELETE:
							csi->ip+=4;				/* socket */
							csi->ip+=4;				/* path */
							continue;

						default:
							csi->ip+=4;				/* socket */
							continue; }

956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
				case CS_COMPARE_ARS:
					csi->ip++;
					csi->ip+=(*csi->ip);
					csi->ip++;
					break;
				case CS_TOGGLE_USER_MISC:
				case CS_COMPARE_USER_MISC:
				case CS_TOGGLE_USER_CHAT:
				case CS_COMPARE_USER_CHAT:
				case CS_TOGGLE_USER_QWK:
				case CS_COMPARE_USER_QWK:
					csi->ip+=5;
					break;
				case CS_REPLACE_TEXT:
					csi->ip+=3;     /* skip inst and text # */
					while(*(csi->ip++));    /* skip string */
					break;
				case CS_USE_INT_VAR:
					csi->ip+=7; // inst, var, offset, len
					break;
				default:
					csi->ip++; }
			continue; }

		if(*csi->ip==CS_ONE_MORE_BYTE) {
981
982
983
			if(inst==CS_END_LOOP && *(csi->ip+1)==CS_END_LOOP)
				break;

984
985
			csi->ip++;				/* skip extension */
			csi->ip++;				/* skip instruction */
986
987
988
989
990
991

			if(*(csi->ip-1)==CS_LOOP_BEGIN) {	/* nested loop */
				skipto(csi,CS_END_LOOP);
				csi->ip+=2;
			}

992
993
994
995
996
997
998
999
1000
			continue; }

		if(*csi->ip==CS_TWO_MORE_BYTES) {
			csi->ip++;				/* skip extension */
			csi->ip++;				/* skip instruction */
			csi->ip++;				/* skip argument */
			continue; }

		if(*csi->ip==CS_THREE_MORE_BYTES) {
For faster browsing, not all history is shown. View entire blame