|
|
1.1 root 1: /* js_global.c */
2:
3: /* Synchronet JavaScript "global" object properties/methods for all servers */
4:
1.1.1.2 ! root 5: /* $Id: js_global.c,v 1.266 2011/09/08 07:10:26 rswindell Exp $ */
1.1 root 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: * *
1.1.1.2 ! root 11: * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html *
1.1 root 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] *
1.1.1.2 ! root 34: *
1.1 root 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"
1.1.1.2 ! root 45: #include "js_rtpool.h"
! 46: #include "js_request.h"
! 47: #include "wordwrap.h"
1.1 root 48:
49: /* SpiderMonkey: */
50: #include <jsfun.h>
51:
52: #define MAX_ANSI_SEQ 16
53: #define MAX_ANSI_PARAMS 8
54:
55: #ifdef JAVASCRIPT
56:
1.1.1.2 ! root 57: typedef struct {
! 58: scfg_t* cfg;
! 59: jsSyncMethodSpec* methods;
! 60: js_startup_t* startup;
! 61: } private_t;
! 62:
1.1 root 63: /* Global Object Properites */
64: enum {
65: GLOB_PROP_ERRNO
66: ,GLOB_PROP_ERRNO_STR
67: ,GLOB_PROP_SOCKET_ERRNO
68: };
69:
70: static JSBool js_system_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
71: {
72: jsint tiny;
73: JSString* js_str;
74:
75: tiny = JSVAL_TO_INT(id);
76:
77: switch(tiny) {
78: case GLOB_PROP_SOCKET_ERRNO:
79: JS_NewNumberValue(cx,ERROR_VALUE,vp);
80: break;
81: case GLOB_PROP_ERRNO:
82: JS_NewNumberValue(cx,errno,vp);
83: break;
84: case GLOB_PROP_ERRNO_STR:
85: if((js_str=JS_NewStringCopyZ(cx, strerror(errno)))==NULL)
86: return(JS_FALSE);
87: *vp = STRING_TO_JSVAL(js_str);
88: break;
89: }
90: return(JS_TRUE);
91: }
92:
93: #define GLOBOBJ_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY|JSPROP_SHARED
94:
1.1.1.2 ! root 95: static jsSyncPropertySpec js_global_properties[] = {
! 96: /* name, tinyid, flags, ver */
1.1 root 97:
1.1.1.2 ! root 98: { "errno" ,GLOB_PROP_ERRNO ,GLOBOBJ_FLAGS, 310 },
! 99: { "errno_str" ,GLOB_PROP_ERRNO_STR ,GLOBOBJ_FLAGS, 310 },
! 100: { "socket_errno" ,GLOB_PROP_SOCKET_ERRNO ,GLOBOBJ_FLAGS, 310 },
1.1 root 101: {0}
102: };
103:
104: typedef struct {
105: JSRuntime* runtime;
106: JSContext* cx;
107: JSContext* parent_cx;
108: JSObject* obj;
109: JSScript* script;
110: msg_queue_t* msg_queue;
111: js_branch_t branch;
112: JSErrorReporter error_reporter;
113: JSNative log;
114: } background_data_t;
115:
116: static void background_thread(void* arg)
117: {
118: background_data_t* bg = (background_data_t*)arg;
119: jsval result=JSVAL_VOID;
120: jsval exit_code;
121:
1.1.1.2 ! root 122: SetThreadName("JS Background");
1.1 root 123: msgQueueAttach(bg->msg_queue);
124: JS_SetContextThread(bg->cx);
1.1.1.2 ! root 125: JS_BEGINREQUEST(bg->cx);
1.1 root 126: if(!JS_ExecuteScript(bg->cx, bg->obj, bg->script, &result)
127: && JS_GetProperty(bg->cx, bg->obj, "exit_code", &exit_code))
128: result=exit_code;
129: js_EvalOnExit(bg->cx, bg->obj, &bg->branch);
130: js_enqueue_value(bg->cx, bg->msg_queue, result, NULL);
131: JS_DestroyScript(bg->cx, bg->script);
1.1.1.2 ! root 132: JS_ENDREQUEST(bg->cx);
1.1 root 133: JS_DestroyContext(bg->cx);
1.1.1.2 ! root 134: jsrt_Release(bg->runtime);
1.1 root 135: free(bg);
136: }
137:
138: static void
139: js_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
140: {
141: background_data_t* bg;
142:
143: if((bg=(background_data_t*)JS_GetContextPrivate(cx))==NULL)
144: return;
145:
146: /* Use parent's context private data */
147: JS_SetContextPrivate(cx, JS_GetContextPrivate(bg->parent_cx));
148:
149: /* Call parent's error reporter */
150: bg->error_reporter(cx, message, report);
151:
152: /* Restore our context private data */
153: JS_SetContextPrivate(cx, bg);
154: }
155:
156: static JSBool js_BranchCallback(JSContext *cx, JSScript* script)
157: {
158: background_data_t* bg;
159:
160: if((bg=(background_data_t*)JS_GetContextPrivate(cx))==NULL)
161: return(JS_FALSE);
162:
163: if(bg->parent_cx!=NULL && !JS_IsRunning(bg->parent_cx)) /* die when parent dies */
164: return(JS_FALSE);
165:
166: return js_CommonBranchCallback(cx,&bg->branch);
167: }
168:
1.1.1.2 ! root 169: #ifdef USE_JS_OPERATION_CALLBACK
! 170: static JSBool
! 171: js_OperationCallback(JSContext *cx)
! 172: {
! 173: JSBool ret;
! 174:
! 175: JS_SetOperationCallback(cx, NULL);
! 176: ret=js_BranchCallback(cx, NULL);
! 177: JS_SetOperationCallback(cx, js_OperationCallback);
! 178: return ret;
! 179: }
! 180: #endif
! 181:
1.1 root 182: static JSBool
183: js_log(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
184: {
185: JSBool retval;
186: background_data_t* bg;
187:
188: if((bg=(background_data_t*)JS_GetContextPrivate(cx))==NULL)
189: return JS_FALSE;
190:
191: /* Use parent's context private data */
192: JS_SetContextPrivate(cx, JS_GetContextPrivate(bg->parent_cx));
193:
194: /* Call parent's log() function */
195: retval = bg->log(cx, obj, argc, argv, rval);
196:
197: /* Restore our context private data */
198: JS_SetContextPrivate(cx, bg);
199:
200: return retval;
201: }
202:
203: /* Create a new value in the new context with a value from the original context */
204: /* Note: objects (including arrays) not currently supported */
205: static jsval* js_CopyValue(JSContext* cx, jsval val, JSContext* new_cx, jsval* rval)
206: {
207: *rval = JSVAL_VOID;
208:
209: if(cx==new_cx
210: || JSVAL_IS_BOOLEAN(val)
211: || JSVAL_IS_NULL(val)
212: || JSVAL_IS_VOID(val)
213: || JSVAL_IS_INT(val))
214: *rval = val;
215: else if(JSVAL_IS_NUMBER(val)) {
216: jsdouble d;
217: if(JS_ValueToNumber(cx,val,&d))
218: JS_NewNumberValue(new_cx,d,rval);
219: }
220: else {
221: JSString* str;
222: size_t len;
223: char* p;
224:
225: if((p=js_ValueToStringBytes(cx,val,&len)) != NULL
226: && (str=JS_NewStringCopyN(new_cx,p,len)) != NULL)
227: *rval=STRING_TO_JSVAL(str);
228: }
229:
230: return rval;
231: }
232:
233: static JSBool
234: js_load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
235: {
236: char path[MAX_PATH+1];
237: uintN i;
238: uintN argn=0;
239: const char* filename;
240: JSScript* script;
1.1.1.2 ! root 241: private_t* p;
1.1 root 242: jsval val;
243: JSObject* js_argv;
244: JSObject* exec_obj;
245: JSContext* exec_cx=cx;
246: JSBool success;
247: JSBool background=JS_FALSE;
248: background_data_t* bg;
1.1.1.2 ! root 249: jsrefcount rc;
1.1 root 250:
251: *rval=JSVAL_VOID;
252:
1.1.1.2 ! root 253: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
1.1 root 254: return(JS_FALSE);
255:
256: exec_obj=JS_GetScopeChain(cx);
257:
258: if(JSVAL_IS_BOOLEAN(argv[argn]))
259: background=JSVAL_TO_BOOLEAN(argv[argn++]);
260:
261: if(background) {
262:
263: if((bg=(background_data_t*)malloc(sizeof(background_data_t)))==NULL)
264: return(JS_FALSE);
265: memset(bg,0,sizeof(background_data_t));
266:
267: bg->parent_cx = cx;
268:
269: /* Setup default values for branch settings */
1.1.1.2 ! root 270: bg->branch.limit=p->startup->branch_limit;
! 271: bg->branch.gc_interval=p->startup->gc_interval;
! 272: bg->branch.yield_interval=p->startup->yield_interval;
! 273: #if 0
1.1 root 274: if(JS_GetProperty(cx, obj,"js",&val)) /* copy branch settings from parent */
275: memcpy(&bg->branch,JS_GetPrivate(cx,JSVAL_TO_OBJECT(val)),sizeof(bg->branch));
1.1.1.2 ! root 276: #endif
1.1 root 277: bg->branch.terminated=NULL; /* could be bad pointer at any time */
278: bg->branch.counter=0;
279: bg->branch.gc_attempts=0;
280:
1.1.1.2 ! root 281: if((bg->runtime = jsrt_GetNew(JAVASCRIPT_MAX_BYTES, 1000, __FILE__, __LINE__))==NULL)
1.1 root 282: return(JS_FALSE);
283:
284: if((bg->cx = JS_NewContext(bg->runtime, JAVASCRIPT_CONTEXT_STACK))==NULL)
285: return(JS_FALSE);
1.1.1.2 ! root 286: JS_BEGINREQUEST(bg->cx);
1.1 root 287:
288: if((bg->obj=js_CreateCommonObjects(bg->cx
1.1.1.2 ! root 289: ,p->cfg /* common config */
1.1 root 290: ,NULL /* node-specific config */
291: ,NULL /* additional global methods */
292: ,0 /* uptime */
293: ,"" /* hostname */
294: ,"" /* socklib_desc */
295: ,&bg->branch /* js */
1.1.1.2 ! root 296: ,p->startup /* js */
1.1 root 297: ,NULL /* client */
298: ,INVALID_SOCKET /* client_socket */
299: ,NULL /* server props */
300: ))==NULL)
301: return(JS_FALSE);
302:
303: bg->msg_queue = msgQueueInit(NULL,MSG_QUEUE_BIDIR);
304:
305: js_CreateQueueObject(bg->cx, bg->obj, "parent_queue", bg->msg_queue);
306:
307: /* Save parent's error reporter (for later use by our error reporter) */
308: bg->error_reporter=JS_SetErrorReporter(cx,NULL);
309: JS_SetErrorReporter(cx,bg->error_reporter);
310: JS_SetErrorReporter(bg->cx,js_ErrorReporter);
311:
312: /* Set our branch callback (which calls the generic branch callback) */
313: JS_SetContextPrivate(bg->cx, bg);
1.1.1.2 ! root 314: #ifdef USE_JS_OPERATION_CALLBACK
! 315: JS_SetOperationCallback(bg->cx, js_OperationCallback);
! 316: #else
1.1 root 317: JS_SetBranchCallback(bg->cx, js_BranchCallback);
1.1.1.2 ! root 318: #endif
1.1 root 319:
320: /* Save parent's 'log' function (for later use by our log function) */
321: if(JS_GetProperty(cx, obj, "log", &val)) {
322: JSFunction* func;
1.1.1.2 ! root 323: if((func=JS_ValueToFunction(cx, val))!=NULL && !(func->flags&JSFUN_INTERPRETED)) {
! 324: bg->log=func->u.n.native;
1.1 root 325: JS_DefineFunction(bg->cx, bg->obj
326: ,"log", js_log, func->nargs, func->flags);
327: }
328: }
329:
330: exec_cx = bg->cx;
331: exec_obj = bg->obj;
332:
333: } else if(JSVAL_IS_OBJECT(argv[argn])) {
334: JSObject* tmp_obj=JSVAL_TO_OBJECT(argv[argn++]);
335: if(!JS_ObjectIsFunction(cx,tmp_obj)) /* Scope specified */
336: exec_obj=tmp_obj;
337: }
338:
339: if(argn==argc) {
340: JS_ReportError(cx,"no filename specified");
341: return(JS_FALSE);
342: }
343: if((filename=js_ValueToStringBytes(cx, argv[argn++], NULL))==NULL)
344: return(JS_FALSE);
345:
346: if(argc>argn || background) {
347:
348: if((js_argv=JS_NewArrayObject(exec_cx, 0, NULL)) == NULL)
349: return(JS_FALSE);
350:
351: JS_DefineProperty(exec_cx, exec_obj, "argv", OBJECT_TO_JSVAL(js_argv)
352: ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
353:
354: for(i=argn; i<argc; i++)
355: JS_SetElement(exec_cx, js_argv, i-argn, js_CopyValue(cx,argv[i],exec_cx,&val));
356:
357: JS_DefineProperty(exec_cx, exec_obj, "argc", INT_TO_JSVAL(argc-argn)
358: ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
359: }
360:
1.1.1.2 ! root 361: rc=JS_SUSPENDREQUEST(cx);
1.1 root 362: errno = 0;
363: if(isfullpath(filename))
1.1.1.2 ! root 364: SAFECOPY(path,filename);
1.1 root 365: else {
1.1.1.2 ! root 366: JSObject* js_load_list = NULL;
! 367:
! 368: path[0]=0; /* Empty path, indicates load file not found (yet) */
! 369:
! 370: JS_RESUMEREQUEST(cx, rc);
! 371: if(JS_GetProperty(cx, obj, "js", &val) && val!=JSVAL_VOID && JSVAL_IS_OBJECT(val)) {
! 372: JSObject* js_obj = JSVAL_TO_OBJECT(val);
! 373:
! 374: /* if js.exec_dir is defined (location of executed script), search their first */
! 375: if(JS_GetProperty(cx, js_obj, "exec_dir", &val) && val!=JSVAL_VOID && JSVAL_IS_STRING(val)) {
! 376: SAFEPRINTF2(path,"%s%s",js_ValueToStringBytes(cx, val, NULL),filename);
! 377: rc=JS_SUSPENDREQUEST(cx);
! 378: if(!fexistcase(path))
! 379: path[0]=0;
! 380: JS_RESUMEREQUEST(cx, rc);
! 381: }
! 382: if(JS_GetProperty(cx, js_obj, JAVASCRIPT_LOAD_PATH_LIST, &val) && val!=JSVAL_VOID && JSVAL_IS_OBJECT(val))
! 383: js_load_list = JSVAL_TO_OBJECT(val);
! 384:
! 385: /* if mods_dir is defined, search mods/js.load_path_list[n] next */
! 386: if(path[0]==0 && p->cfg->mods_dir[0]!=0 && js_load_list!=NULL) {
! 387: jsuint i;
! 388: char prefix[MAX_PATH+1];
! 389:
! 390: for(i=0;path[0]==0;i++) {
! 391: if(!JS_GetElement(cx, js_load_list, i, &val) || val==JSVAL_VOID)
! 392: break;
! 393: SAFECOPY(prefix,js_ValueToStringBytes(cx, val, NULL));
! 394: if(prefix[0]==0)
! 395: continue;
! 396: backslash(prefix);
! 397: rc=JS_SUSPENDREQUEST(cx);
! 398: if(isfullpath(prefix)) {
! 399: SAFEPRINTF2(path,"%s%s",prefix,filename);
! 400: if(!fexistcase(path))
! 401: path[0]=0;
! 402: } else {
! 403: /* relative path */
! 404: SAFEPRINTF3(path,"%s%s%s",p->cfg->mods_dir,prefix,filename);
! 405: if(!fexistcase(path))
! 406: path[0]=0;
! 407: }
! 408: JS_RESUMEREQUEST(cx, rc);
! 409: }
! 410: }
! 411: }
! 412: rc=JS_SUSPENDREQUEST(cx);
! 413: /* if mods_dir is defined, search there next */
! 414: if(path[0]==0 && p->cfg->mods_dir[0]!=0) {
! 415: SAFEPRINTF2(path,"%s%s",p->cfg->mods_dir,filename);
! 416: if(!fexistcase(path))
! 417: path[0]=0;
! 418: }
! 419: /* if js.load_path_list is defined, search exec/load_path_list[n] next */
! 420: if(path[0]==0 && js_load_list!=NULL) {
! 421: jsuint i;
! 422: char prefix[MAX_PATH+1];
! 423:
! 424: for(i=0;path[0]==0;i++) {
! 425: JS_RESUMEREQUEST(cx, rc);
! 426: if(!JS_GetElement(cx, js_load_list, i, &val) || val==JSVAL_VOID) {
! 427: rc=JS_SUSPENDREQUEST(cx);
! 428: break;
! 429: }
! 430: SAFECOPY(prefix,js_ValueToStringBytes(cx, val, NULL));
! 431: rc=JS_SUSPENDREQUEST(cx);
! 432: if(prefix[0]==0)
! 433: continue;
! 434: backslash(prefix);
! 435: if(isfullpath(prefix)) {
! 436: SAFEPRINTF2(path,"%s%s",prefix,filename);
! 437: if(!fexistcase(path))
! 438: path[0]=0;
! 439: } else {
! 440: /* relative path */
! 441: SAFEPRINTF3(path,"%s%s%s",p->cfg->exec_dir,prefix,filename);
! 442: if(!fexistcase(path))
! 443: path[0]=0;
! 444: }
! 445: }
! 446: }
! 447: /* lastly, search exec dir */
! 448: if(path[0]==0)
! 449: SAFEPRINTF2(path,"%s%s",p->cfg->exec_dir,filename);
1.1 root 450: }
1.1.1.2 ! root 451: JS_RESUMEREQUEST(cx, rc);
1.1 root 452:
453: JS_ClearPendingException(exec_cx);
454:
455: if((script=JS_CompileFile(exec_cx, exec_obj, path))==NULL)
456: return(JS_FALSE);
457:
458: if(background) {
459:
460: bg->script = script;
461: *rval = OBJECT_TO_JSVAL(js_CreateQueueObject(cx, obj, NULL, bg->msg_queue));
1.1.1.2 ! root 462: JS_ENDREQUEST(bg->cx);
! 463: JS_ClearContextThread(bg->cx);
1.1 root 464: success = _beginthread(background_thread,0,bg)!=-1;
465:
466: } else {
467:
468: success = JS_ExecuteScript(exec_cx, exec_obj, script, rval);
469: JS_DestroyScript(exec_cx, script);
470: }
471:
472: return(success);
473: }
474:
475: static JSBool
476: js_format(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
477: {
478: char* p;
479: JSString* str;
480:
481: if((p=js_sprintf(cx, 0, argc, argv))==NULL) {
482: JS_ReportError(cx,"js_sprintf failed");
483: return(JS_FALSE);
484: }
485:
486: str = JS_NewStringCopyZ(cx, p);
487: js_sprintf_free(p);
488:
489: if(str==NULL)
490: return(JS_FALSE);
491:
492: *rval = STRING_TO_JSVAL(str);
493: return(JS_TRUE);
494: }
495:
496: static JSBool
497: js_yield(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
498: {
499: BOOL forced=TRUE;
1.1.1.2 ! root 500: jsrefcount rc;
1.1 root 501:
502: if(argc)
503: JS_ValueToBoolean(cx, argv[0], &forced);
1.1.1.2 ! root 504: rc=JS_SUSPENDREQUEST(cx);
1.1 root 505: if(forced) {
506: YIELD();
507: } else {
508: MAYBE_YIELD();
509: }
1.1.1.2 ! root 510: JS_RESUMEREQUEST(cx, rc);
1.1 root 511:
512: return(JS_TRUE);
513: }
514:
515: static JSBool
516: js_mswait(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
517: {
518: int32 val=1;
519: clock_t start=msclock();
1.1.1.2 ! root 520: jsrefcount rc;
1.1 root 521:
522: if(argc)
523: JS_ValueToInt32(cx,argv[0],&val);
1.1.1.2 ! root 524: rc=JS_SUSPENDREQUEST(cx);
1.1 root 525: mswait(val);
1.1.1.2 ! root 526: JS_RESUMEREQUEST(cx, rc);
1.1 root 527:
528: JS_NewNumberValue(cx,msclock()-start,rval);
529:
530: return(JS_TRUE);
531: }
532:
533: static JSBool
534: js_random(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
535: {
536: int32 val=100;
537:
538: if(argc)
539: JS_ValueToInt32(cx,argv[0],&val);
540:
541: JS_NewNumberValue(cx,sbbs_random(val),rval);
542: return(JS_TRUE);
543: }
544:
545: static JSBool
546: js_time(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
547: {
548: JS_NewNumberValue(cx,time(NULL),rval);
549: return(JS_TRUE);
550: }
551:
552:
553: static JSBool
554: js_beep(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
555: {
556: int32 freq=500;
557: int32 dur=500;
1.1.1.2 ! root 558: jsrefcount rc;
1.1 root 559:
560: if(argc)
561: JS_ValueToInt32(cx,argv[0],&freq);
562: if(argc>1)
563: JS_ValueToInt32(cx,argv[1],&dur);
564:
1.1.1.2 ! root 565: rc=JS_SUSPENDREQUEST(cx);
1.1 root 566: sbbs_beep(freq,dur);
1.1.1.2 ! root 567: JS_RESUMEREQUEST(cx, rc);
1.1 root 568: return(JS_TRUE);
569: }
570:
571: static JSBool
572: js_exit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
573: {
574: if(argc)
575: JS_DefineProperty(cx, obj, "exit_code", argv[0]
576: ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
577:
578: return(JS_FALSE);
579: }
580:
581: static JSBool
582: js_crc16(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
583: {
584: char* p;
585: size_t len;
1.1.1.2 ! root 586: jsrefcount rc;
1.1 root 587:
588: if(JSVAL_IS_VOID(argv[0]))
589: return(JS_TRUE);
590:
591: if((p=js_ValueToStringBytes(cx, argv[0], &len))==NULL)
592: return(JS_FALSE);
593:
1.1.1.2 ! root 594: rc=JS_SUSPENDREQUEST(cx);
1.1 root 595: *rval = INT_TO_JSVAL(crc16(p,len));
1.1.1.2 ! root 596: JS_RESUMEREQUEST(cx, rc);
1.1 root 597: return(JS_TRUE);
598: }
599:
600: static JSBool
601: js_crc32(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
602: {
603: char* p;
604: size_t len;
1.1.1.2 ! root 605: uint32_t cs;
! 606: jsrefcount rc;
1.1 root 607:
608: if(JSVAL_IS_VOID(argv[0]))
609: return(JS_TRUE);
610:
611: if((p=js_ValueToStringBytes(cx, argv[0], &len))==NULL)
612: return(JS_FALSE);
613:
1.1.1.2 ! root 614: cs=crc32(p,len);
! 615: rc=JS_SUSPENDREQUEST(cx);
! 616: JS_NewNumberValue(cx,cs,rval);
! 617: JS_RESUMEREQUEST(cx, rc);
1.1 root 618: return(JS_TRUE);
619: }
620:
621: static JSBool
622: js_chksum(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
623: {
624: ulong sum=0;
625: char* p;
626: size_t len;
1.1.1.2 ! root 627: jsrefcount rc;
1.1 root 628:
629: if(JSVAL_IS_VOID(argv[0]))
630: return(JS_TRUE);
631:
632: if((p=js_ValueToStringBytes(cx, argv[0], &len))==NULL)
633: return(JS_FALSE);
634:
1.1.1.2 ! root 635: rc=JS_SUSPENDREQUEST(cx); /* 3.8 seconds on Deuce's computer when len==UINT_MAX/8 */
1.1 root 636: while(len--) sum+=*(p++);
1.1.1.2 ! root 637: JS_RESUMEREQUEST(cx, rc);
1.1 root 638:
639: JS_NewNumberValue(cx,sum,rval);
640: return(JS_TRUE);
641: }
642:
643: static JSBool
644: js_ascii(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
645: {
646: char* p;
647: char str[2];
648: int32 i=0;
649: JSString* js_str;
650:
651: if(JSVAL_IS_VOID(argv[0]))
652: return(JS_TRUE);
653:
654: if(JSVAL_IS_STRING(argv[0])) { /* string to ascii-int */
655:
656: if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL)
657: return(JS_FALSE);
658:
659: *rval=INT_TO_JSVAL(*p);
660: return(JS_TRUE);
661: }
662:
663: /* ascii-int to str */
664: JS_ValueToInt32(cx,argv[0],&i);
665: str[0]=(uchar)i;
666: str[1]=0;
667:
668: if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
669: return(JS_FALSE);
670:
671: *rval = STRING_TO_JSVAL(js_str);
672: return(JS_TRUE);
673: }
674:
675: static JSBool
676: js_ctrl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
677: {
678: char ch;
679: char* p;
680: char str[2];
681: int32 i=0;
682: JSString* js_str;
683:
684: if(JSVAL_IS_VOID(argv[0]))
685: return(JS_TRUE);
686:
687: if(JSVAL_IS_STRING(argv[0])) {
688:
689: if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL)
690: return(JS_FALSE);
691: ch=*p;
692: } else {
693: JS_ValueToInt32(cx,argv[0],&i);
694: ch=(char)i;
695: }
696:
697: str[0]=toupper(ch)&~0x40;
698: str[1]=0;
699:
700: if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
701: return(JS_FALSE);
702:
703: *rval = STRING_TO_JSVAL(js_str);
704: return(JS_TRUE);
705: }
706:
707: static JSBool
708: js_ascii_str(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
709: {
710: char* p;
711: char* buf;
712: JSString* str;
713:
714: if(JSVAL_IS_VOID(argv[0]))
715: return(JS_TRUE);
716:
717: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
718: return(JS_FALSE);
719:
720: if((buf=strdup(p))==NULL)
721: return(JS_FALSE);
722:
723: ascii_str(buf);
724:
725: str = JS_NewStringCopyZ(cx, buf);
726: free(buf);
727: if(str==NULL)
728: return(JS_FALSE);
729:
730: *rval = STRING_TO_JSVAL(str);
731: return(JS_TRUE);
732: }
733:
734:
735: static JSBool
736: js_strip_ctrl(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
737: {
738: char* p;
739: char* buf;
740: JSString* js_str;
741:
742: if(JSVAL_IS_VOID(argv[0]))
743: return(JS_TRUE);
744:
745: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
746: return(JS_FALSE);
747:
1.1.1.2 ! root 748: buf=strip_ctrl(p, NULL);
1.1 root 749:
750: js_str = JS_NewStringCopyZ(cx, buf);
751: free(buf);
752: if(js_str==NULL)
753: return(JS_FALSE);
754:
755: *rval = STRING_TO_JSVAL(js_str);
756: return(JS_TRUE);
757: }
758:
759: static JSBool
760: js_strip_exascii(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
761: {
762: char* p;
763: char* buf;
764: JSString* js_str;
765:
766: if(JSVAL_IS_VOID(argv[0]))
767: return(JS_TRUE);
768:
769: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
770: return(JS_FALSE);
771:
1.1.1.2 ! root 772: buf=strip_exascii(p, NULL);
1.1 root 773:
774: js_str = JS_NewStringCopyZ(cx, buf);
775: free(buf);
776: if(js_str==NULL)
777: return(JS_FALSE);
778:
779: *rval = STRING_TO_JSVAL(js_str);
780: return(JS_TRUE);
781: }
782:
783: static JSBool
784: js_lfexpand(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
785: {
786: ulong i,j;
787: char* inbuf;
788: char* outbuf;
789: JSString* str;
790:
791: if(JSVAL_IS_VOID(argv[0]))
792: return(JS_TRUE);
793:
794: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
795: return(JS_FALSE);
796:
797: if((outbuf=(char*)malloc((strlen(inbuf)*2)+1))==NULL)
798: return(JS_FALSE);
799:
800: for(i=j=0;inbuf[i];i++) {
801: if(inbuf[i]=='\n' && (!i || inbuf[i-1]!='\r'))
802: outbuf[j++]='\r';
803: outbuf[j++]=inbuf[i];
804: }
805: outbuf[j]=0;
806:
807: str = JS_NewStringCopyZ(cx, outbuf);
808: free(outbuf);
809: if(str==NULL)
810: return(JS_FALSE);
811:
812: *rval = STRING_TO_JSVAL(str);
813: return(JS_TRUE);
814: }
815:
816: static JSBool
817: js_word_wrap(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
818: {
1.1.1.2 ! root 819: int32 len=79;
1.1 root 820: int32 oldlen=79;
821: JSBool handle_quotes=JS_TRUE;
822: uchar* inbuf;
823: char* outbuf;
824: JSString* js_str;
1.1.1.2 ! root 825: jsrefcount rc;
1.1 root 826:
827: if(JSVAL_IS_VOID(argv[0]))
828: return(JS_TRUE);
829:
830: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
831: return(JS_FALSE);
832:
833: if(argc>1)
834: JS_ValueToInt32(cx,argv[1],&len);
835:
836: if(argc>2)
837: JS_ValueToInt32(cx,argv[2],&oldlen);
838:
839: if(argc>3 && JSVAL_IS_BOOLEAN(argv[3]))
840: handle_quotes=JSVAL_TO_BOOLEAN(argv[3]);
841:
1.1.1.2 ! root 842: rc=JS_SUSPENDREQUEST(cx);
1.1 root 843:
1.1.1.2 ! root 844: outbuf=wordwrap(inbuf, len, oldlen, handle_quotes);
1.1 root 845:
1.1.1.2 ! root 846: JS_RESUMEREQUEST(cx, rc);
1.1 root 847:
1.1.1.2 ! root 848: if(outbuf==NULL)
! 849: return(JS_FALSE);
1.1 root 850: js_str = JS_NewStringCopyZ(cx, outbuf);
851: free(outbuf);
852: if(js_str==NULL)
853: return(JS_FALSE);
854: *rval = STRING_TO_JSVAL(js_str);
855: return(JS_TRUE);
856: }
857:
858: static JSBool
859: js_quote_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
860: {
861: int32 len=79;
862: int i,l,clen;
863: uchar* inbuf;
864: char* outbuf;
865: char* linebuf;
866: char* prefix=" > ";
867: JSString* js_str;
1.1.1.2 ! root 868: jsrefcount rc;
1.1 root 869:
870: if(JSVAL_IS_VOID(argv[0]))
871: return(JS_TRUE);
872:
873: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
874: return(JS_FALSE);
875:
876: if(argc>1)
877: JS_ValueToInt32(cx,argv[1],&len);
878:
879: if(argc>2)
880: prefix=js_ValueToStringBytes(cx, argv[2], NULL);
881:
1.1.1.2 ! root 882: if((outbuf=(char*)malloc((strlen(inbuf)*(strlen(prefix)+1))+1))==NULL)
1.1 root 883: return(JS_FALSE);
884:
885: len-=strlen(prefix);
886: if(len<=0)
887: return(JS_FALSE);
888:
1.1.1.2 ! root 889: if((linebuf=(char*)alloca((len*3)+2))==NULL) /* (Hopefully) Room for ^A codes. ToDo */
1.1 root 890: return(JS_FALSE);
891:
1.1.1.2 ! root 892: rc=JS_SUSPENDREQUEST(cx);
1.1 root 893: outbuf[0]=0;
894: clen=0;
895: for(i=l=0;inbuf[i];i++) {
896: if(l==0) /* Do not use clen here since if the line starts with ^A, could stay at zero */
897: strcat(outbuf,prefix);
898: if(clen<len || inbuf[i]=='\n' || inbuf[i]=='\r')
899: linebuf[l++]=inbuf[i];
900: if(inbuf[i]=='\x01') { /* Handle CTRL-A */
901: linebuf[l++]=inbuf[++i];
902: if(inbuf[i]=='\x01')
903: clen++;
904: }
905: else
906: clen++;
907: /* ToDo: Handle TABs etc. */
908: if(inbuf[i]=='\n') {
909: strncat(outbuf,linebuf,l);
910: l=0;
911: clen=0;
912: }
913: }
914: if(l) /* remainder */
915: strncat(outbuf,linebuf,l);
1.1.1.2 ! root 916: JS_RESUMEREQUEST(cx, rc);
1.1 root 917:
918: js_str = JS_NewStringCopyZ(cx, outbuf);
919: free(outbuf);
920: if(js_str==NULL)
921: return(JS_FALSE);
922:
923: *rval = STRING_TO_JSVAL(js_str);
924: return(JS_TRUE);
925: }
926:
927: static JSBool
928: js_netaddr_type(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
929: {
930: char* str;
931:
932: if(JSVAL_IS_VOID(argv[0]))
933: return(JS_TRUE);
934:
935: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
936: return(JS_FALSE);
937:
938: *rval = INT_TO_JSVAL(smb_netaddr_type(str));
939:
940: return(JS_TRUE);
941: }
942:
943: static JSBool
944: js_rot13(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
945: {
946: char* p;
947: char* str;
948: JSString* js_str;
949:
950: if(JSVAL_IS_VOID(argv[0]))
951: return(JS_TRUE);
952:
953: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
954: return(JS_FALSE);
955:
956: if((p=strdup(str))==NULL)
957: return(JS_FALSE);
958:
959: js_str = JS_NewStringCopyZ(cx, rot13(p));
960: free(p);
961: if(js_str==NULL)
962: return(JS_FALSE);
963:
964: *rval = STRING_TO_JSVAL(js_str);
965: return(JS_TRUE);
966: }
967:
968: /* This table is used to convert between IBM ex-ASCII and HTML character entities */
969: /* Much of this table supplied by Deuce (thanks!) */
970: static struct {
971: int value;
972: char* name;
973: } exasctbl[128] = {
974: /* HTML val,name ASCII description */
975: { 199 ,"Ccedil" }, /* 128 C, cedilla */
976: { 252 ,"uuml" }, /* 129 u, umlaut */
977: { 233 ,"eacute" }, /* 130 e, acute accent */
978: { 226 ,"acirc" }, /* 131 a, circumflex accent */
979: { 228 ,"auml" }, /* 132 a, umlaut */
980: { 224 ,"agrave" }, /* 133 a, grave accent */
981: { 229 ,"aring" }, /* 134 a, ring */
982: { 231 ,"ccedil" }, /* 135 c, cedilla */
983: { 234 ,"ecirc" }, /* 136 e, circumflex accent */
984: { 235 ,"euml" }, /* 137 e, umlaut */
985: { 232 ,"egrave" }, /* 138 e, grave accent */
986: { 239 ,"iuml" }, /* 139 i, umlaut */
987: { 238 ,"icirc" }, /* 140 i, circumflex accent */
988: { 236 ,"igrave" }, /* 141 i, grave accent */
989: { 196 ,"Auml" }, /* 142 A, umlaut */
990: { 197 ,"Aring" }, /* 143 A, ring */
991: { 201 ,"Eacute" }, /* 144 E, acute accent */
992: { 230 ,"aelig" }, /* 145 ae ligature */
993: { 198 ,"AElig" }, /* 146 AE ligature */
994: { 244 ,"ocirc" }, /* 147 o, circumflex accent */
995: { 246 ,"ouml" }, /* 148 o, umlaut */
996: { 242 ,"ograve" }, /* 149 o, grave accent */
997: { 251 ,"ucirc" }, /* 150 u, circumflex accent */
998: { 249 ,"ugrave" }, /* 151 u, grave accent */
999: { 255 ,"yuml" }, /* 152 y, umlaut */
1000: { 214 ,"Ouml" }, /* 153 O, umlaut */
1001: { 220 ,"Uuml" }, /* 154 U, umlaut */
1002: { 162 ,"cent" }, /* 155 Cent sign */
1003: { 163 ,"pound" }, /* 156 Pound sign */
1004: { 165 ,"yen" }, /* 157 Yen sign */
1005: { 8359 ,NULL }, /* 158 Pt (unicode) */
1006: { 402 ,NULL }, /* 402 Florin (non-standard alsi 159?) */
1007: { 225 ,"aacute" }, /* 160 a, acute accent */
1008: { 237 ,"iacute" }, /* 161 i, acute accent */
1009: { 243 ,"oacute" }, /* 162 o, acute accent */
1010: { 250 ,"uacute" }, /* 163 u, acute accent */
1011: { 241 ,"ntilde" }, /* 164 n, tilde */
1012: { 209 ,"Ntilde" }, /* 165 N, tilde */
1013: { 170 ,"ordf" }, /* 166 Feminine ordinal */
1014: { 186 ,"ordm" }, /* 167 Masculine ordinal */
1015: { 191 ,"iquest" }, /* 168 Inverted question mark */
1016: { 8976 ,NULL }, /* 169 Inverse "Not sign" (unicode) */
1017: { 172 ,"not" }, /* 170 Not sign */
1018: { 189 ,"frac12" }, /* 171 Fraction one-half */
1019: { 188 ,"frac14" }, /* 172 Fraction one-fourth */
1020: { 161 ,"iexcl" }, /* 173 Inverted exclamation point */
1021: { 171 ,"laquo" }, /* 174 Left angle quote */
1022: { 187 ,"raquo" }, /* 175 Right angle quote */
1023: { 9617 ,NULL }, /* 176 drawing symbol (unicode) */
1024: { 9618 ,NULL }, /* 177 drawing symbol (unicode) */
1025: { 9619 ,NULL }, /* 178 drawing symbol (unicode) */
1026: { 9474 ,NULL }, /* 179 drawing symbol (unicode) */
1027: { 9508 ,NULL }, /* 180 drawing symbol (unicode) */
1028: { 9569 ,NULL }, /* 181 drawing symbol (unicode) */
1029: { 9570 ,NULL }, /* 182 drawing symbol (unicode) */
1030: { 9558 ,NULL }, /* 183 drawing symbol (unicode) */
1031: { 9557 ,NULL }, /* 184 drawing symbol (unicode) */
1032: { 9571 ,NULL }, /* 185 drawing symbol (unicode) */
1033: { 9553 ,NULL }, /* 186 drawing symbol (unicode) */
1034: { 9559 ,NULL }, /* 187 drawing symbol (unicode) */
1035: { 9565 ,NULL }, /* 188 drawing symbol (unicode) */
1036: { 9564 ,NULL }, /* 189 drawing symbol (unicode) */
1037: { 9563 ,NULL }, /* 190 drawing symbol (unicode) */
1038: { 9488 ,NULL }, /* 191 drawing symbol (unicode) */
1039: { 9492 ,NULL }, /* 192 drawing symbol (unicode) */
1040: { 9524 ,NULL }, /* 193 drawing symbol (unicode) */
1041: { 9516 ,NULL }, /* 194 drawing symbol (unicode) */
1042: { 9500 ,NULL }, /* 195 drawing symbol (unicode) */
1043: { 9472 ,NULL }, /* 196 drawing symbol (unicode) */
1044: { 9532 ,NULL }, /* 197 drawing symbol (unicode) */
1045: { 9566 ,NULL }, /* 198 drawing symbol (unicode) */
1046: { 9567 ,NULL }, /* 199 drawing symbol (unicode) */
1047: { 9562 ,NULL }, /* 200 drawing symbol (unicode) */
1048: { 9556 ,NULL }, /* 201 drawing symbol (unicode) */
1049: { 9577 ,NULL }, /* 202 drawing symbol (unicode) */
1050: { 9574 ,NULL }, /* 203 drawing symbol (unicode) */
1051: { 9568 ,NULL }, /* 204 drawing symbol (unicode) */
1052: { 9552 ,NULL }, /* 205 drawing symbol (unicode) */
1053: { 9580 ,NULL }, /* 206 drawing symbol (unicode) */
1054: { 9575 ,NULL }, /* 207 drawing symbol (unicode) */
1055: { 9576 ,NULL }, /* 208 drawing symbol (unicode) */
1056: { 9572 ,NULL }, /* 209 drawing symbol (unicode) */
1057: { 9573 ,NULL }, /* 210 drawing symbol (unicode) */
1058: { 9561 ,NULL }, /* 211 drawing symbol (unicode) */
1059: { 9560 ,NULL }, /* 212 drawing symbol (unicode) */
1060: { 9554 ,NULL }, /* 213 drawing symbol (unicode) */
1061: { 9555 ,NULL }, /* 214 drawing symbol (unicode) */
1062: { 9579 ,NULL }, /* 215 drawing symbol (unicode) */
1063: { 9578 ,NULL }, /* 216 drawing symbol (unicode) */
1064: { 9496 ,NULL }, /* 217 drawing symbol (unicode) */
1065: { 9484 ,NULL }, /* 218 drawing symbol (unicode) */
1066: { 9608 ,NULL }, /* 219 drawing symbol (unicode) */
1067: { 9604 ,NULL }, /* 220 drawing symbol (unicode) */
1068: { 9612 ,NULL }, /* 221 drawing symbol (unicode) */
1069: { 9616 ,NULL }, /* 222 drawing symbol (unicode) */
1070: { 9600 ,NULL }, /* 223 drawing symbol (unicode) */
1071: { 945 ,NULL }, /* 224 alpha symbol */
1072: { 223 ,"szlig" }, /* 225 sz ligature (beta symbol) */
1073: { 915 ,NULL }, /* 226 omega symbol */
1074: { 960 ,NULL }, /* 227 pi symbol*/
1075: { 931 ,NULL }, /* 228 epsilon symbol */
1076: { 963 ,NULL }, /* 229 o with stick */
1077: { 181 ,"micro" }, /* 230 Micro sign (Greek mu) */
1078: { 964 ,NULL }, /* 231 greek char? */
1079: { 934 ,NULL }, /* 232 greek char? */
1080: { 920 ,NULL }, /* 233 greek char? */
1081: { 937 ,NULL }, /* 234 greek char? */
1082: { 948 ,NULL }, /* 235 greek char? */
1083: { 8734 ,NULL }, /* 236 infinity symbol (unicode) */
1084: { 966 ,"oslash" }, /* 237 Greek Phi */
1085: { 949 ,NULL }, /* 238 rounded E */
1086: { 8745 ,NULL }, /* 239 unside down U (unicode) */
1087: { 8801 ,NULL }, /* 240 drawing symbol (unicode) */
1088: { 177 ,"plusmn" }, /* 241 Plus or minus */
1089: { 8805 ,NULL }, /* 242 drawing symbol (unicode) */
1090: { 8804 ,NULL }, /* 243 drawing symbol (unicode) */
1091: { 8992 ,NULL }, /* 244 drawing symbol (unicode) */
1092: { 8993 ,NULL }, /* 245 drawing symbol (unicode) */
1093: { 247 ,"divide" }, /* 246 Division sign */
1094: { 8776 ,NULL }, /* 247 two squiggles (unicode) */
1095: { 176 ,"deg" }, /* 248 Degree sign */
1096: { 8729 ,NULL }, /* 249 drawing symbol (unicode) */
1097: { 183 ,"middot" }, /* 250 Middle dot */
1098: { 8730 ,NULL }, /* 251 check mark (unicode) */
1099: { 8319 ,NULL }, /* 252 superscript n (unicode) */
1100: { 178 ,"sup2" }, /* 253 superscript 2 */
1101: { 9632 ,NULL }, /* 254 drawing symbol (unicode) */
1102: { 160 ,"nbsp" } /* 255 non-breaking space */
1103: };
1104:
1105: static struct {
1106: int value;
1107: char* name;
1108: } lowasctbl[32] = {
1109: { 160 ,"nbsp" }, /* NULL non-breaking space */
1110: { 9786 ,NULL }, /* white smiling face */
1111: { 9787 ,NULL }, /* black smiling face */
1112: { 9829 ,"hearts" }, /* black heart suit */
1113: { 9830 ,"diams" }, /* black diamond suit */
1114: { 9827 ,"clubs" }, /* black club suit */
1115: { 9824 ,"spades" }, /* black spade suit */
1116: { 8226 ,"bull" }, /* bullet */
1117: { 9688 ,NULL }, /* inverse bullet */
1118: { 9702 ,NULL }, /* white bullet */
1119: { 9689 ,NULL }, /* inverse white circle */
1120: { 9794 ,NULL }, /* male sign */
1121: { 9792 ,NULL }, /* female sign */
1122: { 9834 ,NULL }, /* eighth note */
1123: { 9835 ,NULL }, /* beamed eighth notes */
1124: { 9788 ,NULL }, /* white sun with rays */
1125: { 9654 ,NULL }, /* black right-pointing triangle */
1126: { 9664 ,NULL }, /* black left-pointing triangle */
1127: { 8597 ,NULL }, /* up down arrow */
1128: { 8252 ,NULL }, /* double exclamation mark */
1129: { 182 ,"para" }, /* pilcrow sign */
1130: { 167 ,"sect" }, /* section sign */
1131: { 9644 ,NULL }, /* black rectangle */
1132: { 8616 ,NULL }, /* up down arrow with base */
1133: { 8593 ,"uarr" }, /* upwards arrow */
1134: { 8595 ,"darr" }, /* downwards arrow */
1135: { 8594 ,"rarr" }, /* rightwards arrow */
1136: { 8592 ,"larr" }, /* leftwards arrow */
1137: { 8985 ,NULL }, /* turned not sign */
1138: { 8596 ,"harr" }, /* left right arrow */
1139: { 9650 ,NULL }, /* black up-pointing triangle */
1140: { 9660 ,NULL } /* black down-pointing triangle */
1141: };
1142:
1143: static JSBool
1144: js_html_encode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1145: {
1146: int ch;
1147: ulong i,j;
1148: uchar* inbuf;
1149: uchar* tmpbuf;
1150: uchar* outbuf;
1151: uchar* param;
1152: char* lastparam;
1153: JSBool exascii=JS_TRUE;
1154: JSBool wsp=JS_TRUE;
1155: JSBool ansi=JS_TRUE;
1156: JSBool ctrl_a=JS_TRUE;
1157: JSString* js_str;
1158: int32 fg=7;
1159: int32 bg=0;
1160: JSBool blink=FALSE;
1161: JSBool bold=FALSE;
1162: int esccount=0;
1163: char ansi_seq[MAX_ANSI_SEQ+1];
1164: int ansi_param[MAX_ANSI_PARAMS];
1165: int k,l;
1166: ulong savepos=0;
1167: int32 hpos=0;
1168: int32 currrow=0;
1169: int savehpos=0;
1170: int savevpos=0;
1171: int32 wraphpos=-2;
1172: int32 wrapvpos=-2;
1173: int32 wrappos=0;
1174: BOOL extchar=FALSE;
1175: ulong obsize;
1176: int32 lastcolor=7;
1177: char tmp1[128];
1178: struct tm tm;
1179: time_t now;
1180: BOOL nodisplay=FALSE;
1.1.1.2 ! root 1181: private_t* p;
1.1 root 1182: uchar attr_stack[64]; /* Saved attributes (stack) */
1183: int attr_sp=0; /* Attribute stack pointer */
1184: ulong clear_screen=0;
1185: JSObject* stateobj=NULL;
1186: jsval val;
1.1.1.2 ! root 1187: jsrefcount rc;
1.1 root 1188:
1189: if(JSVAL_IS_VOID(argv[0]))
1190: return(JS_TRUE);
1191:
1.1.1.2 ! root 1192: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) /* Will this work? Ask DM */
1.1 root 1193: return(JS_FALSE);
1194:
1195: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
1196: return(JS_FALSE);
1197:
1198: if(argc>1 && JSVAL_IS_BOOLEAN(argv[1]))
1199: exascii=JSVAL_TO_BOOLEAN(argv[1]);
1200:
1201: if(argc>2 && JSVAL_IS_BOOLEAN(argv[2]))
1202: wsp=JSVAL_TO_BOOLEAN(argv[2]);
1203:
1204: if(argc>3 && JSVAL_IS_BOOLEAN(argv[3]))
1205: ansi=JSVAL_TO_BOOLEAN(argv[3]);
1206:
1207: if(argc>4 && JSVAL_IS_BOOLEAN(argv[4]))
1208: {
1209: ctrl_a=JSVAL_TO_BOOLEAN(argv[4]);
1210: if(ctrl_a)
1211: ansi=ctrl_a;
1212: }
1213:
1214: if(argc>5 && JSVAL_IS_OBJECT(argv[5])) {
1215: stateobj=JSVAL_TO_OBJECT(argv[5]);
1216: JS_GetProperty(cx,stateobj,"fg",&val);
1217: if(JSVAL_IS_NUMBER(val))
1218: fg=JS_ValueToInt32(cx, val, &fg);
1219: JS_GetProperty(cx,stateobj,"bg",&val);
1220: if(JSVAL_IS_NUMBER(val))
1221: fg=JS_ValueToInt32(cx, val, &bg);
1222: JS_GetProperty(cx,stateobj,"lastcolor",&val);
1223: if(JSVAL_IS_NUMBER(val))
1224: fg=JS_ValueToInt32(cx, val, &lastcolor);
1225: JS_GetProperty(cx,stateobj,"blink",&val);
1226: if(JSVAL_IS_BOOLEAN(val))
1227: fg=JS_ValueToBoolean(cx, val, &blink);
1228: JS_GetProperty(cx,stateobj,"bold",&val);
1229: if(JSVAL_IS_BOOLEAN(val))
1230: fg=JS_ValueToBoolean(cx, val, &bold);
1231: JS_GetProperty(cx,stateobj,"hpos",&val);
1232: if(JSVAL_IS_NUMBER(val))
1233: fg=JS_ValueToInt32(cx, val, &hpos);
1234: JS_GetProperty(cx,stateobj,"currrow",&val);
1235: if(JSVAL_IS_NUMBER(val))
1236: fg=JS_ValueToInt32(cx, val, &currrow);
1237: JS_GetProperty(cx,stateobj,"wraphpos",&val);
1238: if(JSVAL_IS_NUMBER(val))
1239: fg=JS_ValueToInt32(cx, val, &wraphpos);
1240: JS_GetProperty(cx,stateobj,"wrapvpos",&val);
1241: if(JSVAL_IS_NUMBER(val))
1242: fg=JS_ValueToInt32(cx, val, &wrapvpos);
1243: JS_GetProperty(cx,stateobj,"wrappos",&val);
1244: if(JSVAL_IS_NUMBER(val))
1245: fg=JS_ValueToInt32(cx, val, &wrappos);
1246: }
1247:
1248: if((tmpbuf=(char*)malloc((strlen(inbuf)*10)+1))==NULL)
1249: return(JS_FALSE);
1250:
1.1.1.2 ! root 1251: rc=JS_SUSPENDREQUEST(cx);
1.1 root 1252: for(i=j=0;inbuf[i];i++) {
1253: switch(inbuf[i]) {
1254: case TAB:
1255: case LF:
1256: case CR:
1257: if(wsp)
1258: j+=sprintf(tmpbuf+j,"&#%u;",inbuf[i]);
1259: else
1260: tmpbuf[j++]=inbuf[i];
1261: break;
1262: case '"':
1263: j+=sprintf(tmpbuf+j,""");
1264: break;
1265: case '&':
1266: j+=sprintf(tmpbuf+j,"&");
1267: break;
1268: case '<':
1269: j+=sprintf(tmpbuf+j,"<");
1270: break;
1271: case '>':
1272: j+=sprintf(tmpbuf+j,">");
1273: break;
1274: case '\b':
1.1.1.2 ! root 1275: if(j)
! 1276: j--;
1.1 root 1277: break;
1278: default:
1279: if(inbuf[i]&0x80) {
1280: if(exascii) {
1281: ch=inbuf[i]^0x80;
1282: if(exasctbl[ch].name!=NULL)
1283: j+=sprintf(tmpbuf+j,"&%s;",exasctbl[ch].name);
1284: else
1285: j+=sprintf(tmpbuf+j,"&#%u;",exasctbl[ch].value);
1286: } else
1287: tmpbuf[j++]=inbuf[i];
1288: }
1289: else if(inbuf[i]>=' ' && inbuf[i]<DEL)
1290: tmpbuf[j++]=inbuf[i];
1291: #if 0 /* ASCII 127 - Not displayed? */
1292: else if(inbuf[i]==DEL && exascii)
1293: j+=sprintf(tmpbuf+j,"⌂",exasctbl[ch].value);
1294: #endif
1295: else if(inbuf[i]<' ') /* unknown control chars */
1296: {
1297: if(ansi && inbuf[i]==ESC)
1298: {
1299: esccount++;
1300: tmpbuf[j++]=inbuf[i];
1301: }
1.1.1.2 ! root 1302: else if(ctrl_a && inbuf[i]==CTRL_A)
1.1 root 1303: {
1304: esccount++;
1305: tmpbuf[j++]=inbuf[i];
1306: tmpbuf[j++]=inbuf[++i];
1307: }
1308: else if(exascii) {
1309: ch=inbuf[i];
1310: if(lowasctbl[ch].name!=NULL)
1311: j+=sprintf(tmpbuf+j,"&%s;",lowasctbl[ch].name);
1312: else
1313: j+=sprintf(tmpbuf+j,"&#%u;",lowasctbl[ch].value);
1314: } else
1315: j+=sprintf(tmpbuf+j,"&#%u;",inbuf[i]);
1316: }
1317: break;
1318: }
1319: }
1320: tmpbuf[j]=0;
1321:
1322: if(ansi)
1323: {
1324: obsize=(strlen(tmpbuf)+(esccount+1)*MAX_COLOR_STRING)+1;
1325: if(obsize<2048)
1326: obsize=2048;
1327: if((outbuf=(uchar*)malloc(obsize))==NULL)
1328: {
1329: free(tmpbuf);
1.1.1.2 ! root 1330: JS_RESUMEREQUEST(cx, rc);
1.1 root 1331: return(JS_FALSE);
1332: }
1333: j=sprintf(outbuf,"<span style=\"%s\">",htmlansi[7]);
1334: clear_screen=j;
1335: for(i=0;tmpbuf[i];i++) {
1336: if(j>(obsize/2)) /* Completely arbitrary here... must be carefull with this eventually ToDo */
1337: {
1338: obsize+=(obsize/2);
1339: if((param=realloc(outbuf,obsize))==NULL)
1340: {
1341: free(tmpbuf);
1342: free(outbuf);
1.1.1.2 ! root 1343: JS_RESUMEREQUEST(cx, rc);
1.1 root 1344: return(JS_FALSE);
1345: }
1346: outbuf=param;
1347: }
1348: if(tmpbuf[i]==ESC && tmpbuf[i+1]=='[')
1349: {
1350: if(nodisplay)
1351: continue;
1352: k=0;
1353: memset(&ansi_param,0xff,sizeof(int)*MAX_ANSI_PARAMS);
1354: strncpy(ansi_seq, tmpbuf+i+2, MAX_ANSI_SEQ);
1355: ansi_seq[MAX_ANSI_SEQ]=0;
1356: for(lastparam=ansi_seq;*lastparam;lastparam++)
1357: {
1358: if(isalpha(*lastparam))
1359: {
1360: *(++lastparam)=0;
1361: break;
1362: }
1363: }
1364: k=0;
1365: param=ansi_seq;
1366: if(*param=='?') /* This is to fix ESC[?7 whatever that is */
1367: param++;
1368: if(isdigit(*param))
1369: ansi_param[k++]=atoi(ansi_seq);
1370: while(isspace(*param) || isdigit(*param))
1371: param++;
1372: lastparam=param;
1373: while((param=strchr(param,';'))!=NULL)
1374: {
1375: param++;
1376: ansi_param[k++]=atoi(param);
1377: while(isspace(*param) || isdigit(*param))
1378: param++;
1379: lastparam=param;
1380: }
1381: switch(*lastparam)
1382: {
1383: case 'm': /* Colour */
1384: for(k=0;ansi_param[k]>=0;k++)
1385: {
1386: switch(ansi_param[k])
1387: {
1388: case 0:
1389: fg=7;
1390: bg=0;
1391: blink=FALSE;
1392: bold=FALSE;
1393: break;
1394: case 1:
1395: bold=TRUE;
1396: break;
1397: case 2:
1398: bold=FALSE;
1399: break;
1400: case 5:
1401: blink=TRUE;
1402: break;
1403: case 6:
1404: blink=TRUE;
1405: break;
1406: case 7:
1407: l=fg;
1408: fg=bg;
1409: bg=l;
1410: break;
1411: case 8:
1412: fg=bg;
1413: blink=FALSE;
1414: bold=FALSE;
1415: break;
1416: case 30:
1417: case 31:
1418: case 32:
1419: case 33:
1420: case 34:
1421: case 35:
1422: case 36:
1423: case 37:
1424: fg=ansi_param[k]-30;
1425: break;
1426: case 40:
1427: case 41:
1428: case 42:
1429: case 43:
1430: case 44:
1431: case 45:
1432: case 46:
1433: case 47:
1434: bg=ansi_param[k]-40;
1435: break;
1436: }
1437: }
1438: break;
1439: case 'C': /* Move right */
1440: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1441: lastcolor=0;
1442: l=ansi_param[0]>0?ansi_param[0]:1;
1443: if(wrappos==0 && wrapvpos==currrow) {
1444: /* j+=sprintf(outbuf+j,"<!-- \r\nC after A l=%d hpos=%d -->",l,hpos); */
1445: l=l-hpos;
1446: wrapvpos=-2; /* Prevent additional move right */
1447: }
1448: if(l>81-hpos)
1449: l=81-hpos;
1450: for(k=0; k<l; k++)
1451: {
1452: j+=sprintf(outbuf+j,"%s"," ");
1453: hpos++;
1454: }
1455: break;
1456: case 's': /* Save position */
1457: savepos=j;
1458: savehpos=hpos;
1459: savevpos=currrow;
1460: break;
1461: case 'u': /* Restore saved position */
1462: j=savepos;
1463: hpos=savehpos;
1464: currrow=savevpos;
1465: break;
1466: case 'H': /* Move */
1467: k=ansi_param[0];
1468: if(k<=0)
1469: k=1;
1470: k--;
1471: l=ansi_param[1];
1472: if(l<=0)
1473: l=1;
1474: l--;
1475: while(k>currrow)
1476: {
1477: hpos=0;
1478: currrow++;
1479: outbuf[j++]='\r';
1480: outbuf[j++]='\n';
1481: }
1482: if(l>hpos)
1483: {
1484: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1485: lastcolor=0;
1486: while(l>hpos)
1487: {
1488: j+=sprintf(outbuf+j,"%s"," ");
1489: hpos++;
1490: }
1491: }
1492: break;
1493: case 'B': /* Move down */
1494: l=ansi_param[0];
1495: if(l<=0)
1496: l=1;
1497: for(k=0; k < l; k++)
1498: {
1499: currrow++;
1500: outbuf[j++]='\r';
1501: outbuf[j++]='\n';
1502: }
1503: if(hpos!=0 && tmpbuf[i+1]!=CR)
1504: {
1505: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1506: lastcolor=0;
1507: for(k=0; k<hpos ; k++)
1508: {
1509: j+=sprintf(outbuf+j,"%s"," ");
1510: }
1511: break;
1512: }
1513: break;
1514: case 'A': /* Move up */
1515: l=wrappos;
1516: if(j > (ulong)wrappos && hpos==0 && currrow==wrapvpos+1 && ansi_param[0]<=1) {
1517: hpos=wraphpos;
1518: currrow=wrapvpos;
1519: j=wrappos;
1520: wrappos=0; /* Prevent additional move up */
1521: }
1522: break;
1523: case 'J': /* Clear */
1524: if(ansi_param[0]==2) {
1525: j=clear_screen;
1526: hpos=0;
1527: currrow=0;
1528: wraphpos=-2;
1529: wrapvpos=-2;
1530: wrappos=0;
1531: }
1532: break;
1533: }
1534: i+=(int)(lastparam-ansi_seq)+2;
1535: }
1.1.1.2 ! root 1536: else if(ctrl_a && tmpbuf[i]==CTRL_A) /* CTRL-A codes */
1.1 root 1537: {
1538: /* j+=sprintf(outbuf+j,"<!-- CTRL-A-%c (%u) -->",tmpbuf[i+1],tmpbuf[i+1]); */
1539: if(nodisplay && tmpbuf[i+1] != ')')
1540: continue;
1541: if(tmpbuf[i+1]>0x7f)
1542: {
1543: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1544: lastcolor=0;
1545: l=tmpbuf[i+1]-0x7f;
1546: if(l>81-hpos)
1547: l=81-hpos;
1548: for(k=0; k<l; k++)
1549: {
1550: j+=sprintf(outbuf+j,"%s"," ");
1551: hpos++;
1552: }
1553: }
1554: else switch(toupper(tmpbuf[i+1]))
1555: {
1556: case 'K':
1557: fg=0;
1558: break;
1559: case 'R':
1560: fg=1;
1561: break;
1562: case 'G':
1563: fg=2;
1564: break;
1565: case 'Y':
1566: fg=3;
1567: break;
1568: case 'B':
1569: fg=4;
1570: break;
1571: case 'M':
1572: fg=5;
1573: break;
1574: case 'C':
1575: fg=6;
1576: break;
1577: case 'W':
1578: fg=7;
1579: break;
1580: case '0':
1581: bg=0;
1582: break;
1583: case '1':
1584: bg=1;
1585: break;
1586: case '2':
1587: bg=2;
1588: break;
1589: case '3':
1590: bg=3;
1591: break;
1592: case '4':
1593: bg=4;
1594: break;
1595: case '5':
1596: bg=5;
1597: break;
1598: case '6':
1599: bg=6;
1600: break;
1601: case '7':
1602: bg=7;
1603: break;
1604: case 'H':
1605: bold=TRUE;
1606: break;
1607: case 'I':
1608: blink=TRUE;
1609: break;
1610: case '+':
1611: if(attr_sp<(int)sizeof(attr_stack))
1612: attr_stack[attr_sp++]=(blink?(1<<7):0) | (bg << 4) | (bold?(1<<3):0) | (int)fg;
1613: break;
1614: case '-':
1615: if(attr_sp>0)
1616: {
1617: blink=(attr_stack[--attr_sp]&(1<<7))?TRUE:FALSE;
1618: bg=(attr_stack[attr_sp] >> 4) & 7;
1619: blink=(attr_stack[attr_sp]&(1<<3))?TRUE:FALSE;
1620: fg=attr_stack[attr_sp] & 7;
1621: }
1622: else if(bold || blink || bg)
1623: {
1624: bold=FALSE;
1625: blink=FALSE;
1626: fg=7;
1627: bg=0;
1628: }
1629: break;
1630: case '_':
1631: if(blink || bg)
1632: {
1633: bold=FALSE;
1634: blink=FALSE;
1635: fg=7;
1636: bg=0;
1637: }
1638: break;
1639: case 'N':
1640: bold=FALSE;
1641: blink=FALSE;
1642: fg=7;
1643: bg=0;
1644: break;
1645: case 'P':
1646: case 'Q':
1647: case ',':
1648: case ';':
1649: case '.':
1650: case 'S':
1651: case '>':
1.1.1.2 ! root 1652: break;
! 1653: case '<': /* convert non-destructive backspace into destructive backspace */
! 1654: if(j)
! 1655: j--;
1.1 root 1656: break;
1657:
1658: case '!': /* This needs to be fixed! (Somehow) */
1659: case '@':
1660: case '#':
1661: case '$':
1662: case '%':
1663: case '^':
1664: case '&':
1665: case '*':
1666: case '(':
1667: nodisplay=TRUE;
1668: break;
1669: case ')':
1670: nodisplay=FALSE;
1671: break;
1672:
1673: case 'D':
1674: now=time(NULL);
1.1.1.2 ! root 1675: j+=sprintf(outbuf+j,"%s",unixtodstr(p->cfg,now,tmp1));
1.1 root 1676: break;
1677: case 'T':
1678: now=time(NULL);
1679: localtime_r(&now,&tm);
1680: j+=sprintf(outbuf+j,"%02d:%02d %s"
1681: ,tm.tm_hour==0 ? 12
1682: : tm.tm_hour>12 ? tm.tm_hour-12
1683: : tm.tm_hour, tm.tm_min, tm.tm_hour>11 ? "pm":"am");
1684: break;
1685:
1686: case 'L':
1687: currrow=0;
1688: hpos=0;
1689: outbuf[j++]='\r';
1690: outbuf[j++]='\n';
1691: break;
1692: case ']':
1693: currrow++;
1.1.1.2 ! root 1694: if(hpos!=0 && tmpbuf[i+2]!=CR && !(tmpbuf[i+2]==CTRL_A && tmpbuf[i+3]=='['))
1.1 root 1695: {
1696: outbuf[j++]='\r';
1697: outbuf[j++]='\n';
1698: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1699: lastcolor=0;
1700: for(k=0; k<hpos ; k++)
1701: {
1702: j+=sprintf(outbuf+j,"%s"," ");
1703: }
1704: break;
1705: }
1706: outbuf[j++]='\n';
1707: break;
1708: case '[':
1709: outbuf[j++]='\r';
1710: hpos=0;
1711: break;
1712: case 'Z':
1713: outbuf[j++]=0;
1714: break;
1715: case 'A':
1716: default:
1717: if(exascii) {
1718: ch=tmpbuf[i];
1719: if(lowasctbl[ch].name!=NULL)
1720: j+=sprintf(outbuf+j,"&%s;",lowasctbl[ch].name);
1721: else
1722: j+=sprintf(outbuf+j,"&#%u;",lowasctbl[ch].value);
1723: } else
1724: j+=sprintf(outbuf+j,"&#%u;",inbuf[i]);
1725: i--;
1726: }
1727: i++;
1728: }
1729: else
1730: {
1731: if(nodisplay)
1732: continue;
1733: switch(tmpbuf[i])
1734: {
1735: case TAB: /* This assumes that tabs do NOT use the current background. */
1736: l=hpos%8;
1737: if(l==0)
1738: l=8;
1739: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1740: lastcolor=0;
1741: for(k=0; k<l ; k++)
1742: {
1743: j+=sprintf(outbuf+j,"%s"," ");
1744: hpos++;
1745: }
1746: break;
1747: case LF:
1748: wrapvpos=currrow;
1749: if((ulong)wrappos<j-3)
1750: wrappos=j;
1751: currrow++;
1752: if(hpos!=0 && tmpbuf[i+1]!=CR)
1753: {
1754: outbuf[j++]='\r';
1755: outbuf[j++]='\n';
1756: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[0],HTML_COLOR_SUFFIX);
1757: lastcolor=0;
1758: for(k=0; k<hpos ; k++)
1759: {
1760: j+=sprintf(outbuf+j,"%s"," ");
1761: }
1762: break;
1763: }
1764: case CR:
1765: if(wraphpos==-2 || hpos!=0)
1766: wraphpos=hpos;
1767: if((ulong)wrappos<j-3)
1768: wrappos=j;
1769: outbuf[j++]=tmpbuf[i];
1770: hpos=0;
1771: break;
1772: default:
1773: if(lastcolor != ((blink?(1<<7):0) | (bg << 4) | (bold?(1<<3):0) | fg))
1774: {
1775: lastcolor=(blink?(1<<7):0) | (bg << 4) | (bold?(1<<3):0) | fg;
1776: j+=sprintf(outbuf+j,"%s%s%s",HTML_COLOR_PREFIX,htmlansi[lastcolor],HTML_COLOR_SUFFIX);
1777: }
1778: outbuf[j++]=tmpbuf[i];
1779: if(tmpbuf[i]=='&')
1780: extchar=TRUE;
1781: if(tmpbuf[i]==';')
1782: extchar=FALSE;
1783: if(!extchar)
1784: hpos++;
1785: /* ToDo: Fix hard-coded terminal window width (80) */
1786: if(hpos>=80 && tmpbuf[i+1] != '\r' && tmpbuf[i+1] != '\n' && tmpbuf[i+1] != ESC)
1787: {
1788: wrapvpos=-2;
1789: wraphpos=-2;
1790: wrappos=0;
1791: hpos=0;
1792: currrow++;
1793: outbuf[j++]='\r';
1794: outbuf[j++]='\n';
1795: }
1796: }
1797: }
1798: }
1799: strcpy(outbuf+j,"</span>");
1.1.1.2 ! root 1800: JS_RESUMEREQUEST(cx, rc);
1.1 root 1801:
1802: js_str = JS_NewStringCopyZ(cx, outbuf);
1803: free(outbuf);
1804: }
1.1.1.2 ! root 1805: else {
! 1806: JS_RESUMEREQUEST(cx, rc);
1.1 root 1807: js_str = JS_NewStringCopyZ(cx, tmpbuf);
1.1.1.2 ! root 1808: }
1.1 root 1809:
1810: free(tmpbuf); /* assertion here, Feb-20-2006 */
1811: if(js_str==NULL)
1812: return(JS_FALSE);
1813:
1814: *rval = STRING_TO_JSVAL(js_str);
1815:
1816: if(stateobj!=NULL) {
1817: JS_DefineProperty(cx, stateobj, "fg", INT_TO_JSVAL(fg)
1818: ,NULL,NULL,JSPROP_ENUMERATE);
1819: JS_DefineProperty(cx, stateobj, "bg", INT_TO_JSVAL(bg)
1820: ,NULL,NULL,JSPROP_ENUMERATE);
1821: JS_DefineProperty(cx, stateobj, "lastcolor", INT_TO_JSVAL(lastcolor)
1822: ,NULL,NULL,JSPROP_ENUMERATE);
1823: JS_DefineProperty(cx, stateobj, "blink", BOOLEAN_TO_JSVAL(blink)
1824: ,NULL,NULL,JSPROP_ENUMERATE);
1825: JS_DefineProperty(cx, stateobj, "bold", BOOLEAN_TO_JSVAL(bold)
1826: ,NULL,NULL,JSPROP_ENUMERATE);
1827: JS_DefineProperty(cx, stateobj, "hpos", INT_TO_JSVAL(hpos)
1828: ,NULL,NULL,JSPROP_ENUMERATE);
1829: JS_DefineProperty(cx, stateobj, "currrow", INT_TO_JSVAL(currrow)
1830: ,NULL,NULL,JSPROP_ENUMERATE);
1831: JS_DefineProperty(cx, stateobj, "wraphpos", INT_TO_JSVAL(wraphpos)
1832: ,NULL,NULL,JSPROP_ENUMERATE);
1833: JS_DefineProperty(cx, stateobj, "wrapvpos", INT_TO_JSVAL(wrapvpos)
1834: ,NULL,NULL,JSPROP_ENUMERATE);
1835: JS_DefineProperty(cx, stateobj, "wrappos", INT_TO_JSVAL(wrappos)
1836: ,NULL,NULL,JSPROP_ENUMERATE);
1837: }
1838:
1839: return(JS_TRUE);
1840: }
1841:
1842: static JSBool
1843: js_html_decode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1844: {
1845: int ch;
1846: int val;
1847: ulong i,j;
1848: uchar* inbuf;
1849: uchar* outbuf;
1850: char token[16];
1851: size_t t;
1852: JSString* js_str;
1.1.1.2 ! root 1853: jsrefcount rc;
1.1 root 1854:
1855: if(JSVAL_IS_VOID(argv[0]))
1856: return(JS_TRUE);
1857:
1858: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
1859: return(JS_FALSE);
1860:
1861: if((outbuf=(char*)malloc(strlen(inbuf)+1))==NULL)
1862: return(JS_FALSE);
1863:
1.1.1.2 ! root 1864: rc=JS_SUSPENDREQUEST(cx);
1.1 root 1865: for(i=j=0;inbuf[i];i++) {
1866: if(inbuf[i]!='&') {
1867: outbuf[j++]=inbuf[i];
1868: continue;
1869: }
1870: for(i++,t=0; inbuf[i]!=0 && inbuf[i]!=';' && t<sizeof(token)-1; i++, t++)
1871: token[t]=inbuf[i];
1872: if(inbuf[i]==0)
1873: break;
1874: token[t]=0;
1875:
1876: /* First search the ex-ascii table for a name match */
1877: for(ch=0;ch<128;ch++)
1878: if(exasctbl[ch].name!=NULL && strcmp(token,exasctbl[ch].name)==0)
1879: break;
1880: if(ch<128) {
1881: outbuf[j++]=ch|0x80;
1882: continue;
1883: }
1884: if(token[0]=='#') { /* numeric constant */
1885: val=atoi(token+1);
1886:
1887: /* search ex-ascii table for a value match */
1888: for(ch=0;ch<128;ch++)
1889: if(exasctbl[ch].value==val)
1890: break;
1891: if(ch<128) {
1892: outbuf[j++]=ch|0x80;
1893: continue;
1894: }
1895:
1896: if((val>=' ' && val<=0xff) || val=='\r' || val=='\n' || val=='\t') {
1897: outbuf[j++]=val;
1898: continue;
1899: }
1900: }
1901: if(strcmp(token,"quot")==0) {
1902: outbuf[j++]='"';
1903: continue;
1904: }
1905: if(strcmp(token,"amp")==0) {
1906: outbuf[j++]='&';
1907: continue;
1908: }
1909: if(strcmp(token,"lt")==0) {
1910: outbuf[j++]='<';
1911: continue;
1912: }
1913: if(strcmp(token,"gt")==0) {
1914: outbuf[j++]='>';
1915: continue;
1916: }
1917: if(strcmp(token,"curren")==0) {
1918: outbuf[j++]=CTRL_O;
1919: continue;
1920: }
1921: if(strcmp(token,"para")==0) {
1922: outbuf[j++]=CTRL_T;
1923: continue;
1924: }
1925: if(strcmp(token,"sect")==0) {
1926: outbuf[j++]=CTRL_U;
1927: continue;
1928: }
1929: /* Unknown character entity, leave intact */
1930: j+=sprintf(outbuf+j,"&%s;",token);
1931:
1932: }
1933: outbuf[j]=0;
1.1.1.2 ! root 1934: JS_RESUMEREQUEST(cx, rc);
1.1 root 1935:
1936: js_str = JS_NewStringCopyZ(cx, outbuf);
1937: free(outbuf);
1938: if(js_str==NULL)
1939: return(JS_FALSE);
1940:
1941: *rval = STRING_TO_JSVAL(js_str);
1942: return(JS_TRUE);
1943: }
1944:
1945: static JSBool
1946: js_b64_encode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1947: {
1948: int res;
1949: size_t len;
1950: size_t inbuf_len;
1951: uchar* inbuf;
1952: uchar* outbuf;
1953: JSString* js_str;
1.1.1.2 ! root 1954: jsrefcount rc;
1.1 root 1955:
1956: *rval = JSVAL_NULL;
1957:
1958: if(JSVAL_IS_VOID(argv[0]))
1959: return(JS_TRUE);
1960:
1961: if((inbuf=js_ValueToStringBytes(cx, argv[0], &inbuf_len))==NULL)
1962: return(JS_FALSE);
1963:
1964: len=(inbuf_len*10)+1;
1965:
1966: if((outbuf=(char*)malloc(len))==NULL)
1967: return(JS_FALSE);
1968:
1.1.1.2 ! root 1969: rc=JS_SUSPENDREQUEST(cx);
1.1 root 1970: res=b64_encode(outbuf,len,inbuf,inbuf_len);
1.1.1.2 ! root 1971: JS_RESUMEREQUEST(cx, rc);
1.1 root 1972:
1973: if(res<1) {
1974: free(outbuf);
1975: return(JS_TRUE);
1976: }
1977:
1978: js_str = JS_NewStringCopyZ(cx, outbuf);
1979: free(outbuf);
1980: if(js_str==NULL)
1981: return(JS_FALSE);
1982:
1983: *rval = STRING_TO_JSVAL(js_str);
1984: return(JS_TRUE);
1985: }
1986:
1987: static JSBool
1988: js_b64_decode(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
1989: {
1990: int res;
1991: size_t len;
1992: uchar* inbuf;
1993: uchar* outbuf;
1994: JSString* js_str;
1.1.1.2 ! root 1995: jsrefcount rc;
1.1 root 1996:
1997: *rval = JSVAL_NULL;
1998:
1999: if(JSVAL_IS_VOID(argv[0]))
2000: return(JS_TRUE);
2001:
2002: if((inbuf=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2003: return(JS_FALSE);
2004:
2005: len=strlen(inbuf)+1;
2006:
2007: if((outbuf=(char*)malloc(len))==NULL)
2008: return(JS_FALSE);
2009:
1.1.1.2 ! root 2010: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2011: res=b64_decode(outbuf,len,inbuf,strlen(inbuf));
1.1.1.2 ! root 2012: JS_RESUMEREQUEST(cx, rc);
1.1 root 2013:
2014: if(res<1) {
2015: free(outbuf);
2016: return(JS_TRUE);
2017: }
2018:
2019: js_str = JS_NewStringCopyN(cx, outbuf, res);
2020: free(outbuf);
2021: if(js_str==NULL)
2022: return(JS_FALSE);
2023:
2024: *rval = STRING_TO_JSVAL(js_str);
2025: return(JS_TRUE);
2026: }
2027:
2028: static JSBool
2029: js_md5_calc(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval)
2030: {
2031: BYTE digest[MD5_DIGEST_SIZE];
2032: JSBool hex=JS_FALSE;
2033: size_t inbuf_len;
2034: char* inbuf;
2035: char outbuf[64];
2036: JSString* js_str;
1.1.1.2 ! root 2037: jsrefcount rc;
1.1 root 2038:
2039: *rval = JSVAL_NULL;
2040:
2041: if(JSVAL_IS_VOID(argv[0]))
2042: return(JS_TRUE);
2043:
2044: if((inbuf=js_ValueToStringBytes(cx, argv[0], &inbuf_len))==NULL)
2045: return(JS_FALSE);
2046:
2047: if(argc>1 && JSVAL_IS_BOOLEAN(argv[1]))
2048: hex=JSVAL_TO_BOOLEAN(argv[1]);
2049:
1.1.1.2 ! root 2050: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2051: MD5_calc(digest,inbuf,inbuf_len);
2052:
2053: if(hex)
2054: MD5_hex(outbuf,digest);
2055: else
2056: b64_encode(outbuf,sizeof(outbuf),digest,sizeof(digest));
1.1.1.2 ! root 2057: JS_RESUMEREQUEST(cx, rc);
1.1 root 2058:
2059: js_str = JS_NewStringCopyZ(cx, outbuf);
2060: if(js_str==NULL)
2061: return(JS_FALSE);
2062:
2063: *rval = STRING_TO_JSVAL(js_str);
2064: return(JS_TRUE);
2065: }
2066:
2067: static JSBool
1.1.1.2 ! root 2068: js_skipsp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
! 2069: {
! 2070: char* str;
! 2071: JSString* js_str;
! 2072:
! 2073: if(JSVAL_IS_VOID(argv[0]))
! 2074: return(JS_TRUE);
! 2075:
! 2076: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
! 2077: return(JS_FALSE);
! 2078:
! 2079: js_str = JS_NewStringCopyZ(cx, skipsp(str));
! 2080: if(js_str==NULL)
! 2081: return(JS_FALSE);
! 2082:
! 2083: *rval = STRING_TO_JSVAL(js_str);
! 2084: return(JS_TRUE);
! 2085: }
! 2086:
! 2087: static JSBool
1.1 root 2088: js_truncsp(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2089: {
2090: char* p;
2091: char* str;
2092: JSString* js_str;
2093:
2094: if(JSVAL_IS_VOID(argv[0]))
2095: return(JS_TRUE);
2096:
2097: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2098: return(JS_FALSE);
2099:
2100: if((p=strdup(str))==NULL)
2101: return(JS_FALSE);
2102:
2103: truncsp(p);
2104:
2105: js_str = JS_NewStringCopyZ(cx, p);
2106: free(p);
2107: if(js_str==NULL)
2108: return(JS_FALSE);
2109:
2110: *rval = STRING_TO_JSVAL(js_str);
2111: return(JS_TRUE);
2112: }
2113:
2114: static JSBool
2115: js_truncstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2116: {
2117: char* p;
2118: char* str;
2119: char* set;
2120: JSString* js_str;
2121:
2122: if(JSVAL_IS_VOID(argv[0]))
2123: return(JS_TRUE);
2124:
2125: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2126: return(JS_FALSE);
2127:
2128: if((set=js_ValueToStringBytes(cx, argv[1], NULL))==NULL)
2129: return(JS_FALSE);
2130:
2131: if((p=strdup(str))==NULL)
2132: return(JS_FALSE);
2133:
2134: truncstr(p,set);
2135:
2136: js_str = JS_NewStringCopyZ(cx, p);
2137: free(p);
2138: if(js_str==NULL)
2139: return(JS_FALSE);
2140:
2141: *rval = STRING_TO_JSVAL(js_str);
2142: return(JS_TRUE);
2143: }
2144:
2145: static JSBool
2146: js_backslash(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2147: {
2148: char path[MAX_PATH+1];
2149: char* str;
2150: JSString* js_str;
2151:
2152: if(JSVAL_IS_VOID(argv[0]))
2153: return(JS_TRUE);
2154:
2155: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2156: return(JS_FALSE);
2157:
2158: SAFECOPY(path,str);
2159: backslash(path);
2160:
2161: if((js_str = JS_NewStringCopyZ(cx, path))==NULL)
2162: return(JS_FALSE);
2163:
2164: *rval = STRING_TO_JSVAL(js_str);
2165: return(JS_TRUE);
2166: }
2167:
1.1.1.2 ! root 2168: static JSBool
! 2169: js_fullpath(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
! 2170: {
! 2171: char path[MAX_PATH+1];
! 2172: char* str;
! 2173: JSString* js_str;
! 2174: jsrefcount rc;
! 2175:
! 2176: if(JSVAL_IS_VOID(argv[0]))
! 2177: return(JS_TRUE);
! 2178:
! 2179: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
! 2180: return(JS_FALSE);
! 2181:
! 2182: SAFECOPY(path,str);
! 2183: rc=JS_SUSPENDREQUEST(cx);
! 2184: _fullpath(path, str, sizeof(path));
! 2185: JS_RESUMEREQUEST(cx, rc);
! 2186:
! 2187: if((js_str = JS_NewStringCopyZ(cx, path))==NULL)
! 2188: return(JS_FALSE);
! 2189:
! 2190: *rval = STRING_TO_JSVAL(js_str);
! 2191: return(JS_TRUE);
! 2192: }
! 2193:
1.1 root 2194:
2195: static JSBool
2196: js_getfname(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2197: {
2198: char* str;
2199: JSString* js_str;
2200:
2201: if(JSVAL_IS_VOID(argv[0]))
2202: return(JS_TRUE);
2203:
2204: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2205: return(JS_FALSE);
2206:
2207: js_str = JS_NewStringCopyZ(cx, getfname(str));
2208: if(js_str==NULL)
2209: return(JS_FALSE);
2210:
2211: *rval = STRING_TO_JSVAL(js_str);
2212: return(JS_TRUE);
2213: }
2214:
2215: static JSBool
2216: js_getfext(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2217: {
2218: char* str;
2219: char* p;
2220: JSString* js_str;
2221:
2222: if(JSVAL_IS_VOID(argv[0]))
2223: return(JS_TRUE);
2224:
2225: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2226: return(JS_FALSE);
2227:
2228: if((p=getfext(str))==NULL)
2229: return(JS_TRUE);
2230:
2231: js_str = JS_NewStringCopyZ(cx, p);
2232: if(js_str==NULL)
2233: return(JS_FALSE);
2234:
2235: *rval = STRING_TO_JSVAL(js_str);
2236: return(JS_TRUE);
2237: }
2238:
2239: static JSBool
2240: js_getfcase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2241: {
2242: char* str;
2243: char path[MAX_PATH+1];
2244: JSString* js_str;
1.1.1.2 ! root 2245: jsrefcount rc;
1.1 root 2246:
2247: if(JSVAL_IS_VOID(argv[0]))
2248: return(JS_TRUE);
2249:
2250: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2251: return(JS_FALSE);
2252:
2253: SAFECOPY(path,str);
1.1.1.2 ! root 2254: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2255: if(fexistcase(path)) {
1.1.1.2 ! root 2256: JS_RESUMEREQUEST(cx, rc);
! 2257: js_str = JS_NewStringCopyZ(cx, path);
! 2258: if(js_str==NULL)
! 2259: return(JS_FALSE);
! 2260:
! 2261: *rval = STRING_TO_JSVAL(js_str);
! 2262: }
! 2263: else
! 2264: JS_RESUMEREQUEST(cx, rc);
! 2265: return(JS_TRUE);
! 2266: }
! 2267:
! 2268: static JSBool
! 2269: js_dosfname(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
! 2270: {
! 2271: char* str;
! 2272: char path[MAX_PATH+1];
! 2273: JSString* js_str;
! 2274: jsrefcount rc;
! 2275:
! 2276: if(JSVAL_IS_VOID(argv[0]))
! 2277: return(JS_TRUE);
! 2278:
! 2279: #if defined(_WIN32)
! 2280:
! 2281: if((str=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
! 2282: return(JS_FALSE);
! 2283:
! 2284: rc=JS_SUSPENDREQUEST(cx);
! 2285: if(GetShortPathName(str,path,sizeof(path))) {
! 2286: JS_RESUMEREQUEST(cx, rc);
1.1 root 2287: js_str = JS_NewStringCopyZ(cx, path);
2288: if(js_str==NULL)
2289: return(JS_FALSE);
2290:
2291: *rval = STRING_TO_JSVAL(js_str);
2292: }
1.1.1.2 ! root 2293: else
! 2294: JS_RESUMEREQUEST(cx, rc);
! 2295:
! 2296: #else /* No non-Windows equivalent */
! 2297:
! 2298: *rval = argv[0];
! 2299:
! 2300: #endif
! 2301:
1.1 root 2302: return(JS_TRUE);
2303: }
2304:
2305: static JSBool
2306: js_cfgfname(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2307: {
2308: char* path;
2309: char* fname;
2310: char result[MAX_PATH+1];
1.1.1.2 ! root 2311: char* cstr;
! 2312: jsrefcount rc;
1.1 root 2313:
2314: if(JSVAL_IS_VOID(argv[0]))
2315: return(JS_TRUE);
2316:
2317: if((path=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2318: return(JS_FALSE);
2319:
2320: if((fname=js_ValueToStringBytes(cx, argv[1], NULL))==NULL)
2321: return(JS_FALSE);
2322:
1.1.1.2 ! root 2323: rc=JS_SUSPENDREQUEST(cx);
! 2324: cstr = iniFileName(result,sizeof(result),path,fname);
! 2325: JS_RESUMEREQUEST(cx, rc);
! 2326: *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,cstr));
1.1 root 2327:
2328: return(JS_TRUE);
2329: }
2330:
2331: static JSBool
2332: js_fexist(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2333: {
2334: char* p;
1.1.1.2 ! root 2335: jsrefcount rc;
1.1 root 2336:
2337: if(JSVAL_IS_VOID(argv[0]))
2338: return(JS_TRUE);
2339:
2340: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2341: return(JS_FALSE);
2342:
1.1.1.2 ! root 2343: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2344: *rval = BOOLEAN_TO_JSVAL(fexist(p));
1.1.1.2 ! root 2345: JS_RESUMEREQUEST(cx, rc);
1.1 root 2346: return(JS_TRUE);
2347: }
2348:
2349: static JSBool
2350: js_removecase(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2351: {
2352: char* p;
1.1.1.2 ! root 2353: jsrefcount rc;
1.1 root 2354:
2355: if(JSVAL_IS_VOID(argv[0]))
2356: return(JS_TRUE);
2357:
2358: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2359: return(JS_FALSE);
2360:
1.1.1.2 ! root 2361: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2362: *rval = BOOLEAN_TO_JSVAL(removecase(p)==0);
1.1.1.2 ! root 2363: JS_RESUMEREQUEST(cx, rc);
1.1 root 2364: return(JS_TRUE);
2365: }
2366:
2367: static JSBool
2368: js_remove(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2369: {
2370: char* p;
1.1.1.2 ! root 2371: jsrefcount rc;
1.1 root 2372:
2373: if(JSVAL_IS_VOID(argv[0]))
2374: return(JS_TRUE);
2375:
2376: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2377: return(JS_FALSE);
2378:
1.1.1.2 ! root 2379: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2380: *rval = BOOLEAN_TO_JSVAL(remove(p)==0);
1.1.1.2 ! root 2381: JS_RESUMEREQUEST(cx, rc);
1.1 root 2382: return(JS_TRUE);
2383: }
2384:
2385: static JSBool
2386: js_rename(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2387: {
2388: char* oldname;
2389: char* newname;
1.1.1.2 ! root 2390: jsrefcount rc;
1.1 root 2391:
2392: if(JSVAL_IS_VOID(argv[0]))
2393: return(JS_TRUE);
2394:
2395: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
2396: if((oldname=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2397: return(JS_TRUE);
2398: if((newname=js_ValueToStringBytes(cx, argv[1], NULL))==NULL)
2399: return(JS_TRUE);
2400:
1.1.1.2 ! root 2401: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2402: *rval = BOOLEAN_TO_JSVAL(rename(oldname,newname)==0);
1.1.1.2 ! root 2403: JS_RESUMEREQUEST(cx, rc);
1.1 root 2404: return(JS_TRUE);
2405: }
2406:
2407: static JSBool
2408: js_fcopy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2409: {
2410: char* src;
2411: char* dest;
1.1.1.2 ! root 2412: jsrefcount rc;
1.1 root 2413:
2414: if(JSVAL_IS_VOID(argv[0]))
2415: return(JS_TRUE);
2416:
2417: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
2418: if((src=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2419: return(JS_TRUE);
2420: if((dest=js_ValueToStringBytes(cx, argv[1], NULL))==NULL)
2421: return(JS_TRUE);
2422:
1.1.1.2 ! root 2423: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2424: *rval = BOOLEAN_TO_JSVAL(fcopy(src,dest));
1.1.1.2 ! root 2425: JS_RESUMEREQUEST(cx, rc);
1.1 root 2426: return(JS_TRUE);
2427: }
2428:
2429: static JSBool
2430: js_fcompare(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2431: {
2432: char* fn1;
2433: char* fn2;
1.1.1.2 ! root 2434: jsrefcount rc;
1.1 root 2435:
2436: if(JSVAL_IS_VOID(argv[0]))
2437: return(JS_TRUE);
2438:
2439: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
2440: if((fn1=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2441: return(JS_TRUE);
2442: if((fn2=js_ValueToStringBytes(cx, argv[1], NULL))==NULL)
2443: return(JS_TRUE);
2444:
1.1.1.2 ! root 2445: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2446: *rval = BOOLEAN_TO_JSVAL(fcompare(fn1,fn2));
1.1.1.2 ! root 2447: JS_RESUMEREQUEST(cx, rc);
1.1 root 2448: return(JS_TRUE);
2449: }
2450:
2451: static JSBool
2452: js_backup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2453: {
2454: char* fname;
2455: int32 level=5;
2456: BOOL ren=FALSE;
1.1.1.2 ! root 2457: jsrefcount rc;
1.1 root 2458:
2459: if(JSVAL_IS_VOID(argv[0]))
2460: return(JS_TRUE);
2461:
2462: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
2463: if((fname=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2464: return(JS_TRUE);
2465:
2466: if(argc>1)
2467: JS_ValueToInt32(cx,argv[1],&level);
2468: if(argc>2)
2469: JS_ValueToBoolean(cx,argv[2],&ren);
2470:
1.1.1.2 ! root 2471: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2472: *rval = BOOLEAN_TO_JSVAL(backup(fname,level,ren));
1.1.1.2 ! root 2473: JS_RESUMEREQUEST(cx, rc);
1.1 root 2474: return(JS_TRUE);
2475: }
2476:
2477: static JSBool
2478: js_isdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2479: {
2480: char* p;
1.1.1.2 ! root 2481: jsrefcount rc;
1.1 root 2482:
2483: if(JSVAL_IS_VOID(argv[0]))
2484: return(JS_TRUE);
2485:
2486: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2487: return(JS_FALSE);
2488:
1.1.1.2 ! root 2489: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2490: *rval = BOOLEAN_TO_JSVAL(isdir(p));
1.1.1.2 ! root 2491: JS_RESUMEREQUEST(cx, rc);
1.1 root 2492: return(JS_TRUE);
2493: }
2494:
2495: static JSBool
2496: js_fattr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2497: {
2498: char* p;
1.1.1.2 ! root 2499: jsrefcount rc;
! 2500: int attr;
1.1 root 2501:
2502: if(JSVAL_IS_VOID(argv[0]))
2503: return(JS_TRUE);
2504:
2505: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2506: return(JS_FALSE);
2507:
1.1.1.2 ! root 2508: rc=JS_SUSPENDREQUEST(cx);
! 2509: attr=getfattr(p);
! 2510: JS_RESUMEREQUEST(cx, rc);
! 2511: JS_NewNumberValue(cx,attr,rval);
1.1 root 2512: return(JS_TRUE);
2513: }
2514:
2515: static JSBool
2516: js_fdate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2517: {
2518: char* p;
1.1.1.2 ! root 2519: time_t fd;
! 2520: jsrefcount rc;
1.1 root 2521:
2522: if(JSVAL_IS_VOID(argv[0]))
2523: return(JS_TRUE);
2524:
2525: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2526: return(JS_FALSE);
2527:
1.1.1.2 ! root 2528: rc=JS_SUSPENDREQUEST(cx);
! 2529: fd=fdate(p);
! 2530: JS_RESUMEREQUEST(cx, rc);
! 2531: JS_NewNumberValue(cx,fd,rval);
1.1 root 2532: return(JS_TRUE);
2533: }
2534:
2535: static JSBool
2536: js_utime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2537: {
2538: char* fname;
2539: int32 actime;
2540: int32 modtime;
1.1.1.2 ! root 2541: struct utimbuf ut;
! 2542: jsrefcount rc;
1.1 root 2543:
2544: if(JSVAL_IS_VOID(argv[0]))
2545: return(JS_TRUE);
2546:
2547: *rval = JSVAL_FALSE;
2548:
2549: if((fname=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2550: return(JS_FALSE);
2551:
1.1.1.2 ! root 2552: /* use current time as default */
! 2553: ut.actime = ut.modtime = time(NULL);
! 2554:
1.1 root 2555: if(argc>1) {
1.1.1.2 ! root 2556: actime=modtime=ut.actime;
1.1 root 2557: JS_ValueToInt32(cx,argv[1],&actime);
2558: JS_ValueToInt32(cx,argv[2],&modtime);
1.1.1.2 ! root 2559: ut.actime=actime;
! 2560: ut.modtime=modtime;
1.1 root 2561: }
2562:
1.1.1.2 ! root 2563: rc=JS_SUSPENDREQUEST(cx);
! 2564: *rval = BOOLEAN_TO_JSVAL(utime(fname,&ut)==0);
! 2565: JS_RESUMEREQUEST(cx, rc);
1.1 root 2566:
2567: return(JS_TRUE);
2568: }
2569:
2570:
2571: static JSBool
2572: js_flength(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2573: {
2574: char* p;
1.1.1.2 ! root 2575: off_t fl;
! 2576: jsrefcount rc;
1.1 root 2577:
2578: if(JSVAL_IS_VOID(argv[0]))
2579: return(JS_TRUE);
2580:
2581: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2582: return(JS_FALSE);
2583:
1.1.1.2 ! root 2584: rc=JS_SUSPENDREQUEST(cx);
! 2585: fl=flength(p);
! 2586: JS_RESUMEREQUEST(cx, rc);
! 2587: JS_NewNumberValue(cx,(double)fl,rval);
1.1 root 2588: return(JS_TRUE);
2589: }
2590:
2591:
2592: static JSBool
2593: js_ftouch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2594: {
2595: char* fname;
1.1.1.2 ! root 2596: jsrefcount rc;
1.1 root 2597:
2598: if(JSVAL_IS_VOID(argv[0]))
2599: return(JS_TRUE);
2600:
2601: if((fname=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2602: return(JS_FALSE);
2603:
1.1.1.2 ! root 2604: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2605: *rval = BOOLEAN_TO_JSVAL(ftouch(fname));
1.1.1.2 ! root 2606: JS_RESUMEREQUEST(cx, rc);
1.1 root 2607: return(JS_TRUE);
2608: }
2609:
2610: static JSBool
2611: js_fmutex(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2612: {
2613: char* fname;
2614: char* text=NULL;
2615: int32 max_age=0;
2616: uintN argn=0;
1.1.1.2 ! root 2617: jsrefcount rc;
1.1 root 2618:
2619: if(JSVAL_IS_VOID(argv[0]))
2620: return(JS_TRUE);
2621:
2622: if((fname=js_ValueToStringBytes(cx, argv[argn++], NULL))==NULL)
2623: return(JS_FALSE);
2624: if(argc > argn && JSVAL_IS_STRING(argv[argn]))
2625: text=js_ValueToStringBytes(cx, argv[argn++], NULL);
2626: if(argc > argn && JSVAL_IS_NUMBER(argv[argn]))
2627: JS_ValueToInt32(cx, argv[argn++], &max_age);
2628:
1.1.1.2 ! root 2629: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2630: *rval = BOOLEAN_TO_JSVAL(fmutex(fname,text,max_age));
1.1.1.2 ! root 2631: JS_RESUMEREQUEST(cx, rc);
1.1 root 2632: return(JS_TRUE);
2633: }
2634:
2635: static JSBool
2636: js_sound(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2637: {
2638: char* p;
1.1.1.2 ! root 2639: jsrefcount rc;
1.1 root 2640:
2641: if(!argc) { /* Stop playing sound */
2642: #ifdef _WIN32
2643: PlaySound(NULL,NULL,0);
2644: #endif
2645: *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
2646: return(JS_TRUE);
2647: }
2648:
2649: if(JSVAL_IS_VOID(argv[0]))
2650: return(JS_TRUE);
2651:
2652: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2653: return(JS_FALSE);
2654:
1.1.1.2 ! root 2655: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2656: #ifdef _WIN32
2657: *rval = BOOLEAN_TO_JSVAL(PlaySound(p, NULL, SND_ASYNC|SND_FILENAME));
2658: #else
2659: *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
2660: #endif
1.1.1.2 ! root 2661: JS_RESUMEREQUEST(cx, rc);
1.1 root 2662:
2663: return(JS_TRUE);
2664: }
2665:
2666: static JSBool
2667: js_directory(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2668: {
2669: int i;
2670: int32 flags=GLOB_MARK;
2671: char* p;
2672: glob_t g;
2673: JSObject* array;
2674: JSString* js_str;
2675: jsint len=0;
2676: jsval val;
1.1.1.2 ! root 2677: jsrefcount rc;
1.1 root 2678:
2679: if(JSVAL_IS_VOID(argv[0]))
2680: return(JS_TRUE);
2681:
2682: *rval = JSVAL_NULL;
2683:
2684: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2685: return(JS_FALSE);
2686:
2687: if(argc>1)
2688: JS_ValueToInt32(cx,argv[1],&flags);
2689:
2690: if((array = JS_NewArrayObject(cx, 0, NULL))==NULL)
2691: return(JS_FALSE);
2692:
1.1.1.2 ! root 2693: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2694: glob(p,flags,NULL,&g);
1.1.1.2 ! root 2695: JS_RESUMEREQUEST(cx, rc);
1.1 root 2696: for(i=0;i<(int)g.gl_pathc;i++) {
2697: if((js_str=JS_NewStringCopyZ(cx,g.gl_pathv[i]))==NULL)
2698: break;
2699: val=STRING_TO_JSVAL(js_str);
2700: if(!JS_SetElement(cx, array, len++, &val))
2701: break;
2702: }
1.1.1.2 ! root 2703: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2704: globfree(&g);
1.1.1.2 ! root 2705: JS_RESUMEREQUEST(cx, rc);
1.1 root 2706:
2707: *rval = OBJECT_TO_JSVAL(array);
2708:
2709: return(JS_TRUE);
2710: }
2711:
2712: static JSBool
2713: js_wildmatch(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2714: {
2715: BOOL case_sensitive=FALSE;
2716: BOOL path=FALSE;
2717: char* fname;
2718: char* spec="*";
2719: uintN argn=0;
1.1.1.2 ! root 2720: jsrefcount rc;
1.1 root 2721:
2722: if(JSVAL_IS_BOOLEAN(argv[argn]))
2723: JS_ValueToBoolean(cx, argv[argn++], &case_sensitive);
2724:
2725: if((fname=js_ValueToStringBytes(cx, argv[argn++], NULL))==NULL)
2726: return(JS_FALSE);
2727:
2728: if(argn<argc && argv[argn]!=JSVAL_VOID)
2729: if((spec=js_ValueToStringBytes(cx, argv[argn++], NULL))==NULL)
2730: return(JS_FALSE);
2731:
2732: if(argn<argc && argv[argn]!=JSVAL_VOID)
2733: JS_ValueToBoolean(cx, argv[argn++], &path);
2734:
1.1.1.2 ! root 2735: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2736: if(case_sensitive)
2737: *rval = BOOLEAN_TO_JSVAL(wildmatch(fname, spec, path));
2738: else
2739: *rval = BOOLEAN_TO_JSVAL(wildmatchi(fname, spec, path));
1.1.1.2 ! root 2740: JS_RESUMEREQUEST(cx, rc);
1.1 root 2741:
2742: return(JS_TRUE);
2743: }
2744:
2745:
2746: static JSBool
2747: js_freediskspace(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2748: {
2749: int32 unit=0;
2750: char* p;
1.1.1.2 ! root 2751: ulong fd;
! 2752: jsrefcount rc;
1.1 root 2753:
2754: if(JSVAL_IS_VOID(argv[0]))
2755: return(JS_TRUE);
2756:
2757: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2758: return(JS_FALSE);
2759:
2760: if(argc>1)
2761: JS_ValueToInt32(cx,argv[1],&unit);
2762:
1.1.1.2 ! root 2763: rc=JS_SUSPENDREQUEST(cx);
! 2764: fd=getfreediskspace(p,unit);
! 2765: JS_RESUMEREQUEST(cx, rc);
! 2766: JS_NewNumberValue(cx,fd,rval);
1.1 root 2767:
2768: return(JS_TRUE);
2769: }
2770:
2771: static JSBool
2772: js_disksize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2773: {
2774: int32 unit=0;
2775: char* p;
1.1.1.2 ! root 2776: ulong ds;
! 2777: jsrefcount rc;
1.1 root 2778:
2779: if(JSVAL_IS_VOID(argv[0]))
2780: return(JS_TRUE);
2781:
2782: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2783: return(JS_FALSE);
2784:
2785: if(argc>1)
2786: JS_ValueToInt32(cx,argv[1],&unit);
2787:
1.1.1.2 ! root 2788: rc=JS_SUSPENDREQUEST(cx);
! 2789: ds=getdisksize(p,unit);
! 2790: JS_RESUMEREQUEST(cx, rc);
! 2791: JS_NewNumberValue(cx,ds,rval);
1.1 root 2792:
2793: return(JS_TRUE);
2794: }
2795:
2796: static JSBool
2797: js_socket_select(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2798: {
2799: JSObject* inarray=NULL;
2800: JSObject* rarray;
2801: BOOL poll_for_write=FALSE;
2802: fd_set socket_set;
2803: fd_set* rd_set=NULL;
2804: fd_set* wr_set=NULL;
2805: uintN argn;
2806: SOCKET sock;
2807: SOCKET maxsock=0;
2808: struct timeval tv = {0, 0};
2809: jsuint i;
2810: jsuint limit;
2811: SOCKET* index;
2812: jsval val;
2813: int len=0;
1.1.1.2 ! root 2814: jsrefcount rc;
1.1 root 2815:
2816: *rval = JSVAL_NULL;
2817:
2818: for(argn=0;argn<argc;argn++) {
2819: if(JSVAL_IS_BOOLEAN(argv[argn]))
2820: poll_for_write=JSVAL_TO_BOOLEAN(argv[argn]);
2821: else if(JSVAL_IS_OBJECT(argv[argn]))
2822: inarray = JSVAL_TO_OBJECT(argv[argn]);
2823: else if(JSVAL_IS_NUMBER(argv[argn]))
2824: js_timeval(cx,argv[argn],&tv);
2825: }
2826:
2827: if(inarray==NULL || !JS_IsArrayObject(cx, inarray))
2828: return(JS_TRUE); /* This not a fatal error */
2829:
2830: if(!JS_GetArrayLength(cx, inarray, &limit))
2831: return(JS_TRUE);
2832:
2833: /* Return array */
2834: if((rarray = JS_NewArrayObject(cx, 0, NULL))==NULL)
2835: return(JS_FALSE);
2836:
2837: if((index=(SOCKET *)alloca(sizeof(SOCKET)*limit))==NULL)
2838: return(JS_FALSE);
2839:
2840: FD_ZERO(&socket_set);
2841: if(poll_for_write)
2842: wr_set=&socket_set;
2843: else
2844: rd_set=&socket_set;
2845:
2846: for(i=0;i<limit;i++) {
2847: if(!JS_GetElement(cx, inarray, i, &val))
2848: break;
2849: sock=js_socket(cx,val);
2850: index[i]=sock;
2851: if(sock!=INVALID_SOCKET) {
2852: FD_SET(sock,&socket_set);
2853: if(sock>maxsock)
2854: maxsock=sock;
2855: }
2856: }
2857:
1.1.1.2 ! root 2858: rc=JS_SUSPENDREQUEST(cx);
! 2859: if(select(maxsock+1,rd_set,wr_set,NULL,&tv) >= 0) {
1.1 root 2860:
1.1.1.2 ! root 2861: for(i=0;i<limit;i++) {
! 2862: if(index[i]!=INVALID_SOCKET && FD_ISSET(index[i],&socket_set)) {
! 2863: val=INT_TO_JSVAL(i);
! 2864: JS_RESUMEREQUEST(cx, rc);
! 2865: if(!JS_SetElement(cx, rarray, len++, &val)) {
! 2866: rc=JS_SUSPENDREQUEST(cx);
! 2867: break;
! 2868: }
! 2869: rc=JS_SUSPENDREQUEST(cx);
! 2870: }
1.1 root 2871: }
2872:
1.1.1.2 ! root 2873: *rval = OBJECT_TO_JSVAL(rarray);
! 2874: }
! 2875: JS_RESUMEREQUEST(cx, rc);
1.1 root 2876:
2877: return(JS_TRUE);
2878: }
2879:
2880: static JSBool
2881: js_mkdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2882: {
2883: char* p;
1.1.1.2 ! root 2884: jsrefcount rc;
1.1 root 2885:
2886: if(JSVAL_IS_VOID(argv[0]))
2887: return(JS_TRUE);
2888:
2889: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2890: return(JS_FALSE);
2891:
1.1.1.2 ! root 2892: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2893: *rval = BOOLEAN_TO_JSVAL(MKDIR(p)==0);
1.1.1.2 ! root 2894: JS_RESUMEREQUEST(cx, rc);
! 2895: return(JS_TRUE);
! 2896: }
! 2897:
! 2898: static JSBool
! 2899: js_mkpath(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
! 2900: {
! 2901: char* p;
! 2902: jsrefcount rc;
! 2903:
! 2904: if(JSVAL_IS_VOID(argv[0]))
! 2905: return(JS_TRUE);
! 2906:
! 2907: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
! 2908: return(JS_FALSE);
! 2909:
! 2910: rc=JS_SUSPENDREQUEST(cx);
! 2911: *rval = BOOLEAN_TO_JSVAL(mkpath(p)==0);
! 2912: JS_RESUMEREQUEST(cx, rc);
1.1 root 2913: return(JS_TRUE);
2914: }
2915:
2916: static JSBool
2917: js_rmdir(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2918: {
2919: char* p;
1.1.1.2 ! root 2920: jsrefcount rc;
1.1 root 2921:
2922: if(JSVAL_IS_VOID(argv[0]))
2923: return(JS_TRUE);
2924:
2925: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2926: return(JS_FALSE);
2927:
1.1.1.2 ! root 2928: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2929: *rval = BOOLEAN_TO_JSVAL(rmdir(p)==0);
1.1.1.2 ! root 2930: JS_RESUMEREQUEST(cx, rc);
1.1 root 2931: return(JS_TRUE);
2932: }
2933:
2934:
2935: static JSBool
2936: js_strftime(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2937: {
2938: char str[128];
2939: char* fmt;
2940: int32 i=time(NULL);
2941: time_t t;
2942: struct tm tm;
2943: JSString* js_str;
1.1.1.2 ! root 2944: jsrefcount rc;
1.1 root 2945:
2946: if(JSVAL_IS_VOID(argv[0]))
2947: return(JS_TRUE);
2948:
2949: if((fmt=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2950: return(JS_FALSE);
2951:
2952: if(argc>1)
2953: JS_ValueToInt32(cx,argv[1],&i);
2954:
1.1.1.2 ! root 2955: rc=JS_SUSPENDREQUEST(cx);
1.1 root 2956: strcpy(str,"-Invalid time-");
2957: t=i;
1.1.1.2 ! root 2958: if(localtime_r(&t,&tm)!=NULL)
! 2959: strftime(str,sizeof(str),fmt,&tm);
! 2960: JS_RESUMEREQUEST(cx, rc);
1.1 root 2961:
2962: if((js_str=JS_NewStringCopyZ(cx, str))==NULL)
2963: return(JS_FALSE);
2964:
2965: *rval = STRING_TO_JSVAL(js_str);
2966: return(JS_TRUE);
2967: }
2968:
2969: static JSBool
2970: js_resolve_ip(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
2971: {
2972: struct in_addr addr;
2973: JSString* str;
2974: char* p;
1.1.1.2 ! root 2975: jsrefcount rc;
1.1 root 2976:
2977: *rval = JSVAL_NULL;
2978:
2979: if(JSVAL_IS_VOID(argv[0]))
2980: return(JS_TRUE);
2981:
2982: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
2983: return(JS_FALSE);
2984:
1.1.1.2 ! root 2985: rc=JS_SUSPENDREQUEST(cx);
! 2986: addr.s_addr=resolve_ip(p);
! 2987: JS_RESUMEREQUEST(cx, rc);
! 2988: if(addr.s_addr==INADDR_NONE)
1.1 root 2989: return(JS_TRUE);
2990:
2991: if((str=JS_NewStringCopyZ(cx, inet_ntoa(addr)))==NULL)
2992: return(JS_FALSE);
2993:
2994: *rval = STRING_TO_JSVAL(str);
2995: return(JS_TRUE);
2996: }
2997:
2998:
2999: static JSBool
3000: js_resolve_host(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
3001: {
3002: struct in_addr addr;
3003: HOSTENT* h;
3004: char* p;
1.1.1.2 ! root 3005: jsrefcount rc;
1.1 root 3006:
3007: *rval = JSVAL_NULL;
3008:
3009: if(JSVAL_IS_VOID(argv[0]))
3010: return(JS_TRUE);
3011:
3012: if((p=js_ValueToStringBytes(cx, argv[0], NULL))==NULL)
3013: return(JS_FALSE);
3014:
1.1.1.2 ! root 3015: rc=JS_SUSPENDREQUEST(cx);
1.1 root 3016: addr.s_addr=inet_addr(p);
3017: h=gethostbyaddr((char *)&addr,sizeof(addr),AF_INET);
1.1.1.2 ! root 3018: JS_RESUMEREQUEST(cx, rc);
1.1 root 3019:
3020: if(h!=NULL && h->h_name!=NULL)
3021: *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,h->h_name));
3022:
3023: return(JS_TRUE);
3024:
3025: }
3026:
3027: extern link_list_t named_queues; /* js_queue.c */
3028:
3029: static JSBool
3030: js_list_named_queues(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
3031: {
3032: JSObject* array;
3033: jsint len=0;
3034: jsval val;
3035: list_node_t* node;
3036: msg_queue_t* q;
1.1.1.2 ! root 3037: jsrefcount rc;
1.1 root 3038:
3039: if((array = JS_NewArrayObject(cx, 0, NULL))==NULL)
3040: return(JS_FALSE);
3041:
1.1.1.2 ! root 3042: rc=JS_SUSPENDREQUEST(cx);
! 3043: listLock(&named_queues);
! 3044: for(node=named_queues.first;node!=NULL;node=node->next) {
1.1 root 3045: if((q=listNodeData(node))==NULL)
3046: continue;
1.1.1.2 ! root 3047: JS_RESUMEREQUEST(cx, rc);
1.1 root 3048: val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,q->name));
1.1.1.2 ! root 3049: if(!JS_SetElement(cx, array, len++, &val)) {
! 3050: rc=JS_SUSPENDREQUEST(cx);
1.1 root 3051: break;
1.1.1.2 ! root 3052: }
! 3053: rc=JS_SUSPENDREQUEST(cx);
1.1 root 3054: }
1.1.1.2 ! root 3055: listUnlock(&named_queues);
! 3056: JS_RESUMEREQUEST(cx, rc);
1.1 root 3057:
3058: *rval = OBJECT_TO_JSVAL(array);
3059:
3060: return(JS_TRUE);
3061: }
3062:
3063: static JSBool
3064: js_flags_str(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
3065: {
3066: char* p;
3067: char str[64];
3068: jsdouble d;
3069: JSString* js_str;
3070:
3071: if(JSVAL_IS_VOID(argv[0]))
3072: return(JS_TRUE);
3073:
3074: if(JSVAL_IS_STRING(argv[0])) { /* string to long */
3075:
3076: if((p=JS_GetStringBytes(JSVAL_TO_STRING(argv[0])))==NULL)
3077: return(JS_FALSE);
3078:
3079: JS_NewNumberValue(cx,aftol(p),rval);
3080: return(JS_TRUE);
3081: }
3082:
3083: /* number to string */
3084: JS_ValueToNumber(cx,argv[0],&d);
3085:
3086: if((js_str = JS_NewStringCopyZ(cx, ltoaf((long)d,str)))==NULL)
3087: return(JS_FALSE);
3088:
3089: *rval = STRING_TO_JSVAL(js_str);
3090: return(JS_TRUE);
3091: }
3092:
3093: static jsSyncMethodSpec js_global_functions[] = {
3094: {"exit", js_exit, 0, JSTYPE_VOID, "[exit_code]"
3095: ,JSDOCSTR("stop script execution, "
3096: "optionally setting the global property <tt>exit_code</tt> to the specified numeric value")
3097: ,311
3098: },
3099: {"load", js_load, 1, JSTYPE_UNDEF
3100: ,JSDOCSTR("[<i>bool</i> background or <i>object</i> scope,] <i>string</i> filename [,args]")
3101: ,JSDOCSTR("load and execute a JavaScript module (<i>filename</i>), "
3102: "optionally specifying a target <i>scope</i> object (default: <i>this</i>) "
3103: "and a list of arguments to pass to the module (as <i>argv</i>). "
3104: "Returns the result (last executed statement) of the executed script "
3105: "or a newly created <i>Queue</i> object if <i>background</i> is <i>true</i>).<br><br>"
3106: "<b>Background</b> (added in v3.12):<br>"
3107: "If <i>background</i> is <i>true</i>, the loaded script runs in the background "
3108: "(in a child thread) but may communicate with the parent "
3109: "script/thread by reading from and/or writing to the <i>parent_queue</i> "
3110: "(an automatically created <i>Queue</i> object). "
3111: "The result (last executed statement) of the executed script "
1.1.1.2 ! root 3112: "(or the optional <i>exit_code</i> passed to the <i>exit()</i> function) "
1.1 root 3113: "will be automatically written to the <i>parent_queue</i> "
3114: "which may be read later by the parent script (using <i>load_result.read()</i>, for example).")
3115: ,312
3116: },
3117: {"sleep", js_mswait, 0, JSTYPE_ALIAS },
3118: {"mswait", js_mswait, 0, JSTYPE_NUMBER, JSDOCSTR("[milliseconds=<tt>1</tt>]")
3119: ,JSDOCSTR("millisecond wait/sleep routine (AKA sleep), returns number of elapsed clock ticks (in v3.13)")
3120: ,313
3121: },
3122: {"yield", js_yield, 0, JSTYPE_VOID, JSDOCSTR("[forced=<tt>true</tt>]")
3123: ,JSDOCSTR("release current thread time-slice, "
3124: "a <i>forced</i> yield will yield to all other pending tasks (lowering CPU utilization), "
3125: "a non-<i>forced</i> yield will yield only to pending tasks of equal or higher priority. "
3126: "<i>forced</i> defaults to <i>true</i>")
3127: ,311
3128: },
3129: {"random", js_random, 1, JSTYPE_NUMBER, JSDOCSTR("max_number=<tt>100</tt>")
3130: ,JSDOCSTR("return random integer between <tt>0</tt> and <i>max_number</i>-1")
3131: ,310
3132: },
3133: {"time", js_time, 0, JSTYPE_NUMBER, ""
3134: ,JSDOCSTR("return current time and date in Unix (time_t) format "
3135: "(number of seconds since Jan-01-1970)")
3136: ,310
3137: },
3138: {"beep", js_beep, 0, JSTYPE_VOID, JSDOCSTR("[frequency=<tt>500</tt>] [,duration=<tt>500</tt>]")
3139: ,JSDOCSTR("produce a tone on the local speaker at specified frequency for specified duration (in milliseconds)")
3140: ,310
3141: },
3142: {"sound", js_sound, 0, JSTYPE_BOOLEAN, JSDOCSTR("[filename]")
3143: ,JSDOCSTR("play a waveform (.wav) sound file (currently, on Windows platforms only)")
3144: ,310
3145: },
3146: {"ctrl", js_ctrl, 1, JSTYPE_STRING, JSDOCSTR("number or string")
3147: ,JSDOCSTR("return ASCII control character representing character passed - Example: <tt>ctrl('C') returns '\3'</tt>")
3148: ,311
3149: },
3150: {"ascii", js_ascii, 1, JSTYPE_UNDEF, JSDOCSTR("[string text] or [number value]")
3151: ,JSDOCSTR("convert single character to numeric ASCII value or vice-versa (returns number OR string)")
3152: ,310
3153: },
3154: {"ascii_str", js_ascii_str, 1, JSTYPE_STRING, JSDOCSTR("text")
3155: ,JSDOCSTR("convert extended-ASCII in text string to plain ASCII, returns modified string")
3156: ,310
3157: },
3158: {"strip_ctrl", js_strip_ctrl, 1, JSTYPE_STRING, JSDOCSTR("text")
3159: ,JSDOCSTR("strip control characters from string, returns modified string")
3160: ,310
3161: },
3162: {"strip_exascii", js_strip_exascii, 1, JSTYPE_STRING, JSDOCSTR("text")
3163: ,JSDOCSTR("strip extended-ASCII characters from string, returns modified string")
3164: ,310
3165: },
1.1.1.2 ! root 3166: {"skipsp", js_skipsp, 1, JSTYPE_STRING, JSDOCSTR("text")
! 3167: ,JSDOCSTR("skip (trim) white-space characters off <b>beginning</b> of string, returns modified string")
! 3168: ,315
! 3169: },
1.1 root 3170: {"truncsp", js_truncsp, 1, JSTYPE_STRING, JSDOCSTR("text")
1.1.1.2 ! root 3171: ,JSDOCSTR("truncate (trim) white-space characters off <b>end</b> of string, returns modified string")
1.1 root 3172: ,310
3173: },
3174: {"truncstr", js_truncstr, 2, JSTYPE_STRING, JSDOCSTR("text, charset")
3175: ,JSDOCSTR("truncate (trim) string at first char in <i>charset</i>, returns modified string")
3176: ,310
3177: },
3178: {"lfexpand", js_lfexpand, 1, JSTYPE_STRING, JSDOCSTR("text")
3179: ,JSDOCSTR("expand line-feeds (LF) to carriage-return/line-feeds (CRLF), returns modified string")
3180: ,310
3181: },
3182: {"wildmatch", js_wildmatch, 2, JSTYPE_BOOLEAN, JSDOCSTR("[case_sensitive=<tt>false</tt>,] string [,pattern=<tt>'*'</tt>] [,path=<tt>false</tt>]")
3183: ,JSDOCSTR("returns <tt>true</tt> if the <i>string</i> matches the wildcard <i>pattern</i> (wildcards supported are '*' and '?'), "
3184: "if <i>path</i> is <tt>true</tt>, '*' will not match path delimeter characters (e.g. '/')")
3185: ,314
3186: },
3187: {"backslash", js_backslash, 1, JSTYPE_STRING, JSDOCSTR("path")
3188: ,JSDOCSTR("returns directory path with trailing (platform-specific) path delimeter "
3189: "(i.e. \"slash\" or \"backslash\")")
3190: ,312
3191: },
1.1.1.2 ! root 3192: {"fullpath", js_fullpath, 1, JSTYPE_STRING, JSDOCSTR("path")
! 3193: ,JSDOCSTR("Creates an absolute or full path name for the specified relative path name.")
! 3194: ,315
! 3195: },
1.1 root 3196: {"file_getname", js_getfname, 1, JSTYPE_STRING, JSDOCSTR("path/filename")
3197: ,JSDOCSTR("returns filename portion of passed path string")
3198: ,311
3199: },
3200: {"file_getext", js_getfext, 1, JSTYPE_STRING, JSDOCSTR("path/filename")
3201: ,JSDOCSTR("returns file extension portion of passed path/filename string (including '.') "
3202: "or <i>undefined</i> if no extension is found")
3203: ,311
3204: },
3205: {"file_getcase", js_getfcase, 1, JSTYPE_STRING, JSDOCSTR("path/filename")
1.1.1.2 ! root 3206: ,JSDOCSTR("returns correct case of filename (long version of filename on Windows) "
1.1 root 3207: "or <i>undefined</i> if the file doesn't exist")
3208: ,311
3209: },
3210: {"file_cfgname", js_cfgfname, 2, JSTYPE_STRING, JSDOCSTR("path, filename")
3211: ,JSDOCSTR("returns completed configuration filename from supplied <i>path</i> and <i>filename</i>, "
3212: "optionally including the local hostname (e.g. <tt>path/file.<i>host</i>.<i>domain</i>.ext</tt> "
3213: "or <tt>path/file.<i>host</i>.ext</tt>) if such a variation of the filename exists")
3214: ,312
3215: },
1.1.1.2 ! root 3216: {"file_getdosname", js_dosfname, 1, JSTYPE_STRING, JSDOCSTR("path/filename")
! 3217: ,JSDOCSTR("returns DOS-compatible (Micros~1 shortened) version of specified <i>path/filename</i>"
! 3218: "(on Windows only)<br>"
! 3219: "returns unmodified <i>path/filename</i> on other platforms")
! 3220: ,315
! 3221: },
1.1 root 3222: {"file_exists", js_fexist, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename")
3223: ,JSDOCSTR("verify a file's existence")
3224: ,310
3225: },
3226: {"file_remove", js_remove, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename")
3227: ,JSDOCSTR("delete a file")
3228: ,310
3229: },
3230: {"file_removecase", js_removecase, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename")
3231: ,JSDOCSTR("delete files case insensitively")
3232: ,314
3233: },
3234: {"file_rename", js_rename, 2, JSTYPE_BOOLEAN, JSDOCSTR("path/oldname, path/newname")
3235: ,JSDOCSTR("rename a file, possibly moving it to another directory in the process")
3236: ,311
3237: },
3238: {"file_copy", js_fcopy, 2, JSTYPE_BOOLEAN, JSDOCSTR("path/source, path/destination")
3239: ,JSDOCSTR("copy a file from one directory or filename to another")
3240: ,311
3241: },
3242: {"file_backup", js_backup, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename [,level=<tt>5</tt>] [,rename=<tt>false</tt>]")
3243: ,JSDOCSTR("backup the specified <i>filename</i> as <tt>filename.<i>number</i>.extension</tt> "
3244: "where <i>number</i> is the backup number 0 through <i>level</i>-1 "
3245: "(default backup <i>level</i> is 5), "
3246: "if <i>rename</i> is <i>true</i>, the original file is renamed instead of copied "
3247: "(default is <i>false</i>)")
3248: ,311
3249: },
3250: {"file_isdir", js_isdir, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename")
3251: ,JSDOCSTR("check if specified <i>filename</i> is a directory")
3252: ,310
3253: },
3254: {"file_attrib", js_fattr, 1, JSTYPE_NUMBER, JSDOCSTR("path/filename")
3255: ,JSDOCSTR("get a file's permissions/attributes")
3256: ,310
3257: },
3258: {"file_date", js_fdate, 1, JSTYPE_NUMBER, JSDOCSTR("path/filename")
3259: ,JSDOCSTR("get a file's last modified date/time (in time_t format)")
3260: ,310
3261: },
3262: {"file_size", js_flength, 1, JSTYPE_NUMBER, JSDOCSTR("path/filename")
3263: ,JSDOCSTR("get a file's length (in bytes)")
3264: ,310
3265: },
3266: {"file_utime", js_utime, 3, JSTYPE_BOOLEAN, JSDOCSTR("path/filename [,access_time=<i>current</i>] [,mod_time=<i>current</i>]")
3267: ,JSDOCSTR("change a file's last accessed and modification date/time (in time_t format), "
3268: "or change to current time")
3269: ,311
3270: },
3271: {"file_touch", js_ftouch, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename")
3272: ,JSDOCSTR("updates a file's last modification date/time to current time, "
3273: "creating an empty file if it doesn't already exist")
3274: ,311
3275: },
3276: {"file_mutex", js_fmutex, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/filename [,text=<i>local_hostname</i>] [,max_age=<tt>0</tt>]")
3277: ,JSDOCSTR("attempts to create an mutual-exclusion (e.g. lock) file, "
3278: "optionally with the contents of <i>text</i>. "
3279: "If a non-zero <i>max_age</i> (supported in v3.13b+) is specified "
3280: "and the lock file exists, but is older than this value (in seconds), "
3281: "it is presumed stale and removed/over-written")
3282: ,312
3283: },
3284: {"file_compare", js_fcompare, 2, JSTYPE_BOOLEAN, JSDOCSTR("path/file1, path/file2")
3285: ,JSDOCSTR("compare 2 files, returning <i>true</i> if they are identical, <i>false</i> otherwise")
3286: ,314
3287: },
3288: {"directory", js_directory, 1, JSTYPE_ARRAY, JSDOCSTR("path/pattern [,flags=<tt>GLOB_MARK</tt>]")
3289: ,JSDOCSTR("returns an array of directory entries, "
3290: "<i>pattern</i> is the path and filename or wildcards to search for (e.g. '/subdir/*.txt'), "
3291: "<i>flags</i> is a bitfield of optional <tt>glob</tt> flags (default is <tt>GLOB_MARK</tt>)")
3292: ,310
3293: },
3294: {"dir_freespace", js_freediskspace, 2, JSTYPE_NUMBER, JSDOCSTR("directory [,unit_size=<tt>1</tt>]")
3295: ,JSDOCSTR("returns the amount of available disk space in the specified <i>directory</i> "
3296: "using the specified <i>unit_size</i> in bytes (default: 1), "
3297: "specify a <i>unit_size</i> of <tt>1024</tt> to return the available space in <i>kilobytes</i>.")
3298: ,311
3299: },
3300: {"disk_size", js_disksize, 2, JSTYPE_NUMBER, JSDOCSTR("directory [,unit_size=<tt>1</tt>]")
3301: ,JSDOCSTR("returns the total disk size of the specified <i>directory</i> "
3302: "using the specified <i>unit_size</i> in bytes (default: 1), "
3303: "specify a <i>unit_size</i> of <tt>1024</tt> to return the total disk size in <i>kilobytes</i>.")
3304: ,314
3305: },
3306: {"socket_select", js_socket_select, 0, JSTYPE_ARRAY, JSDOCSTR("[array of socket objects or descriptors] [,timeout=<tt>0</tt>] [,write=<tt>false</tt>]")
3307: ,JSDOCSTR("checks an array of socket objects or descriptors for read or write ability (default is <i>read</i>), "
3308: "default timeout value is 0.0 seconds (immediate timeout), "
1.1.1.2 ! root 3309: "returns an array of 0-based index values into the socket array, representing the sockets that were ready for reading or writing, or <i>null</i> on error")
1.1 root 3310: ,311
3311: },
3312: {"mkdir", js_mkdir, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/directory")
3313: ,JSDOCSTR("make a directory")
3314: ,310
3315: },
1.1.1.2 ! root 3316: {"mkpath", js_mkpath, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/directory")
! 3317: ,JSDOCSTR("make a path to a directory (creating all necessary sub-directories)")
! 3318: ,315
! 3319: },
1.1 root 3320: {"rmdir", js_rmdir, 1, JSTYPE_BOOLEAN, JSDOCSTR("path/directory")
3321: ,JSDOCSTR("remove a directory")
3322: ,310
3323: },
3324: {"strftime", js_strftime, 1, JSTYPE_STRING, JSDOCSTR("format [,time=<i>current</i>]")
3325: ,JSDOCSTR("return a formatted time string (ala C strftime)")
3326: ,310
3327: },
3328: {"format", js_format, 1, JSTYPE_STRING, JSDOCSTR("format [,args]")
3329: ,JSDOCSTR("return a formatted string (ala the standard C <tt>sprintf</tt> function)")
3330: ,310
3331: },
3332: {"html_encode", js_html_encode, 1, JSTYPE_STRING, JSDOCSTR("text [,ex_ascii=<tt>true</tt>] [,white_space=<tt>true</tt>] [,ansi=<tt>true</tt>] [,ctrl_a=<tt>true</tt>] [, state (object)]")
3333: ,JSDOCSTR("return an HTML-encoded text string (using standard HTML character entities), "
3334: "escaping IBM extended-ASCII, white-space characters, ANSI codes, and CTRL-A codes by default."
3335: "Optionally storing the current ANSI state in <i>state</i> object")
3336: ,311
3337: },
3338: {"html_decode", js_html_decode, 1, JSTYPE_STRING, JSDOCSTR("html")
3339: ,JSDOCSTR("return a decoded HTML-encoded text string")
3340: ,311
3341: },
3342: {"word_wrap", js_word_wrap, 1, JSTYPE_STRING, JSDOCSTR("text [,line_length=<tt>79</tt> [, orig_line_length=<tt>79</tt> [, handle_quotes=<tt>true</tt>]]]]")
3343: ,JSDOCSTR("returns a word-wrapped version of the text string argument optionally handing quotes magically, "
3344: "<i>line_length</i> defaults to <i>79</i> <i>orig_line_length</i> defaults to <i>79</i> "
3345: "and <i>handle_quotes</i> defaults to <i>true</i>")
3346: ,311
3347: },
3348: {"quote_msg", js_quote_msg, 1, JSTYPE_STRING, JSDOCSTR("text [,line_length=<tt>79</tt>] [,prefix=<tt>\" > \"</tt>]")
3349: ,JSDOCSTR("returns a quoted version of the message text string argument, <i>line_length</i> defaults to <i>79</i>, "
3350: "<i>prefix</i> defaults to <tt>\" > \"</tt>")
3351: ,311
3352: },
3353: {"rot13_translate", js_rot13, 1, JSTYPE_STRING, JSDOCSTR("text")
3354: ,JSDOCSTR("returns ROT13-translated version of text string (will encode or decode text)")
3355: ,311
3356: },
3357: {"base64_encode", js_b64_encode, 1, JSTYPE_STRING, JSDOCSTR("text")
3358: ,JSDOCSTR("returns base64-encoded version of text string or <i>null</i> on error")
3359: ,311
3360: },
3361: {"base64_decode", js_b64_decode, 1, JSTYPE_STRING, JSDOCSTR("text")
3362: ,JSDOCSTR("returns base64-decoded text string or <i>null</i> on error")
3363: ,311
3364: },
3365: {"crc16_calc", js_crc16, 1, JSTYPE_NUMBER, JSDOCSTR("text")
3366: ,JSDOCSTR("calculate and return 16-bit CRC of text string")
3367: ,311
3368: },
3369: {"crc32_calc", js_crc32, 1, JSTYPE_NUMBER, JSDOCSTR("text")
3370: ,JSDOCSTR("calculate and return 32-bit CRC of text string")
3371: ,311
3372: },
3373: {"chksum_calc", js_chksum, 1, JSTYPE_NUMBER, JSDOCSTR("text")
3374: ,JSDOCSTR("calculate and return 32-bit checksum of text string")
3375: ,311
3376: },
3377: {"md5_calc", js_md5_calc, 1, JSTYPE_STRING, JSDOCSTR("text [,hex=<tt>false</tt>]")
3378: ,JSDOCSTR("calculate and return 128-bit MD5 digest of text string, result encoded in base64 (default) or hexadecimal")
3379: ,311
3380: },
3381: {"gethostbyname", js_resolve_ip, 1, JSTYPE_ALIAS },
3382: {"resolve_ip", js_resolve_ip, 1, JSTYPE_STRING, JSDOCSTR("hostname")
3383: ,JSDOCSTR("resolve IP address of specified hostname (AKA gethostbyname)")
3384: ,311
3385: },
3386: {"gethostbyaddr", js_resolve_host, 1, JSTYPE_ALIAS },
3387: {"resolve_host", js_resolve_host, 1, JSTYPE_STRING, JSDOCSTR("ip_address")
3388: ,JSDOCSTR("resolve hostname of specified IP address (AKA gethostbyaddr)")
3389: ,311
3390: },
3391: {"netaddr_type", js_netaddr_type, 1, JSTYPE_NUMBER, JSDOCSTR("email_address")
3392: ,JSDOCSTR("returns the proper message <i>net_type</i> for the specified <i>email_address</i>, "
3393: "(e.g. <tt>NET_INTERNET</tt> for Internet e-mail or <tt>NET_NONE</tt> for local e-mail)")
3394: ,312
3395: },
3396: {"list_named_queues",js_list_named_queues,0,JSTYPE_ARRAY, JSDOCSTR("")
3397: ,JSDOCSTR("returns an array of <i>named queues</i> (created with the <i>Queue</i> constructor)")
3398: ,312
3399: },
3400: {"flags_str", js_flags_str, 1, JSTYPE_UNDEF, JSDOCSTR("[string] or [number]")
3401: ,JSDOCSTR("convert a string of security flags (letters) into their numeric value or vice-versa "
3402: "(returns number OR string) - (added in v3.13)")
3403: ,313
3404: },
3405: {0}
3406: };
3407:
3408: static jsConstIntSpec js_global_const_ints[] = {
3409: /* Numeric error constants from errno.h (platform-dependant) */
3410: {"EPERM" ,EPERM },
3411: {"ENOENT" ,ENOENT },
3412: {"ESRCH" ,ESRCH },
3413: {"EIO" ,EIO },
3414: {"ENXIO" ,ENXIO },
3415: {"E2BIG" ,E2BIG },
3416: {"ENOEXEC" ,ENOEXEC },
3417: {"EBADF" ,EBADF },
3418: {"ECHILD" ,ECHILD },
3419: {"EAGAIN" ,EAGAIN },
3420: {"ENOMEM" ,ENOMEM },
3421: {"EACCES" ,EACCES },
3422: {"EFAULT" ,EFAULT },
3423: {"EBUSY" ,EBUSY },
3424: {"EEXIST" ,EEXIST },
3425: {"EXDEV" ,EXDEV },
3426: {"ENODEV" ,ENODEV },
3427: {"ENOTDIR" ,ENOTDIR },
3428: {"EISDIR" ,EISDIR },
3429: {"EINVAL" ,EINVAL },
3430: {"ENFILE" ,ENFILE },
3431: {"EMFILE" ,EMFILE },
3432: {"ENOTTY" ,ENOTTY },
3433: {"EFBIG" ,EFBIG },
3434: {"ENOSPC" ,ENOSPC },
3435: {"ESPIPE" ,ESPIPE },
3436: {"EROFS" ,EROFS },
3437: {"EMLINK" ,EMLINK },
3438: {"EPIPE" ,EPIPE },
3439: {"EDOM" ,EDOM },
3440: {"ERANGE" ,ERANGE },
3441: {"EDEADLOCK" ,EDEADLOCK },
3442: {"ENAMETOOLONG" ,ENAMETOOLONG },
3443: {"ENOTEMPTY" ,ENOTEMPTY },
3444:
3445: /* Socket errors */
3446: {"EINTR" ,EINTR },
3447: {"ENOTSOCK" ,ENOTSOCK },
3448: {"EMSGSIZE" ,EMSGSIZE },
3449: {"EWOULDBLOCK" ,EWOULDBLOCK },
3450: {"EPROTOTYPE" ,EPROTOTYPE },
3451: {"ENOPROTOOPT" ,ENOPROTOOPT },
3452: {"EPROTONOSUPPORT" ,EPROTONOSUPPORT},
3453: {"ESOCKTNOSUPPORT" ,ESOCKTNOSUPPORT},
3454: {"EOPNOTSUPP" ,EOPNOTSUPP },
3455: {"EPFNOSUPPORT" ,EPFNOSUPPORT },
3456: {"EAFNOSUPPORT" ,EAFNOSUPPORT },
3457: {"EADDRINUSE" ,EADDRINUSE },
3458: {"EADDRNOTAVAIL" ,EADDRNOTAVAIL },
3459: {"ECONNABORTED" ,ECONNABORTED },
3460: {"ECONNRESET" ,ECONNRESET },
3461: {"ENOBUFS" ,ENOBUFS },
3462: {"EISCONN" ,EISCONN },
3463: {"ENOTCONN" ,ENOTCONN },
3464: {"ESHUTDOWN" ,ESHUTDOWN },
3465: {"ETIMEDOUT" ,ETIMEDOUT },
3466: {"ECONNREFUSED" ,ECONNREFUSED },
3467: {"EINPROGRESS" ,EINPROGRESS },
3468:
3469: /* Log priority values from syslog.h/sbbsdefs.h (possibly platform-dependant) */
3470: {"LOG_EMERG" ,LOG_EMERG },
3471: {"LOG_ALERT" ,LOG_ALERT },
3472: {"LOG_CRIT" ,LOG_CRIT },
3473: {"LOG_ERR" ,LOG_ERR },
3474: {"LOG_ERROR" ,LOG_ERR },
3475: {"LOG_WARNING" ,LOG_WARNING },
3476: {"LOG_NOTICE" ,LOG_NOTICE },
3477: {"LOG_INFO" ,LOG_INFO },
3478: {"LOG_DEBUG" ,LOG_DEBUG },
3479:
3480: /* Other useful constants */
3481: {"INVALID_SOCKET" ,INVALID_SOCKET },
3482:
3483: /* Terminator (Governor Arnold) */
3484: {0}
3485: };
3486:
1.1.1.2 ! root 3487: static void js_global_finalize(JSContext *cx, JSObject *obj)
1.1 root 3488: {
1.1.1.2 ! root 3489: private_t* p;
1.1 root 3490:
1.1.1.2 ! root 3491: p=(private_t*)JS_GetPrivate(cx,obj);
1.1 root 3492:
1.1.1.2 ! root 3493: if(p!=NULL)
! 3494: free(p);
! 3495:
! 3496: p=NULL;
! 3497: JS_SetPrivate(cx,obj,p);
! 3498: }
! 3499:
! 3500: static JSBool js_global_resolve(JSContext *cx, JSObject *obj, jsval id)
! 3501: {
! 3502: char* name=NULL;
! 3503: private_t* p;
! 3504: JSBool ret=JS_TRUE;
! 3505:
! 3506: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
! 3507: return(JS_FALSE);
! 3508:
! 3509: if(id != JSVAL_NULL && id != JS_DEFAULT_XML_NAMESPACE_ID)
! 3510: name=JS_GetStringBytes(JSVAL_TO_STRING(id));
! 3511:
! 3512: if(p->methods) {
! 3513: if(js_SyncResolve(cx, obj, name, NULL, p->methods, NULL, 0)==JS_FALSE)
! 3514: ret=JS_FALSE;
! 3515: }
! 3516: if(js_SyncResolve(cx, obj, name, js_global_properties, js_global_functions, js_global_const_ints, 0)==JS_FALSE)
! 3517: ret=JS_FALSE;
! 3518: return(ret);
! 3519: }
! 3520:
! 3521: static JSBool js_global_enumerate(JSContext *cx, JSObject *obj)
! 3522: {
! 3523: return(js_global_resolve(cx, obj, JSVAL_NULL));
! 3524: }
! 3525:
! 3526: static JSClass js_global_class = {
! 3527: "Global" /* name */
! 3528: ,JSCLASS_HAS_PRIVATE /* flags */
! 3529: ,JS_PropertyStub /* addProperty */
! 3530: ,JS_PropertyStub /* delProperty */
! 3531: ,js_system_get /* getProperty */
! 3532: ,JS_PropertyStub /* setProperty */
! 3533: ,js_global_enumerate /* enumerate */
! 3534: ,js_global_resolve /* resolve */
! 3535: ,JS_ConvertStub /* convert */
! 3536: ,js_global_finalize /* finalize */
! 3537: };
1.1 root 3538:
1.1.1.2 ! root 3539: JSObject* DLLCALL js_CreateGlobalObject(JSContext* cx, scfg_t* cfg, jsSyncMethodSpec* methods, js_startup_t* startup)
! 3540: {
! 3541: JSObject* glob;
! 3542: private_t* p;
! 3543:
! 3544: if((p = (private_t*)malloc(sizeof(private_t)))==NULL)
1.1 root 3545: return(NULL);
3546:
1.1.1.2 ! root 3547: p->cfg = cfg;
! 3548: p->methods = methods;
! 3549: p->startup = startup;
! 3550:
! 3551: if((glob = JS_NewObject(cx, &js_global_class, NULL, NULL)) ==NULL)
1.1 root 3552: return(NULL);
3553:
1.1.1.2 ! root 3554: if(!JS_SetPrivate(cx, glob, p)) /* Store a pointer to scfg_t and the new methods */
1.1 root 3555: return(NULL);
3556:
1.1.1.2 ! root 3557: if (!JS_InitStandardClasses(cx, glob))
1.1 root 3558: return(NULL);
3559:
3560: #ifdef BUILD_JSDOCS
3561: js_DescribeSyncObject(cx,glob
3562: ,"Top-level functions and properties (common to all servers and services)",310);
3563: #endif
3564:
3565: return(glob);
3566: }
3567:
3568: JSObject* DLLCALL js_CreateCommonObjects(JSContext* js_cx
3569: ,scfg_t* cfg /* common */
3570: ,scfg_t* node_cfg /* node-specific */
3571: ,jsSyncMethodSpec* methods /* global */
3572: ,time_t uptime /* system */
3573: ,char* host_name /* system */
3574: ,char* socklib_desc /* system */
3575: ,js_branch_t* branch /* js */
1.1.1.2 ! root 3576: ,js_startup_t* js_startup /* js */
1.1 root 3577: ,client_t* client /* client */
3578: ,SOCKET client_socket /* client */
3579: ,js_server_props_t* props /* server */
3580: )
3581: {
3582: JSObject* js_glob;
3583:
3584: if(node_cfg==NULL)
3585: node_cfg=cfg;
3586:
3587: /* Global Object */
1.1.1.2 ! root 3588: if((js_glob=js_CreateGlobalObject(js_cx, cfg, methods, js_startup))==NULL)
1.1 root 3589: return(NULL);
3590:
3591: /* System Object */
3592: if(js_CreateSystemObject(js_cx, js_glob, node_cfg, uptime, host_name, socklib_desc)==NULL)
3593: return(NULL);
3594:
3595: /* Internal JS Object */
3596: if(branch!=NULL
1.1.1.2 ! root 3597: && js_CreateInternalJsObject(js_cx, js_glob, branch, js_startup)==NULL)
1.1 root 3598: return(NULL);
3599:
3600: /* Client Object */
3601: if(client!=NULL
3602: && js_CreateClientObject(js_cx, js_glob, "client", client, client_socket)==NULL)
3603: return(NULL);
3604:
3605: /* Server */
3606: if(props!=NULL
3607: && js_CreateServerObject(js_cx, js_glob, props)==NULL)
3608: return(NULL);
3609:
3610: /* Socket Class */
3611: if(js_CreateSocketClass(js_cx, js_glob)==NULL)
3612: return(NULL);
3613:
3614: /* Queue Class */
3615: if(js_CreateQueueClass(js_cx, js_glob)==NULL)
3616: return(NULL);
3617:
3618: /* MsgBase Class */
3619: if(js_CreateMsgBaseClass(js_cx, js_glob, cfg)==NULL)
3620: return(NULL);
3621:
3622: /* File Class */
3623: if(js_CreateFileClass(js_cx, js_glob)==NULL)
3624: return(NULL);
3625:
3626: /* User class */
3627: if(js_CreateUserClass(js_cx, js_glob, cfg)==NULL)
3628: return(NULL);
3629:
1.1.1.2 ! root 3630: /* COM Class */
! 3631: if(js_CreateCOMClass(js_cx, js_glob)==NULL)
! 3632: return(NULL);
! 3633:
1.1 root 3634: /* Area Objects */
1.1.1.2 ! root 3635: if(!js_CreateUserObjects(js_cx, js_glob, cfg, /* user: */NULL, client, /* html_index_fname: */NULL, /* subscan: */NULL))
1.1 root 3636: return(NULL);
3637:
3638: return(js_glob);
3639: }
3640: #endif /* JAVSCRIPT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.