|
|
1.1 ! root 1: /* js_file.c */ ! 2: ! 3: /* Synchronet JavaScript "File" Object */ ! 4: ! 5: /* $Id: js_file.c,v 1.78 2004/12/31 02:39:19 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2004 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include "sbbs.h" ! 39: #include "md5.h" ! 40: #include "base64.h" ! 41: #include "uucode.h" ! 42: #include "yenc.h" ! 43: #include "ini_file.h" ! 44: ! 45: #ifdef JAVASCRIPT ! 46: ! 47: typedef struct ! 48: { ! 49: FILE* fp; ! 50: char name[MAX_PATH+1]; ! 51: char mode[4]; ! 52: uchar etx; ! 53: BOOL external; /* externally created, don't close */ ! 54: BOOL debug; ! 55: BOOL rot13; ! 56: BOOL yencoded; ! 57: BOOL uuencoded; ! 58: BOOL b64encoded; ! 59: BOOL network_byte_order; ! 60: ! 61: } private_t; ! 62: ! 63: static const char* getprivate_failure = "line %d %s JS_GetPrivate failed"; ! 64: ! 65: static void dbprintf(BOOL error, private_t* p, char* fmt, ...) ! 66: { ! 67: va_list argptr; ! 68: char sbuf[1024]; ! 69: ! 70: if(p==NULL || (!p->debug && !error)) ! 71: return; ! 72: ! 73: va_start(argptr,fmt); ! 74: vsnprintf(sbuf,sizeof(sbuf),fmt,argptr); ! 75: sbuf[sizeof(sbuf)-1]=0; ! 76: va_end(argptr); ! 77: ! 78: lprintf(LOG_DEBUG,"%04u File %s%s",p->fp ? fileno(p->fp) : 0,error ? "ERROR: ":"",sbuf); ! 79: } ! 80: ! 81: /* Converts fopen() style 'mode' string into open() style 'flags' integer */ ! 82: ! 83: static int fopenflags(char *mode) ! 84: { ! 85: int flags=0; ! 86: ! 87: if(strchr(mode,'b')) ! 88: flags|=O_BINARY; ! 89: else ! 90: flags|=O_TEXT; ! 91: ! 92: if(strchr(mode,'w')) { ! 93: flags|=O_CREAT|O_TRUNC; ! 94: if(strchr(mode,'+')) ! 95: flags|=O_RDWR; ! 96: else ! 97: flags|=O_WRONLY; ! 98: return(flags); ! 99: } ! 100: ! 101: if(strchr(mode,'a')) { ! 102: flags|=O_CREAT|O_APPEND; ! 103: if(strchr(mode,'+')) ! 104: flags|=O_RDWR; ! 105: else ! 106: flags|=O_WRONLY; ! 107: return(flags); ! 108: } ! 109: ! 110: if(strchr(mode,'r')) { ! 111: if(strchr(mode,'+')) ! 112: flags|=O_RDWR; ! 113: else ! 114: flags|=O_RDONLY; ! 115: } ! 116: ! 117: if(strchr(mode,'e')) ! 118: flags|=O_EXCL; ! 119: ! 120: return(flags); ! 121: } ! 122: ! 123: /* File Object Methods */ ! 124: ! 125: static JSBool ! 126: js_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 127: { ! 128: char* mode="w+"; /* default mode */ ! 129: BOOL shareable=FALSE; ! 130: int file; ! 131: uintN i; ! 132: jsint bufsize=2*1024; ! 133: JSString* str; ! 134: private_t* p; ! 135: ! 136: *rval = JSVAL_FALSE; ! 137: ! 138: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 139: JS_ReportError(cx,getprivate_failure,WHERE); ! 140: return(JS_FALSE); ! 141: } ! 142: ! 143: if(p->fp!=NULL) ! 144: return(JS_TRUE); ! 145: ! 146: for(i=0;i<argc;i++) { ! 147: if(JSVAL_IS_STRING(argv[i])) { /* mode */ ! 148: if((str = JS_ValueToString(cx, argv[i]))==NULL) { ! 149: JS_ReportError(cx,"Invalid mode specified: %s",str); ! 150: return(JS_TRUE); ! 151: } ! 152: mode=JS_GetStringBytes(str); ! 153: } else if(JSVAL_IS_BOOLEAN(argv[i])) /* shareable */ ! 154: shareable=JSVAL_TO_BOOLEAN(argv[i]); ! 155: else if(JSVAL_IS_NUMBER(argv[i])) /* bufsize */ ! 156: JS_ValueToInt32(cx,argv[i],&bufsize); ! 157: } ! 158: SAFECOPY(p->mode,mode); ! 159: ! 160: if(shareable) ! 161: p->fp=fopen(p->name,p->mode); ! 162: else { ! 163: if((file=nopen(p->name,fopenflags(p->mode)))!=-1) { ! 164: if((p->fp=fdopen(file,p->mode))==NULL) ! 165: close(file); ! 166: } ! 167: } ! 168: if(p->fp!=NULL) { ! 169: *rval = JSVAL_TRUE; ! 170: dbprintf(FALSE, p, "opened: %s",p->name); ! 171: if(!bufsize) ! 172: setvbuf(p->fp,NULL,_IONBF,0); /* no buffering */ ! 173: else ! 174: setvbuf(p->fp,NULL,_IOFBF,bufsize); ! 175: } ! 176: ! 177: return(JS_TRUE); ! 178: } ! 179: ! 180: ! 181: static JSBool ! 182: js_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 183: { ! 184: private_t* p; ! 185: ! 186: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 187: JS_ReportError(cx,getprivate_failure,WHERE); ! 188: return(JS_FALSE); ! 189: } ! 190: ! 191: *rval = JSVAL_VOID; ! 192: ! 193: if(p->fp==NULL) ! 194: return(JS_TRUE); ! 195: ! 196: fclose(p->fp); ! 197: ! 198: dbprintf(FALSE, p, "closed"); ! 199: ! 200: p->fp=NULL; ! 201: ! 202: return(JS_TRUE); ! 203: } ! 204: ! 205: static JSBool ! 206: js_read(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 207: { ! 208: char* cp; ! 209: char* buf; ! 210: char* uubuf; ! 211: int32 len; ! 212: int32 offset; ! 213: int32 uulen; ! 214: JSString* str; ! 215: private_t* p; ! 216: ! 217: *rval = JSVAL_NULL; ! 218: ! 219: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 220: JS_ReportError(cx,getprivate_failure,WHERE); ! 221: return(JS_FALSE); ! 222: } ! 223: ! 224: if(p->fp==NULL) ! 225: return(JS_TRUE); ! 226: ! 227: if(argc) ! 228: JS_ValueToInt32(cx,argv[0],&len); ! 229: else { ! 230: len=filelength(fileno(p->fp)); ! 231: offset=ftell(p->fp); ! 232: if(offset>0) ! 233: len-=offset; ! 234: } ! 235: if(len<0) ! 236: len=512; ! 237: ! 238: if((buf=malloc(len+1))==NULL) ! 239: return(JS_TRUE); ! 240: ! 241: len = fread(buf,1,len,p->fp); ! 242: if(len<0) ! 243: len=0; ! 244: buf[len]=0; ! 245: ! 246: if(p->etx) { ! 247: cp=strchr(buf,p->etx); ! 248: if(cp) *cp=0; ! 249: } ! 250: ! 251: if(p->rot13) ! 252: rot13(buf); ! 253: ! 254: if(p->uuencoded || p->b64encoded || p->yencoded) { ! 255: uulen=len*2; ! 256: if((uubuf=malloc(uulen))==NULL) ! 257: return(JS_TRUE); ! 258: if(p->uuencoded) ! 259: uulen=uuencode(uubuf,uulen,buf,len); ! 260: else if(p->yencoded) ! 261: uulen=yencode(uubuf,uulen,buf,len); ! 262: else ! 263: uulen=b64_encode(uubuf,uulen,buf,len); ! 264: if(uulen>=0) { ! 265: free(buf); ! 266: buf=uubuf; ! 267: } else ! 268: free(uubuf); ! 269: } ! 270: ! 271: str = JS_NewStringCopyZ(cx, buf); ! 272: ! 273: free(buf); ! 274: ! 275: if(str==NULL) ! 276: return(JS_FALSE); ! 277: ! 278: *rval = STRING_TO_JSVAL(str); ! 279: ! 280: dbprintf(FALSE, p, "read %u bytes",len); ! 281: ! 282: return(JS_TRUE); ! 283: } ! 284: ! 285: static JSBool ! 286: js_readln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 287: { ! 288: char* cp; ! 289: char* buf; ! 290: int32 len=512; ! 291: JSString* js_str; ! 292: private_t* p; ! 293: ! 294: *rval = JSVAL_NULL; ! 295: ! 296: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 297: JS_ReportError(cx,getprivate_failure,WHERE); ! 298: return(JS_FALSE); ! 299: } ! 300: ! 301: if(p->fp==NULL) ! 302: return(JS_TRUE); ! 303: ! 304: if(argc) ! 305: JS_ValueToInt32(cx,argv[0],&len); ! 306: ! 307: if((buf=malloc(len))==NULL) ! 308: return(JS_TRUE); ! 309: ! 310: if(fgets(buf,len,p->fp)!=NULL) { ! 311: len=strlen(buf); ! 312: while(len>0 && (buf[len-1]=='\r' || buf[len-1]=='\n')) ! 313: len--; ! 314: buf[len]=0; ! 315: if(p->etx) { ! 316: cp=strchr(buf,p->etx); ! 317: if(cp) *cp=0; ! 318: } ! 319: if(p->rot13) ! 320: rot13(buf); ! 321: if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL) ! 322: *rval = STRING_TO_JSVAL(js_str); ! 323: } ! 324: ! 325: free(buf); ! 326: ! 327: return(JS_TRUE); ! 328: } ! 329: ! 330: static JSBool ! 331: js_readbin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 332: { ! 333: BYTE b; ! 334: WORD w; ! 335: DWORD l; ! 336: size_t size=sizeof(DWORD); ! 337: private_t* p; ! 338: ! 339: *rval = INT_TO_JSVAL(-1); ! 340: ! 341: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 342: JS_ReportError(cx,getprivate_failure,WHERE); ! 343: return(JS_FALSE); ! 344: } ! 345: ! 346: if(p->fp==NULL) ! 347: return(JS_TRUE); ! 348: ! 349: if(argc) ! 350: JS_ValueToInt32(cx,argv[0],(int32*)&size); ! 351: ! 352: switch(size) { ! 353: case sizeof(BYTE): ! 354: if(fread(&b,1,size,p->fp)==size) ! 355: *rval = INT_TO_JSVAL(b); ! 356: break; ! 357: case sizeof(WORD): ! 358: if(fread(&w,1,size,p->fp)==size) { ! 359: if(p->network_byte_order) ! 360: w=ntohs(w); ! 361: *rval = INT_TO_JSVAL(w); ! 362: } ! 363: break; ! 364: case sizeof(DWORD): ! 365: if(fread(&l,1,size,p->fp)==size) { ! 366: if(p->network_byte_order) ! 367: l=ntohl(l); ! 368: JS_NewNumberValue(cx,l,rval); ! 369: } ! 370: break; ! 371: } ! 372: ! 373: return(JS_TRUE); ! 374: } ! 375: ! 376: static JSBool ! 377: js_readall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 378: { ! 379: jsint len=0; ! 380: jsval line; ! 381: JSObject* array; ! 382: private_t* p; ! 383: ! 384: *rval = JSVAL_NULL; ! 385: ! 386: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 387: JS_ReportError(cx,getprivate_failure,WHERE); ! 388: return(JS_FALSE); ! 389: } ! 390: ! 391: if(p->fp==NULL) ! 392: return(JS_TRUE); ! 393: ! 394: array = JS_NewArrayObject(cx, 0, NULL); ! 395: ! 396: while(!feof(p->fp)) { ! 397: js_readln(cx, obj, 0, NULL, &line); ! 398: if(line==JSVAL_NULL) ! 399: break; ! 400: if(!JS_SetElement(cx, array, len++, &line)) ! 401: break; ! 402: } ! 403: *rval = OBJECT_TO_JSVAL(array); ! 404: ! 405: return(JS_TRUE); ! 406: } ! 407: ! 408: static jsval get_value(JSContext *cx, char* value) ! 409: { ! 410: char* p; ! 411: BOOL f=FALSE; ! 412: jsval val; ! 413: ! 414: if(value==NULL || *value==0) ! 415: return(JSVAL_VOID); ! 416: ! 417: /* integer or float? */ ! 418: for(p=value;*p;p++) { ! 419: if(*p=='.' && !f) ! 420: f=TRUE; ! 421: else if(!isdigit(*p)) ! 422: break; ! 423: } ! 424: if(*p==0) { ! 425: JS_NewNumberValue(cx, f ? atof(value) : strtoul(value,NULL,10), &val); ! 426: return(val); ! 427: } ! 428: /* hexadecimal number? */ ! 429: if(!strncmp(value,"0x",2)) { ! 430: for(p=value+2;*p;p++) ! 431: if(!isxdigit(*p)) ! 432: break; ! 433: if(*p==0) { ! 434: JS_NewNumberValue(cx,strtoul(value,NULL,0),&val); ! 435: return(val); ! 436: } ! 437: } ! 438: /* Boolean? */ ! 439: if(!stricmp(value,"true")) ! 440: return(JSVAL_TRUE); ! 441: if(!stricmp(value,"false")) ! 442: return(JSVAL_FALSE); ! 443: ! 444: /* String */ ! 445: return(STRING_TO_JSVAL(JS_NewStringCopyZ(cx,value))); ! 446: } ! 447: ! 448: static JSBool ! 449: js_iniGetValue(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 450: { ! 451: char* section=ROOT_SECTION; ! 452: char* key; ! 453: char** list; ! 454: char buf[INI_MAX_VALUE_LEN]; ! 455: int32 i; ! 456: jsval val; ! 457: jsval dflt=argv[2]; ! 458: private_t* p; ! 459: JSObject* array; ! 460: ! 461: *rval = JSVAL_VOID; ! 462: ! 463: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 464: JS_ReportError(cx,getprivate_failure,WHERE); ! 465: return(JS_FALSE); ! 466: } ! 467: ! 468: if(p->fp==NULL) ! 469: return(JS_TRUE); ! 470: ! 471: if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL) ! 472: section=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); ! 473: key=JS_GetStringBytes(JS_ValueToString(cx, argv[1])); ! 474: ! 475: if(dflt==JSVAL_VOID) { /* unspecified default value */ ! 476: *rval=get_value(cx,iniReadString(p->fp,section,key,NULL,buf)); ! 477: return(JS_TRUE); ! 478: } ! 479: ! 480: switch(JSVAL_TAG(dflt)) { ! 481: case JSVAL_BOOLEAN: ! 482: *rval = BOOLEAN_TO_JSVAL( ! 483: iniReadBool(p->fp,section,key,JSVAL_TO_BOOLEAN(dflt))); ! 484: break; ! 485: case JSVAL_DOUBLE: ! 486: JS_NewNumberValue(cx ! 487: ,iniReadFloat(p->fp,section,key,*JSVAL_TO_DOUBLE(dflt)),rval); ! 488: break; ! 489: case JSVAL_OBJECT: ! 490: array = JS_NewArrayObject(cx, 0, NULL); ! 491: list=iniReadStringList(p->fp,section,key,",",JS_GetStringBytes(JS_ValueToString(cx,dflt))); ! 492: for(i=0;list && list[i];i++) { ! 493: val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i])); ! 494: if(!JS_SetElement(cx, array, i, &val)) ! 495: break; ! 496: } ! 497: iniFreeStringList(list); ! 498: *rval = OBJECT_TO_JSVAL(array); ! 499: break; ! 500: default: ! 501: if(JSVAL_IS_NUMBER(dflt)) { ! 502: JS_ValueToInt32(cx,dflt,&i); ! 503: JS_NewNumberValue(cx,iniReadInteger(p->fp,section,key,i),rval); ! 504: } else ! 505: *rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx ! 506: ,iniReadString(p->fp,section,key,JS_GetStringBytes(JS_ValueToString(cx,dflt)),buf))); ! 507: break; ! 508: } ! 509: ! 510: return(JS_TRUE); ! 511: } ! 512: ! 513: static JSBool ! 514: js_iniSetValue(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 515: { ! 516: char* section=ROOT_SECTION; ! 517: char* key; ! 518: char* result=NULL; ! 519: int32 i; ! 520: jsval value=argv[2]; ! 521: private_t* p; ! 522: str_list_t list; ! 523: ! 524: *rval = JSVAL_FALSE; ! 525: ! 526: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 527: JS_ReportError(cx,getprivate_failure,WHERE); ! 528: return(JS_FALSE); ! 529: } ! 530: ! 531: if(p->fp==NULL) ! 532: return(JS_TRUE); ! 533: ! 534: if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL) ! 535: section=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); ! 536: key=JS_GetStringBytes(JS_ValueToString(cx, argv[1])); ! 537: ! 538: if((list=iniReadFile(p->fp))==NULL) ! 539: return(JS_TRUE); ! 540: ! 541: if(value==JSVAL_VOID) /* unspecified value */ ! 542: result = iniSetString(&list,section,key,"",NULL); ! 543: else { ! 544: ! 545: switch(JSVAL_TAG(value)) { ! 546: case JSVAL_BOOLEAN: ! 547: result = iniSetBool(&list,section,key,JSVAL_TO_BOOLEAN(value),NULL); ! 548: break; ! 549: case JSVAL_DOUBLE: ! 550: result = iniSetFloat(&list,section,key,*JSVAL_TO_DOUBLE(value),NULL); ! 551: break; ! 552: default: ! 553: if(JSVAL_IS_NUMBER(value)) { ! 554: JS_ValueToInt32(cx,value,&i); ! 555: result = iniSetInteger(&list,section,key,i,NULL); ! 556: } else ! 557: result = iniSetString(&list,section,key ! 558: ,JS_GetStringBytes(JS_ValueToString(cx,value)),NULL); ! 559: break; ! 560: } ! 561: } ! 562: ! 563: if(result != NULL) ! 564: *rval = BOOLEAN_TO_JSVAL(iniWriteFile(p->fp,list)); ! 565: ! 566: strListFree(&list); ! 567: ! 568: return(JS_TRUE); ! 569: } ! 570: ! 571: ! 572: static JSBool ! 573: js_iniGetSections(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 574: { ! 575: char* prefix=NULL; ! 576: char** list; ! 577: jsint i; ! 578: jsval val; ! 579: JSObject* array; ! 580: private_t* p; ! 581: ! 582: *rval = JSVAL_NULL; ! 583: ! 584: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 585: JS_ReportError(cx,getprivate_failure,WHERE); ! 586: return(JS_FALSE); ! 587: } ! 588: ! 589: if(p->fp==NULL) ! 590: return(JS_TRUE); ! 591: ! 592: if(argc) ! 593: prefix=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); ! 594: ! 595: array = JS_NewArrayObject(cx, 0, NULL); ! 596: ! 597: list = iniReadSectionList(p->fp,prefix); ! 598: for(i=0;list && list[i];i++) { ! 599: val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i])); ! 600: if(!JS_SetElement(cx, array, i, &val)) ! 601: break; ! 602: } ! 603: iniFreeStringList(list); ! 604: ! 605: *rval = OBJECT_TO_JSVAL(array); ! 606: ! 607: return(JS_TRUE); ! 608: } ! 609: ! 610: static JSBool ! 611: js_iniGetKeys(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 612: { ! 613: char* section=ROOT_SECTION; ! 614: char** list; ! 615: jsint i; ! 616: jsval val; ! 617: JSObject* array; ! 618: private_t* p; ! 619: ! 620: *rval = JSVAL_NULL; ! 621: ! 622: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 623: JS_ReportError(cx,getprivate_failure,WHERE); ! 624: return(JS_FALSE); ! 625: } ! 626: ! 627: if(p->fp==NULL) ! 628: return(JS_TRUE); ! 629: ! 630: if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL) ! 631: section=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); ! 632: array = JS_NewArrayObject(cx, 0, NULL); ! 633: ! 634: list = iniReadKeyList(p->fp,section); ! 635: for(i=0;list && list[i];i++) { ! 636: val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,list[i])); ! 637: if(!JS_SetElement(cx, array, i, &val)) ! 638: break; ! 639: } ! 640: iniFreeStringList(list); ! 641: ! 642: *rval = OBJECT_TO_JSVAL(array); ! 643: ! 644: return(JS_TRUE); ! 645: } ! 646: ! 647: static JSBool ! 648: js_iniGetObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 649: { ! 650: char* section=ROOT_SECTION; ! 651: jsint i; ! 652: JSObject* object; ! 653: private_t* p; ! 654: named_string_t** list; ! 655: ! 656: *rval = JSVAL_NULL; ! 657: ! 658: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 659: JS_ReportError(cx,getprivate_failure,WHERE); ! 660: return(JS_FALSE); ! 661: } ! 662: ! 663: if(p->fp==NULL) ! 664: return(JS_TRUE); ! 665: ! 666: if(argv[0]!=JSVAL_VOID && argv[0]!=JSVAL_NULL) ! 667: section=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); ! 668: object = JS_NewObject(cx, NULL, NULL, obj); ! 669: ! 670: list = iniReadNamedStringList(p->fp,section); ! 671: for(i=0;list && list[i];i++) { ! 672: JS_DefineProperty(cx, object, list[i]->name ! 673: ,get_value(cx,list[i]->value) ! 674: ,NULL,NULL,JSPROP_ENUMERATE); ! 675: ! 676: } ! 677: iniFreeNamedStringList(list); ! 678: ! 679: *rval = OBJECT_TO_JSVAL(object); ! 680: ! 681: return(JS_TRUE); ! 682: } ! 683: ! 684: static JSBool ! 685: js_iniSetObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 686: { ! 687: jsint i; ! 688: JSObject* object; ! 689: JSIdArray* id_array; ! 690: jsval set_argv[3]; ! 691: ! 692: *rval = JSVAL_FALSE; ! 693: ! 694: set_argv[0]=argv[0]; /* section */ ! 695: ! 696: if(!JSVAL_IS_OBJECT(argv[1]) || argv[1]==JSVAL_NULL) ! 697: return(JS_TRUE); ! 698: ! 699: object = JSVAL_TO_OBJECT(argv[1]); ! 700: ! 701: if((id_array=JS_Enumerate(cx,object))==NULL) ! 702: return(JS_TRUE); ! 703: ! 704: for(i=0; i<id_array->length; i++) { ! 705: /* property */ ! 706: JS_IdToValue(cx,id_array->vector[i],&set_argv[1]); ! 707: /* value */ ! 708: JS_GetProperty(cx,object,JS_GetStringBytes(JSVAL_TO_STRING(set_argv[1])),&set_argv[2]); ! 709: if(!js_iniSetValue(cx,obj,3,set_argv,rval)) ! 710: break; ! 711: } ! 712: ! 713: return(JS_TRUE); ! 714: } ! 715: ! 716: ! 717: static JSBool ! 718: js_iniGetAllObjects(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 719: { ! 720: char* name="name"; ! 721: char* sec_name; ! 722: char* prefix=NULL; ! 723: char** sec_list; ! 724: jsint i,k; ! 725: jsval val; ! 726: JSObject* array; ! 727: JSObject* object; ! 728: private_t* p; ! 729: named_string_t** key_list; ! 730: ! 731: *rval = JSVAL_NULL; ! 732: ! 733: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 734: JS_ReportError(cx,getprivate_failure,WHERE); ! 735: return(JS_FALSE); ! 736: } ! 737: ! 738: if(p->fp==NULL) ! 739: return(JS_TRUE); ! 740: ! 741: if(argc) ! 742: name=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); ! 743: ! 744: if(argc>1) ! 745: prefix=JS_GetStringBytes(JS_ValueToString(cx, argv[1])); ! 746: ! 747: array = JS_NewArrayObject(cx, 0, NULL); ! 748: ! 749: sec_list = iniReadSectionList(p->fp,prefix); ! 750: for(i=0;sec_list && sec_list[i];i++) { ! 751: object = JS_NewObject(cx, NULL, NULL, obj); ! 752: ! 753: sec_name=sec_list[i]; ! 754: if(prefix!=NULL) ! 755: sec_name+=strlen(prefix); ! 756: JS_DefineProperty(cx, object, name ! 757: ,STRING_TO_JSVAL(JS_NewStringCopyZ(cx,sec_name)) ! 758: ,NULL,NULL,JSPROP_ENUMERATE); ! 759: ! 760: key_list = iniReadNamedStringList(p->fp,sec_list[i]); ! 761: for(k=0;key_list && key_list[k];k++) ! 762: JS_DefineProperty(cx, object, key_list[k]->name ! 763: ,get_value(cx,key_list[k]->value) ! 764: ,NULL,NULL,JSPROP_ENUMERATE); ! 765: iniFreeNamedStringList(key_list); ! 766: ! 767: val=OBJECT_TO_JSVAL(object); ! 768: if(!JS_SetElement(cx, array, i, &val)) ! 769: break; ! 770: } ! 771: iniFreeStringList(sec_list); ! 772: ! 773: *rval = OBJECT_TO_JSVAL(array); ! 774: ! 775: return(JS_TRUE); ! 776: } ! 777: ! 778: static JSBool ! 779: js_iniSetAllObjects(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 780: { ! 781: char* name="name"; ! 782: jsuint i; ! 783: jsuint count; ! 784: JSObject* array; ! 785: jsval set_argv[2]; ! 786: ! 787: *rval = JSVAL_FALSE; ! 788: ! 789: if(!JSVAL_IS_OBJECT(argv[0])) ! 790: return(JS_TRUE); ! 791: ! 792: array = JSVAL_TO_OBJECT(argv[0]); ! 793: ! 794: if(!JS_IsArrayObject(cx, array)) ! 795: return(JS_TRUE); ! 796: ! 797: if(!JS_GetArrayLength(cx, array, &count)) ! 798: return(JS_TRUE); ! 799: ! 800: if(argc>1) ! 801: name=JS_GetStringBytes(JS_ValueToString(cx, argv[1])); ! 802: ! 803: /* enumerate the array */ ! 804: for(i=0; i<count; i++) { ! 805: if(!JS_GetElement(cx, array, i, &set_argv[1])) ! 806: break; ! 807: if(!JSVAL_IS_OBJECT(set_argv[1])) /* must be an array of objects */ ! 808: break; ! 809: if(!JS_GetProperty(cx, JSVAL_TO_OBJECT(set_argv[1]), name, &set_argv[0])) ! 810: continue; ! 811: if(!js_iniSetObject(cx, obj, 2, set_argv, rval)) ! 812: break; ! 813: } ! 814: ! 815: return(JS_TRUE); ! 816: } ! 817: ! 818: static JSBool ! 819: js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 820: { ! 821: char* cp; ! 822: char* uubuf=NULL; ! 823: int len; /* string length */ ! 824: int tlen; /* total length to write (may be greater than len) */ ! 825: private_t* p; ! 826: ! 827: *rval = JSVAL_FALSE; ! 828: ! 829: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 830: JS_ReportError(cx,getprivate_failure,WHERE); ! 831: return(JS_FALSE); ! 832: } ! 833: ! 834: if(p->fp==NULL) ! 835: return(JS_TRUE); ! 836: ! 837: cp=JS_GetStringBytes(JS_ValueToString(cx, argv[0])); ! 838: len=strlen(cp); ! 839: ! 840: if((p->uuencoded || p->b64encoded || p->yencoded) ! 841: && len && (uubuf=malloc(len))!=NULL) { ! 842: if(p->uuencoded) ! 843: len=uudecode(uubuf,len,cp,len); ! 844: else if(p->yencoded) ! 845: len=ydecode(uubuf,len,cp,len); ! 846: else ! 847: len=b64_decode(uubuf,len,cp,len); ! 848: if(len<0) { ! 849: free(uubuf); ! 850: return(JS_TRUE); ! 851: } ! 852: cp=uubuf; ! 853: } ! 854: ! 855: if(p->rot13) ! 856: rot13(cp); ! 857: ! 858: tlen=len; ! 859: if(argc>1) { ! 860: JS_ValueToInt32(cx,argv[1],(int32*)&tlen); ! 861: if(len>tlen) ! 862: len=tlen; ! 863: } ! 864: ! 865: if(fwrite(cp,1,len,p->fp)==(size_t)len) { ! 866: if(tlen>len) { ! 867: len=tlen-len; ! 868: if((cp=malloc(len))==NULL) { ! 869: dbprintf(TRUE, p, "malloc failure of %u bytes", len); ! 870: return(JS_TRUE); ! 871: } ! 872: memset(cp,p->etx,len); ! 873: fwrite(cp,1,len,p->fp); ! 874: free(cp); ! 875: } ! 876: dbprintf(FALSE, p, "wrote %u bytes",tlen); ! 877: *rval = JSVAL_TRUE; ! 878: } else ! 879: dbprintf(TRUE, p, "write of %u bytes failed",len); ! 880: ! 881: if(uubuf!=NULL) ! 882: free(uubuf); ! 883: ! 884: return(JS_TRUE); ! 885: } ! 886: ! 887: static JSBool ! 888: js_writeln(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 889: { ! 890: char* cp=""; ! 891: JSString* str; ! 892: private_t* p; ! 893: ! 894: *rval = JSVAL_FALSE; ! 895: ! 896: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 897: JS_ReportError(cx,getprivate_failure,WHERE); ! 898: return(JS_FALSE); ! 899: } ! 900: ! 901: if(p->fp==NULL) ! 902: return(JS_TRUE); ! 903: ! 904: if(argc) { ! 905: if((str = JS_ValueToString(cx, argv[0]))==NULL) { ! 906: JS_ReportError(cx,"JS_ValueToString failed"); ! 907: return(JS_FALSE); ! 908: } ! 909: cp = JS_GetStringBytes(str); ! 910: } ! 911: ! 912: if(p->rot13) ! 913: rot13(cp); ! 914: ! 915: if(fprintf(p->fp,"%s\n",cp)!=0) ! 916: *rval = JSVAL_TRUE; ! 917: ! 918: return(JS_TRUE); ! 919: } ! 920: ! 921: static JSBool ! 922: js_writebin(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 923: { ! 924: BYTE b; ! 925: WORD w; ! 926: DWORD l; ! 927: int32 val=0; ! 928: size_t wr=0; ! 929: size_t size=sizeof(DWORD); ! 930: private_t* p; ! 931: ! 932: *rval = JSVAL_FALSE; ! 933: ! 934: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 935: JS_ReportError(cx,getprivate_failure,WHERE); ! 936: return(JS_FALSE); ! 937: } ! 938: ! 939: if(p->fp==NULL) ! 940: return(JS_TRUE); ! 941: ! 942: JS_ValueToInt32(cx,argv[0],&val); ! 943: if(argc>1) ! 944: JS_ValueToInt32(cx,argv[1],(int32*)&size); ! 945: ! 946: switch(size) { ! 947: case sizeof(BYTE): ! 948: b = (BYTE)val; ! 949: wr=fwrite(&b,1,size,p->fp); ! 950: break; ! 951: case sizeof(WORD): ! 952: w = (WORD)val; ! 953: if(p->network_byte_order) ! 954: w=htons(w); ! 955: wr=fwrite(&w,1,size,p->fp); ! 956: break; ! 957: case sizeof(DWORD): ! 958: l = val; ! 959: if(p->network_byte_order) ! 960: l=htonl(l); ! 961: wr=fwrite(&l,1,size,p->fp); ! 962: break; ! 963: default: ! 964: /* unknown size */ ! 965: dbprintf(TRUE, p, "unsupported binary write size: %d",size); ! 966: break; ! 967: } ! 968: if(wr==size) ! 969: *rval = JSVAL_TRUE; ! 970: ! 971: return(JS_TRUE); ! 972: } ! 973: ! 974: static JSBool ! 975: js_writeall(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 976: { ! 977: jsuint i; ! 978: jsuint limit; ! 979: JSObject* array; ! 980: jsval elemval; ! 981: private_t* p; ! 982: ! 983: *rval = JSVAL_FALSE; ! 984: ! 985: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 986: JS_ReportError(cx,getprivate_failure,WHERE); ! 987: return(JS_FALSE); ! 988: } ! 989: ! 990: if(p->fp==NULL) ! 991: return(JS_TRUE); ! 992: ! 993: if(!JSVAL_IS_OBJECT(argv[0])) ! 994: return(JS_TRUE); ! 995: ! 996: array = JSVAL_TO_OBJECT(argv[0]); ! 997: ! 998: if(!JS_IsArrayObject(cx, array)) ! 999: return(JS_TRUE); ! 1000: ! 1001: if(!JS_GetArrayLength(cx, array, &limit)) ! 1002: return(JS_FALSE); ! 1003: ! 1004: *rval = JSVAL_TRUE; ! 1005: ! 1006: for(i=0;i<limit;i++) { ! 1007: if(!JS_GetElement(cx, array, i, &elemval)) ! 1008: break; ! 1009: js_writeln(cx, obj, 1, &elemval, rval); ! 1010: if(*rval!=JSVAL_TRUE) ! 1011: break; ! 1012: } ! 1013: ! 1014: return(JS_TRUE); ! 1015: } ! 1016: ! 1017: static JSBool ! 1018: js_lock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1019: { ! 1020: int32 offset=0; ! 1021: int32 len=0; ! 1022: private_t* p; ! 1023: ! 1024: *rval = JSVAL_FALSE; ! 1025: ! 1026: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 1027: JS_ReportError(cx,getprivate_failure,WHERE); ! 1028: return(JS_FALSE); ! 1029: } ! 1030: ! 1031: if(p->fp==NULL) ! 1032: return(JS_TRUE); ! 1033: ! 1034: /* offset */ ! 1035: if(argc) ! 1036: JS_ValueToInt32(cx,argv[0],&offset); ! 1037: ! 1038: /* length */ ! 1039: if(argc>1) ! 1040: JS_ValueToInt32(cx,argv[1],&len); ! 1041: ! 1042: if(len==0) ! 1043: len=filelength(fileno(p->fp))-offset; ! 1044: ! 1045: if(lock(fileno(p->fp),offset,len)==0) ! 1046: *rval = JSVAL_TRUE; ! 1047: ! 1048: return(JS_TRUE); ! 1049: } ! 1050: ! 1051: static JSBool ! 1052: js_unlock(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1053: { ! 1054: int32 offset=0; ! 1055: int32 len=0; ! 1056: private_t* p; ! 1057: ! 1058: *rval = JSVAL_FALSE; ! 1059: ! 1060: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 1061: JS_ReportError(cx,getprivate_failure,WHERE); ! 1062: return(JS_FALSE); ! 1063: } ! 1064: ! 1065: if(p->fp==NULL) ! 1066: return(JS_TRUE); ! 1067: ! 1068: /* offset */ ! 1069: if(argc) ! 1070: JS_ValueToInt32(cx,argv[0],&offset); ! 1071: ! 1072: /* length */ ! 1073: if(argc>1) ! 1074: JS_ValueToInt32(cx,argv[1],&len); ! 1075: ! 1076: if(len==0) ! 1077: len=filelength(fileno(p->fp))-offset; ! 1078: ! 1079: if(unlock(fileno(p->fp),offset,len)==0) ! 1080: *rval = JSVAL_TRUE; ! 1081: ! 1082: return(JS_TRUE); ! 1083: } ! 1084: ! 1085: static JSBool ! 1086: js_delete(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1087: { ! 1088: private_t* p; ! 1089: ! 1090: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 1091: JS_ReportError(cx,getprivate_failure,WHERE); ! 1092: return(JS_FALSE); ! 1093: } ! 1094: ! 1095: if(p->fp!=NULL) { /* close it if it's open */ ! 1096: fclose(p->fp); ! 1097: p->fp=NULL; ! 1098: } ! 1099: ! 1100: *rval = BOOLEAN_TO_JSVAL(remove(p->name)==0); ! 1101: ! 1102: return(JS_TRUE); ! 1103: } ! 1104: ! 1105: static JSBool ! 1106: js_flush(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1107: { ! 1108: private_t* p; ! 1109: ! 1110: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 1111: JS_ReportError(cx,getprivate_failure,WHERE); ! 1112: return(JS_FALSE); ! 1113: } ! 1114: ! 1115: if(p->fp==NULL) ! 1116: *rval = JSVAL_FALSE; ! 1117: else ! 1118: *rval = BOOLEAN_TO_JSVAL(fflush(p->fp)==0); ! 1119: ! 1120: return(JS_TRUE); ! 1121: } ! 1122: ! 1123: static JSBool ! 1124: js_rewind(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1125: { ! 1126: private_t* p; ! 1127: ! 1128: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 1129: JS_ReportError(cx,getprivate_failure,WHERE); ! 1130: return(JS_FALSE); ! 1131: } ! 1132: ! 1133: if(p->fp==NULL) ! 1134: *rval = JSVAL_FALSE; ! 1135: else { ! 1136: *rval = JSVAL_TRUE; ! 1137: rewind(p->fp); ! 1138: } ! 1139: ! 1140: return(JS_TRUE); ! 1141: } ! 1142: ! 1143: static JSBool ! 1144: js_clear_error(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1145: { ! 1146: private_t* p; ! 1147: ! 1148: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 1149: JS_ReportError(cx,getprivate_failure,WHERE); ! 1150: return(JS_FALSE); ! 1151: } ! 1152: ! 1153: if(p->fp==NULL) ! 1154: *rval = JSVAL_FALSE; ! 1155: else { ! 1156: clearerr(p->fp); ! 1157: *rval = JSVAL_TRUE; ! 1158: } ! 1159: ! 1160: return(JS_TRUE); ! 1161: } ! 1162: ! 1163: static JSBool ! 1164: js_fprintf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1165: { ! 1166: char* cp; ! 1167: uintN i; ! 1168: JSString * fmt; ! 1169: JSString * str; ! 1170: va_list arglist[64]; ! 1171: private_t* p; ! 1172: ! 1173: *rval = JSVAL_FALSE; ! 1174: ! 1175: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 1176: JS_ReportError(cx,getprivate_failure,WHERE); ! 1177: return(JS_FALSE); ! 1178: } ! 1179: ! 1180: if(p->fp==NULL) ! 1181: return(JS_TRUE); ! 1182: ! 1183: if((fmt=JS_ValueToString(cx, argv[0]))==NULL) { ! 1184: JS_ReportError(cx,"JS_ValueToString failed"); ! 1185: return(JS_FALSE); ! 1186: } ! 1187: ! 1188: memset(arglist,0,sizeof(arglist)); /* Initialize arglist to NULLs */ ! 1189: ! 1190: for (i = 1; i < argc && i<sizeof(arglist)/sizeof(arglist[0]); i++) { ! 1191: if(JSVAL_IS_DOUBLE(argv[i])) ! 1192: arglist[i-1]=(char*)(unsigned long)*JSVAL_TO_DOUBLE(argv[i]); ! 1193: else if(JSVAL_IS_INT(argv[i])) ! 1194: arglist[i-1]=(char *)JSVAL_TO_INT(argv[i]); ! 1195: else { ! 1196: if((str=JS_ValueToString(cx, argv[i]))==NULL) { ! 1197: JS_ReportError(cx,"JS_ValueToString failed"); ! 1198: return(JS_FALSE); ! 1199: } ! 1200: arglist[i-1]=JS_GetStringBytes(str); ! 1201: } ! 1202: } ! 1203: ! 1204: if((cp=JS_vsmprintf(JS_GetStringBytes(fmt),(char*)arglist))==NULL) { ! 1205: JS_ReportError(cx,"JS_vsmprintf failed"); ! 1206: return(JS_FALSE); ! 1207: } ! 1208: ! 1209: *rval = INT_TO_JSVAL(fwrite(cp,1,strlen(cp),p->fp)); ! 1210: JS_smprintf_free(cp); ! 1211: ! 1212: return(JS_TRUE); ! 1213: } ! 1214: ! 1215: ! 1216: /* File Object Properites */ ! 1217: enum { ! 1218: FILE_PROP_NAME ! 1219: ,FILE_PROP_MODE ! 1220: ,FILE_PROP_ETX ! 1221: ,FILE_PROP_EXISTS ! 1222: ,FILE_PROP_DATE ! 1223: ,FILE_PROP_IS_OPEN ! 1224: ,FILE_PROP_EOF ! 1225: ,FILE_PROP_ERROR ! 1226: ,FILE_PROP_DESCRIPTOR ! 1227: ,FILE_PROP_DEBUG ! 1228: ,FILE_PROP_POSITION ! 1229: ,FILE_PROP_LENGTH ! 1230: ,FILE_PROP_ATTRIBUTES ! 1231: ,FILE_PROP_YENCODED ! 1232: ,FILE_PROP_UUENCODED ! 1233: ,FILE_PROP_B64ENCODED ! 1234: ,FILE_PROP_ROT13 ! 1235: ,FILE_PROP_NETWORK_ORDER ! 1236: /* dynamically calculated */ ! 1237: ,FILE_PROP_CHKSUM ! 1238: ,FILE_PROP_CRC16 ! 1239: ,FILE_PROP_CRC32 ! 1240: ,FILE_PROP_MD5_HEX ! 1241: ,FILE_PROP_MD5_B64 ! 1242: }; ! 1243: ! 1244: ! 1245: static JSBool js_file_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) ! 1246: { ! 1247: int32 i=0; ! 1248: jsint tiny; ! 1249: private_t* p; ! 1250: ! 1251: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 1252: JS_ReportError(cx,getprivate_failure,WHERE); ! 1253: return(JS_FALSE); ! 1254: } ! 1255: ! 1256: tiny = JSVAL_TO_INT(id); ! 1257: ! 1258: dbprintf(FALSE, p, "setting property %d",tiny); ! 1259: ! 1260: switch(tiny) { ! 1261: case FILE_PROP_DEBUG: ! 1262: JS_ValueToBoolean(cx,*vp,&(p->debug)); ! 1263: break; ! 1264: case FILE_PROP_YENCODED: ! 1265: JS_ValueToBoolean(cx,*vp,&(p->yencoded)); ! 1266: break; ! 1267: case FILE_PROP_UUENCODED: ! 1268: JS_ValueToBoolean(cx,*vp,&(p->uuencoded)); ! 1269: break; ! 1270: case FILE_PROP_B64ENCODED: ! 1271: JS_ValueToBoolean(cx,*vp,&(p->b64encoded)); ! 1272: break; ! 1273: case FILE_PROP_ROT13: ! 1274: JS_ValueToBoolean(cx,*vp,&(p->rot13)); ! 1275: break; ! 1276: case FILE_PROP_NETWORK_ORDER: ! 1277: JS_ValueToBoolean(cx,*vp,&(p->network_byte_order)); ! 1278: break; ! 1279: case FILE_PROP_POSITION: ! 1280: if(p->fp!=NULL) { ! 1281: JS_ValueToInt32(cx,*vp,&i); ! 1282: fseek(p->fp,i,SEEK_SET); ! 1283: } ! 1284: break; ! 1285: case FILE_PROP_DATE: ! 1286: JS_ValueToInt32(cx,*vp,&i); ! 1287: setfdate(p->name,i); ! 1288: break; ! 1289: case FILE_PROP_LENGTH: ! 1290: if(p->fp!=NULL) { ! 1291: JS_ValueToInt32(cx,*vp,&i); ! 1292: chsize(fileno(p->fp),i); ! 1293: } ! 1294: break; ! 1295: case FILE_PROP_ATTRIBUTES: ! 1296: JS_ValueToInt32(cx,*vp,&i); ! 1297: CHMOD(p->name,i); ! 1298: break; ! 1299: case FILE_PROP_ETX: ! 1300: JS_ValueToInt32(cx,*vp,&i); ! 1301: p->etx = (uchar)i; ! 1302: break; ! 1303: } ! 1304: ! 1305: return(JS_TRUE); ! 1306: } ! 1307: ! 1308: static JSBool js_file_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp) ! 1309: { ! 1310: char str[128]; ! 1311: size_t i; ! 1312: size_t rd; ! 1313: long offset; ! 1314: ulong sum=0; ! 1315: ushort c16=0; ! 1316: ulong c32=~0; ! 1317: MD5 md5_ctx; ! 1318: BYTE block[4096]; ! 1319: BYTE digest[MD5_DIGEST_SIZE]; ! 1320: jsint tiny; ! 1321: JSString* js_str=NULL; ! 1322: private_t* p; ! 1323: ! 1324: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) { ! 1325: JS_ReportError(cx,getprivate_failure,WHERE); ! 1326: return(JS_FALSE); ! 1327: } ! 1328: ! 1329: tiny = JSVAL_TO_INT(id); ! 1330: ! 1331: #if 0 /* just too much */ ! 1332: dbprintf(FALSE, sock, "getting property %d",tiny); ! 1333: #endif ! 1334: ! 1335: switch(tiny) { ! 1336: case FILE_PROP_NAME: ! 1337: if((js_str=JS_NewStringCopyZ(cx, p->name))==NULL) ! 1338: return(JS_FALSE); ! 1339: *vp = STRING_TO_JSVAL(js_str); ! 1340: break; ! 1341: case FILE_PROP_MODE: ! 1342: if((js_str=JS_NewStringCopyZ(cx, p->mode))==NULL) ! 1343: return(JS_FALSE); ! 1344: *vp = STRING_TO_JSVAL(js_str); ! 1345: break; ! 1346: case FILE_PROP_EXISTS: ! 1347: if(p->fp) /* open? */ ! 1348: *vp = JSVAL_TRUE; ! 1349: else ! 1350: *vp = BOOLEAN_TO_JSVAL(fexistcase(p->name)); ! 1351: break; ! 1352: case FILE_PROP_DATE: ! 1353: JS_NewNumberValue(cx,fdate(p->name),vp); ! 1354: break; ! 1355: case FILE_PROP_IS_OPEN: ! 1356: *vp = BOOLEAN_TO_JSVAL(p->fp!=NULL); ! 1357: break; ! 1358: case FILE_PROP_EOF: ! 1359: if(p->fp) ! 1360: *vp = BOOLEAN_TO_JSVAL(feof(p->fp)!=0); ! 1361: else ! 1362: *vp = JSVAL_TRUE; ! 1363: break; ! 1364: case FILE_PROP_ERROR: ! 1365: if(p->fp) ! 1366: *vp = INT_TO_JSVAL(ferror(p->fp)); ! 1367: else ! 1368: *vp = INT_TO_JSVAL(errno); ! 1369: break; ! 1370: case FILE_PROP_POSITION: ! 1371: if(p->fp) ! 1372: JS_NewNumberValue(cx,ftell(p->fp),vp); ! 1373: else ! 1374: *vp = INT_TO_JSVAL(-1); ! 1375: break; ! 1376: case FILE_PROP_LENGTH: ! 1377: if(p->fp) /* open? */ ! 1378: JS_NewNumberValue(cx,filelength(fileno(p->fp)),vp); ! 1379: else ! 1380: JS_NewNumberValue(cx,flength(p->name),vp); ! 1381: break; ! 1382: case FILE_PROP_ATTRIBUTES: ! 1383: JS_NewNumberValue(cx,getfattr(p->name),vp); ! 1384: break; ! 1385: case FILE_PROP_DEBUG: ! 1386: *vp = BOOLEAN_TO_JSVAL(p->debug); ! 1387: break; ! 1388: case FILE_PROP_YENCODED: ! 1389: *vp = BOOLEAN_TO_JSVAL(p->yencoded); ! 1390: break; ! 1391: case FILE_PROP_UUENCODED: ! 1392: *vp = BOOLEAN_TO_JSVAL(p->uuencoded); ! 1393: break; ! 1394: case FILE_PROP_B64ENCODED: ! 1395: *vp = BOOLEAN_TO_JSVAL(p->b64encoded); ! 1396: break; ! 1397: case FILE_PROP_ROT13: ! 1398: *vp = BOOLEAN_TO_JSVAL(p->rot13); ! 1399: break; ! 1400: case FILE_PROP_NETWORK_ORDER: ! 1401: *vp = BOOLEAN_TO_JSVAL(p->network_byte_order); ! 1402: break; ! 1403: case FILE_PROP_DESCRIPTOR: ! 1404: if(p->fp) ! 1405: *vp = INT_TO_JSVAL(fileno(p->fp)); ! 1406: else ! 1407: *vp = INT_TO_JSVAL(-1); ! 1408: break; ! 1409: case FILE_PROP_ETX: ! 1410: *vp = INT_TO_JSVAL(p->etx); ! 1411: break; ! 1412: case FILE_PROP_CHKSUM: ! 1413: case FILE_PROP_CRC16: ! 1414: case FILE_PROP_CRC32: ! 1415: *vp = JSVAL_ZERO; ! 1416: if(p->fp==NULL) ! 1417: break; ! 1418: /* fall-through */ ! 1419: case FILE_PROP_MD5_HEX: ! 1420: case FILE_PROP_MD5_B64: ! 1421: *vp = JSVAL_VOID; ! 1422: if(p->fp==NULL) ! 1423: break; ! 1424: offset=ftell(p->fp); /* save current file position */ ! 1425: fseek(p->fp,0,SEEK_SET); ! 1426: ! 1427: /* Initialization */ ! 1428: switch(tiny) { ! 1429: case FILE_PROP_MD5_HEX: ! 1430: case FILE_PROP_MD5_B64: ! 1431: MD5_open(&md5_ctx); ! 1432: break; ! 1433: } ! 1434: ! 1435: /* calculate */ ! 1436: while(!feof(p->fp)) { ! 1437: if((rd=fread(block,1,sizeof(block),p->fp))<1) ! 1438: break; ! 1439: switch(tiny) { ! 1440: case FILE_PROP_CHKSUM: ! 1441: for(i=0;i<rd;i++) ! 1442: sum+=block[i]; ! 1443: break; ! 1444: case FILE_PROP_CRC16: ! 1445: for(i=0;i<rd;i++) ! 1446: c16=ucrc16(block[i],c16); ! 1447: break; ! 1448: case FILE_PROP_CRC32: ! 1449: for(i=0;i<rd;i++) ! 1450: c32=ucrc32(block[i],c32); ! 1451: break; ! 1452: case FILE_PROP_MD5_HEX: ! 1453: case FILE_PROP_MD5_B64: ! 1454: MD5_digest(&md5_ctx,block,rd); ! 1455: break; ! 1456: } ! 1457: } ! 1458: ! 1459: /* finalize */ ! 1460: switch(tiny) { ! 1461: case FILE_PROP_CHKSUM: ! 1462: JS_NewNumberValue(cx,sum,vp); ! 1463: break; ! 1464: case FILE_PROP_CRC16: ! 1465: if(!JS_NewNumberValue(cx,c16,vp)) ! 1466: *vp=JSVAL_ZERO; ! 1467: break; ! 1468: case FILE_PROP_CRC32: ! 1469: if(!JS_NewNumberValue(cx,~c32,vp)) ! 1470: *vp=JSVAL_ZERO; ! 1471: break; ! 1472: case FILE_PROP_MD5_HEX: ! 1473: case FILE_PROP_MD5_B64: ! 1474: MD5_close(&md5_ctx,digest); ! 1475: if(tiny==FILE_PROP_MD5_HEX) ! 1476: MD5_hex(str,digest); ! 1477: else ! 1478: b64_encode(str,sizeof(str)-1,digest,sizeof(digest)); ! 1479: js_str=JS_NewStringCopyZ(cx, str); ! 1480: break; ! 1481: } ! 1482: fseek(p->fp,offset,SEEK_SET); /* restore saved file position */ ! 1483: if(js_str!=NULL) ! 1484: *vp = STRING_TO_JSVAL(js_str); ! 1485: break; ! 1486: } ! 1487: ! 1488: return(JS_TRUE); ! 1489: } ! 1490: ! 1491: #define FILE_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY ! 1492: ! 1493: static jsSyncPropertySpec js_file_properties[] = { ! 1494: /* name ,tinyid ,flags, ver */ ! 1495: { "name" ,FILE_PROP_NAME ,FILE_PROP_FLAGS, 310}, ! 1496: { "mode" ,FILE_PROP_MODE ,FILE_PROP_FLAGS, 310}, ! 1497: { "exists" ,FILE_PROP_EXISTS ,FILE_PROP_FLAGS, 310}, ! 1498: { "is_open" ,FILE_PROP_IS_OPEN ,FILE_PROP_FLAGS, 310}, ! 1499: { "eof" ,FILE_PROP_EOF ,FILE_PROP_FLAGS, 310}, ! 1500: { "error" ,FILE_PROP_ERROR ,FILE_PROP_FLAGS, 310}, ! 1501: { "descriptor" ,FILE_PROP_DESCRIPTOR ,FILE_PROP_FLAGS, 310}, ! 1502: /* writeable */ ! 1503: { "etx" ,FILE_PROP_ETX ,JSPROP_ENUMERATE, 310}, ! 1504: { "debug" ,FILE_PROP_DEBUG ,JSPROP_ENUMERATE, 310}, ! 1505: { "position" ,FILE_PROP_POSITION ,JSPROP_ENUMERATE, 310}, ! 1506: { "date" ,FILE_PROP_DATE ,JSPROP_ENUMERATE, 311}, ! 1507: { "length" ,FILE_PROP_LENGTH ,JSPROP_ENUMERATE, 310}, ! 1508: { "attributes" ,FILE_PROP_ATTRIBUTES ,JSPROP_ENUMERATE, 310}, ! 1509: { "network_byte_order",FILE_PROP_NETWORK_ORDER,JSPROP_ENUMERATE, 311}, ! 1510: { "rot13" ,FILE_PROP_ROT13 ,JSPROP_ENUMERATE, 311}, ! 1511: { "uue" ,FILE_PROP_UUENCODED ,JSPROP_ENUMERATE, 311}, ! 1512: { "yenc" ,FILE_PROP_YENCODED ,JSPROP_ENUMERATE, 311}, ! 1513: { "base64" ,FILE_PROP_B64ENCODED ,JSPROP_ENUMERATE, 311}, ! 1514: /* dynamically calculated */ ! 1515: { "crc16" ,FILE_PROP_CRC16 ,FILE_PROP_FLAGS, 311}, ! 1516: { "crc32" ,FILE_PROP_CRC32 ,FILE_PROP_FLAGS, 311}, ! 1517: { "chksum" ,FILE_PROP_CHKSUM ,FILE_PROP_FLAGS, 311}, ! 1518: { "md5_hex" ,FILE_PROP_MD5_HEX ,FILE_PROP_FLAGS, 311}, ! 1519: { "md5_base64" ,FILE_PROP_MD5_B64 ,FILE_PROP_FLAGS, 311}, ! 1520: {0} ! 1521: }; ! 1522: ! 1523: #ifdef _DEBUG ! 1524: static char* file_prop_desc[] = { ! 1525: "filename specified in constructor - <small>READ ONLY</small>" ! 1526: ,"mode string specified in <i>open</i> call - <small>READ ONLY</small>" ! 1527: ,"<i>true</i> if the file exists - <small>READ ONLY</small>" ! 1528: ,"<i>true</i> if the file has been opened successfully - <small>READ ONLY</small>" ! 1529: ,"<i>true</i> if the current file position is at the <i>end of file</i> - <small>READ ONLY</small>" ! 1530: ,"the last occurred error value (use clear_error to clear) - <small>READ ONLY</small>" ! 1531: ,"the open file descriptor (advanced use only) - <small>READ ONLY</small>" ! 1532: ,"end-of-text character (advanced use only), if non-zero used by <i>read</i>, <i>readln</i>, and <i>write</i>" ! 1533: ,"set to <i>true</i> to enable debug log output" ! 1534: ,"the current file position (offset in bytes), change value to seek within file" ! 1535: ,"last modified date/time (in time_t format)" ! 1536: ,"the current length of the file (in bytes)" ! 1537: ,"file mode/attributes" ! 1538: ,"set to <i>true</i> if binary data is to be written and read in Network Byte Order (big end first)" ! 1539: ,"set to <i>true</i> to enable automatic ROT13 translatation of text" ! 1540: ,"set to <i>true</i> to enable automatic Unix-to-Unix encode and decode on <tt>read</tt> and <tt>write</tt> calls" ! 1541: ,"set to <i>true</i> to enable automatic yEnc encode and decode on <tt>read</tt> and <tt>write</tt> calls" ! 1542: ,"set to <i>true</i> to enable automatic Base64 encode and decode on <tt>read</tt> and <tt>write</tt> calls" ! 1543: ,"calculated 16-bit CRC of file contents - <small>READ ONLY</small>" ! 1544: ,"calculated 32-bit CRC of file contents - <small>READ ONLY</small>" ! 1545: ,"calculated 32-bit checksum of file contents - <small>READ ONLY</small>" ! 1546: ,"calculated 128-bit MD5 digest of file contents as hexadecimal string - <small>READ ONLY</small>" ! 1547: ,"calculated 128-bit MD5 digest of file contents as base64-encoded string - <small>READ ONLY</small>" ! 1548: ,NULL ! 1549: }; ! 1550: #endif ! 1551: ! 1552: ! 1553: static jsSyncMethodSpec js_file_functions[] = { ! 1554: {"open", js_open, 1, JSTYPE_BOOLEAN, JSDOCSTR("[string mode, boolean shareable, number buflen]") ! 1555: ,JSDOCSTR("open file, <i>shareable</i> defaults to <i>false</i>, <i>buflen</i> defaults to 2048 bytes, " ! 1556: "mode (default: <tt>'w+'</tt>) specifies the type of access requested for the file, as follows:<br>" ! 1557: "<tt>r </tt> open for reading; if the file does not exist or cannot be found, the open call fails<br>" ! 1558: "<tt>w </tt> open an empty file for writing; if the given file exists, its contents are destroyed<br>" ! 1559: "<tt>a </tt> open for writing at the end of the file (appending); creates the file first if it doesn�t exist<br>" ! 1560: "<tt>r+</tt> open for both reading and writing (the file must exist)<br>" ! 1561: "<tt>w+</tt> open an empty file for both reading and writing; if the given file exists, its contents are destroyed<br>" ! 1562: "<tt>a+</tt> open for reading and appending<br>" ! 1563: "<tt>b </tt> open in binary (untranslated) mode; translations involving carriage-return and linefeed characters are suppressed (e.g. <tt>r+b</tt>)<br>" ! 1564: "<tt>e </tt> open a <i>non-shareable</i> file (that must not already exist) for <i>exclusive</i> access <i>(introduced in v3.12)</i><br>" ! 1565: ) ! 1566: ,310 ! 1567: }, ! 1568: {"close", js_close, 0, JSTYPE_VOID, "" ! 1569: ,JSDOCSTR("close file") ! 1570: ,310 ! 1571: }, ! 1572: {"remove", js_delete, 0, JSTYPE_BOOLEAN, "" ! 1573: ,JSDOCSTR("remove the file from the disk") ! 1574: ,310 ! 1575: }, ! 1576: {"clearError", js_clear_error, 0, JSTYPE_ALIAS }, ! 1577: {"clear_error", js_clear_error, 0, JSTYPE_BOOLEAN, "" ! 1578: ,JSDOCSTR("clears the current error value (AKA clearError)") ! 1579: ,310 ! 1580: }, ! 1581: {"flush", js_flush, 0, JSTYPE_BOOLEAN, "" ! 1582: ,JSDOCSTR("flush/commit buffers to disk") ! 1583: ,310 ! 1584: }, ! 1585: {"rewind", js_rewind, 0, JSTYPE_BOOLEAN, "" ! 1586: ,JSDOCSTR("repositions the file pointer (<i>position</i>) to the beginning of a file " ! 1587: "and clears error and end-of-file indicators") ! 1588: ,311 ! 1589: }, ! 1590: {"lock", js_lock, 2, JSTYPE_BOOLEAN, JSDOCSTR("[offset, length]") ! 1591: ,JSDOCSTR("lock file record for exclusive access (file must be opened <i>shareable</i>)") ! 1592: ,310 ! 1593: }, ! 1594: {"unlock", js_unlock, 2, JSTYPE_BOOLEAN, JSDOCSTR("[offset, length]") ! 1595: ,JSDOCSTR("unlock file record for exclusive access") ! 1596: ,310 ! 1597: }, ! 1598: {"read", js_read, 0, JSTYPE_STRING, JSDOCSTR("[maxlen]") ! 1599: ,JSDOCSTR("read a string from file (optionally unix-to-unix or base64 decoding in the process), " ! 1600: "<i>maxlen</i> defaults to the current length of the file minus the current file position") ! 1601: ,310 ! 1602: }, ! 1603: {"readln", js_readln, 0, JSTYPE_STRING, JSDOCSTR("[maxlen]") ! 1604: ,JSDOCSTR("read a line-feed terminated string, <i>maxlen</i> defaults to 512 characters") ! 1605: ,310 ! 1606: }, ! 1607: {"readBin", js_readbin, 0, JSTYPE_NUMBER, JSDOCSTR("[bytes]") ! 1608: ,JSDOCSTR("read a binary integer from the file, default number of <i>bytes</i> is 4 (32-bits)") ! 1609: ,310 ! 1610: }, ! 1611: {"readAll", js_readall, 0, JSTYPE_ARRAY, "" ! 1612: ,JSDOCSTR("read all lines into an array of strings") ! 1613: ,310 ! 1614: }, ! 1615: {"write", js_write, 1, JSTYPE_BOOLEAN, JSDOCSTR("string text [,len]") ! 1616: ,JSDOCSTR("write a string to the file (optionally unix-to-unix or base64 decoding in the process)") ! 1617: ,310 ! 1618: }, ! 1619: {"writeln", js_writeln, 0, JSTYPE_BOOLEAN, JSDOCSTR("[string text]") ! 1620: ,JSDOCSTR("write a line-feed terminated string to the file") ! 1621: ,310 ! 1622: }, ! 1623: {"writeBin", js_writebin, 1, JSTYPE_BOOLEAN, JSDOCSTR("value [,bytes]") ! 1624: ,JSDOCSTR("write a binary integer to the file, default number of <i>bytes</i> is 4 (32-bits)") ! 1625: ,310 ! 1626: }, ! 1627: {"writeAll", js_writeall, 0, JSTYPE_BOOLEAN, JSDOCSTR("array lines") ! 1628: ,JSDOCSTR("write an array of strings to file") ! 1629: ,310 ! 1630: }, ! 1631: {"printf", js_fprintf, 0, JSTYPE_NUMBER, JSDOCSTR("string format [,args]") ! 1632: ,JSDOCSTR("write a formatted string to the file (ala fprintf) - " ! 1633: "<small>CAUTION: for experienced C programmers ONLY</small>") ! 1634: ,310 ! 1635: }, ! 1636: {"iniGetSections", js_iniGetSections, 0, JSTYPE_ARRAY, JSDOCSTR("[prefix]") ! 1637: ,JSDOCSTR("parse all section names from a <tt>.ini</tt> file (format = '<tt>[section]</tt>') " ! 1638: "and return the section names as an <i>array of strings</i>, " ! 1639: "optionally, only those section names that begin with the specified <i>prefix</i>") ! 1640: ,311 ! 1641: }, ! 1642: {"iniGetKeys", js_iniGetKeys, 1, JSTYPE_ARRAY, JSDOCSTR("[section]") ! 1643: ,JSDOCSTR("parse all key names from the specified <i>section</i> in a <tt>.ini</tt> file " ! 1644: "and return the key names as an <i>array of strings</i>. " ! 1645: "if <i>section</i> is undefined, returns key names from the <i>root</i> section") ! 1646: ,311 ! 1647: }, ! 1648: {"iniGetValue", js_iniGetValue, 3, JSTYPE_UNDEF, JSDOCSTR("section, key [,default]") ! 1649: ,JSDOCSTR("parse a key from a <tt>.ini</tt> file and return its value (format = '<tt>key = value</tt>'). " ! 1650: "returns the specified <i>default</i> value if the key or value is missing or invalid. " ! 1651: "to parse a key from the <i>root</i> section, pass <i>null</i> for <i>section</i>. " ! 1652: "will return a <i>bool</i>, <i>number</i>, <i>string</i>, or an <i>array of strings</i> " ! 1653: "determined by the type of <i>default</i> value specified") ! 1654: ,311 ! 1655: }, ! 1656: {"iniSetValue", js_iniSetValue, 3, JSTYPE_BOOLEAN, JSDOCSTR("section, key, value") ! 1657: ,JSDOCSTR("set the specified <i>key</i> to the specified <i>value</i> in the specified <i>section</i> " ! 1658: "of a <tt>.ini</tt> file. " ! 1659: "to set a key in the <i>root</i> section, pass <i>null</i> for <i>section</i>. ") ! 1660: ,312 ! 1661: }, ! 1662: {"iniGetObject", js_iniGetObject, 1, JSTYPE_OBJECT, JSDOCSTR("[section]") ! 1663: ,JSDOCSTR("parse an entire section from a .ini file " ! 1664: "and return all of its keys and values as properties of an object. " ! 1665: "if <i>section</i> is undefined, returns key and values from the <i>root</i> section") ! 1666: ,311 ! 1667: }, ! 1668: {"iniSetObject", js_iniSetObject, 2, JSTYPE_BOOLEAN, JSDOCSTR("section, object") ! 1669: ,JSDOCSTR("write all the properties of the specified <i>object</i> as separate <tt>key=value</tt> pairs " ! 1670: "in the specified <i>section</i> of a <tt>.ini</tt> file. " ! 1671: "to write an object in the <i>root</i> section, pass <i>null</i> for <i>section</i>. ") ! 1672: ,312 ! 1673: }, ! 1674: {"iniGetAllObjects",js_iniGetAllObjects,1, JSTYPE_ARRAY, JSDOCSTR("[name_property] [,prefix]") ! 1675: ,JSDOCSTR("parse all sections from a .ini file and return all (non-<i>root</i>) sections " ! 1676: "in an array of objects with each section's keys as properties of each object. " ! 1677: "<i>name_property</i> is the name of the property to create to contain the section's name " ! 1678: "(default is <tt>\"name\"</tt>), " ! 1679: "the optional <i>prefix</i> has the same use as in the <tt>iniGetSections</tt> method, " ! 1680: "if a <i>prefix</i> is specified, it is removed from each section's name" ) ! 1681: ,311 ! 1682: }, ! 1683: {"iniSetAllObjects",js_iniSetAllObjects,1, JSTYPE_ARRAY, JSDOCSTR("object array [,name_property]") ! 1684: ,JSDOCSTR("write an array of objects to a .ini file, each object in its own section named " ! 1685: "after the object's <i>name_property</i> (default: <tt>name</tt>)") ! 1686: ,312 ! 1687: }, ! 1688: {0} ! 1689: }; ! 1690: ! 1691: /* File Destructor */ ! 1692: ! 1693: static void js_finalize_file(JSContext *cx, JSObject *obj) ! 1694: { ! 1695: private_t* p; ! 1696: ! 1697: if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) ! 1698: return; ! 1699: ! 1700: if(p->external==JS_FALSE && p->fp!=NULL) ! 1701: fclose(p->fp); ! 1702: ! 1703: dbprintf(FALSE, p, "closed: %s",p->name); ! 1704: ! 1705: free(p); ! 1706: ! 1707: JS_SetPrivate(cx, obj, NULL); ! 1708: } ! 1709: ! 1710: static JSClass js_file_class = { ! 1711: "File" /* name */ ! 1712: ,JSCLASS_HAS_PRIVATE /* flags */ ! 1713: ,JS_PropertyStub /* addProperty */ ! 1714: ,JS_PropertyStub /* delProperty */ ! 1715: ,js_file_get /* getProperty */ ! 1716: ,js_file_set /* setProperty */ ! 1717: ,JS_EnumerateStub /* enumerate */ ! 1718: ,JS_ResolveStub /* resolve */ ! 1719: ,JS_ConvertStub /* convert */ ! 1720: ,js_finalize_file /* finalize */ ! 1721: }; ! 1722: ! 1723: /* File Constructor (creates file descriptor) */ ! 1724: ! 1725: static JSBool ! 1726: js_file_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) ! 1727: { ! 1728: JSString* str; ! 1729: private_t* p; ! 1730: ! 1731: if((str = JS_ValueToString(cx, argv[0]))==NULL) { ! 1732: JS_ReportError(cx,"No filename specified"); ! 1733: return(JS_FALSE); ! 1734: } ! 1735: ! 1736: *rval = JSVAL_VOID; ! 1737: ! 1738: if((p=(private_t*)calloc(1,sizeof(private_t)))==NULL) { ! 1739: JS_ReportError(cx,"calloc failed"); ! 1740: return(JS_FALSE); ! 1741: } ! 1742: ! 1743: SAFECOPY(p->name,JS_GetStringBytes(str)); ! 1744: ! 1745: if(!JS_SetPrivate(cx, obj, p)) { ! 1746: dbprintf(TRUE, p, "JS_SetPrivate failed"); ! 1747: return(JS_FALSE); ! 1748: } ! 1749: ! 1750: if(!js_DefineSyncProperties(cx, obj, js_file_properties)) { ! 1751: dbprintf(TRUE, p, "js_DefineSyncProperties failed"); ! 1752: return(JS_FALSE); ! 1753: } ! 1754: ! 1755: if(!js_DefineSyncMethods(cx, obj, js_file_functions, FALSE)) { ! 1756: dbprintf(TRUE, p, "js_DefineSyncMethods failed"); ! 1757: return(JS_FALSE); ! 1758: } ! 1759: ! 1760: #ifdef _DEBUG ! 1761: js_DescribeSyncObject(cx,obj,"Class used for opening, creating, reading, or writing files on the local file system<p>" ! 1762: "Special features include:</h2><ol type=disc>" ! 1763: "<li>Exclusive-access files (default) or shared files<ol type=circle>" ! 1764: "<li>optional record-locking" ! 1765: "<li>buffered or non-buffered I/O" ! 1766: "</ol>" ! 1767: "<li>Support for binary files<ol type=circle>" ! 1768: "<li>native or network byte order (endian)" ! 1769: "<li>automatic Unix-to-Unix (<i>UUE</i>), yEncode (<i>yEnc</i>) or Base64 encoding/decoding" ! 1770: "</ol>" ! 1771: "<li>Support for ASCII text files<ol type=circle>" ! 1772: "<li>supports line-based I/O<ol type=square>" ! 1773: "<li>entire file may be read or written as an array of strings" ! 1774: "<li>individual lines may be read or written one line at a time" ! 1775: "</ol>" ! 1776: "<li>supports fixed-length records<ol type=square>" ! 1777: "<li>optional end-of-text (<i>etx</i>) character for automatic record padding/termination" ! 1778: "<li>Synchronet <tt>.dat</tt> files use an <i>etx</i> value of 3 (Ctrl-C)" ! 1779: "</ol>" ! 1780: "<li>supports <tt>.ini</tt> formated configuration files<ol type=square>" ! 1781: "<li>concept and support of <i>root</i> ini sections added in v3.12" ! 1782: "</ol>" ! 1783: "<li>optional ROT13 encoding/translation" ! 1784: "</ol>" ! 1785: "<li>Dynamically-calculated industry standard checksums (e.g. CRC-16, CRC-32, MD5)" ! 1786: "</ol>" ! 1787: ,310 ! 1788: ); ! 1789: js_DescribeSyncConstructor(cx,obj,"To create a new File object: <tt>var f = new File(<i>filename</i>)</tt>"); ! 1790: js_CreateArrayOfStrings(cx, obj, "_property_desc_list", file_prop_desc, JSPROP_READONLY); ! 1791: #endif ! 1792: ! 1793: dbprintf(FALSE, p, "object constructed"); ! 1794: return(JS_TRUE); ! 1795: } ! 1796: ! 1797: JSObject* DLLCALL js_CreateFileClass(JSContext* cx, JSObject* parent) ! 1798: { ! 1799: JSObject* sockobj; ! 1800: ! 1801: sockobj = JS_InitClass(cx, parent, NULL ! 1802: ,&js_file_class ! 1803: ,js_file_constructor ! 1804: ,1 /* number of constructor args */ ! 1805: ,NULL /* props, set in constructor */ ! 1806: ,NULL /* funcs, set in constructor */ ! 1807: ,NULL,NULL); ! 1808: ! 1809: return(sockobj); ! 1810: } ! 1811: ! 1812: JSObject* DLLCALL js_CreateFileObject(JSContext* cx, JSObject* parent, char *name, FILE* fp) ! 1813: { ! 1814: JSObject* obj; ! 1815: private_t* p; ! 1816: ! 1817: obj = JS_DefineObject(cx, parent, name, &js_file_class, NULL ! 1818: ,JSPROP_ENUMERATE|JSPROP_READONLY); ! 1819: ! 1820: if(obj==NULL) ! 1821: return(NULL); ! 1822: ! 1823: if(!js_DefineSyncProperties(cx, obj, js_file_properties)) ! 1824: return(NULL); ! 1825: ! 1826: if (!js_DefineSyncMethods(cx, obj, js_file_functions, FALSE)) ! 1827: return(NULL); ! 1828: ! 1829: if((p=(private_t*)calloc(1,sizeof(private_t)))==NULL) ! 1830: return(NULL); ! 1831: ! 1832: p->fp=fp; ! 1833: p->debug=JS_FALSE; ! 1834: p->external=JS_TRUE; ! 1835: ! 1836: if(!JS_SetPrivate(cx, obj, p)) { ! 1837: dbprintf(TRUE, p, "JS_SetPrivate failed"); ! 1838: return(NULL); ! 1839: } ! 1840: ! 1841: dbprintf(FALSE, p, "object created"); ! 1842: ! 1843: return(obj); ! 1844: } ! 1845: ! 1846: ! 1847: #endif /* JAVSCRIPT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.