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