|
|
1.1 root 1: /* js_global.c */
2:
3: /* Synchronet JavaScript "global" object properties/methods for all servers */
4:
5: /* $Id: js_global.c,v 1.141 2004/12/31 02:39:19 rswindell Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This program is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU General Public License for more details: gpl.txt or *
18: * http://www.fsf.org/copyleft/gpl.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #define JS_THREADSAFE /* needed for JS_SetContextThread */
39:
40: #include "sbbs.h"
41: #include "md5.h"
42: #include "base64.h"
43: #include "htmlansi.h"
44: #include "ini_file.h"
45:
46: #define MAX_ANSI_SEQ 16
47: #define MAX_ANSI_PARAMS 8
48:
49: #ifdef JAVASCRIPT
50:
51: /* Global Object Properites */
52: enum {
53: GLOB_PROP_ERRNO
54: ,GLOB_PROP_ERRNO_STR
55: };
56:
57: static JSBool js_system_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
58: {
59: jsint tiny;
60: JSString* js_str;
61:
62: tiny = JSVAL_TO_INT(id);
63:
64: switch(tiny) {
65: case GLOB_PROP_ERRNO:
66: JS_NewNumberValue(cx,errno,vp);
67: break;
68: case GLOB_PROP_ERRNO_STR:
69: if((js_str=JS_NewStringCopyZ(cx, strerror(errno)))==NULL)
70: return(JS_FALSE);
71: *vp = STRING_TO_JSVAL(js_str);
72: break;
73: }
74: return(JS_TRUE);
75: }
76:
77: #define GLOBOBJ_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED
78:
79: static struct JSPropertySpec js_global_properties[] = {
80: /* name, tinyid, flags */
81:
82: { "errno", GLOB_PROP_ERRNO, GLOBOBJ_FLAGS },
83: { "errno_str",GLOB_PROP_ERRNO_STR,GLOBOBJ_FLAGS },
84: {0}
85: };
86:
87: typedef struct {
88: JSRuntime* runtime;
89: JSContext* cx;
90: JSContext* parent_cx;
91: JSObject* obj;
92: JSScript* script;
93: msg_queue_t* msg_queue;
94: js_branch_t branch;
95: JSErrorReporter error_reporter;
96: } background_data_t;
97:
98: static void background_thread(void* arg)
99: {
100: background_data_t* bg = (background_data_t*)arg;
101: jsval result=JSVAL_VOID;
102:
103: msgQueueAttach(bg->msg_queue);
104: JS_SetContextThread(bg->cx);
105: if(JS_ExecuteScript(bg->cx, bg->obj, bg->script, &result) && result!=JSVAL_VOID)
106: js_enqueue_value(bg->cx, bg->msg_queue, result, NULL);
107: JS_DestroyScript(bg->cx, bg->script);
108: JS_DestroyContext(bg->cx);
109: JS_DestroyRuntime(bg->runtime);
110: free(bg);
111: }
112:
113: static void
114: js_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
115: {
116: background_data_t* bg;
117:
118: if((bg=(background_data_t*)JS_GetContextPrivate(cx))==NULL)
119: return;
120:
121: /* Use parent's context private data */
122: JS_SetContextPrivate(cx, JS_GetContextPrivate(bg->parent_cx));
123:
124: /* Call parent's error reporter */
125: bg->error_reporter(cx, message, report);
126:
127: /* Restore our context private data */
128: JS_SetContextPrivate(cx, bg);
129: }
130:
131: static JSBool js_BranchCallback(JSContext *cx, JSScript* script)
132: {
133: background_data_t* bg;
134:
135: if((bg=(background_data_t*)JS_GetContextPrivate(cx))==NULL)
136: return(JS_FALSE);
137:
138: if(bg->parent_cx!=NULL && !JS_IsRunning(bg->parent_cx)) /* die when parent dies */
139: return(JS_FALSE);
140:
141: return js_CommonBranchCallback(cx,&bg->branch);
142: }
143:
144: static JSBool
145: js_load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
146: {
147: char path[MAX_PATH+1];
148: uintN i;
149: uintN argn=0;
150: const char* filename;
151: JSScript* script;
152: scfg_t* cfg;
153: jsval val;
154: JSObject* js_argv;
155: JSObject* exec_obj;
156: JSContext* exec_cx=cx;
157: JSBool success;
158: JSBool background=JS_FALSE;
159: background_data_t* bg;
160:
161: *rval=JSVAL_VOID;
162:
163: if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
164: return(JS_FALSE);
165:
166: exec_obj=JS_GetScopeChain(cx);
167:
168: if(JSVAL_IS_BOOLEAN(argv[argn]))
169: background=JSVAL_TO_BOOLEAN(argv[argn++]);
170:
171: if(background) {
172:
173: if((bg=(background_data_t*)malloc(sizeof(background_data_t)))==NULL)
174: return(JS_FALSE);
175: memset(bg,0,sizeof(background_data_t));
176:
177: bg->parent_cx = cx;
178:
179: /* Setup default values for branch settings */
180: bg->branch.limit=JAVASCRIPT_BRANCH_LIMIT;
181: bg->branch.gc_interval=JAVASCRIPT_GC_INTERVAL;
182: bg->branch.yield_interval=JAVASCRIPT_YIELD_INTERVAL;
183: if(JS_GetProperty(cx, obj,"js",&val)) /* copy branch settings from parent */
184: memcpy(&bg->branch,JS_GetPrivate(cx,JSVAL_TO_OBJECT(val)),sizeof(bg->branch));
185: bg->branch.terminated=NULL; /* could be bad pointer at any time */
186: bg->branch.counter=0;
187: bg->branch.gc_attempts=0;
188:
189: if((bg->runtime = JS_NewRuntime(JAVASCRIPT_MAX_BYTES))==NULL)
190: return(JS_FALSE);
191:
192: if((bg->cx = JS_NewContext(bg->runtime, JAVASCRIPT_CONTEXT_STACK))==NULL)
193: return(JS_FALSE);
194:
195: if((bg->obj=js_CreateCommonObjects(bg->cx
196: ,cfg /* common config */
197: ,NULL /* node-specific config */
198: ,NULL /* additional global methods */
199: ,0 /* uptime */
200: ,"" /* hostname */
201: ,"" /* socklib_desc */
202: ,&bg->branch /* js */
203: ,NULL /* client */
204: ,INVALID_SOCKET /* client_socket */
205: ,NULL /* server props */
206: ))==NULL)
207: return(JS_FALSE);
208:
209: bg->msg_queue = msgQueueInit(NULL,MSG_QUEUE_BIDIR);
210:
211: js_CreateQueueObject(bg->cx, bg->obj, "parent_queue", bg->msg_queue);
212:
213: /* Save parent's error reporter (for later use by our error reporter) */
214: bg->error_reporter=JS_SetErrorReporter(cx,NULL);
215: JS_SetErrorReporter(cx,bg->error_reporter);
216: JS_SetErrorReporter(bg->cx,js_ErrorReporter);
217:
218: /* Set our branch callback (which calls the generic branch callback) */
219: JS_SetContextPrivate(bg->cx, bg);
220: JS_SetBranchCallback(bg->cx, js_BranchCallback);
221:
222: exec_cx = bg->cx;
223: exec_obj = bg->obj;
224:
225: } else if(JSVAL_IS_OBJECT(argv[argn])) /* Scope specified */
226: obj=JSVAL_TO_OBJECT(argv[argn++]);
227:
228: if((filename=JS_GetStringBytes(JS_ValueToString(cx, argv[argn++])))==NULL)
229: return(JS_FALSE);
230:
231: if(argc>argn) {
232:
233: if((js_argv=JS_NewArrayObject(exec_cx, 0, NULL)) == NULL)
234: return(JS_FALSE);
235:
236: JS_DefineProperty(exec_cx, exec_obj, "argv", OBJECT_TO_JSVAL(js_argv)
237: ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
238:
239: for(i=argn; i<argc; i++)
240: JS_SetElement(exec_cx, js_argv, i-argn, &argv[i]);
241:
242: JS_DefineProperty(exec_cx, exec_obj, "argc", INT_TO_JSVAL(argc-argn)
243: ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
244: }
245:
246: errno = 0;
247: if(isfullpath(filename))
248: strcpy(path,filename);
249: else {
250: sprintf(path,"%s%s",cfg->mods_dir,filename);
251: if(cfg->mods_dir[0]==0 || !fexistcase(path))
252: sprintf(path,"%s%s",cfg->exec_dir,filename);
253: }
254:
255: JS_ClearPendingException(exec_cx);
256:
257: if((script=JS_CompileFile(exec_cx, exec_obj, path))==NULL)
258: return(JS_FALSE);
259:
260: if(background) {
261:
262: bg->script = script;
263: *rval = OBJECT_TO_JSVAL(js_CreateQueueObject(cx, obj, NULL, bg->msg_queue));
264: success = _beginthread(background_thread,0,bg)!=-1;
265:
266: } else {
267:
268: success = JS_ExecuteScript(exec_cx, exec_obj, script, rval);
269: JS_DestroyScript(exec_cx, script);
270: }
271:
272: return(success);
273: }
274:
275: static JSBool
276: js_format(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
277: {
278: char* p;
279: char* fmt;
280: uintN i;
281: JSString * str;
282: va_list arglist[64];
283:
284: if((fmt=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
285: return(JS_FALSE);
286:
287: memset(arglist,0,sizeof(arglist)); /* Initialize arglist to NULLs */
288:
289: for (i = 1; i < argc && i<sizeof(arglist)/sizeof(arglist[0]); i++) {
290: if(JSVAL_IS_DOUBLE(argv[i]))
291: arglist[i-1]=(char*)(unsigned long)*JSVAL_TO_DOUBLE(argv[i]);
292: else if(JSVAL_IS_INT(argv[i]))
293: arglist[i-1]=(char *)JSVAL_TO_INT(argv[i]);
294: else {
295: if((str=JS_ValueToString(cx, argv[i]))==NULL) {
296: JS_ReportError(cx,"JS_ValueToString failed");
297: return(JS_FALSE);
298: }
299: arglist[i-1]=JS_GetStringBytes(str);
300: }
301: }
302:
303: if((p=JS_vsmprintf(fmt,(char*)arglist))==NULL)
304: return(JS_FALSE);
305:
306: str = JS_NewStringCopyZ(cx, p);
307: JS_smprintf_free(p);
308:
309: if(str==NULL)
310: return(JS_FALSE);
311:
312: *rval = STRING_TO_JSVAL(str);
313: return(JS_TRUE);
314: }
315:
316: static JSBool
317: js_yield(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
318: {
319: BOOL forced=TRUE;
320:
321: if(argc)
322: JS_ValueToBoolean(cx, argv[0], &forced);
323: if(forced) {
324: YIELD();
325: } else {
326: MAYBE_YIELD();
327: }
328:
329: *rval = JSVAL_VOID;
330: return(JS_TRUE);
331: }
332:
333: static JSBool
334: js_mswait(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
335: {
336: int32 val=1;
337:
338: if(argc)
339: JS_ValueToInt32(cx,argv[0],&val);
340: mswait(val);
341:
342: *rval = JSVAL_VOID;
343: return(JS_TRUE);
344: }
345:
346: static JSBool
347: js_random(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
348: {
349: int32 val=100;
350:
351: if(argc)
352: JS_ValueToInt32(cx,argv[0],&val);
353:
354: JS_NewNumberValue(cx,sbbs_random(val),rval);
355: return(JS_TRUE);
356: }
357:
358: static JSBool
359: js_time(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
360: {
361: JS_NewNumberValue(cx,time(NULL),rval);
362: return(JS_TRUE);
363: }
364:
365:
366: static JSBool
367: js_beep(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
368: {
369: int32 freq=500;
370: int32 dur=500;
371:
372: if(argc)
373: JS_ValueToInt32(cx,argv[0],&freq);
374: if(argc>1)
375: JS_ValueToInt32(cx,argv[1],&dur);
376:
377: sbbs_beep(freq,dur);
378: *rval = JSVAL_VOID;
379: return(JS_TRUE);
380: }
381:
382: static JSBool
383: js_exit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
384: {
385: *rval = JSVAL_VOID;
386: if(argc)
387: JS_DefineProperty(cx, obj, "exit_code", argv[0]
388: ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
389:
390: return(JS_FALSE);
391: }
392:
393: static JSBool
394: js_crc16(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
395: {
396: char* str;
397:
398: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
399: return(JS_FALSE);
400:
401: *rval = INT_TO_JSVAL(crc16(str,0));
402: return(JS_TRUE);
403: }
404:
405: static JSBool
406: js_crc32(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
407: {
408: char* str;
409:
410: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
411: return(JS_FALSE);
412:
413: JS_NewNumberValue(cx,crc32(str,strlen(str)),rval);
414: return(JS_TRUE);
415: }
416:
417: static JSBool
418: js_chksum(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
419: {
420: ulong sum=0;
421: char* p;
422:
423: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
424: return(JS_FALSE);
425:
426: while(*p) sum+=*(p++);
427:
428: JS_NewNumberValue(cx,sum,rval);
429: return(JS_TRUE);
430: }
431:
432: static JSBool
433: js_ascii(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
434: {
435: char* p;
436: char str[2];
437: int32 i=0;
438: JSString* js_str;
439:
440: if(JSVAL_IS_STRING(argv[0])) { /* string to ascii-int */
441:
442: if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL)
443: return(JS_FALSE);
444:
445: *rval=INT_TO_JSVAL(*p);
446: return(JS_TRUE);
447: }
448:
449: /* ascii-int to str */
450: JS_ValueToInt32(cx,argv[0],&i);
451: str[0]=(uchar)i;
452: str[1]=0;
453:
454: if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
455: return(JS_FALSE);
456:
457: *rval = STRING_TO_JSVAL(js_str);
458: return(JS_TRUE);
459: }
460:
461: static JSBool
462: js_ctrl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
463: {
464: char ch;
465: char* p;
466: char str[2];
467: int32 i=0;
468: JSString* js_str;
469:
470: if(JSVAL_IS_STRING(argv[0])) {
471:
472: if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL)
473: return(JS_FALSE);
474: ch=*p;
475: } else {
476: JS_ValueToInt32(cx,argv[0],&i);
477: ch=(char)i;
478: }
479:
480: str[0]=toupper(ch)&~0x20;
481: str[1]=0;
482:
483: if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
484: return(JS_FALSE);
485:
486: *rval = STRING_TO_JSVAL(js_str);
487: return(JS_TRUE);
488: }
489:
490: static JSBool
491: js_ascii_str(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
492: {
493: char* p;
494: char* str;
495: JSString* js_str;
496:
497: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
498: return(JS_FALSE);
499:
500: if((p=strdup(str))==NULL)
501: return(JS_FALSE);
502:
503: ascii_str(p);
504:
505: js_str = JS_NewStringCopyZ(cx, p);
506: free(p);
507: if(js_str==NULL)
508: return(JS_FALSE);
509:
510: *rval = STRING_TO_JSVAL(js_str);
511: return(JS_TRUE);
512: }
513:
514:
515: static JSBool
516: js_strip_ctrl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
517: {
518: char* p;
519: char* str;
520: JSString* js_str;
521:
522: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
523: return(JS_FALSE);
524:
525: if((p=strdup(str))==NULL)
526: return(JS_FALSE);
527:
528: strip_ctrl(p);
529:
530: js_str = JS_NewStringCopyZ(cx, p);
531: free(p);
532: if(js_str==NULL)
533: return(JS_FALSE);
534:
535: *rval = STRING_TO_JSVAL(js_str);
536: return(JS_TRUE);
537: }
538:
539: static JSBool
540: js_strip_exascii(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
541: {
542: char* p;
543: char* str;
544: JSString* js_str;
545:
546: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
547: return(JS_FALSE);
548:
549: if((p=strdup(str))==NULL)
550: return(JS_FALSE);
551:
552: strip_exascii(p);
553:
554: js_str = JS_NewStringCopyZ(cx, p);
555: free(p);
556: if(js_str==NULL)
557: return(JS_FALSE);
558:
559: *rval = STRING_TO_JSVAL(js_str);
560: return(JS_TRUE);
561: }
562:
563: static JSBool
564: js_lfexpand(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
565: {
566: ulong i,j;
567: char* inbuf;
568: char* outbuf;
569: JSString* js_str;
570:
571: if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
572: return(JS_FALSE);
573:
574: if((outbuf=(char*)malloc((strlen(inbuf)*2)+1))==NULL)
575: return(JS_FALSE);
576:
577: for(i=j=0;inbuf[i];i++) {
578: if(inbuf[i]=='\n' && (!i || inbuf[i-1]!='\r'))
579: outbuf[j++]='\r';
580: outbuf[j++]=inbuf[i];
581: }
582: outbuf[j]=0;
583:
584: js_str = JS_NewStringCopyZ(cx, outbuf);
585: free(outbuf);
586: if(js_str==NULL)
587: return(JS_FALSE);
588:
589: *rval = STRING_TO_JSVAL(js_str);
590: return(JS_TRUE);
591: }
592:
593: static JSBool
594: js_word_wrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
595: {
596: int32 l,len=79;
597: ulong i,k;
598: int col=1;
599: uchar* inbuf;
600: char* outbuf;
601: char* linebuf;
602: JSString* js_str;
603:
604: if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
605: return(JS_FALSE);
606:
607: if((outbuf=(char*)malloc((strlen(inbuf)*2)+1))==NULL)
608: return(JS_FALSE);
609:
610: if(argc>1)
611: JS_ValueToInt32(cx,argv[1],&len);
612:
613: if((linebuf=(char*)malloc((len*2)+2))==NULL) /* room for ^A codes */
614: return(JS_FALSE);
615:
616: outbuf[0]=0;
617: for(i=l=0;inbuf[i];) {
618: if(inbuf[i]=='\r' || inbuf[i]==FF) {
619: strncat(outbuf,linebuf,l);
620: l=0;
621: col=1;
622: }
623: else if(inbuf[i]=='\t') {
624: if((col%8)==0)
625: col++;
626: col+=(col%8);
627: } else if(inbuf[i]==CTRL_A && inbuf[i+1]!=0) {
628: if(l<(len*2)) {
629: strncpy(linebuf+l,inbuf+i,2);
630: l+=2;
631: }
632: i+=2;
633: continue;
634: } else if(inbuf[i]>=' ')
635: col++;
636: linebuf[l]=inbuf[i++];
637: if(col<=len) {
638: l++;
639: continue;
640: }
641: /* wrap line here */
642: k=l;
643: while(k && linebuf[k]>' ' && linebuf[k-1]!=CTRL_A) k--;
644: if(k==0) /* continuous printing chars, no word wrap possible */
645: strncat(outbuf,linebuf,l+1);
646: else {
647: i-=(l-k); /* rewind to start of next word */
648: linebuf[k]=0;
649: truncsp(linebuf);
650: strcat(outbuf,linebuf);
651: }
652: strcat(outbuf,"\r\n");
653: /* skip white space (but no more than one LF) for starting of new line */
654: while(inbuf[i] && inbuf[i]<=' ' && inbuf[i]!='\n' && inbuf[i]!=CTRL_A) i++;
655: if(inbuf[i]=='\n') i++;
656: l=0;
657: col=1;
658: }
659: if(l) /* remainder */
660: strncat(outbuf,linebuf,l);
661:
662: js_str = JS_NewStringCopyZ(cx, outbuf);
663: free(outbuf);
664: if(js_str==NULL)
665: return(JS_FALSE);
666:
667: *rval = STRING_TO_JSVAL(js_str);
668: return(JS_TRUE);
669: }
670:
671: static JSBool
672: js_quote_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
673: {
674: int32 len=79;
675: int i,l;
676: uchar* inbuf;
677: char* outbuf;
678: char* linebuf;
679: char* prefix=" > ";
680: JSString* js_str;
681:
682: if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
683: return(JS_FALSE);
684:
685: if(argc>1)
686: JS_ValueToInt32(cx,argv[1],&len);
687:
688: if(argc>2)
689: prefix=JS_GetStringBytes(JS_ValueToString(cx, argv[2]));
690:
691: if((outbuf=(char*)malloc((strlen(inbuf)*strlen(prefix))+1))==NULL)
692: return(JS_FALSE);
693:
694: if((linebuf=(char*)malloc(len+1))==NULL)
695: return(JS_FALSE);
696:
697: outbuf[0]=0;
698: for(i=l=0;inbuf[i];i++) {
699: if(l==0)
700: strcat(outbuf,prefix);
701: if(l<len)
702: linebuf[l++]=inbuf[i];
703: if(inbuf[i]=='\n') {
704: strncat(outbuf,linebuf,l);
705: l=0;
706: }
707: }
708: if(l) /* remainder */
709: strncat(outbuf,linebuf,l);
710:
711: js_str = JS_NewStringCopyZ(cx, outbuf);
712: free(outbuf);
713: if(js_str==NULL)
714: return(JS_FALSE);
715:
716: *rval = STRING_TO_JSVAL(js_str);
717: return(JS_TRUE);
718: }
719:
720: static JSBool
721: js_netaddr_type(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
722: {
723: char* str;
724:
725: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
726: return(JS_FALSE);
727:
728: *rval = INT_TO_JSVAL(smb_netaddr_type(str));
729:
730: return(JS_TRUE);
731: }
732:
733: static JSBool
734: js_rot13(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
735: {
736: char* p;
737: char* str;
738: JSString* js_str;
739:
740: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
741: return(JS_FALSE);
742:
743: if((p=strdup(str))==NULL)
744: return(JS_FALSE);
745:
746: js_str = JS_NewStringCopyZ(cx, rot13(p));
747: free(p);
748: if(js_str==NULL)
749: return(JS_FALSE);
750:
751: *rval = STRING_TO_JSVAL(js_str);
752: return(JS_TRUE);
753: }
754:
755: /* This table is used to convert between IBM ex-ASCII and HTML character entities */
756: /* Much of this table supplied by Deuce (thanks!) */
757: static struct {
758: int value;
759: char* name;
760: } exasctbl[128] = {
761: /* HTML val,name ASCII description */
762: { 199 ,"Ccedil" }, /* 128 C, cedilla */
763: { 252 ,"uuml" }, /* 129 u, umlaut */
764: { 233 ,"eacute" }, /* 130 e, acute accent */
765: { 226 ,"acirc" }, /* 131 a, circumflex accent */
766: { 228 ,"auml" }, /* 132 a, umlaut */
767: { 224 ,"agrave" }, /* 133 a, grave accent */
768: { 229 ,"aring" }, /* 134 a, ring */
769: { 231 ,"ccedil" }, /* 135 c, cedilla */
770: { 234 ,"ecirc" }, /* 136 e, circumflex accent */
771: { 235 ,"euml" }, /* 137 e, umlaut */
772: { 232 ,"egrave" }, /* 138 e, grave accent */
773: { 239 ,"iuml" }, /* 139 i, umlaut */
774: { 238 ,"icirc" }, /* 140 i, circumflex accent */
775: { 236 ,"igrave" }, /* 141 i, grave accent */
776: { 196 ,"Auml" }, /* 142 A, umlaut */
777: { 197 ,"Aring" }, /* 143 A, ring */
778: { 201 ,"Eacute" }, /* 144 E, acute accent */
779: { 230 ,"aelig" }, /* 145 ae ligature */
780: { 198 ,"AElig" }, /* 146 AE ligature */
781: { 244 ,"ocirc" }, /* 147 o, circumflex accent */
782: { 246 ,"ouml" }, /* 148 o, umlaut */
783: { 242 ,"ograve" }, /* 149 o, grave accent */
784: { 251 ,"ucirc" }, /* 150 u, circumflex accent */
785: { 249 ,"ugrave" }, /* 151 u, grave accent */
786: { 255 ,"yuml" }, /* 152 y, umlaut */
787: { 214 ,"Ouml" }, /* 153 O, umlaut */
788: { 220 ,"Uuml" }, /* 154 U, umlaut */
789: { 162 ,"cent" }, /* 155 Cent sign */
790: { 163 ,"pound" }, /* 156 Pound sign */
791: { 165 ,"yen" }, /* 157 Yen sign */
792: { 8359 ,NULL }, /* 158 Pt (unicode) */
793: { 402 ,NULL }, /* 402 Florin (non-standard alsi 159?) */
794: { 225 ,"aacute" }, /* 160 a, acute accent */
795: { 237 ,"iacute" }, /* 161 i, acute accent */
796: { 243 ,"oacute" }, /* 162 o, acute accent */
797: { 250 ,"uacute" }, /* 163 u, acute accent */
798: { 241 ,"ntilde" }, /* 164 n, tilde */
799: { 209 ,"Ntilde" }, /* 165 N, tilde */
800: { 170 ,"ordf" }, /* 166 Feminine ordinal */
801: { 186 ,"ordm" }, /* 167 Masculine ordinal */
802: { 191 ,"iquest" }, /* 168 Inverted question mark */
803: { 8976 ,NULL }, /* 169 Inverse "Not sign" (unicode) */
804: { 172 ,"not" }, /* 170 Not sign */
805: { 189 ,"frac12" }, /* 171 Fraction one-half */
806: { 188 ,"frac14" }, /* 172 Fraction one-fourth */
807: { 161 ,"iexcl" }, /* 173 Inverted exclamation point */
808: { 171 ,"laquo" }, /* 174 Left angle quote */
809: { 187 ,"raquo" }, /* 175 Right angle quote */
810: { 9617 ,NULL }, /* 176 drawing symbol (unicode) */
811: { 9618 ,NULL }, /* 177 drawing symbol (unicode) */
812: { 9619 ,NULL }, /* 178 drawing symbol (unicode) */
813: { 9474 ,NULL }, /* 179 drawing symbol (unicode) */
814: { 9508 ,NULL }, /* 180 drawing symbol (unicode) */
815: { 9569 ,NULL }, /* 181 drawing symbol (unicode) */
816: { 9570 ,NULL }, /* 182 drawing symbol (unicode) */
817: { 9558 ,NULL }, /* 183 drawing symbol (unicode) */
818: { 9557 ,NULL }, /* 184 drawing symbol (unicode) */
819: { 9571 ,NULL }, /* 185 drawing symbol (unicode) */
820: { 9553 ,NULL }, /* 186 drawing symbol (unicode) */
821: { 9559 ,NULL }, /* 187 drawing symbol (unicode) */
822: { 9565 ,NULL }, /* 188 drawing symbol (unicode) */
823: { 9564 ,NULL }, /* 189 drawing symbol (unicode) */
824: { 9563 ,NULL }, /* 190 drawing symbol (unicode) */
825: { 9488 ,NULL }, /* 191 drawing symbol (unicode) */
826: { 9492 ,NULL }, /* 192 drawing symbol (unicode) */
827: { 9524 ,NULL }, /* 193 drawing symbol (unicode) */
828: { 9516 ,NULL }, /* 194 drawing symbol (unicode) */
829: { 9500 ,NULL }, /* 195 drawing symbol (unicode) */
830: { 9472 ,NULL }, /* 196 drawing symbol (unicode) */
831: { 9532 ,NULL }, /* 197 drawing symbol (unicode) */
832: { 9566 ,NULL }, /* 198 drawing symbol (unicode) */
833: { 9567 ,NULL }, /* 199 drawing symbol (unicode) */
834: { 9562 ,NULL }, /* 200 drawing symbol (unicode) */
835: { 9556 ,NULL }, /* 201 drawing symbol (unicode) */
836: { 9577 ,NULL }, /* 202 drawing symbol (unicode) */
837: { 9574 ,NULL }, /* 203 drawing symbol (unicode) */
838: { 9568 ,NULL }, /* 204 drawing symbol (unicode) */
839: { 9552 ,NULL }, /* 205 drawing symbol (unicode) */
840: { 9580 ,NULL }, /* 206 drawing symbol (unicode) */
841: { 9575 ,NULL }, /* 207 drawing symbol (unicode) */
842: { 9576 ,NULL }, /* 208 drawing symbol (unicode) */
843: { 9572 ,NULL }, /* 209 drawing symbol (unicode) */
844: { 9573 ,NULL }, /* 210 drawing symbol (unicode) */
845: { 9561 ,NULL }, /* 211 drawing symbol (unicode) */
846: { 9560 ,NULL }, /* 212 drawing symbol (unicode) */
847: { 9554 ,NULL }, /* 213 drawing symbol (unicode) */
848: { 9555 ,NULL }, /* 214 drawing symbol (unicode) */
849: { 9579 ,NULL }, /* 215 drawing symbol (unicode) */
850: { 9578 ,NULL }, /* 216 drawing symbol (unicode) */
851: { 9496 ,NULL }, /* 217 drawing symbol (unicode) */
852: { 9484 ,NULL }, /* 218 drawing symbol (unicode) */
853: { 9608 ,NULL }, /* 219 drawing symbol (unicode) */
854: { 9604 ,NULL }, /* 220 drawing symbol (unicode) */
855: { 9612 ,NULL }, /* 221 drawing symbol (unicode) */
856: { 9616 ,NULL }, /* 222 drawing symbol (unicode) */
857: { 9600 ,NULL }, /* 223 drawing symbol (unicode) */
858: { 945 ,NULL }, /* 224 alpha symbol */
859: { 223 ,"szlig" }, /* 225 sz ligature (beta symbol) */
860: { 915 ,NULL }, /* 226 omega symbol */
861: { 960 ,NULL }, /* 227 pi symbol*/
862: { 931 ,NULL }, /* 228 epsilon symbol */
863: { 963 ,NULL }, /* 229 o with stick */
864: { 181 ,"micro" }, /* 230 Micro sign (Greek mu) */
865: { 964 ,NULL }, /* 231 greek char? */
866: { 934 ,NULL }, /* 232 greek char? */
867: { 920 ,NULL }, /* 233 greek char? */
868: { 937 ,NULL }, /* 234 greek char? */
869: { 948 ,NULL }, /* 235 greek char? */
870: { 8734 ,NULL }, /* 236 infinity symbol (unicode) */
871: { 966 ,"oslash" }, /* 237 Greek Phi */
872: { 949 ,NULL }, /* 238 rounded E */
873: { 8745 ,NULL }, /* 239 unside down U (unicode) */
874: { 8801 ,NULL }, /* 240 drawing symbol (unicode) */
875: { 177 ,"plusmn" }, /* 241 Plus or minus */
876: { 8805 ,NULL }, /* 242 drawing symbol (unicode) */
877: { 8804 ,NULL }, /* 243 drawing symbol (unicode) */
878: { 8992 ,NULL }, /* 244 drawing symbol (unicode) */
879: { 8993 ,NULL }, /* 245 drawing symbol (unicode) */
880: { 247 ,"divide" }, /* 246 Division sign */
881: { 8776 ,NULL }, /* 247 two squiggles (unicode) */
882: { 176 ,"deg" }, /* 248 Degree sign */
883: { 8729 ,NULL }, /* 249 drawing symbol (unicode) */
884: { 183 ,"middot" }, /* 250 Middle dot */
885: { 8730 ,NULL }, /* 251 check mark (unicode) */
886: { 8319 ,NULL }, /* 252 superscript n (unicode) */
887: { 178 ,"sup2" }, /* 253 superscript 2 */
888: { 9632 ,NULL }, /* 254 drawing symbol (unicode) */
889: { 160 ,"nbsp" } /* 255 non-breaking space */
890: };
891:
892: static struct {
893: int value;
894: char* name;
895: } lowasctbl[32] = {
896: { 160 ,"nbsp" }, /* NULL non-breaking space */
897: { 9786 ,NULL }, /* white smiling face */
898: { 9787 ,NULL }, /* black smiling face */
899: { 9829 ,"hearts" }, /* black heart suit */
900: { 9830 ,"diams" }, /* black diamond suit */
901: { 9827 ,"clubs" }, /* black club suit */
902: { 9824 ,"spades" }, /* black spade suit */
903: { 8226 ,"bull" }, /* bullet */
904: { 9688 ,NULL }, /* inverse bullet */
905: { 9702 ,NULL }, /* white bullet */
906: { 9689 ,NULL }, /* inverse white circle */
907: { 9794 ,NULL }, /* male sign */
908: { 9792 ,NULL }, /* female sign */
909: { 9834 ,NULL }, /* eighth note */
910: { 9835 ,NULL }, /* beamed eighth notes */
911: { 9788 ,NULL }, /* white sun with rays */
912: { 9654 ,NULL }, /* black right-pointing triangle */
913: { 9664 ,NULL }, /* black left-pointing triangle */
914: { 8597 ,NULL }, /* up down arrow */
915: { 8252 ,NULL }, /* double exclamation mark */
916: { 182 ,"para" }, /* pilcrow sign */
917: { 167 ,"sect" }, /* section sign */
918: { 9644 ,NULL }, /* black rectangle */
919: { 8616 ,NULL }, /* up down arrow with base */
920: { 8593 ,"uarr" }, /* upwards arrow */
921: { 8595 ,"darr" }, /* downwards arrow */
922: { 8594 ,"rarr" }, /* rightwards arrow */
923: { 8592 ,"larr" }, /* leftwards arrow */
924: { 8985 ,NULL }, /* turned not sign */
925: { 8596 ,"harr" }, /* left right arrow */
926: { 9650 ,NULL }, /* black up-pointing triangle */
927: { 9660 ,NULL } /* black down-pointing triangle */
928: };
929:
930: static JSBool
931: js_html_encode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
932: {
933: int ch;
934: ulong i,j;
935: uchar* inbuf;
936: uchar* tmpbuf;
937: uchar* outbuf;
938: uchar* param;
939: char* lastparam;
940: JSBool exascii=JS_TRUE;
941: JSBool wsp=JS_TRUE;
942: JSBool ansi=JS_TRUE;
943: JSBool ctrl_a=JS_TRUE;
944: JSString* js_str;
945: int fg=7;
946: int bg=0;
947: BOOL blink=FALSE;
948: BOOL bold=FALSE;
949: int esccount=0;
950: char ansi_seq[MAX_ANSI_SEQ+1];
951: int ansi_param[MAX_ANSI_PARAMS];
952: int k,l;
953: ulong savepos=0;
954: int hpos=0;
955: int currrow=0;
956: int savehpos=0;
957: int savevpos=0;
958: int wraphpos=-2;
959: int wrapvpos=-2;
960: ulong wrappos=0;
961: BOOL extchar=FALSE;
962: ulong obsize;
963: int lastcolor=7;
964: char tmp1[128];
965: struct tm tm;
966: time_t now;
967: BOOL nodisplay=FALSE;
968: scfg_t* cfg;
969: uchar attr_stack[64]; /* Saved attributes (stack) */
970: int attr_sp=0; /* Attribute stack pointer */
971: ulong clear_screen=0;
972:
973: if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) /* Will this work? Ask DM */
974: return(JS_FALSE);
975:
976: if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
977: return(JS_FALSE);
978:
979: if(argc>1 && JSVAL_IS_BOOLEAN(argv[1]))
980: exascii=JSVAL_TO_BOOLEAN(argv[1]);
981:
982: if(argc>2 && JSVAL_IS_BOOLEAN(argv[2]))
983: wsp=JSVAL_TO_BOOLEAN(argv[2]);
984:
985: if(argc>3 && JSVAL_IS_BOOLEAN(argv[3]))
986: ansi=JSVAL_TO_BOOLEAN(argv[3]);
987:
988: if(argc>4 && JSVAL_IS_BOOLEAN(argv[4]))
989: {
990: ctrl_a=JSVAL_TO_BOOLEAN(argv[4]);
991: if(ctrl_a)
992: ansi=ctrl_a;
993: }
994:
995: if((tmpbuf=(char*)malloc((strlen(inbuf)*10)+1))==NULL)
996: return(JS_FALSE);
997:
998: for(i=j=0;inbuf[i];i++) {
999: switch(inbuf[i]) {
1000: case TAB:
1001: case LF:
1002: case CR:
1003: if(wsp)
1004: j+=sprintf(tmpbuf+j,"&#%u;",inbuf[i]);
1005: else
1006: tmpbuf[j++]=inbuf[i];
1007: break;
1008: case '"':
1009: j+=sprintf(tmpbuf+j,""");
1010: break;
1011: case '&':
1012: j+=sprintf(tmpbuf+j,"&");
1013: break;
1014: case '<':
1015: j+=sprintf(tmpbuf+j,"<");
1016: break;
1017: case '>':
1018: j+=sprintf(tmpbuf+j,">");
1019: break;
1020: case '\b':
1021: j--;
1022: break;
1023: default:
1024: if(inbuf[i]&0x80) {
1025: if(exascii) {
1026: ch=inbuf[i]^0x80;
1027: if(exasctbl[ch].name!=NULL)
1028: j+=sprintf(tmpbuf+j,"&%s;",exasctbl[ch].name);
1029: else
1030: j+=sprintf(tmpbuf+j,"&#%u;",exasctbl[ch].value);
1031: } else
1032: tmpbuf[j++]=inbuf[i];
1033: }
1034: else if(inbuf[i]>=' ' && inbuf[i]<DEL)
1035: tmpbuf[j++]=inbuf[i];
1036: #if 0 /* ASCII 127 - Not displayed? */
1037: else if(inbuf[i]==DEL && exascii)
1038: j+=sprintf(tmpbuf+j,"⌂",exasctbl[ch].value);
1039: #endif
1040: else if(inbuf[i]<' ') /* unknown control chars */
1041: {
1042: if(ansi && inbuf[i]==ESC)
1043: {
1044: esccount++;
1045: tmpbuf[j++]=inbuf[i];
1046: }
1047: else if(ctrl_a && inbuf[i]==1)
1048: {
1049: esccount++;
1050: tmpbuf[j++]=inbuf[i];
1051: tmpbuf[j++]=inbuf[++i];
1052: }
1053: else if(exascii) {
1054: ch=inbuf[i];
1055: if(lowasctbl[ch].name!=NULL)
1056: j+=sprintf(tmpbuf+j,"&%s;",lowasctbl[ch].name);
1057: else
1058: j+=sprintf(tmpbuf+j,"&#%u;",lowasctbl[ch].value);
1059: } else
1060: j+=sprintf(tmpbuf+j,"&#%u;",inbuf[i]);
1061: }
1062: break;
1063: }
1064: }
1065: tmpbuf[j]=0;
1066:
1067: if(ansi)
1068: {
1069: obsize=(strlen(tmpbuf)+(esccount+1)*MAX_COLOR_STRING)+1;
1070: if(obsize<2048)
1071: obsize=2048;
1072: if((outbuf=(uchar*)malloc(obsize))==NULL)
1073: {
1074: free(tmpbuf);
1075: return(JS_FALSE);
1076: }
1077: j=sprintf(outbuf,"<span style=\"%s\">",htmlansi[7]);
1078: clear_screen=j;
1079: for(i=0;tmpbuf[i];i++) {
1080: if(j>(obsize/2)) /* Completely arbitrary here... must be carefull with this eventually ToDo */
1081: {
1082: obsize+=(obsize/2);
1083: if((param=realloc(outbuf,obsize))==NULL)
1084: {
1085: free(tmpbuf);
1086: free(outbuf);
1087: return(JS_FALSE);
1088: }
1089: outbuf=param;
1090: }
1091: if(tmpbuf[i]==ESC && tmpbuf[i+1]=='[')
1092: {
1093: if(nodisplay)
1094: continue;
1095: k=0;
1096: memset(&ansi_param,0xff,sizeof(int)*MAX_ANSI_PARAMS);
1097: strncpy(ansi_seq, tmpbuf+i+2, MAX_ANSI_SEQ);
1098: ansi_seq[MAX_ANSI_SEQ]=0;
1099: for(lastparam=ansi_seq;*lastparam;lastparam++)
1100: {
1101: if(isalpha(*lastparam))
1102: {
1103: *(++lastparam)=0;
1104: break;
1105: }
1106: }
1107: k=0;
1108: param=ansi_seq;
1109: if(*param=='?') /* This is to fix ESC[?7 whatever that is */
1110: param++;
1111: if(isdigit(*param))
1112: ansi_param[k++]=atoi(ansi_seq);
1113: while(isspace(*param) || isdigit(*param))
1114: param++;
1115: lastparam=param;
1116: while((param=strchr(param,';'))!=NULL)
1117: {
1118: param++;
1119: ansi_param[k++]=atoi(param);
1120: while(isspace(*param) || isdigit(*param))
1121: param++;
1122: lastparam=param;
1123: }
1124: switch(*lastparam)
1125: {
1126: case 'm': /* Colour */
1127: for(k=0;ansi_param[k]>=0;k++)
1128: {
1129: switch(ansi_param[k])
1130: {
1131: case 0:
1132: fg=7;
1133: bg=0;
1134: blink=FALSE;
1135: bold=FALSE;
1136: break;
1137: case 1:
1138: bold=TRUE;
1139: break;
1140: case 2:
1141: bold=FALSE;
1142: break;
1143: case 5:
1144: blink=TRUE;
1145: break;
1146: case 6:
1147: blink=TRUE;
1148: break;
1149: case 7:
1150: l=fg;
1151: fg=bg;
1152: bg=l;
1153: break;
1154: case 8:
1155: fg=bg;
1156: blink=FALSE;
1157: bold=FALSE;
1158: break;
1159: case 30:
1160: case 31:
1161: case 32:
1162: case 33:
1163: case 34:
1164: case 35:
1165: case 36:
1166: case 37:
1167: fg=ansi_param[k]-30;
1168: break;
1169: case 40:
1170: case 41:
1171: case 42:
1172: case 43:
1173: case 44:
1174: case 45:
1175: case 46:
1176: case 47:
1177: bg=ansi_param[k]-40;
1178: break;
1179: }
1180: }
1181: break;
1182: case 'C': /* Move right */
1183: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1184: lastcolor=0;
1185: l=ansi_param[0]>0?ansi_param[0]:1;
1186: if(wrappos==0 && wrapvpos==currrow) {
1187: /* j+=sprintf(outbuf+j,"<!-- \r\nC after A l=%d hpos=%d -->",l,hpos); */
1188: l=l-hpos;
1189: wrapvpos=-2; /* Prevent additional move right */
1190: }
1191: if(l>81-hpos)
1192: l=81-hpos;
1193: for(k=0; k<l; k++)
1194: {
1195: j+=sprintf(outbuf+j,"%s"," ");
1196: hpos++;
1197: }
1198: break;
1199: case 's': /* Save position */
1200: savepos=j;
1201: savehpos=hpos;
1202: savevpos=currrow;
1203: break;
1204: case 'u': /* Restore saved position */
1205: j=savepos;
1206: hpos=savehpos;
1207: currrow=savevpos;
1208: break;
1209: case 'H': /* Move */
1210: k=ansi_param[0];
1211: if(k<=0)
1212: k=1;
1213: k--;
1214: l=ansi_param[1];
1215: if(l<=0)
1216: l=1;
1217: l--;
1218: while(k>currrow)
1219: {
1220: hpos=0;
1221: currrow++;
1222: outbuf[j++]='\r';
1223: outbuf[j++]='\n';
1224: }
1225: if(l>hpos)
1226: {
1227: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1228: lastcolor=0;
1229: while(l>hpos)
1230: {
1231: j+=sprintf(outbuf+j,"%s"," ");
1232: hpos++;
1233: }
1234: }
1235: break;
1236: case 'B': /* Move down */
1237: l=ansi_param[0];
1238: if(l<=0)
1239: l=1;
1240: for(k=0; k < l; k++)
1241: {
1242: currrow++;
1243: outbuf[j++]='\r';
1244: outbuf[j++]='\n';
1245: }
1246: if(hpos!=0 && tmpbuf[i+1]!=CR)
1247: {
1248: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1249: lastcolor=0;
1250: for(k=0; k<hpos ; k++)
1251: {
1252: j+=sprintf(outbuf+j,"%s"," ");
1253: }
1254: break;
1255: }
1256: break;
1257: case 'A': /* Move up */
1258: l=wrappos;
1259: if(j > wrappos && hpos==0 && currrow==wrapvpos+1 && ansi_param[0]<=1) {
1260: hpos=wraphpos;
1261: currrow=wrapvpos;
1262: j=wrappos;
1263: wrappos=0; /* Prevent additional move up */
1264: }
1265: break;
1266: case 'J': /* Clear */
1267: if(ansi_param[0]==2) {
1268: j=clear_screen;
1269: hpos=0;
1270: currrow=0;
1271: wraphpos=-2;
1272: wrapvpos=-2;
1273: wrappos=0;
1274: }
1275: break;
1276: }
1277: i+=(int)(lastparam-ansi_seq)+2;
1278: }
1279: else if(ctrl_a && tmpbuf[i]==1) /* CTRL-A codes */
1280: {
1281: /* j+=sprintf(outbuf+j,"<!-- CTRL-A-%c (%u) -->",tmpbuf[i+1],tmpbuf[i+1]); */
1282: if(nodisplay && tmpbuf[i+1] != ')')
1283: continue;
1284: if(tmpbuf[i+1]>0x7f)
1285: {
1286: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1287: lastcolor=0;
1288: l=tmpbuf[i+1]-0x7f;
1289: if(l>81-hpos)
1290: l=81-hpos;
1291: for(k=0; k<l; k++)
1292: {
1293: j+=sprintf(outbuf+j,"%s"," ");
1294: hpos++;
1295: }
1296: }
1297: else switch(toupper(tmpbuf[i+1]))
1298: {
1299: case 'K':
1300: fg=0;
1301: break;
1302: case 'R':
1303: fg=1;
1304: break;
1305: case 'G':
1306: fg=2;
1307: break;
1308: case 'Y':
1309: fg=3;
1310: break;
1311: case 'B':
1312: fg=4;
1313: break;
1314: case 'M':
1315: fg=5;
1316: break;
1317: case 'C':
1318: fg=6;
1319: break;
1320: case 'W':
1321: fg=7;
1322: break;
1323: case '0':
1324: bg=0;
1325: break;
1326: case '1':
1327: bg=1;
1328: break;
1329: case '2':
1330: bg=2;
1331: break;
1332: case '3':
1333: bg=3;
1334: break;
1335: case '4':
1336: bg=4;
1337: break;
1338: case '5':
1339: bg=5;
1340: break;
1341: case '6':
1342: bg=6;
1343: break;
1344: case '7':
1345: bg=7;
1346: break;
1347: case 'H':
1348: bold=TRUE;
1349: break;
1350: case 'I':
1351: blink=TRUE;
1352: break;
1353: case '+':
1354: if(attr_sp<(int)sizeof(attr_stack))
1355: attr_stack[attr_sp++]=(blink?(1<<7):0) | (bg << 4) | (bold?(1<<3):0) | fg;
1356: break;
1357: case '-':
1358: if(attr_sp>0)
1359: {
1360: blink=(attr_stack[--attr_sp]&(1<<7))?TRUE:FALSE;
1361: bg=(attr_stack[attr_sp] >> 4) & 7;
1362: blink=(attr_stack[attr_sp]&(1<<3))?TRUE:FALSE;
1363: fg=attr_stack[attr_sp] & 7;
1364: }
1365: else if(bold || blink || bg)
1366: {
1367: bold=FALSE;
1368: blink=FALSE;
1369: fg=7;
1370: bg=0;
1371: }
1372: break;
1373: case '_':
1374: if(blink || bg)
1375: {
1376: bold=FALSE;
1377: blink=FALSE;
1378: fg=7;
1379: bg=0;
1380: }
1381: break;
1382: case 'N':
1383: bold=FALSE;
1384: blink=FALSE;
1385: fg=7;
1386: bg=0;
1387: break;
1388: case 'P':
1389: case 'Q':
1390: case ',':
1391: case ';':
1392: case '.':
1393: case 'S':
1394: case '>':
1395: case '<':
1396: break;
1397:
1398: case '!': /* This needs to be fixed! (Somehow) */
1399: case '@':
1400: case '#':
1401: case '$':
1402: case '%':
1403: case '^':
1404: case '&':
1405: case '*':
1406: case '(':
1407: nodisplay=TRUE;
1408: break;
1409: case ')':
1410: nodisplay=FALSE;
1411: break;
1412:
1413: case 'D':
1414: now=time(NULL);
1415: j+=sprintf(outbuf+j,"%s",unixtodstr(cfg,now,tmp1));
1416: break;
1417: case 'T':
1418: now=time(NULL);
1419: localtime_r(&now,&tm);
1420: j+=sprintf(outbuf+j,"%02d:%02d %s"
1421: ,tm.tm_hour==0 ? 12
1422: : tm.tm_hour>12 ? tm.tm_hour-12
1423: : tm.tm_hour, tm.tm_min, tm.tm_hour>11 ? "pm":"am");
1424: break;
1425:
1426: case 'L':
1427: currrow=0;
1428: hpos=0;
1429: outbuf[j++]='\r';
1430: outbuf[j++]='\n';
1431: break;
1432: case ']':
1433: currrow++;
1434: if(hpos!=0 && tmpbuf[i+2]!=CR && !(tmpbuf[i+2]==1 && tmpbuf[i+3]=='['))
1435: {
1436: outbuf[j++]='\r';
1437: outbuf[j++]='\n';
1438: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1439: lastcolor=0;
1440: for(k=0; k<hpos ; k++)
1441: {
1442: j+=sprintf(outbuf+j,"%s"," ");
1443: }
1444: break;
1445: }
1446: outbuf[j++]='\n';
1447: break;
1448: case '[':
1449: outbuf[j++]='\r';
1450: hpos=0;
1451: break;
1452: case 'Z':
1453: outbuf[j++]=0;
1454: break;
1455: case 'A':
1456: default:
1457: if(exascii) {
1458: ch=tmpbuf[i];
1459: if(lowasctbl[ch].name!=NULL)
1460: j+=sprintf(outbuf+j,"&%s;",lowasctbl[ch].name);
1461: else
1462: j+=sprintf(outbuf+j,"&#%u;",lowasctbl[ch].value);
1463: } else
1464: j+=sprintf(outbuf+j,"&#%u;",inbuf[i]);
1465: i--;
1466: }
1467: i++;
1468: }
1469: else
1470: {
1471: if(nodisplay)
1472: continue;
1473: switch(tmpbuf[i])
1474: {
1475: case TAB: /* This assumes that tabs do NOT use the current background. */
1476: l=hpos%8;
1477: if(l==0)
1478: l=8;
1479: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1480: lastcolor=0;
1481: for(k=0; k<l ; k++)
1482: {
1483: j+=sprintf(outbuf+j,"%s"," ");
1484: hpos++;
1485: }
1486: break;
1487: case LF:
1488: wrapvpos=currrow;
1489: if(wrappos<j-3)
1490: wrappos=j;
1491: currrow++;
1492: if(hpos!=0 && tmpbuf[i+1]!=CR)
1493: {
1494: outbuf[j++]='\r';
1495: outbuf[j++]='\n';
1496: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1497: lastcolor=0;
1498: for(k=0; k<hpos ; k++)
1499: {
1500: j+=sprintf(outbuf+j,"%s"," ");
1501: }
1502: break;
1503: }
1504: case CR:
1505: if(wraphpos==-2 || hpos!=0)
1506: wraphpos=hpos;
1507: if(wrappos<j-3)
1508: wrappos=j;
1509: outbuf[j++]=tmpbuf[i];
1510: hpos=0;
1511: break;
1512: default:
1513: if(lastcolor != ((blink?(1<<7):0) | (bg << 4) | (bold?(1<<3):0) | fg))
1514: {
1515: lastcolor=(blink?(1<<7):0) | (bg << 4) | (bold?(1<<3):0) | fg;
1516: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[lastcolor],HTML_COLOR_SUFFIX);
1517: }
1518: if(hpos>=80 && tmpbuf[i+1] != '\r' && tmpbuf[i+1] != '\n' && tmpbuf[i+1] != ESC)
1519: {
1520: wrapvpos=-2;
1521: wraphpos=-2;
1522: wrappos=0;
1523: hpos=0;
1524: currrow++;
1525: outbuf[j++]='\r';
1526: outbuf[j++]='\n';
1527: }
1528: outbuf[j++]=tmpbuf[i];
1529: if(tmpbuf[i]=='&')
1530: extchar=TRUE;
1531: if(tmpbuf[i]==';')
1532: extchar=FALSE;
1533: if(!extchar)
1534: hpos++;
1535: }
1536: }
1537: }
1538: strcpy(outbuf+j,"</span>");
1539:
1540: js_str = JS_NewStringCopyZ(cx, outbuf);
1541: free(outbuf);
1542: }
1543: else
1544: js_str = JS_NewStringCopyZ(cx, tmpbuf);
1545:
1546: free(tmpbuf);
1547: if(js_str==NULL)
1548: return(JS_FALSE);
1549:
1550: *rval = STRING_TO_JSVAL(js_str);
1551: return(JS_TRUE);
1552: }
1553:
1554: static JSBool
1555: js_html_decode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1556: {
1557: int ch;
1558: int val;
1559: ulong i,j;
1560: uchar* inbuf;
1561: uchar* outbuf;
1562: char token[16];
1563: size_t t;
1564: JSString* js_str;
1565:
1566: if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1567: return(JS_FALSE);
1568:
1569: if((outbuf=(char*)malloc(strlen(inbuf)+1))==NULL)
1570: return(JS_FALSE);
1571:
1572: for(i=j=0;inbuf[i];i++) {
1573: if(inbuf[i]!='&') {
1574: outbuf[j++]=inbuf[i];
1575: continue;
1576: }
1577: for(i++,t=0; inbuf[i]!=0 && inbuf[i]!=';' && t<sizeof(token)-1; i++, t++)
1578: token[t]=inbuf[i];
1579: if(inbuf[i]==0)
1580: break;
1581: token[t]=0;
1582:
1583: /* First search the ex-ascii table for a name match */
1584: for(ch=0;ch<128;ch++)
1585: if(exasctbl[ch].name!=NULL && strcmp(token,exasctbl[ch].name)==0)
1586: break;
1587: if(ch<128) {
1588: outbuf[j++]=ch|0x80;
1589: continue;
1590: }
1591: if(token[0]=='#') { /* numeric constant */
1592: val=atoi(token+1);
1593:
1594: /* search ex-ascii table for a value match */
1595: for(ch=0;ch<128;ch++)
1596: if(exasctbl[ch].value==val)
1597: break;
1598: if(ch<128) {
1599: outbuf[j++]=ch|0x80;
1600: continue;
1601: }
1602:
1603: if((val>=' ' && val<=0xff) || val=='\r' || val=='\n' || val=='\t') {
1604: outbuf[j++]=val;
1605: continue;
1606: }
1607: }
1608: if(strcmp(token,"quot")==0) {
1609: outbuf[j++]='"';
1610: continue;
1611: }
1612: if(strcmp(token,"amp")==0) {
1613: outbuf[j++]='&';
1614: continue;
1615: }
1616: if(strcmp(token,"lt")==0) {
1617: outbuf[j++]='<';
1618: continue;
1619: }
1620: if(strcmp(token,"gt")==0) {
1621: outbuf[j++]='>';
1622: continue;
1623: }
1624: if(strcmp(token,"curren")==0) {
1625: outbuf[j++]=CTRL_O;
1626: continue;
1627: }
1628: if(strcmp(token,"para")==0) {
1629: outbuf[j++]=CTRL_T;
1630: continue;
1631: }
1632: if(strcmp(token,"sect")==0) {
1633: outbuf[j++]=CTRL_U;
1634: continue;
1635: }
1636: /* Unknown character entity, leave intact */
1637: j+=sprintf(outbuf+j,"&%s;",token);
1638:
1639: }
1640: outbuf[j]=0;
1641:
1642: js_str = JS_NewStringCopyZ(cx, outbuf);
1643: free(outbuf);
1644: if(js_str==NULL)
1645: return(JS_FALSE);
1646:
1647: *rval = STRING_TO_JSVAL(js_str);
1648: return(JS_TRUE);
1649: }
1650:
1651: static JSBool
1652: js_b64_encode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1653: {
1654: int res;
1655: size_t len;
1656: uchar* inbuf;
1657: uchar* outbuf;
1658: JSString* js_str;
1659:
1660: *rval = JSVAL_NULL;
1661:
1662: if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1663: return(JS_FALSE);
1664:
1665: len=(strlen(inbuf)*10)+1;
1666: if((outbuf=(char*)malloc(len))==NULL)
1667: return(JS_FALSE);
1668:
1669: res=b64_encode(outbuf,len,inbuf,strlen(inbuf));
1670:
1671: if(res<1) {
1672: free(outbuf);
1673: return(JS_TRUE);
1674: }
1675:
1676: js_str = JS_NewStringCopyZ(cx, outbuf);
1677: free(outbuf);
1678: if(js_str==NULL)
1679: return(JS_FALSE);
1680:
1681: *rval = STRING_TO_JSVAL(js_str);
1682: return(JS_TRUE);
1683: }
1684:
1685: static JSBool
1686: js_b64_decode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1687: {
1688: int res;
1689: size_t len;
1690: uchar* inbuf;
1691: uchar* outbuf;
1692: JSString* js_str;
1693:
1694: *rval = JSVAL_NULL;
1695:
1696: if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1697: return(JS_FALSE);
1698:
1699: len=strlen(inbuf)+1;
1700: if((outbuf=(char*)malloc(len))==NULL)
1701: return(JS_FALSE);
1702:
1703: res=b64_decode(outbuf,len,inbuf,strlen(inbuf));
1704:
1705: if(res<1) {
1706: free(outbuf);
1707: return(JS_TRUE);
1708: }
1709:
1710: js_str = JS_NewStringCopyN(cx, outbuf, res);
1711: free(outbuf);
1712: if(js_str==NULL)
1713: return(JS_FALSE);
1714:
1715: *rval = STRING_TO_JSVAL(js_str);
1716: return(JS_TRUE);
1717: }
1718:
1719: static JSBool
1720: js_md5_calc(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
1721: {
1722: BYTE digest[MD5_DIGEST_SIZE];
1723: JSBool hex=JS_FALSE;
1724: char* inbuf;
1725: char outbuf[64];
1726: JSString* js_str;
1727:
1728: *rval = JSVAL_NULL;
1729:
1730: if((inbuf=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1731: return(JS_FALSE);
1732:
1733: if(argc>1 && JSVAL_IS_BOOLEAN(argv[1]))
1734: hex=JSVAL_TO_BOOLEAN(argv[1]);
1735:
1736: MD5_calc(digest,inbuf,strlen(inbuf));
1737:
1738: if(hex)
1739: MD5_hex(outbuf,digest);
1740: else
1741: b64_encode(outbuf,sizeof(outbuf),digest,sizeof(digest));
1742:
1743: js_str = JS_NewStringCopyZ(cx, outbuf);
1744: if(js_str==NULL)
1745: return(JS_FALSE);
1746:
1747: *rval = STRING_TO_JSVAL(js_str);
1748: return(JS_TRUE);
1749: }
1750:
1751: static JSBool
1752: js_truncsp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1753: {
1754: char* p;
1755: char* str;
1756: JSString* js_str;
1757:
1758: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1759: return(JS_FALSE);
1760:
1761: if((p=strdup(str))==NULL)
1762: return(JS_FALSE);
1763:
1764: truncsp(p);
1765:
1766: js_str = JS_NewStringCopyZ(cx, p);
1767: free(p);
1768: if(js_str==NULL)
1769: return(JS_FALSE);
1770:
1771: *rval = STRING_TO_JSVAL(js_str);
1772: return(JS_TRUE);
1773: }
1774:
1775: static JSBool
1776: js_truncstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1777: {
1778: char* p;
1779: char* str;
1780: char* set;
1781: JSString* js_str;
1782:
1783: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1784: return(JS_FALSE);
1785:
1786: if((set=JS_GetStringBytes(JS_ValueToString(cx, argv[1])))==NULL)
1787: return(JS_FALSE);
1788:
1789: if((p=strdup(str))==NULL)
1790: return(JS_FALSE);
1791:
1792: truncstr(p,set);
1793:
1794: js_str = JS_NewStringCopyZ(cx, p);
1795: free(p);
1796: if(js_str==NULL)
1797: return(JS_FALSE);
1798:
1799: *rval = STRING_TO_JSVAL(js_str);
1800: return(JS_TRUE);
1801: }
1802:
1803: static JSBool
1804: js_backslash(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1805: {
1806: char path[MAX_PATH+1];
1807: char* str;
1808: JSString* js_str;
1809:
1810: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1811: return(JS_FALSE);
1812:
1813: SAFECOPY(path,str);
1814: backslash(path);
1815:
1816: if((js_str = JS_NewStringCopyZ(cx, path))==NULL)
1817: return(JS_FALSE);
1818:
1819: *rval = STRING_TO_JSVAL(js_str);
1820: return(JS_TRUE);
1821: }
1822:
1823:
1824: static JSBool
1825: js_getfname(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1826: {
1827: char* str;
1828: JSString* js_str;
1829:
1830: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1831: return(JS_FALSE);
1832:
1833: js_str = JS_NewStringCopyZ(cx, getfname(str));
1834: if(js_str==NULL)
1835: return(JS_FALSE);
1836:
1837: *rval = STRING_TO_JSVAL(js_str);
1838: return(JS_TRUE);
1839: }
1840:
1841: static JSBool
1842: js_getfext(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1843: {
1844: char* str;
1845: char* p;
1846: JSString* js_str;
1847:
1848: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1849: return(JS_FALSE);
1850:
1851: *rval = JSVAL_VOID;
1852:
1853: if((p=getfext(str))==NULL)
1854: return(JS_TRUE);
1855:
1856: js_str = JS_NewStringCopyZ(cx, p);
1857: if(js_str==NULL)
1858: return(JS_FALSE);
1859:
1860: *rval = STRING_TO_JSVAL(js_str);
1861: return(JS_TRUE);
1862: }
1863:
1864: static JSBool
1865: js_getfcase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1866: {
1867: char* str;
1868: char path[MAX_PATH+1];
1869: JSString* js_str;
1870:
1871: if((str=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1872: return(JS_FALSE);
1873:
1874: *rval = JSVAL_VOID;
1875:
1876: SAFECOPY(path,str);
1877: if(fexistcase(path)) {
1878: js_str = JS_NewStringCopyZ(cx, path);
1879: if(js_str==NULL)
1880: return(JS_FALSE);
1881:
1882: *rval = STRING_TO_JSVAL(js_str);
1883: }
1884: return(JS_TRUE);
1885: }
1886:
1887: static JSBool
1888: js_cfgfname(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1889: {
1890: char* path;
1891: char* fname;
1892: char result[MAX_PATH+1];
1893:
1894: if((path=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1895: return(JS_FALSE);
1896:
1897: if((fname=JS_GetStringBytes(JS_ValueToString(cx, argv[1])))==NULL)
1898: return(JS_FALSE);
1899:
1900: *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,iniFileName(result,sizeof(result),path,fname)));
1901:
1902: return(JS_TRUE);
1903: }
1904:
1905: static JSBool
1906: js_fexist(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1907: {
1908: char* p;
1909:
1910: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
1911: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
1912: return(JS_TRUE);
1913: }
1914:
1915: *rval = BOOLEAN_TO_JSVAL(fexist(p));
1916: return(JS_TRUE);
1917: }
1918:
1919: static JSBool
1920: js_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1921: {
1922: char* p;
1923:
1924: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
1925: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
1926: return(JS_TRUE);
1927: }
1928:
1929: *rval = BOOLEAN_TO_JSVAL(remove(p)==0);
1930: return(JS_TRUE);
1931: }
1932:
1933: static JSBool
1934: js_rename(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1935: {
1936: char* oldname;
1937: char* newname;
1938:
1939: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
1940: if((oldname=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1941: return(JS_TRUE);
1942: if((newname=JS_GetStringBytes(JS_ValueToString(cx, argv[1])))==NULL)
1943: return(JS_TRUE);
1944:
1945: *rval = BOOLEAN_TO_JSVAL(rename(oldname,newname)==0);
1946: return(JS_TRUE);
1947: }
1948:
1949: static JSBool
1950: js_fcopy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1951: {
1952: char* src;
1953: char* dest;
1954:
1955: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
1956: if((src=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1957: return(JS_TRUE);
1958: if((dest=JS_GetStringBytes(JS_ValueToString(cx, argv[1])))==NULL)
1959: return(JS_TRUE);
1960:
1961: *rval = BOOLEAN_TO_JSVAL(fcopy(src,dest));
1962: return(JS_TRUE);
1963: }
1964:
1965: static JSBool
1966: js_backup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1967: {
1968: char* fname;
1969: int32 level=5;
1970: BOOL ren=FALSE;
1971:
1972: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
1973: if((fname=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
1974: return(JS_TRUE);
1975:
1976: if(argc>1)
1977: JS_ValueToInt32(cx,argv[1],&level);
1978: if(argc>2)
1979: JS_ValueToBoolean(cx,argv[2],&ren);
1980:
1981: *rval = BOOLEAN_TO_JSVAL(backup(fname,level,ren));
1982: return(JS_TRUE);
1983: }
1984:
1985: static JSBool
1986: js_isdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1987: {
1988: char* p;
1989:
1990: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
1991: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
1992: return(JS_TRUE);
1993: }
1994:
1995: *rval = BOOLEAN_TO_JSVAL(isdir(p));
1996: return(JS_TRUE);
1997: }
1998:
1999: static JSBool
2000: js_fattr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2001: {
2002: char* p;
2003:
2004: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
2005: *rval = INT_TO_JSVAL(-1);
2006: return(JS_TRUE);
2007: }
2008:
2009: JS_NewNumberValue(cx,getfattr(p),rval);
2010: return(JS_TRUE);
2011: }
2012:
2013: static JSBool
2014: js_fdate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2015: {
2016: char* p;
2017:
2018: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
2019: *rval = INT_TO_JSVAL(-1);
2020: return(JS_TRUE);
2021: }
2022:
2023: JS_NewNumberValue(cx,fdate(p),rval);
2024: return(JS_TRUE);
2025: }
2026:
2027: static JSBool
2028: js_utime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2029: {
2030: char* fname;
2031: int32 actime;
2032: int32 modtime;
2033: struct utimbuf tbuf;
2034: struct utimbuf* t=NULL;
2035:
2036: *rval = JSVAL_FALSE;
2037:
2038: if((fname=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
2039: return(JS_TRUE);
2040:
2041: if(argc>1) {
2042: memset(&tbuf,0,sizeof(tbuf));
2043: actime=modtime=time(NULL);
2044: JS_ValueToInt32(cx,argv[1],&actime);
2045: JS_ValueToInt32(cx,argv[2],&modtime);
2046: tbuf.actime=actime;
2047: tbuf.modtime=modtime;
2048: t=&tbuf;
2049: }
2050:
2051: *rval = BOOLEAN_TO_JSVAL(utime(fname,t)==0);
2052:
2053: return(JS_TRUE);
2054: }
2055:
2056:
2057: static JSBool
2058: js_flength(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2059: {
2060: char* p;
2061:
2062: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
2063: *rval = INT_TO_JSVAL(-1);
2064: return(JS_TRUE);
2065: }
2066:
2067: JS_NewNumberValue(cx,flength(p),rval);
2068: return(JS_TRUE);
2069: }
2070:
2071:
2072: static JSBool
2073: js_ftouch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2074: {
2075: char* fname;
2076:
2077: if((fname=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
2078: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
2079: return(JS_TRUE);
2080: }
2081:
2082: *rval = BOOLEAN_TO_JSVAL(ftouch(fname));
2083: return(JS_TRUE);
2084: }
2085:
2086: static JSBool
2087: js_fmutex(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2088: {
2089: char* fname;
2090: char* text=NULL;
2091:
2092: if((fname=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
2093: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
2094: return(JS_TRUE);
2095: }
2096: if(argc>1)
2097: text=JS_GetStringBytes(JS_ValueToString(cx,argv[1]));
2098:
2099: *rval = BOOLEAN_TO_JSVAL(fmutex(fname,text));
2100: return(JS_TRUE);
2101: }
2102:
2103: static JSBool
2104: js_sound(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2105: {
2106: char* p;
2107:
2108: if(!argc) { /* Stop playing sound */
2109: #ifdef _WIN32
2110: PlaySound(NULL,NULL,0);
2111: #endif
2112: *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
2113: return(JS_TRUE);
2114: }
2115:
2116: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
2117: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
2118: return(JS_TRUE);
2119: }
2120:
2121: #ifdef _WIN32
2122: *rval = BOOLEAN_TO_JSVAL(PlaySound(p, NULL, SND_ASYNC|SND_FILENAME));
2123: #else
2124: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
2125: #endif
2126:
2127: return(JS_TRUE);
2128: }
2129:
2130: static JSBool
2131: js_directory(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2132: {
2133: int i;
2134: int32 flags=GLOB_MARK;
2135: char* p;
2136: glob_t g;
2137: JSObject* array;
2138: JSString* js_str;
2139: jsint len=0;
2140: jsval val;
2141:
2142: *rval = JSVAL_NULL;
2143:
2144: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
2145: return(JS_TRUE);
2146:
2147: if(argc>1)
2148: JS_ValueToInt32(cx,argv[1],&flags);
2149:
2150: if((array = JS_NewArrayObject(cx, 0, NULL))==NULL)
2151: return(JS_FALSE);
2152:
2153: glob(p,flags,NULL,&g);
2154: for(i=0;i<(int)g.gl_pathc;i++) {
2155: if((js_str=JS_NewStringCopyZ(cx,g.gl_pathv[i]))==NULL)
2156: break;
2157: val=STRING_TO_JSVAL(js_str);
2158: if(!JS_SetElement(cx, array, len++, &val))
2159: break;
2160: }
2161: globfree(&g);
2162:
2163: *rval = OBJECT_TO_JSVAL(array);
2164:
2165: return(JS_TRUE);
2166: }
2167:
2168: static JSBool
2169: js_freediskspace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2170: {
2171: int32 unit=0;
2172: char* p;
2173:
2174: *rval = JSVAL_VOID;
2175:
2176: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL)
2177: return(JS_TRUE);
2178:
2179: if(argc>1)
2180: JS_ValueToInt32(cx,argv[1],&unit);
2181:
2182: JS_NewNumberValue(cx,getfreediskspace(p,unit),rval);
2183:
2184: return(JS_TRUE);
2185: }
2186:
2187:
2188: static JSBool
2189: js_socket_select(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2190: {
2191: JSObject* inarray=NULL;
2192: JSObject* rarray;
2193: BOOL poll_for_write=FALSE;
2194: fd_set socket_set;
2195: fd_set* rd_set=NULL;
2196: fd_set* wr_set=NULL;
2197: uintN argn;
2198: SOCKET sock;
2199: SOCKET maxsock=0;
2200: struct timeval tv = {0, 0};
2201: jsuint i;
2202: jsuint limit;
2203: SOCKET* index;
2204: jsval val;
2205: int len=0;
2206:
2207: *rval = JSVAL_NULL;
2208:
2209: for(argn=0;argn<argc;argn++) {
2210: if(JSVAL_IS_BOOLEAN(argv[argn]))
2211: poll_for_write=JSVAL_TO_BOOLEAN(argv[argn]);
2212: else if(JSVAL_IS_OBJECT(argv[argn]))
2213: inarray = JSVAL_TO_OBJECT(argv[argn]);
2214: else if(JSVAL_IS_NUMBER(argv[argn]))
2215: js_timeval(cx,argv[argn],&tv);
2216: }
2217:
2218: if(inarray==NULL || !JS_IsArrayObject(cx, inarray))
2219: return(JS_TRUE); /* This not a fatal error */
2220:
2221: if(!JS_GetArrayLength(cx, inarray, &limit))
2222: return(JS_TRUE);
2223:
2224: /* Return array */
2225: if((rarray = JS_NewArrayObject(cx, 0, NULL))==NULL)
2226: return(JS_FALSE);
2227:
2228: if((index=(SOCKET *)MALLOC(sizeof(SOCKET)*limit))==NULL)
2229: return(JS_FALSE);
2230:
2231: FD_ZERO(&socket_set);
2232: if(poll_for_write)
2233: wr_set=&socket_set;
2234: else
2235: rd_set=&socket_set;
2236:
2237: for(i=0;i<limit;i++) {
2238: if(!JS_GetElement(cx, inarray, i, &val))
2239: break;
2240: sock=js_socket(cx,val);
2241: index[i]=sock;
2242: if(sock!=INVALID_SOCKET) {
2243: FD_SET(sock,&socket_set);
2244: if(sock>maxsock)
2245: maxsock=sock;
2246: }
2247: }
2248:
2249: if(select(maxsock+1,rd_set,wr_set,NULL,&tv)<0)
2250: lprintf(LOG_DEBUG,"Error in socket_select() %s (%d)",strerror(errno),errno);
2251:
2252: for(i=0;i<limit;i++) {
2253: if(index[i]!=INVALID_SOCKET && FD_ISSET(index[i],&socket_set)) {
2254: val=INT_TO_JSVAL(i);
2255: if(!JS_SetElement(cx, rarray, len++, &val))
2256: break;
2257: }
2258: }
2259: free(index);
2260:
2261: *rval = OBJECT_TO_JSVAL(rarray);
2262:
2263: return(JS_TRUE);
2264: }
2265:
2266: static JSBool
2267: js_mkdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2268: {
2269: char* p;
2270:
2271: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
2272: *rval = INT_TO_JSVAL(-1);
2273: return(JS_TRUE);
2274: }
2275:
2276: *rval = BOOLEAN_TO_JSVAL(MKDIR(p)==0);
2277: return(JS_TRUE);
2278: }
2279:
2280: static JSBool
2281: js_rmdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2282: {
2283: char* p;
2284:
2285: if((p=JS_GetStringBytes(JS_ValueToString(cx, argv[0])))==NULL) {
2286: *rval = INT_TO_JSVAL(-1);
2287: return(JS_TRUE);
2288: }
2289:
2290: *rval = BOOLEAN_TO_JSVAL(rmdir(p)==0);
2291: return(JS_TRUE);
2292: }
2293:
2294:
2295: static JSBool
2296: js_strftime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2297: {
2298: char str[128];
2299: char* fmt;
2300: int32 i=time(NULL);
2301: time_t t;
2302: struct tm tm;
2303: JSString* js_str;
2304:
2305: fmt=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
2306: if(argc>1)
2307: JS_ValueToInt32(cx,argv[1],&i);
2308:
2309: strcpy(str,"-Invalid time-");
2310: t=i;
2311: if(localtime_r(&t,&tm)==NULL)
2312: memset(&tm,0,sizeof(tm));
2313: strftime(str,sizeof(str),fmt,&tm);
2314:
2315: if((js_str=JS_NewStringCopyZ(cx, str))==NULL)
2316: return(JS_FALSE);
2317:
2318: *rval = STRING_TO_JSVAL(js_str);
2319: return(JS_TRUE);
2320: }
2321:
2322: static JSBool
2323: js_resolve_ip(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2324: {
2325: struct in_addr addr;
2326: JSString* str;
2327:
2328: *rval = JSVAL_NULL;
2329:
2330: if(argv[0]==JSVAL_VOID)
2331: return(JS_TRUE);
2332:
2333: if((addr.s_addr=resolve_ip(JS_GetStringBytes(JS_ValueToString(cx, argv[0]))))
2334: ==INADDR_NONE)
2335: return(JS_TRUE);
2336:
2337: if((str=JS_NewStringCopyZ(cx, inet_ntoa(addr)))==NULL)
2338: return(JS_FALSE);
2339:
2340: *rval = STRING_TO_JSVAL(str);
2341: return(JS_TRUE);
2342: }
2343:
2344:
2345: static JSBool
2346: js_resolve_host(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2347: {
2348: struct in_addr addr;
2349: HOSTENT* h;
2350:
2351: *rval = JSVAL_NULL;
2352:
2353: if(argv[0]==JSVAL_VOID)
2354: return(JS_TRUE);
2355:
2356: addr.s_addr=inet_addr(JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
2357: h=gethostbyaddr((char *)&addr,sizeof(addr),AF_INET);
2358:
2359: if(h!=NULL && h->h_name!=NULL)
2360: *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,h->h_name));
2361:
2362: return(JS_TRUE);
2363:
2364: }
2365:
2366: extern link_list_t named_queues; /* js_queue.c */
2367:
2368: static JSBool
2369: js_list_named_queues(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2370: {
2371: JSObject* array;
2372: jsint len=0;
2373: jsval val;
2374: list_node_t* node;
2375: msg_queue_t* q;
2376:
2377: if((array = JS_NewArrayObject(cx, 0, NULL))==NULL)
2378: return(JS_FALSE);
2379:
2380: for(node=listFirstNode(&named_queues);node!=NULL;node=listNextNode(node)) {
2381: if((q=listNodeData(node))==NULL)
2382: continue;
2383: val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,q->name));
2384: if(!JS_SetElement(cx, array, len++, &val))
2385: break;
2386: }
2387:
2388: *rval = OBJECT_TO_JSVAL(array);
2389:
2390: return(JS_TRUE);
2391: }
2392:
2393: static JSClass js_global_class = {
2394: "Global" /* name */
2395: ,JSCLASS_HAS_PRIVATE /* flags */
2396: ,JS_PropertyStub /* addProperty */
2397: ,JS_PropertyStub /* delProperty */
2398: ,js_system_get /* getProperty */
2399: ,JS_PropertyStub /* setProperty */
2400: ,JS_EnumerateStub /* enumerate */
2401: ,JS_ResolveStub /* resolve */
2402: ,JS_ConvertStub /* convert */
2403: ,JS_FinalizeStub /* finalize */
2404: };
2405:
2406: static jsSyncMethodSpec js_global_functions[] = {
2407: {"exit", js_exit, 0, JSTYPE_VOID, "[number exit_code]"
2408: ,JSDOCSTR("stop script execution, "
2409: "optionally setting the global property <tt>exit_code</tt> to the specified numeric value")
2410: ,311
2411: },
2412: {"load", js_load, 1, JSTYPE_UNDEF
2413: ,JSDOCSTR("[<i>bool</i> background or <i>object</i> scope,] <i>string</i> filename [,args]")
2414: ,JSDOCSTR("load and execute a JavaScript module (<i>filename</i>), "
2415: "optionally specifying a target <i>scope</i> object (default: <i>this</i>) "
2416: "and a list of arguments to pass to the module (as <i>argv</i>). "
2417: "Returns the result (last executed statement) of the executed script "
2418: "or a newly created <i>Queue</i> object if <i>background</i> is <i>true</i>).<br><br>"
2419: "<b>Background</b> (added in v3.12):<br>"
2420: "If <i>background</i> is <i>true</i>, the loaded script runs in the background "
2421: "(in a child thread) but may communicate with the parent "
2422: "script/thread by reading from and/or writing to the <i>parent_queue</i> "
2423: "(an automatically created <i>Queue</i> object). "
2424: "The result (last executed statement) of the executed script will also be automatically "
2425: "written to the <i>parent_queue</i> "
2426: "which may be read later by the parent script.")
2427: ,312
2428: },
2429: {"sleep", js_mswait, 0, JSTYPE_ALIAS },
2430: {"mswait", js_mswait, 0, JSTYPE_VOID, JSDOCSTR("[number milliseconds]")
2431: ,JSDOCSTR("millisecond wait/sleep routine (AKA sleep)")
2432: ,310
2433: },
2434: {"yield", js_yield, 0, JSTYPE_VOID, JSDOCSTR("[bool forced]")
2435: ,JSDOCSTR("release current thread time-slice, "
2436: "a <i>forced</i> yield will yield to all other pending tasks (lowering CPU utilization), "
2437: "a non-<i>forced</i> yield will yield only to pending tasks of equal or higher priority. "
2438: "<i>forced</i> defaults to <i>true</i>")
2439: ,311
2440: },
2441: {"random", js_random, 1, JSTYPE_NUMBER, JSDOCSTR("number max")
2442: ,JSDOCSTR("return random integer between 0 and max-1")
2443: ,310
2444: },
2445: {"time", js_time, 0, JSTYPE_NUMBER, ""
2446: ,JSDOCSTR("return current time in Unix (time_t) format (number of seconds since Jan-01-1970)")
2447: ,310
2448: },
2449: {"beep", js_beep, 0, JSTYPE_VOID, JSDOCSTR("[number freq, duration]")
2450: ,JSDOCSTR("produce a tone on the local speaker at specified frequency for specified duration (in milliseconds)")
2451: ,310
2452: },
2453: {"sound", js_sound, 0, JSTYPE_BOOLEAN, JSDOCSTR("[string filename]")
2454: ,JSDOCSTR("play a waveform (.wav) sound file (currently, on Windows platforms only)")
2455: ,310
2456: },
2457: {"ctrl", js_ctrl, 1, JSTYPE_STRING, JSDOCSTR("number or string")
2458: ,JSDOCSTR("return ASCII control character representing character passed - Example: <tt>ctrl('C') returns '\3'</tt>")
2459: ,311
2460: },
2461: {"ascii", js_ascii, 1, JSTYPE_UNDEF, JSDOCSTR("[string text] or [number value]")
2462: ,JSDOCSTR("convert string to ASCII value or vice-versa (returns number OR string)")
2463: ,310
2464: },
2465: {"ascii_str", js_ascii_str, 1, JSTYPE_STRING, JSDOCSTR("string text")
2466: ,JSDOCSTR("convert extended-ASCII in string to plain ASCII")
2467: ,310
2468: },
2469: {"strip_ctrl", js_strip_ctrl, 1, JSTYPE_STRING, JSDOCSTR("string text")
2470: ,JSDOCSTR("strip control characters from string")
2471: ,310
2472: },
2473: {"strip_exascii", js_strip_exascii, 1, JSTYPE_STRING, JSDOCSTR("string text")
2474: ,JSDOCSTR("strip extended-ASCII characters from string")
2475: ,310
2476: },
2477: {"truncsp", js_truncsp, 1, JSTYPE_STRING, JSDOCSTR("string text")
2478: ,JSDOCSTR("truncate (trim) white-space characters off end of string")
2479: ,310
2480: },
2481: {"truncstr", js_truncstr, 2, JSTYPE_STRING, JSDOCSTR("string text, charset")
2482: ,JSDOCSTR("truncate (trim) string at first char in <i>charset</i>")
2483: ,310
2484: },
2485: {"lfexpand", js_lfexpand, 1, JSTYPE_STRING, JSDOCSTR("string text")
2486: ,JSDOCSTR("expand line-feeds (LF) to carriage-return/line-feeds (CRLF)")
2487: ,310
2488: },
2489: {"backslash", js_backslash, 1, JSTYPE_STRING, JSDOCSTR("string path")
2490: ,JSDOCSTR("returns directory path with trailing (platform-specific) path delimeter "
2491: "(i.e. \"slash\" or \"backslash\")")
2492: ,312
2493: },
2494: {"file_getname", js_getfname, 1, JSTYPE_STRING, JSDOCSTR("string path")
2495: ,JSDOCSTR("returns filename portion of passed path string")
2496: ,311
2497: },
2498: {"file_getext", js_getfext, 1, JSTYPE_STRING, JSDOCSTR("string path")
2499: ,JSDOCSTR("returns file extension portion of passed path/filename string (including '.') "
2500: "or <i>undefined</i> if no extension is found")
2501: ,311
2502: },
2503: {"file_getcase", js_getfcase, 1, JSTYPE_STRING, JSDOCSTR("string filename")
2504: ,JSDOCSTR("returns correct case of filename (long version of filename on Win32) "
2505: "or <i>undefined</i> if the file doesn't exist")
2506: ,311
2507: },
2508: {"file_cfgname", js_cfgfname, 2, JSTYPE_STRING, JSDOCSTR("string path, filename")
2509: ,JSDOCSTR("returns completed configuration filename from supplied <i>path</i> and <i>filename</i>, "
2510: "optionally including the local hostname (e.g. <tt>path/file.<i>host</i>.<i>domain</i>.ext</tt> "
2511: "or <tt>path/file.<i>host</i>.ext</tt>) if such a variation of the filename exists")
2512: ,312
2513: },
2514: {"file_exists", js_fexist, 1, JSTYPE_BOOLEAN, JSDOCSTR("string filename")
2515: ,JSDOCSTR("verify a file's existence")
2516: ,310
2517: },
2518: {"file_remove", js_remove, 1, JSTYPE_BOOLEAN, JSDOCSTR("string filename")
2519: ,JSDOCSTR("delete a file")
2520: ,310
2521: },
2522: {"file_rename", js_rename, 2, JSTYPE_BOOLEAN, JSDOCSTR("oldname, newname")
2523: ,JSDOCSTR("rename a file, possibly moving it to another directory in the process")
2524: ,311
2525: },
2526: {"file_copy", js_fcopy, 2, JSTYPE_BOOLEAN, JSDOCSTR("source, destination")
2527: ,JSDOCSTR("copy a file from one directory or filename to another")
2528: ,311
2529: },
2530: {"file_backup", js_backup, 1, JSTYPE_BOOLEAN, JSDOCSTR("string filename [,number level] [,bool rename]")
2531: ,JSDOCSTR("backup the specified <i>filename</i> as <tt>filename.<i>number</i>.extension</tt> "
2532: "where <i>number</i> is the backup number 0 through <i>level</i>-1 "
2533: "(default backup <i>level</i> is 5), "
2534: "if <i>rename</i> is <i>true</i>, the original file is renamed instead of copied "
2535: "(default is <i>false</i>)")
2536: ,311
2537: },
2538: {"file_isdir", js_isdir, 1, JSTYPE_BOOLEAN, JSDOCSTR("string filename")
2539: ,JSDOCSTR("check if specified <i>filename</i> is a directory")
2540: ,310
2541: },
2542: {"file_attrib", js_fattr, 1, JSTYPE_NUMBER, JSDOCSTR("string filename")
2543: ,JSDOCSTR("get a file's permissions/attributes")
2544: ,310
2545: },
2546: {"file_date", js_fdate, 1, JSTYPE_NUMBER, JSDOCSTR("string filename")
2547: ,JSDOCSTR("get a file's last modified date/time (in time_t format)")
2548: ,310
2549: },
2550: {"file_size", js_flength, 1, JSTYPE_NUMBER, JSDOCSTR("string filename")
2551: ,JSDOCSTR("get a file's length (in bytes)")
2552: ,310
2553: },
2554: {"file_utime", js_utime, 3, JSTYPE_BOOLEAN, JSDOCSTR("string filename [,access_time] [,mod_time]")
2555: ,JSDOCSTR("change a file's last accessed and modification date/time (in time_t format), "
2556: "or change to current time")
2557: ,311
2558: },
2559: {"file_touch", js_ftouch, 1, JSTYPE_BOOLEAN, JSDOCSTR("string filename")
2560: ,JSDOCSTR("updates a file's last modification date/time to current time, "
2561: "creating an empty file if it doesn't already exist")
2562: ,311
2563: },
2564: {"file_mutex", js_fmutex, 1, JSTYPE_BOOLEAN, JSDOCSTR("string filename [,text]")
2565: ,JSDOCSTR("attempts to create an exclusive (e.g. lock) file, "
2566: "optionally with the contents of <i>text</i>")
2567: ,312
2568: },
2569: {"directory", js_directory, 1, JSTYPE_ARRAY, JSDOCSTR("string pattern [,flags]")
2570: ,JSDOCSTR("returns an array of directory entries, "
2571: "<i>pattern</i> is the path and filename or wildcards to search for (e.g. '/subdir/*.txt'), "
2572: "<i>flags</i> is a bitfield of optional <tt>glob</tt> flags (default is <tt>GLOB_MARK</tt>)")
2573: ,310
2574: },
2575: {"dir_freespace", js_freediskspace, 2, JSTYPE_NUMBER, JSDOCSTR("string directory [,unit_size]")
2576: ,JSDOCSTR("returns the amount of available disk space in the specified <i>directory</i> "
2577: "using the specified <i>unit_size</i> in bytes (default: 1), "
2578: "specify a <i>unit_size</i> of <tt>1024</tt> to return the available space in <i>kilobytes</i>.")
2579: ,311
2580: },
2581: {"socket_select", js_socket_select, 0, JSTYPE_ARRAY, JSDOCSTR("[array of socket objects or descriptors] [,number timeout] [,bool write]")
2582: ,JSDOCSTR("checks an array of socket objects or descriptors for read or write ability (default is <i>read</i>), "
2583: "default timeout value is 0.0 seconds (immediate timeout), "
2584: "returns an array of 0-based index values into the socket array, representing the sockets that were ready for reading or writing")
2585: ,311
2586: },
2587: {"mkdir", js_mkdir, 1, JSTYPE_BOOLEAN, JSDOCSTR("string directory")
2588: ,JSDOCSTR("make a directory")
2589: ,310
2590: },
2591: {"rmdir", js_rmdir, 1, JSTYPE_BOOLEAN, JSDOCSTR("string directory")
2592: ,JSDOCSTR("remove a directory")
2593: ,310
2594: },
2595: {"strftime", js_strftime, 1, JSTYPE_STRING, JSDOCSTR("string format [,number time]")
2596: ,JSDOCSTR("return a formatted time string (ala C strftime)")
2597: ,310
2598: },
2599: {"format", js_format, 1, JSTYPE_STRING, JSDOCSTR("string format [,args]")
2600: ,JSDOCSTR("return a formatted string (ala sprintf) - "
2601: "<small>CAUTION: for experienced C programmers ONLY</small>")
2602: ,310
2603: },
2604: {"html_encode", js_html_encode, 1, JSTYPE_STRING, JSDOCSTR("string text [,bool ex_ascii] [,bool white_space] [,bool ansi] [,bool ctrl_a]")
2605: ,JSDOCSTR("return an HTML-encoded text string (using standard HTML character entities), "
2606: "escaping IBM extended-ASCII, white-space characters, ANSI codes, and CTRL-A codes by default")
2607: ,311
2608: },
2609: {"html_decode", js_html_decode, 1, JSTYPE_STRING, JSDOCSTR("string text")
2610: ,JSDOCSTR("return a decoded HTML-encoded text string")
2611: ,311
2612: },
2613: {"word_wrap", js_word_wrap, 1, JSTYPE_STRING, JSDOCSTR("string text [,line_length]")
2614: ,JSDOCSTR("returns a word-wrapped version of the text string argument, <i>line_length</i> defaults to <i>79</i>")
2615: ,311
2616: },
2617: {"quote_msg", js_quote_msg, 1, JSTYPE_STRING, JSDOCSTR("string text [,line_length] [,prefix]")
2618: ,JSDOCSTR("returns a quoted version of the message text string argument, <i>line_length</i> defaults to <i>79</i>, "
2619: "<i>prefix</i> defaults to <tt>\" > \"</tt>")
2620: ,311
2621: },
2622: {"rot13_translate", js_rot13, 1, JSTYPE_STRING, JSDOCSTR("string text")
2623: ,JSDOCSTR("returns ROT13-translated version of text string (will encode or decode text)")
2624: ,311
2625: },
2626: {"base64_encode", js_b64_encode, 1, JSTYPE_STRING, JSDOCSTR("string text")
2627: ,JSDOCSTR("returns base64-encoded version of text string or <i>null</i> on error")
2628: ,311
2629: },
2630: {"base64_decode", js_b64_decode, 1, JSTYPE_STRING, JSDOCSTR("string text")
2631: ,JSDOCSTR("returns base64-decoded text string or <i>null</i> on error")
2632: ,311
2633: },
2634: {"crc16_calc", js_crc16, 1, JSTYPE_NUMBER, JSDOCSTR("string text")
2635: ,JSDOCSTR("calculate and return 16-bit CRC of text string")
2636: ,311
2637: },
2638: {"crc32_calc", js_crc32, 1, JSTYPE_NUMBER, JSDOCSTR("string text")
2639: ,JSDOCSTR("calculate and return 32-bit CRC of text string")
2640: ,311
2641: },
2642: {"chksum_calc", js_chksum, 1, JSTYPE_NUMBER, JSDOCSTR("string text")
2643: ,JSDOCSTR("calculate and return 32-bit checksum of text string")
2644: ,311
2645: },
2646: {"md5_calc", js_md5_calc, 1, JSTYPE_STRING, JSDOCSTR("string text [,bool hex]")
2647: ,JSDOCSTR("calculate and return 128-bit MD5 digest of text string, result encoded in base64 (default) or hexadecimal")
2648: ,311
2649: },
2650: {"gethostbyname", js_resolve_ip, 1, JSTYPE_ALIAS },
2651: {"resolve_ip", js_resolve_ip, 1, JSTYPE_STRING, JSDOCSTR("string hostname")
2652: ,JSDOCSTR("resolve IP address of specified hostname (AKA gethostbyname)")
2653: ,311
2654: },
2655: {"gethostbyaddr", js_resolve_host, 1, JSTYPE_ALIAS },
2656: {"resolve_host", js_resolve_host, 1, JSTYPE_STRING, JSDOCSTR("string ip_address")
2657: ,JSDOCSTR("resolve hostname of specified IP address (AKA gethostbyaddr)")
2658: ,311
2659: },
2660: {"netaddr_type", js_netaddr_type, 1, JSTYPE_NUMBER, JSDOCSTR("string email_address")
2661: ,JSDOCSTR("returns the proper message <i>net_type</i> for the specified <i>email_address</i>, "
2662: "(e.g. <tt>NET_INTERNET</tt> for Internet e-mail or <tt>NET_NONE</tt> for local e-mail)")
2663: ,312
2664: },
2665: {"list_named_queues",js_list_named_queues,0,JSTYPE_ARRAY, JSDOCSTR("")
2666: ,JSDOCSTR("returns an array of <i>named queues</i> (created with the <i>Queue</i> constructor)")
2667: ,312
2668: },
2669:
2670: {0}
2671: };
2672:
2673: static jsConstIntSpec js_global_const_ints[] = {
2674: /* Numeric error constants from errno.h (platform-dependant) */
2675: {"EPERM" ,EPERM },
2676: {"ENOENT" ,ENOENT },
2677: {"ESRCH" ,ESRCH },
2678: {"EIO" ,EIO },
2679: {"ENXIO" ,ENXIO },
2680: {"E2BIG" ,E2BIG },
2681: {"ENOEXEC" ,ENOEXEC },
2682: {"EBADF" ,EBADF },
2683: {"ECHILD" ,ECHILD },
2684: {"EAGAIN" ,EAGAIN },
2685: {"ENOMEM" ,ENOMEM },
2686: {"EACCES" ,EACCES },
2687: {"EFAULT" ,EFAULT },
2688: {"EBUSY" ,EBUSY },
2689: {"EEXIST" ,EEXIST },
2690: {"EXDEV" ,EXDEV },
2691: {"ENODEV" ,ENODEV },
2692: {"ENOTDIR" ,ENOTDIR },
2693: {"EISDIR" ,EISDIR },
2694: {"EINVAL" ,EINVAL },
2695: {"ENFILE" ,ENFILE },
2696: {"EMFILE" ,EMFILE },
2697: {"ENOTTY" ,ENOTTY },
2698: {"EFBIG" ,EFBIG },
2699: {"ENOSPC" ,ENOSPC },
2700: {"ESPIPE" ,ESPIPE },
2701: {"EROFS" ,EROFS },
2702: {"EMLINK" ,EMLINK },
2703: {"EPIPE" ,EPIPE },
2704: {"EDOM" ,EDOM },
2705: {"ERANGE" ,ERANGE },
2706: {"EDEADLOCK" ,EDEADLOCK },
2707: {"ENAMETOOLONG" ,ENAMETOOLONG },
2708: {"ENOTEMPTY" ,ENOTEMPTY },
2709:
2710: /* Socket errors */
2711: {"EINTR" ,EINTR },
2712: {"ENOTSOCK" ,ENOTSOCK },
2713: {"EMSGSIZE" ,EMSGSIZE },
2714: {"EWOULDBLOCK" ,EWOULDBLOCK },
2715: {"EPROTOTYPE" ,EPROTOTYPE },
2716: {"ENOPROTOOPT" ,ENOPROTOOPT },
2717: {"EPROTONOSUPPORT" ,EPROTONOSUPPORT},
2718: {"ESOCKTNOSUPPORT" ,ESOCKTNOSUPPORT},
2719: {"EOPNOTSUPP" ,EOPNOTSUPP },
2720: {"EPFNOSUPPORT" ,EPFNOSUPPORT },
2721: {"EAFNOSUPPORT" ,EAFNOSUPPORT },
2722: {"EADDRINUSE" ,EADDRINUSE },
2723: {"EADDRNOTAVAIL" ,EADDRNOTAVAIL },
2724: {"ECONNABORTED" ,ECONNABORTED },
2725: {"ECONNRESET" ,ECONNRESET },
2726: {"ENOBUFS" ,ENOBUFS },
2727: {"EISCONN" ,EISCONN },
2728: {"ENOTCONN" ,ENOTCONN },
2729: {"ESHUTDOWN" ,ESHUTDOWN },
2730: {"ETIMEDOUT" ,ETIMEDOUT },
2731: {"ECONNREFUSED" ,ECONNREFUSED },
2732: {"EINPROGRESS" ,EINPROGRESS },
2733:
2734: /* Log priority values from syslog.h/sbbsdefs.h (possibly platform-dependant) */
2735: {"LOG_EMERG" ,LOG_EMERG },
2736: {"LOG_ALERT" ,LOG_ALERT },
2737: {"LOG_CRIT" ,LOG_CRIT },
2738: {"LOG_ERR" ,LOG_ERR },
2739: {"LOG_ERROR" ,LOG_ERR },
2740: {"LOG_WARNING" ,LOG_WARNING },
2741: {"LOG_NOTICE" ,LOG_NOTICE },
2742: {"LOG_INFO" ,LOG_INFO },
2743: {"LOG_DEBUG" ,LOG_DEBUG },
2744:
2745: /* Other useful constants */
2746: {"INVALID_SOCKET" ,INVALID_SOCKET },
2747:
2748: /* Terminator (Governor Arnold) */
2749: {0}
2750: };
2751:
2752: JSObject* DLLCALL js_CreateGlobalObject(JSContext* cx, scfg_t* cfg, jsSyncMethodSpec* methods)
2753: {
2754: JSObject* glob;
2755:
2756: if((glob = JS_NewObject(cx, &js_global_class, NULL, NULL)) ==NULL)
2757: return(NULL);
2758:
2759: if (!JS_InitStandardClasses(cx, glob))
2760: return(NULL);
2761:
2762: if(methods!=NULL && !js_DefineSyncMethods(cx, glob, methods, TRUE))
2763: return(NULL);
2764:
2765: if(!js_DefineSyncMethods(cx, glob, js_global_functions, TRUE))
2766: return(NULL);
2767:
2768: if(!JS_DefineProperties(cx, glob, js_global_properties))
2769: return(NULL);
2770:
2771: if(!JS_SetPrivate(cx, glob, cfg)) /* Store a pointer to scfg_t */
2772: return(NULL);
2773:
2774: #ifdef _DEBUG
2775: js_DescribeSyncObject(cx,glob
2776: ,"Top-level functions and properties (common to all servers and services)",310);
2777: #endif
2778:
2779: if(!js_DefineConstIntegers(cx, glob, js_global_const_ints, JSPROP_READONLY))
2780: return(NULL);
2781:
2782: return(glob);
2783: }
2784:
2785: JSObject* DLLCALL js_CreateCommonObjects(JSContext* js_cx
2786: ,scfg_t* cfg /* common */
2787: ,scfg_t* node_cfg /* node-specific */
2788: ,jsSyncMethodSpec* methods /* global */
2789: ,time_t uptime /* system */
2790: ,char* host_name /* system */
2791: ,char* socklib_desc /* system */
2792: ,js_branch_t* branch /* js */
2793: ,client_t* client /* client */
2794: ,SOCKET client_socket /* client */
2795: ,js_server_props_t* props /* server */
2796: )
2797: {
2798: JSObject* js_glob;
2799:
2800: if(node_cfg==NULL)
2801: node_cfg=cfg;
2802:
2803: /* Global Object */
2804: if((js_glob=js_CreateGlobalObject(js_cx, cfg, methods))==NULL)
2805: return(NULL);
2806:
2807: /* System Object */
2808: if(js_CreateSystemObject(js_cx, js_glob, node_cfg, uptime, host_name, socklib_desc)==NULL)
2809: return(NULL);
2810:
2811: /* Internal JS Object */
2812: if(branch!=NULL
2813: && js_CreateInternalJsObject(js_cx, js_glob, branch)==NULL)
2814: return(NULL);
2815:
2816: /* Client Object */
2817: if(client!=NULL
2818: && js_CreateClientObject(js_cx, js_glob, "client", client, client_socket)==NULL)
2819: return(NULL);
2820:
2821: /* Server */
2822: if(props!=NULL
2823: && js_CreateServerObject(js_cx, js_glob, props)==NULL)
2824: return(NULL);
2825:
2826: /* Socket Class */
2827: if(js_CreateSocketClass(js_cx, js_glob)==NULL)
2828: return(NULL);
2829:
2830: /* Queue Class */
2831: if(js_CreateQueueClass(js_cx, js_glob)==NULL)
2832: return(NULL);
2833:
2834: /* MsgBase Class */
2835: if(js_CreateMsgBaseClass(js_cx, js_glob, cfg)==NULL)
2836: return(NULL);
2837:
2838: /* File Class */
2839: if(js_CreateFileClass(js_cx, js_glob)==NULL)
2840: return(NULL);
2841:
2842: /* User class */
2843: if(js_CreateUserClass(js_cx, js_glob, cfg)==NULL)
2844: return(NULL);
2845:
2846: /* Area Objects */
2847: if(!js_CreateUserObjects(js_cx, js_glob, cfg, NULL, NULL, NULL))
2848: return(NULL);
2849:
2850: return(js_glob);
2851: }
2852:
2853:
2854: #endif /* JAVSCRIPT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.