diff --git a/src/sbbs3/js_console.cpp b/src/sbbs3/js_console.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e04cb4d432f7bacba2cf1bb878f669763746038b --- /dev/null +++ b/src/sbbs3/js_console.cpp @@ -0,0 +1,905 @@ +/* js_console.cpp */ + +/* Synchronet JavaScript "Console" Object */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2001 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include "sbbs.h" + +#ifdef JAVASCRIPT + +/*****************************/ +/* Console Object Properites */ +/*****************************/ +enum { + CON_PROP_ONLINE + ,CON_PROP_STATUS + ,CON_PROP_LNCNTR + ,CON_PROP_TOS + ,CON_PROP_ROWS + ,CON_PROP_AUTOTERM + ,CON_PROP_TIMEOUT /* User inactivity timeout reference */ + ,CON_PROP_TIMELEFT_WARN /* low timeleft warning flag */ +}; + +static JSBool js_console_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + ulong val; + jsint tiny; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + tiny = JSVAL_TO_INT(id); + + switch(tiny) { + case CON_PROP_ONLINE: + val=sbbs->online; + break; + case CON_PROP_STATUS: + val=sbbs->console; + break; + case CON_PROP_LNCNTR: + val=sbbs->lncntr; + break; + case CON_PROP_TOS: + val=sbbs->tos; + break; + case CON_PROP_ROWS: + val=sbbs->rows; + break; + case CON_PROP_AUTOTERM: + val=sbbs->autoterm; + break; + case CON_PROP_TIMEOUT: + val=sbbs->timeout; + break; + case CON_PROP_TIMELEFT_WARN: + val=sbbs->timeleft_warn; + break; + default: + return(JS_TRUE); + } + + *vp = INT_TO_JSVAL(val); + + return(JS_TRUE); +} + +static JSBool js_console_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + long val; + jsint tiny; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + tiny = JSVAL_TO_INT(id); + + JS_ValueToInt32(cx, *vp, &val); + + switch(tiny) { + case CON_PROP_ONLINE: + sbbs->online=val; + break; + case CON_PROP_STATUS: + sbbs->console=val; + break; + case CON_PROP_LNCNTR: + sbbs->lncntr=val; + break; + case CON_PROP_TOS: + sbbs->tos=val; + break; + case CON_PROP_ROWS: + sbbs->rows=val; + break; + case CON_PROP_AUTOTERM: + sbbs->autoterm=val; + break; + case CON_PROP_TIMEOUT: + sbbs->timeout=val; + break; + case CON_PROP_TIMELEFT_WARN: + sbbs->timeleft_warn=val; + break; + default: + return(JS_TRUE); + } + + return(JS_TRUE); +} + +#define CON_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY + +static struct JSPropertySpec js_console_properties[] = { +/* name ,tinyid ,flags ,getter,setter */ + + { "online" ,CON_PROP_ONLINE ,CON_PROP_FLAGS ,NULL,NULL}, + { "status" ,CON_PROP_STATUS ,CON_PROP_FLAGS ,NULL,NULL}, + { "line_counter" ,CON_PROP_LNCNTR ,CON_PROP_FLAGS ,NULL,NULL}, + { "top_of_screen" ,CON_PROP_TOS ,CON_PROP_FLAGS ,NULL,NULL}, + { "rows" ,CON_PROP_ROWS ,CON_PROP_FLAGS ,NULL,NULL}, + { "autoterm" ,CON_PROP_AUTOTERM ,CON_PROP_FLAGS ,NULL,NULL}, + { "timeout" ,CON_PROP_TIMEOUT ,CON_PROP_FLAGS ,NULL,NULL}, + { "timeleft_warning" ,CON_PROP_TIMELEFT_WARN ,CON_PROP_FLAGS ,NULL,NULL}, + {0} +}; + +/**************************/ +/* Console Object Methods */ +/**************************/ + +static JSBool +js_inkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char key[2]; + long mode=0; + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(argc && JSVAL_IS_INT(argv[0])) + mode=JSVAL_TO_INT(argv[0]); + key[0]=sbbs->inkey(mode); + key[1]=0; + + js_str = JS_NewStringCopyZ(cx, key); + *rval = STRING_TO_JSVAL(js_str); + + return(JS_TRUE); +} + +static JSBool +js_getkey(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char key[2]; + long mode=0; + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(argc && JSVAL_IS_INT(argv[0])) + mode=JSVAL_TO_INT(argv[0]); + key[0]=sbbs->getkey(mode); + key[1]=0; + + js_str = JS_NewStringCopyZ(cx, key); + *rval = STRING_TO_JSVAL(js_str); + + return(JS_TRUE); +} + +static JSBool +js_getstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char *p; + long mode=0; + uintN i; + size_t maxlen=0; + sbbs_t* sbbs; + JSString* js_str=NULL; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + for(i=0;i<argc;i++) { + if(JSVAL_IS_INT(argv[i])) { + if(!maxlen) + maxlen=JSVAL_TO_INT(argv[i]); + else + mode=JSVAL_TO_INT(argv[i]); + continue; + } + if(JSVAL_IS_STRING(argv[i])) { + js_str = JS_ValueToString(cx, argv[i]); + if (!js_str) + return(JS_FALSE); + } + } + + if(!maxlen) maxlen=128; + + if((p=(char *)calloc(1,maxlen+1))==NULL) + return(JS_FALSE); + + if(js_str!=NULL) + sprintf(p,"%.*s",maxlen,JS_GetStringBytes(js_str)); + + sbbs->getstr(p,maxlen,mode); + + js_str = JS_NewStringCopyZ(cx, p); + + free(p); + + *rval = STRING_TO_JSVAL(js_str); + + return(JS_TRUE); +} + +static JSBool +js_getnum(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + ulong maxnum=~0; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(argc && JSVAL_IS_INT(argv[0])) + maxnum=JSVAL_TO_INT(argv[0]); + + *rval = INT_TO_JSVAL(sbbs->getnum(maxnum)); + + return(JS_TRUE); +} + +static JSBool +js_getkeys(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char key[2]; + uintN i; + long val; + ulong maxnum=~0; + sbbs_t* sbbs; + JSString* js_str=NULL; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + for(i=0;i<argc;i++) { + if(JSVAL_IS_INT(argv[i])) { + maxnum=JSVAL_TO_INT(argv[i]); + continue; + } + if(JSVAL_IS_STRING(argv[i])) { + js_str = JS_ValueToString(cx, argv[i]); + } + } + if (!js_str) + return(JS_FALSE); + + val=sbbs->getkeys(JS_GetStringBytes(js_str),maxnum); + + if(val==-1) { // abort + *rval = INT_TO_JSVAL(0); + } else if(val<0) { // number + val&=~0x80000000; + *rval = INT_TO_JSVAL(val); + } else { // key + key[0]=(uchar)val; + key[1]=0; + js_str = JS_NewStringCopyZ(cx, key); + *rval = STRING_TO_JSVAL(js_str); + } + + return(JS_TRUE); +} + +static JSBool +js_gettemplate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char str[128]; + long mode=0; + uintN i; + sbbs_t* sbbs; + JSString* js_str=NULL; + JSString* js_fmt=NULL; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + for(i=0;i<argc;i++) { + if(JSVAL_IS_STRING(argv[i])) { + if(js_fmt==NULL) + js_fmt = JS_ValueToString(cx, argv[i]); + else + js_str = JS_ValueToString(cx, argv[i]); + } else if (JSVAL_IS_INT(argv[i])) + mode=JSVAL_TO_INT(argv[i]); + } + + if(js_fmt==NULL) + return(JS_FALSE); + + if(js_str==NULL) + str[0]=0; + else + sprintf(str, "%.*s", sizeof(str)-1, JS_GetStringBytes(js_str)); + + sbbs->gettmplt(str,JS_GetStringBytes(js_fmt),mode); + js_str = JS_NewStringCopyZ(cx, str); + *rval = STRING_TO_JSVAL(js_str); + + return(JS_TRUE); +} + +static JSBool +js_ungetstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char* p; + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if((js_str=JS_ValueToString(cx, argv[0]))==NULL) + return(JS_FALSE); + + p=JS_GetStringBytes(js_str); + + while(p && *p) + sbbs->ungetkey(*(p++)); + + return(JS_TRUE); +} + +static JSBool +js_yesno(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if((js_str=JS_ValueToString(cx, argv[0]))==NULL) + return(JS_FALSE); + + *rval = BOOLEAN_TO_JSVAL(sbbs->yesno(JS_GetStringBytes(js_str))); + + return(JS_TRUE); +} + +static JSBool +js_noyes(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if((js_str=JS_ValueToString(cx, argv[0]))==NULL) + return(JS_FALSE); + + *rval = BOOLEAN_TO_JSVAL(sbbs->noyes(JS_GetStringBytes(js_str))); + + return(JS_TRUE); +} + +static JSBool +js_mnemonics(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if((js_str=JS_ValueToString(cx, argv[0]))==NULL) + return(JS_FALSE); + + sbbs->mnemonics(JS_GetStringBytes(js_str)); + + return(JS_TRUE); +} + +static JSBool +js_clear(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->CLS; + + return(JS_TRUE); +} + +static JSBool +js_clearline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->clearline(); + + return(JS_TRUE); +} + +static JSBool +js_crlf(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->outchar(CR); + sbbs->outchar(LF); + + return(JS_TRUE); +} + +static JSBool +js_attr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->attr(JSVAL_TO_INT(argv[0])); + + return(JS_TRUE); +} + +static JSBool +js_pause(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->pause(); + + return(JS_TRUE); +} + +static JSBool +js_print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString* str; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return(JS_FALSE); + + sbbs->bputs(JS_GetStringBytes(str)); + + return(JS_TRUE); +} + +static JSBool +js_write(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString* str; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return(JS_FALSE); + + sbbs->rputs(JS_GetStringBytes(str)); + + return(JS_TRUE); +} + +static JSBool +js_putmsg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + long mode=0; + JSString* str; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return(JS_FALSE); + + if(argc>1 && JSVAL_IS_INT(argv[1])) + mode=JSVAL_TO_INT(argv[1]); + + sbbs->putmsg(JS_GetStringBytes(str),mode); + + return(JS_TRUE); +} + +static JSBool +js_printfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + long mode=0; + JSString* str; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return(JS_FALSE); + + if(argc>1 && JSVAL_IS_INT(argv[1])) + mode=JSVAL_TO_INT(argv[1]); + + sbbs->printfile(JS_GetStringBytes(str),mode); + + return(JS_TRUE); +} + +static JSBool +js_printtail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + int lines=0; + long mode=0; + uintN i; + sbbs_t* sbbs; + JSString* js_str=NULL; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + for(i=0;i<argc;i++) { + if(JSVAL_IS_INT(argv[i])) { + if(!lines) + lines=JSVAL_TO_INT(argv[i]); + else + mode=JSVAL_TO_INT(argv[i]); + } else if(JSVAL_IS_STRING(argv[i])) + js_str = JS_ValueToString(cx, argv[i]); + } + + if(js_str==NULL) + return(JS_FALSE); + + if(!lines) + lines=5; + + sbbs->printtail(JS_GetStringBytes(js_str),lines,mode); + + return(JS_TRUE); +} + +static JSBool +js_menu(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString* str; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return(JS_FALSE); + + sbbs->menu(JS_GetStringBytes(str)); + + return(JS_TRUE); +} + +static JSBool +js_uselect(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + uintN i; + int num=0; + char* title; + char* item; + char* ar_str; + uchar* ar; + sbbs_t* sbbs; + JSString* js_str; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(!argc) { + *rval = INT_TO_JSVAL(sbbs->uselect(0,0,NULL,NULL,NULL)); + return(JS_TRUE); + } + + for(i=0;i<argc;i++) { + if(!JSVAL_IS_STRING(argv[i])) { + num = JSVAL_TO_INT(argv[i]); + continue; + } + if((js_str=JS_ValueToString(cx, argv[i]))==NULL) + return(JS_FALSE); + + if(title==NULL) + title=JS_GetStringBytes(js_str); + else if(item==NULL) + item=JS_GetStringBytes(js_str); + else { + ar_str=JS_GetStringBytes(js_str); + ar=arstr(NULL,ar_str,&sbbs->cfg); + } + } + + *rval = INT_TO_JSVAL(sbbs->uselect(1, num, title, item, ar)); + + return(JS_TRUE); +} + +static JSBool +js_center(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + JSString* str; + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + str = JS_ValueToString(cx, argv[0]); + if (!str) + return(JS_FALSE); + + sbbs->center(JS_GetStringBytes(str)); + + return(JS_TRUE); +} + +static JSBool +js_saveline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->slatr[sbbs->slcnt]=sbbs->latr; + sprintf(sbbs->slbuf[sbbs->slcnt<SAVE_LINES ? sbbs->slcnt++ : sbbs->slcnt] + ,"%.*s",sbbs->lbuflen,sbbs->lbuf); + sbbs->lbuflen=0; + + return(JS_TRUE); +} + +static JSBool +js_restoreline(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->lbuflen=0; + sbbs->attr(sbbs->slatr[--sbbs->slcnt]); + sbbs->rputs(sbbs->slbuf[sbbs->slcnt]); + sbbs->curatr=LIGHTGRAY; + + return(JS_TRUE); +} + +static JSBool +js_ansi_save(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->ANSI_SAVE(); + + return(JS_TRUE); +} + + +static JSBool +js_ansi_restore(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->ANSI_RESTORE(); + + return(JS_TRUE); +} + +static JSBool +js_ansi_gotoxy(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if(argc<2) + return(JS_FALSE); + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->GOTOXY(JSVAL_TO_INT(argv[0]),JSVAL_TO_INT(argv[1])); + + return(JS_TRUE); +} + +static JSBool +js_ansi_up(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(argc) + sbbs->rprintf("\x1b[%dA",JSVAL_TO_INT(argv[0])); + else + sbbs->rputs("\x1b[A"); + + return(JS_TRUE); +} + +static JSBool +js_ansi_down(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(argc) + sbbs->rprintf("\x1b[%dB",JSVAL_TO_INT(argv[0])); + else + sbbs->rputs("\x1b[B"); + + return(JS_TRUE); +} + +static JSBool +js_ansi_right(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(argc) + sbbs->rprintf("\x1b[%dC",JSVAL_TO_INT(argv[0])); + else + sbbs->rputs("\x1b[C"); + + return(JS_TRUE); +} + +static JSBool +js_ansi_left(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + if(argc) + sbbs->rprintf("\x1b[%dD",JSVAL_TO_INT(argv[0])); + else + sbbs->rputs("\x1b[D"); + + return(JS_TRUE); +} + +static JSBool +js_ansi_getlines(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + sbbs_t* sbbs; + + if((sbbs=(sbbs_t*)JS_GetContextPrivate(cx))==NULL) + return(JS_FALSE); + + sbbs->ansi_getlines(); + + return(JS_TRUE); +} + +static JSFunctionSpec js_console_functions[] = { + {"inkey", js_inkey, 0}, // get key - no wait + {"getkey", js_getkey, 0}, // get key - with wait + {"getstr", js_getstr, 0}, // get string + {"getnum", js_getnum, 0}, // get number + {"getkeys", js_getkeys, 1}, // get one of a list of keys + {"gettemplate", js_gettemplate, 1}, // get a string based on template + {"ungetstr", js_ungetstr, 1}, // put a string in the keyboard buffer + {"yesno", js_yesno, 1}, // Y/n question + {"noyes", js_noyes, 1}, // N/y question + {"mnemonics", js_mnemonics, 1}, // mnemonics input + {"clear", js_clear, 0}, // clear screen + {"clearline", js_clearline, 0}, // clear current line + {"crlf", js_crlf, 0}, // output cr/lf + {"attr", js_attr, 1}, // set current text attribute + {"pause", js_pause, 0}, // pause + {"print", js_print, 1}, // display a string (supports ^A and @-codes) + {"write", js_write, 1}, // display a raw string + {"putmsg", js_putmsg, 1}, // display message text (^A, @-codes, etc) with mode + {"center", js_center, 1}, // display a string centered on the screen + {"printfile", js_printfile, 1}, // print a file, optional mode + {"printtail", js_printtail, 2}, // print last x lines of file, optional mode + {"menu", js_menu, 1}, // print menu (auto-extension) + {"uselect", js_uselect, 0}, // user selection menu + {"saveline", js_saveline, 0}, // save last output line + {"restoreline", js_restoreline, 0}, // restore last output line + {"ansi_pushxy", js_ansi_save, 0}, + {"ansi_popxy", js_ansi_restore, 0}, + {"ansi_gotoxy", js_ansi_gotoxy, 2}, + {"ansi_up", js_ansi_up, 0}, + {"ansi_down", js_ansi_down, 0}, + {"ansi_right", js_ansi_right, 0}, + {"ansi_left", js_ansi_left, 0}, + {"ansi_getlines", js_ansi_getlines, 0}, + {0} +}; + + +static JSClass js_console_class = { + "Console" /* name */ + ,0 /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,js_console_get /* getProperty */ + ,js_console_set /* setProperty */ + ,JS_EnumerateStub /* enumerate */ + ,JS_ResolveStub /* resolve */ + ,JS_ConvertStub /* convert */ + ,JS_FinalizeStub /* finalize */ +}; + +JSObject* js_CreateConsoleObject(JSContext* cx, JSObject* parent) +{ + JSObject* obj; + + obj = JS_DefineObject(cx, parent, "console", &js_console_class, NULL, 0); + + if(obj==NULL) + return(NULL); + + if(!JS_DefineProperties(cx, obj, js_console_properties)) + return(NULL); + + if (!JS_DefineFunctions(cx, obj, js_console_functions)) + return(NULL); + + return(obj); +} + +#endif /* JAVSCRIPT */ \ No newline at end of file diff --git a/src/sbbs3/js_file_area.c b/src/sbbs3/js_file_area.c new file mode 100644 index 0000000000000000000000000000000000000000..efcf98aafa1d41bc27994072c922c9871541d28a --- /dev/null +++ b/src/sbbs3/js_file_area.c @@ -0,0 +1,158 @@ +/* js_file_area.c */ + +/* Synchronet JavaScript "File Area" Object */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2001 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include "sbbs.h" + +#ifdef JAVASCRIPT + +static JSClass js_file_area_class = { + "FileArea" /* name */ + ,JSCLASS_HAS_PRIVATE /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,JS_PropertyStub /* getProperty */ + ,JS_PropertyStub /* setProperty */ + ,JS_EnumerateStub /* enumerate */ + ,JS_ResolveStub /* resolve */ + ,JS_ConvertStub /* convert */ + ,JS_FinalizeStub /* finalize */ +}; + +JSObject* DLLCALL js_CreateFileAreaObject(scfg_t* cfg, JSContext* cx, JSObject* parent, user_t* user + ,char* html_index_file) +{ + char vpath[MAX_PATH+1]; + JSObject* areaobj; + JSObject* libobj; + JSObject* dirobj; + JSObject* lib_list; + JSObject* dir_list; + jsval val; + jsint index; + uint l,d; + + areaobj = JS_DefineObject(cx, parent, "file_area", &js_file_area_class, NULL, 0); + + if(areaobj==NULL) + return(NULL); + + /* lib_list[] */ + if((lib_list=JS_NewArrayObject(cx, 0, NULL))==NULL) + return(NULL); + + val=OBJECT_TO_JSVAL(lib_list); + if(!JS_SetProperty(cx, areaobj, "lib_list", &val)) + return(NULL); + + for(l=0;l<cfg->total_libs;l++) { + + if(!chk_ar(cfg,cfg->lib[l]->ar,user)) + continue; + + if((libobj=JS_NewObject(cx, &js_file_area_class, NULL, NULL))==NULL) + return(NULL); + + val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->lib[l]->sname)); + if(!JS_SetProperty(cx, libobj, "name", &val)) + return(NULL); + + val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->lib[l]->lname)); + if(!JS_SetProperty(cx, libobj, "description", &val)) + return(NULL); + + sprintf(vpath,"/%s/%s",cfg->lib[l]->sname,html_index_file); + val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx, vpath)); + if(!JS_SetProperty(cx, libobj, "link", &val)) + return(NULL); + + /* dir_list[] */ + if((dir_list=JS_NewArrayObject(cx, 0, NULL))==NULL) + return(NULL); + + val=OBJECT_TO_JSVAL(dir_list); + if(!JS_SetProperty(cx, libobj, "dir_list", &val)) + return(NULL); + + + for(d=0;d<cfg->total_dirs;d++) { + if(cfg->dir[d]->lib!=l) + continue; + if(!chk_ar(cfg,cfg->dir[d]->ar,user)) + continue; + + if((dirobj=JS_NewObject(cx, &js_file_area_class, NULL, NULL))==NULL) + return(NULL); + + val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->dir[d]->code)); + if(!JS_SetProperty(cx, dirobj, "code", &val)) + return(NULL); + + val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->dir[d]->sname)); + if(!JS_SetProperty(cx, dirobj, "name", &val)) + return(NULL); + + val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->dir[d]->lname)); + if(!JS_SetProperty(cx, dirobj, "description", &val)) + return(NULL); + + sprintf(vpath,"/%s/%s/%s" + ,cfg->lib[l]->sname + ,cfg->dir[d]->code + ,html_index_file); + + val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx, vpath)); + if(!JS_SetProperty(cx, dirobj, "link", &val)) + return(NULL); + + if(!JS_GetArrayLength(cx, dir_list, &index)) + return(NULL); + + val=OBJECT_TO_JSVAL(dirobj); + JS_SetElement(cx, dir_list, index, &val); + } + + if(!JS_GetArrayLength(cx, lib_list, &index)) + return(NULL); + + val=OBJECT_TO_JSVAL(libobj); + JS_SetElement(cx, lib_list, index, &val); + } + + return(areaobj); +} + +#endif /* JAVSCRIPT */ \ No newline at end of file diff --git a/src/sbbs3/js_global.c b/src/sbbs3/js_global.c new file mode 100644 index 0000000000000000000000000000000000000000..793e96ec191c421ae579ed61a74cb801cfb3815f --- /dev/null +++ b/src/sbbs3/js_global.c @@ -0,0 +1,188 @@ +/* js_global.c */ + +/* Synchronet JavaScript "global" object properties/methods for all servers */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2001 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include "sbbs.h" + +#ifdef JAVASCRIPT + +static JSBool +js_load(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char path[MAX_PATH+1]; + uintN i; + JSString* str; + const char* filename; + JSScript* script; + JSBool ok; + jsval result; + scfg_t* cfg; + + if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) + return JS_FALSE; + + for (i = 0; i < argc; i++) { + str = JS_ValueToString(cx, argv[i]); + if (!str) + return JS_FALSE; + argv[i] = STRING_TO_JSVAL(str); + filename = JS_GetStringBytes(str); + errno = 0; + if(!strchr(filename,BACKSLASH)) + sprintf(path,"%s%s",cfg->exec_dir,filename); + else + strcpy(path,filename); + script = JS_CompileFile(cx, obj, path); + if (!script) + ok = JS_FALSE; + else { + ok = JS_ExecuteScript(cx, obj, script, &result); + JS_DestroyScript(cx, script); + } + if (!ok) + return JS_FALSE; + } + + return JS_TRUE; +} + +static JSBool +js_format(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + char* p; + uintN i; + JSString * fmt; + JSString * str; + va_list arglist[64]; + + fmt = JS_ValueToString(cx, argv[0]); + if (!fmt) + return JS_FALSE; + + for (i = 1; i < argc && i<sizeof(arglist)/sizeof(arglist[0]); i++) { + if(JSVAL_IS_STRING(argv[i])) { + str = JS_ValueToString(cx, argv[i]); + if (!str) + return JS_FALSE; + arglist[i-1]=JS_GetStringBytes(str); + } else if(JSVAL_IS_INT(argv[i])) + arglist[i-1]=(char *)JSVAL_TO_INT(argv[i]); + else + arglist[i-1]=NULL; + } + + if((p=JS_vsmprintf(JS_GetStringBytes(fmt),(char*)arglist))==NULL) + return(JS_FALSE); + + str = JS_NewStringCopyZ(cx, p); + JS_smprintf_free(p); + + *rval = STRING_TO_JSVAL(str); + + return JS_TRUE; +} + +static JSBool +js_mswait(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + int val=1; + + if(argc) + val=JSVAL_TO_INT(argv[0]); + mswait(val); + + return(JS_TRUE); +} + +static JSBool +js_beep(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + int freq=500; + int dur=500; + + if(argc) + freq=JSVAL_TO_INT(argv[0]); + if(argc>1) + dur=JSVAL_TO_INT(argv[1]); + + sbbs_beep(freq,dur); + + return(JS_TRUE); +} + +static JSBool +js_exit(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) +{ + return(JS_FALSE); +} + +static JSClass js_global_class ={ + "Global", + JSCLASS_HAS_PRIVATE, /* needed for scfg_t ptr */ + JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub, + JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub + }; + +static JSFunctionSpec js_global_functions[] = { + {"exit", js_exit, 0}, /* stop execution */ + {"load", js_load, 1}, /* Load and execute a javascript file */ + {"format", js_format, 1}, /* return a formatted string (ala printf) */ + {"mswait", js_mswait, 0}, /* millisecond wait/sleep routine */ + {"sleep", js_mswait, 0}, /* millisecond wait/sleep routine */ + {"beep", js_beep, 0}, /* local beep (freq, dur) */ + {0} +}; + +JSObject* DLLCALL js_CreateGlobalObject(scfg_t* cfg, JSContext* cx) +{ + JSObject* glob; + + if((glob = JS_NewObject(cx, &js_global_class, NULL, NULL)) ==NULL) + return(NULL); + + if (!JS_InitStandardClasses(cx, glob)) + return(NULL); + + if (!JS_DefineFunctions(cx, glob, js_global_functions)) + return(NULL); + + if(!JS_SetPrivate(cx, glob, cfg)) /* Store a pointer to scfg_t */ + return(NULL); + + return(glob); +} + +#endif /* JAVSCRIPT */ \ No newline at end of file diff --git a/src/sbbs3/js_system.c b/src/sbbs3/js_system.c new file mode 100644 index 0000000000000000000000000000000000000000..756a819b1b64d54ff4dace6ae3eb803ebe8164a6 --- /dev/null +++ b/src/sbbs3/js_system.c @@ -0,0 +1,623 @@ +/* js_system.c */ + +/* Synchronet JavaScript "system" Object */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2001 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include "sbbs.h" + +#ifdef JAVASCRIPT + +/* System Object Properites */ +enum { + SYS_PROP_NAME + ,SYS_PROP_OP + ,SYS_PROP_ID + ,SYS_PROP_MISC + ,SYS_PROP_PSNAME + ,SYS_PROP_PSNUM + ,SYS_PROP_INETADDR + ,SYS_PROP_LOCATION + ,SYS_PROP_TIMEZONE + ,SYS_PROP_PWDAYS + ,SYS_PROP_DELDAYS + + ,SYS_PROP_LASTUSERON + ,SYS_PROP_FREEDISKSPACE + + ,SYS_PROP_NODES + ,SYS_PROP_LASTNODE + +}; + +static JSBool js_system_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint tiny; + scfg_t* cfg; + + if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) + return JS_FALSE; + + tiny = JSVAL_TO_INT(id); + + switch(tiny) { + case SYS_PROP_NAME: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->sys_name)); + break; + case SYS_PROP_OP: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->sys_op)); + break; + case SYS_PROP_ID: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->sys_id)); + break; + case SYS_PROP_MISC: + *vp = INT_TO_JSVAL(cfg->sys_misc); + break; + case SYS_PROP_PSNAME: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->sys_psname)); + break; + case SYS_PROP_PSNUM: + *vp = INT_TO_JSVAL(cfg->sys_psnum); + break; + case SYS_PROP_INETADDR: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->sys_inetaddr)); + break; + case SYS_PROP_LOCATION: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, cfg->sys_location)); + break; + case SYS_PROP_TIMEZONE: + *vp = INT_TO_JSVAL(cfg->sys_timezone); + break; + case SYS_PROP_NODES: + *vp = INT_TO_JSVAL(cfg->sys_nodes); + break; + case SYS_PROP_LASTNODE: + *vp = INT_TO_JSVAL(cfg->sys_lastnode); + break; + case SYS_PROP_PWDAYS: + *vp = INT_TO_JSVAL(cfg->sys_pwdays); + break; + case SYS_PROP_DELDAYS: + *vp = INT_TO_JSVAL(cfg->sys_deldays); + break; + + case SYS_PROP_LASTUSERON: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, lastuseron)); + break; + case SYS_PROP_FREEDISKSPACE: + *vp = INT_TO_JSVAL(getfreediskspace(cfg->temp_dir)); + break; + + } + + return(TRUE); +} + +static JSBool js_system_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint tiny; + scfg_t* cfg; + + if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) + return JS_FALSE; + + tiny = JSVAL_TO_INT(id); + + switch(tiny) { + case SYS_PROP_MISC: + JS_ValueToInt32(cx, *vp, &cfg->sys_misc); + break; + } + + return(TRUE); +} + + +#define SYSOBJ_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY + +static struct JSPropertySpec js_system_properties[] = { +/* name, tinyid, flags, getter, setter */ + + { "name", SYS_PROP_NAME, SYSOBJ_FLAGS, NULL, NULL }, + { "operator", SYS_PROP_OP, SYSOBJ_FLAGS, NULL, NULL }, + { "qwk_id", SYS_PROP_ID, SYSOBJ_FLAGS, NULL, NULL }, + { "settings", SYS_PROP_MISC, JSPROP_ENUMERATE, NULL, NULL }, + { "psname", SYS_PROP_PSNAME, SYSOBJ_FLAGS, NULL, NULL }, + { "psnum", SYS_PROP_PSNUM, SYSOBJ_FLAGS, NULL, NULL }, + { "inetaddr", SYS_PROP_INETADDR, SYSOBJ_FLAGS, NULL, NULL }, + { "location", SYS_PROP_LOCATION, SYSOBJ_FLAGS, NULL, NULL }, + { "timezone", SYS_PROP_TIMEZONE, SYSOBJ_FLAGS, NULL, NULL }, + { "pwdays", SYS_PROP_PWDAYS, SYSOBJ_FLAGS, NULL, NULL }, + { "deldays", SYS_PROP_DELDAYS, SYSOBJ_FLAGS, NULL, NULL }, + + { "nodes", SYS_PROP_NODES, SYSOBJ_FLAGS, NULL, NULL }, + { "lastnode", SYS_PROP_LASTNODE, SYSOBJ_FLAGS, NULL, NULL }, + + { "freediskspace", SYS_PROP_FREEDISKSPACE, SYSOBJ_FLAGS, NULL, NULL }, + {0} +}; + +static JSClass js_system_class = { + "System" /* name */ + ,JSCLASS_HAS_PRIVATE /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,js_system_get /* getProperty */ + ,js_system_set /* setProperty */ + ,JS_EnumerateStub /* enumerate */ + ,JS_ResolveStub /* resolve */ + ,JS_ConvertStub /* convert */ + ,JS_FinalizeStub /* finalize */ +}; + +/* System Stats Propertiess */ +enum { + SYSSTAT_PROP_LOGONS + ,SYSSTAT_PROP_LTODAY + ,SYSSTAT_PROP_TIMEON + ,SYSSTAT_PROP_TTODAY + ,SYSSTAT_PROP_ULS + ,SYSSTAT_PROP_ULB + ,SYSSTAT_PROP_DLS + ,SYSSTAT_PROP_DLB + ,SYSSTAT_PROP_PTODAY + ,SYSSTAT_PROP_ETODAY + ,SYSSTAT_PROP_FTODAY + ,SYSSTAT_PROP_NUSERS + + ,SYSSTAT_PROP_TOTALUSERS + ,SYSSTAT_PROP_TOTALFILES + ,SYSSTAT_PROP_TOTALMSGS + ,SYSSTAT_PROP_TOTALMAIL + ,SYSSTAT_PROP_FEEDBACK + +}; + +static JSBool js_sysstats_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint tiny; + scfg_t* cfg; + stats_t stats; + uint i; + ulong l; + + if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL) + return JS_FALSE; + + tiny = JSVAL_TO_INT(id); + + if(!getstats(cfg, 0, &stats)) + return(FALSE); + + switch(tiny) { + case SYSSTAT_PROP_LOGONS: + *vp = INT_TO_JSVAL(stats.logons); + break; + case SYSSTAT_PROP_LTODAY: + *vp = INT_TO_JSVAL(stats.ltoday); + break; + case SYSSTAT_PROP_TIMEON: + *vp = INT_TO_JSVAL(stats.timeon); + break; + case SYSSTAT_PROP_TTODAY: + *vp = INT_TO_JSVAL(stats.ttoday); + break; + case SYSSTAT_PROP_ULS: + *vp = INT_TO_JSVAL(stats.uls); + break; + case SYSSTAT_PROP_ULB: + *vp = INT_TO_JSVAL(stats.ulb); + break; + case SYSSTAT_PROP_DLS: + *vp = INT_TO_JSVAL(stats.dls); + break; + case SYSSTAT_PROP_DLB: + *vp = INT_TO_JSVAL(stats.dlb); + break; + case SYSSTAT_PROP_PTODAY: + *vp = INT_TO_JSVAL(stats.ptoday); + break; + case SYSSTAT_PROP_ETODAY: + *vp = INT_TO_JSVAL(stats.etoday); + break; + case SYSSTAT_PROP_FTODAY: + *vp = INT_TO_JSVAL(stats.ftoday); + break; + case SYSSTAT_PROP_NUSERS: + *vp = INT_TO_JSVAL(stats.nusers); + break; + + case SYSSTAT_PROP_TOTALUSERS: + *vp = INT_TO_JSVAL(lastuser(cfg)); + break; + case SYSSTAT_PROP_TOTALMSGS: + l=0; + for(i=0;i<cfg->total_subs;i++) + l+=getposts(cfg,i); + *vp = INT_TO_JSVAL(l); + break; + case SYSSTAT_PROP_TOTALFILES: + l=0; + for(i=0;i<cfg->total_dirs;i++) + l+=getfiles(cfg,i); + *vp = INT_TO_JSVAL(l); + break; + case SYSSTAT_PROP_TOTALMAIL: + *vp = INT_TO_JSVAL(getmail(cfg, 0,0)); + break; + case SYSSTAT_PROP_FEEDBACK: + *vp = INT_TO_JSVAL(getmail(cfg, 1,0)); + break; + } + + return(TRUE); +} + +#define SYSSTAT_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY + +static struct JSPropertySpec js_sysstats_properties[] = { +/* name, tinyid, flags, getter, setter */ + + { "total_logons", SYSSTAT_PROP_LOGONS, SYSSTAT_FLAGS, NULL, NULL }, + { "logons_today", SYSSTAT_PROP_LTODAY, SYSSTAT_FLAGS, NULL, NULL }, + { "total_timeon", SYSSTAT_PROP_TIMEON, SYSSTAT_FLAGS, NULL, NULL }, + { "timeon_today", SYSSTAT_PROP_TTODAY, SYSSTAT_FLAGS, NULL, NULL }, + { "total_files", SYSSTAT_PROP_TOTALFILES, SYSSTAT_FLAGS, NULL, NULL }, + { "files_uploaded_today", SYSSTAT_PROP_ULS, SYSSTAT_FLAGS, NULL, NULL }, + { "bytes_uploaded_today", SYSSTAT_PROP_ULB, SYSSTAT_FLAGS, NULL, NULL }, + { "files_downloaded_today", SYSSTAT_PROP_DLS, SYSSTAT_FLAGS, NULL, NULL }, + { "bytes_downloaded_today", SYSSTAT_PROP_DLB, SYSSTAT_FLAGS, NULL, NULL }, + { "total_messages", SYSSTAT_PROP_TOTALMSGS, SYSSTAT_FLAGS, NULL, NULL }, + { "messages_posted_today", SYSSTAT_PROP_PTODAY, SYSSTAT_FLAGS, NULL, NULL }, + { "total_email", SYSSTAT_PROP_TOTALMAIL, SYSSTAT_FLAGS, NULL, NULL }, + { "email_sent_today", SYSSTAT_PROP_ETODAY, SYSSTAT_FLAGS, NULL, NULL }, + { "total_feedback", SYSSTAT_PROP_FEEDBACK, SYSSTAT_FLAGS, NULL, NULL }, + { "feedback_sent_today", SYSSTAT_PROP_FTODAY, SYSSTAT_FLAGS, NULL, NULL }, + { "total_users", SYSSTAT_PROP_TOTALUSERS, SYSSTAT_FLAGS, NULL, NULL }, + { "new_users_today", SYSSTAT_PROP_NUSERS, SYSSTAT_FLAGS, NULL, NULL }, + {0} +}; + +static JSClass js_sysstats_class = { + "Stats" /* name */ + ,JSCLASS_HAS_PRIVATE /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,js_sysstats_get /* getProperty */ + ,JS_PropertyStub /* setProperty */ + ,JS_EnumerateStub /* enumerate */ + ,JS_ResolveStub /* resolve */ + ,JS_ConvertStub /* convert */ + ,JS_FinalizeStub /* finalize */ +}; + +/* node properties */ +enum { + /* raw node_t fields */ + NODE_PROP_STATUS + ,NODE_PROP_ERRORS + ,NODE_PROP_ACTION + ,NODE_PROP_USERON + ,NODE_PROP_CONNECTION + ,NODE_PROP_MISC + ,NODE_PROP_AUX + ,NODE_PROP_EXTAUX + + /* convenience strings */ + ,NODE_PROP_USERON_NAME +}; + +static JSBool js_node_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + char str[128]; + uint node_num; + jsint tiny; + node_t node; + scfg_t* cfg; + JSObject* sysobj; + JSObject* node_list; + + tiny = JSVAL_TO_INT(id); + + if((node_list=JS_GetParent(cx, obj))==NULL) + return(JS_FALSE); + + if((sysobj=JS_GetParent(cx, node_list))==NULL) + return(JS_FALSE); + + if((cfg=(scfg_t*)JS_GetPrivate(cx,sysobj))==NULL) + return(JS_FALSE); + + node_num=(uint)JS_GetPrivate(cx,obj)>>1; + + memset(&node,0,sizeof(node)); + if(getnodedat(cfg, node_num, &node, 0)) { + *vp = INT_TO_JSVAL(0); + return(JS_TRUE); + } + + switch(tiny) { + case NODE_PROP_STATUS: + *vp = INT_TO_JSVAL((int)node.status); + break; + case NODE_PROP_ERRORS: + *vp = INT_TO_JSVAL((int)node.errors); + break; + case NODE_PROP_ACTION: + *vp = INT_TO_JSVAL((int)node.action); + break; + case NODE_PROP_USERON: + *vp = INT_TO_JSVAL((int)node.useron); + break; + case NODE_PROP_CONNECTION: + *vp = INT_TO_JSVAL((int)node.connection); + break; + case NODE_PROP_MISC: + *vp = INT_TO_JSVAL((int)node.misc); + break; + case NODE_PROP_AUX: + *vp = INT_TO_JSVAL((int)node.aux); + break; + case NODE_PROP_EXTAUX: + *vp = INT_TO_JSVAL((int)node.extaux); + break; + + case NODE_PROP_USERON_NAME: + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,username(cfg,node.useron,str))); + break; + + } + return(JS_TRUE); +} + +static JSBool js_node_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + uint node_num; + uint val; + jsint tiny; + node_t node; + scfg_t* cfg; + JSObject* sysobj; + JSObject* node_list; + + if((node_list=JS_GetParent(cx, obj))==NULL) + return(JS_FALSE); + + if((sysobj=JS_GetParent(cx, node_list))==NULL) + return(JS_FALSE); + + if((cfg=(scfg_t*)JS_GetPrivate(cx,sysobj))==NULL) + return(JS_FALSE); + + node_num=(uint)JS_GetPrivate(cx,obj)>>1; + + memset(&node,0,sizeof(node)); + if(getnodedat(cfg, node_num, &node, 1)) + return(JS_TRUE); + + JS_ValueToInt32(cx, *vp, &val); + + tiny = JSVAL_TO_INT(id); + + switch(tiny) { + case NODE_PROP_STATUS: + node.status=val; + break; + case NODE_PROP_ERRORS: + node.errors=val; + break; + case NODE_PROP_ACTION: + node.action=val; + break; + case NODE_PROP_USERON: + node.useron=val; + break; + case NODE_PROP_CONNECTION: + node.connection=val; + break; + case NODE_PROP_MISC: + node.misc=val; + break; + case NODE_PROP_AUX: + node.aux=val; + break; + case NODE_PROP_EXTAUX: + node.extaux=val; + break; + } + putnodedat(cfg,node_num,&node); + + return(JS_TRUE); +} + +static struct JSPropertySpec js_node_properties[] = { +/* name, tinyid, flags, getter, setter */ + +/* raw node_t fields */ + { "status", NODE_PROP_STATUS, JSPROP_ENUMERATE, NULL, NULL }, + { "errors", NODE_PROP_ERRORS, JSPROP_ENUMERATE, NULL, NULL }, + { "action", NODE_PROP_ACTION, JSPROP_ENUMERATE, NULL, NULL }, + { "useron", NODE_PROP_USERON, JSPROP_ENUMERATE, NULL, NULL }, + { "connection", NODE_PROP_CONNECTION, JSPROP_ENUMERATE, NULL, NULL }, + { "misc", NODE_PROP_MISC, JSPROP_ENUMERATE, NULL, NULL }, + { "aux", NODE_PROP_AUX, JSPROP_ENUMERATE, NULL, NULL }, + { "extaux", NODE_PROP_EXTAUX, JSPROP_ENUMERATE, NULL, NULL }, + +/* convenience strings */ + { "useron_name", NODE_PROP_USERON_NAME, JSPROP_ENUMERATE|JSPROP_READONLY, NULL, NULL }, + + {0} +}; + +static JSClass js_node_class = { + "Node" /* name */ + ,JSCLASS_HAS_PRIVATE /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,js_node_get /* getProperty */ + ,js_node_set /* setProperty */ + ,JS_EnumerateStub /* enumerate */ + ,JS_ResolveStub /* resolve */ + ,JS_ConvertStub /* convert */ + ,JS_FinalizeStub /* finalize */ +}; + +extern const char* beta_version; + +JSObject* DLLCALL js_CreateSystemObject(scfg_t* cfg, JSContext* cx, JSObject* parent) +{ + char str[256]; + uint i; + jsval val; + JSObject* sysobj; + JSObject* statsobj; + JSObject* nodeobj; + JSObject* node_list; + + sysobj = JS_DefineObject(cx, parent, "system", &js_system_class, NULL, 0); + + if(sysobj==NULL) + return(NULL); + + if(!JS_SetPrivate(cx, sysobj, cfg)) /* Store a pointer to scfg_t */ + return(NULL); + + /****************************/ + /* static string properties */ + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, VERSION)); + if(!JS_SetProperty(cx, sysobj, "version", &val)) + return(NULL); + + sprintf(str,"%c",REVISION); + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str)); + if(!JS_SetProperty(cx, sysobj, "revision", &val)) + return(NULL); + + sprintf(str,"%s%c%s",VERSION,REVISION,beta_version); + truncsp(str); +#if defined(_DEBUG) + strcat(str," Debug"); +#endif + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str)); + if(!JS_SetProperty(cx, sysobj, "full_version", &val)) + return(NULL); + + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, VERSION_NOTICE)); + if(!JS_SetProperty(cx, sysobj, "version_notice", &val)) + return(NULL); + + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, PLATFORM_DESC)); + if(!JS_SetProperty(cx, sysobj, "platform", &val)) + return(NULL); + + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, socklib_version(str))); + if(!JS_SetProperty(cx, sysobj, "socket_lib", &val)) + return(NULL); + + sprintf(str,"SMBLIB %s",smb_lib_ver()); + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str)); + if(!JS_SetProperty(cx, sysobj, "msgbase_lib", &val)) + return(NULL); + + COMPILER_DESC(str); + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str)); + if(!JS_SetProperty(cx, sysobj, "compiled_with", &val)) + return(NULL); + + sprintf(str,"%s %.5s",__DATE__,__TIME__); + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, str)); + if(!JS_SetProperty(cx, sysobj, "compiled_when", &val)) + return(NULL); + + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, COPYRIGHT_NOTICE)); + if(!JS_SetProperty(cx, sysobj, "copyright", &val)) + return(NULL); + + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx + ,(char *)JS_GetImplementationVersion())); + if(!JS_SetProperty(cx, sysobj, "js_version", &val)) + return(NULL); + + val = STRING_TO_JSVAL(JS_NewStringCopyZ(cx,os_version(str))); + if(!JS_SetProperty(cx, sysobj, "os_version", &val)) + return(NULL); + + /***********************/ + + if(!JS_DefineProperties(cx, sysobj, js_system_properties)) + return(NULL); + + statsobj = JS_DefineObject(cx, sysobj, "stats", &js_sysstats_class, NULL, 0); + + if(statsobj==NULL) + return(NULL); + + JS_SetPrivate(cx, statsobj, cfg); /* Store a pointer to scfg_t */ + + if(!JS_DefineProperties(cx, statsobj, js_sysstats_properties)) + return(NULL); + + /* node_list property */ + + if((node_list=JS_NewArrayObject(cx, 0, NULL))==NULL) + return(NULL); + + for(i=0;i<cfg->sys_nodes && i<cfg->sys_lastnode;i++) { + + nodeobj = JS_NewObject(cx, &js_node_class, NULL, node_list); + + if(nodeobj==NULL) + return(NULL); + + /* Store node number */ + /* We have to shift it to make it look like a pointer to JS. :-( */ + if(!JS_SetPrivate(cx, nodeobj, (char*)((i+1)<<1))) + return(NULL); + + if(!JS_DefineProperties(cx, nodeobj, js_node_properties)) + return(NULL); + + val=OBJECT_TO_JSVAL(nodeobj); + if(!JS_SetElement(cx, node_list, i, &val)) + return(NULL); + } + + if(!JS_DefineProperty(cx, sysobj, "node_list", OBJECT_TO_JSVAL(node_list) + , NULL, NULL, 0)) + return(NULL); + + return(sysobj); +} + +#endif /* JAVSCRIPT */ \ No newline at end of file diff --git a/src/sbbs3/js_user.c b/src/sbbs3/js_user.c new file mode 100644 index 0000000000000000000000000000000000000000..8b911acf70db9e87dc8a9aa92bf1cb6c9bc578cd --- /dev/null +++ b/src/sbbs3/js_user.c @@ -0,0 +1,478 @@ +/* userobj.c */ + +/* Synchronet JavaScript "User" Object */ + +/* $Id$ */ + +/**************************************************************************** + * @format.tab-size 4 (Plain Text/Source Code File Header) * + * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * + * * + * Copyright 2001 Rob Swindell - http://www.synchro.net/copyright.html * + * * + * This program is free software; you can redistribute it and/or * + * modify it under the terms of the GNU General Public License * + * as published by the Free Software Foundation; either version 2 * + * of the License, or (at your option) any later version. * + * See the GNU General Public License for more details: gpl.txt or * + * http://www.fsf.org/copyleft/gpl.html * + * * + * Anonymous FTP access to the most recent released source is available at * + * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * + * * + * Anonymous CVS access to the development source and modification history * + * is available at cvs.synchro.net:/cvsroot/sbbs, example: * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs login * + * (just hit return, no password is necessary) * + * cvs -d :pserver:anonymous@cvs.synchro.net:/cvsroot/sbbs checkout src * + * * + * For Synchronet coding style and modification guidelines, see * + * http://www.synchro.net/source.html * + * * + * You are encouraged to submit any modifications (preferably in Unix diff * + * format) via e-mail to mods@synchro.net * + * * + * Note: If this box doesn't appear square, then you need to fix your tabs. * + ****************************************************************************/ + +#include "sbbs.h" + +#ifdef JAVASCRIPT + +/* User Object Properites */ +enum { + USER_PROP_ALIAS + ,USER_PROP_NAME + ,USER_PROP_HANDLE + ,USER_PROP_NOTE + ,USER_PROP_COMP + ,USER_PROP_COMMENT + ,USER_PROP_NETMAIL + ,USER_PROP_ADDRESS + ,USER_PROP_LOCATION + ,USER_PROP_ZIPCODE + ,USER_PROP_PASS + ,USER_PROP_PHONE + ,USER_PROP_BIRTH + ,USER_PROP_MODEM + ,USER_PROP_LASTON + ,USER_PROP_FIRSTON + ,USER_PROP_EXPIRE + ,USER_PROP_PWMOD + ,USER_PROP_LOGONS + ,USER_PROP_LTODAY + ,USER_PROP_TIMEON + ,USER_PROP_TEXTRA + ,USER_PROP_TTODAY + ,USER_PROP_TLAST + ,USER_PROP_POSTS + ,USER_PROP_EMAILS + ,USER_PROP_FBACKS + ,USER_PROP_ETODAY + ,USER_PROP_PTODAY + ,USER_PROP_ULB + ,USER_PROP_ULS + ,USER_PROP_DLB + ,USER_PROP_DLS + ,USER_PROP_CDT + ,USER_PROP_MIN + ,USER_PROP_LEVEL + ,USER_PROP_FLAGS1 + ,USER_PROP_FLAGS2 + ,USER_PROP_FLAGS3 + ,USER_PROP_FLAGS4 + ,USER_PROP_EXEMPT + ,USER_PROP_REST + ,USER_PROP_ROWS + ,USER_PROP_SEX + ,USER_PROP_MISC + ,USER_PROP_LEECH + ,USER_PROP_CURSUB + ,USER_PROP_CURDIR + ,USER_PROP_FREECDT + ,USER_PROP_XEDIT + ,USER_PROP_SHELL + ,USER_PROP_QWK + ,USER_PROP_TMPEXT + ,USER_PROP_CHAT + ,USER_PROP_NS_TIME + ,USER_PROP_PROT +}; + +static JSBool js_user_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + jsint tiny; + user_t* user; + + if((user=(user_t*)JS_GetPrivate(cx,obj))==NULL) + return JS_FALSE; + + tiny = JSVAL_TO_INT(id); + + switch(tiny) { + case USER_PROP_MISC: + JS_ValueToInt32(cx, *vp, &user->misc); + break; + } + + return(TRUE); +} + +static JSBool js_user_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + char* p=NULL; + char tmp[128]; + ulong val; + jsint tiny; + user_t* user; + + if((user=(user_t*)JS_GetPrivate(cx,obj))==NULL) + return JS_FALSE; + + tiny = JSVAL_TO_INT(id); + + switch(tiny) { + case USER_PROP_ALIAS: + p=user->alias; + break; + case USER_PROP_NAME: + p=user->name; + break; + case USER_PROP_HANDLE: + p=user->handle; + break; + case USER_PROP_NOTE: + p=user->note; + break; + case USER_PROP_COMP: + p=user->comp; + break; + case USER_PROP_COMMENT: + p=user->comment; + break; + case USER_PROP_NETMAIL: + p=user->netmail; + break; + case USER_PROP_ADDRESS: + p=user->address; + break; + case USER_PROP_LOCATION: + p=user->location; + break; + case USER_PROP_ZIPCODE: + p=user->zipcode; + break; + case USER_PROP_PASS: + p=user->pass; + break; + case USER_PROP_PHONE: + p=user->phone; + break; + case USER_PROP_BIRTH: + p=user->birth; + break; + case USER_PROP_MODEM: + p=user->modem; + break; + case USER_PROP_LASTON: + val=user->laston; + break; + case USER_PROP_FIRSTON: + val=user->firston; + break; + case USER_PROP_EXPIRE: + val=user->expire; + break; + case USER_PROP_PWMOD: + val=user->pwmod; + break; + case USER_PROP_LOGONS: + val=user->logons; + break; + case USER_PROP_LTODAY: + val=user->ltoday; + break; + case USER_PROP_TIMEON: + val=user->timeon; + break; + case USER_PROP_TEXTRA: + val=user->textra; + break; + case USER_PROP_TTODAY: + val=user->ttoday; + break; + case USER_PROP_TLAST: + val=user->tlast; + break; + case USER_PROP_POSTS: + val=user->posts; + break; + case USER_PROP_EMAILS: + val=user->emails; + break; + case USER_PROP_FBACKS: + val=user->fbacks; + break; + case USER_PROP_ETODAY: + val=user->etoday; + break; + case USER_PROP_PTODAY: + val=user->ptoday; + break; + case USER_PROP_ULB: + val=user->ulb; + break; + case USER_PROP_ULS: + val=user->uls; + break; + case USER_PROP_DLB: + val=user->dlb; + break; + case USER_PROP_DLS: + val=user->dls; + break; + case USER_PROP_CDT: + val=user->cdt; + break; + case USER_PROP_MIN: + val=user->min; + break; + case USER_PROP_LEVEL: + val=user->level; + break; + case USER_PROP_FLAGS1: + val=user->flags1; + break; + case USER_PROP_FLAGS2: + val=user->flags2; + break; + case USER_PROP_FLAGS3: + val=user->flags3; + break; + case USER_PROP_FLAGS4: + val=user->flags4; + break; + case USER_PROP_EXEMPT: + val=user->exempt; + break; + case USER_PROP_REST: + val=user->rest; + break; + case USER_PROP_ROWS: + val=user->rows; + break; + case USER_PROP_SEX: + sprintf(tmp,"%c",user->sex); + p=tmp; + break; + case USER_PROP_MISC: + val=user->misc; + break; + case USER_PROP_LEECH: + val=user->leech; + break; + case USER_PROP_CURSUB: + p=user->cursub; + break; + case USER_PROP_CURDIR: + p=user->curdir; + break; + case USER_PROP_FREECDT: + val=user->freecdt; + break; + case USER_PROP_XEDIT: + val=user->xedit; + break; + case USER_PROP_SHELL: + val=user->shell; + break; + case USER_PROP_QWK: + val=user->qwk; + break; + case USER_PROP_TMPEXT: + p=user->tmpext; + break; + case USER_PROP_CHAT: + val=user->laston; + break; + case USER_PROP_NS_TIME: + val=user->laston; + break; + case USER_PROP_PROT: + sprintf(tmp,"%c",user->prot); + p=tmp; + break; + default: + return(TRUE); + } + if(p!=NULL) + *vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, p)); + else + *vp = INT_TO_JSVAL(val); + + return(TRUE); +} + +#define USEROBJ_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY + +static struct JSPropertySpec js_user_properties[] = { +/* name ,tinyid ,flags, getter, setter */ + + { "alias" ,USER_PROP_ALIAS ,USEROBJ_FLAGS, NULL,NULL}, + { "name" ,USER_PROP_NAME ,USEROBJ_FLAGS, NULL,NULL}, + { "handle" ,USER_PROP_HANDLE ,USEROBJ_FLAGS, NULL,NULL}, + { "note" ,USER_PROP_NOTE ,USEROBJ_FLAGS, NULL,NULL}, + { "ip_address" ,USER_PROP_NOTE ,USEROBJ_FLAGS, NULL,NULL}, + { "computer" ,USER_PROP_COMP ,USEROBJ_FLAGS, NULL,NULL}, + { "host_name" ,USER_PROP_COMP ,USEROBJ_FLAGS, NULL,NULL}, + { "comment" ,USER_PROP_COMMENT ,USEROBJ_FLAGS, NULL,NULL}, + { "netmail" ,USER_PROP_NETMAIL ,USEROBJ_FLAGS, NULL,NULL}, + { "email" ,USER_PROP_NETMAIL ,USEROBJ_FLAGS, NULL,NULL}, + { "address" ,USER_PROP_ADDRESS ,USEROBJ_FLAGS, NULL,NULL}, + { "location" ,USER_PROP_LOCATION ,USEROBJ_FLAGS, NULL,NULL}, + { "zipcode" ,USER_PROP_ZIPCODE ,USEROBJ_FLAGS, NULL,NULL}, + { "phone" ,USER_PROP_PHONE ,USEROBJ_FLAGS, NULL,NULL}, + { "birthdate" ,USER_PROP_BIRTH ,USEROBJ_FLAGS, NULL,NULL}, + { "modem" ,USER_PROP_MODEM ,USEROBJ_FLAGS, NULL,NULL}, + { "connection" ,USER_PROP_MODEM ,USEROBJ_FLAGS, NULL,NULL}, + { "screen_rows" ,USER_PROP_ROWS ,USEROBJ_FLAGS, NULL,NULL}, + { "gender" ,USER_PROP_SEX ,USEROBJ_FLAGS, NULL,NULL}, + { "cursub" ,USER_PROP_CURSUB ,USEROBJ_FLAGS, NULL,NULL}, + { "curdir" ,USER_PROP_CURDIR ,USEROBJ_FLAGS, NULL,NULL}, + { "editor" ,USER_PROP_XEDIT ,USEROBJ_FLAGS, NULL,NULL}, + { "command_shell" ,USER_PROP_SHELL ,USEROBJ_FLAGS, NULL,NULL}, + { "settings" ,USER_PROP_MISC ,USEROBJ_FLAGS, NULL,NULL}, + { "qwk_settings" ,USER_PROP_QWK ,USEROBJ_FLAGS, NULL,NULL}, + { "chat_settings" ,USER_PROP_CHAT ,USEROBJ_FLAGS, NULL,NULL}, + { "temp_file_ext" ,USER_PROP_TMPEXT ,USEROBJ_FLAGS, NULL,NULL}, + { "newscan_date" ,USER_PROP_NS_TIME ,USEROBJ_FLAGS, NULL,NULL}, + { "download_protocol" ,USER_PROP_PROT ,USEROBJ_FLAGS, NULL,NULL}, + {0} +}; + +/* user.stats: These should be READ ONLY by nature */ +static struct JSPropertySpec js_user_stats_properties[] = { +/* name ,tinyid ,flags, getter, setter */ + + { "laston_date" ,USER_PROP_LASTON ,USEROBJ_FLAGS, NULL,NULL}, + { "firston_date" ,USER_PROP_FIRSTON ,USEROBJ_FLAGS, NULL,NULL}, + { "total_logons" ,USER_PROP_LOGONS ,USEROBJ_FLAGS, NULL,NULL}, + { "logons_today" ,USER_PROP_LTODAY ,USEROBJ_FLAGS, NULL,NULL}, + { "total_timeon" ,USER_PROP_TIMEON ,USEROBJ_FLAGS, NULL,NULL}, + { "timeon_today" ,USER_PROP_TTODAY ,USEROBJ_FLAGS, NULL,NULL}, + { "timeon_last_logon" ,USER_PROP_TLAST ,USEROBJ_FLAGS, NULL,NULL}, + { "total_posts" ,USER_PROP_POSTS ,USEROBJ_FLAGS, NULL,NULL}, + { "total_emails" ,USER_PROP_EMAILS ,USEROBJ_FLAGS, NULL,NULL}, + { "total_feedbacks" ,USER_PROP_FBACKS ,USEROBJ_FLAGS, NULL,NULL}, + { "email_today" ,USER_PROP_ETODAY ,USEROBJ_FLAGS, NULL,NULL}, + { "posts_today" ,USER_PROP_PTODAY ,USEROBJ_FLAGS, NULL,NULL}, + { "bytes_uploaded" ,USER_PROP_ULB ,USEROBJ_FLAGS, NULL,NULL}, + { "files_uploaded" ,USER_PROP_ULS ,USEROBJ_FLAGS, NULL,NULL}, + { "bytes_downloaded" ,USER_PROP_DLB ,USEROBJ_FLAGS, NULL,NULL}, + { "files_downloaded" ,USER_PROP_DLS ,USEROBJ_FLAGS, NULL,NULL}, + { "leech_attempts" ,USER_PROP_LEECH ,USEROBJ_FLAGS, NULL,NULL}, + {0} +}; + +/* user.security */ +static struct JSPropertySpec js_user_security_properties[] = { +/* name ,tinyid ,flags, getter, setter */ + + { "password" ,USER_PROP_PASS ,USEROBJ_FLAGS, NULL,NULL}, + { "password_date" ,USER_PROP_PWMOD ,USEROBJ_FLAGS, NULL,NULL}, + { "level" ,USER_PROP_LEVEL ,USEROBJ_FLAGS, NULL,NULL}, + { "flags1" ,USER_PROP_FLAGS1 ,USEROBJ_FLAGS, NULL,NULL}, + { "flags2" ,USER_PROP_FLAGS2 ,USEROBJ_FLAGS, NULL,NULL}, + { "flags3" ,USER_PROP_FLAGS3 ,USEROBJ_FLAGS, NULL,NULL}, + { "flags4" ,USER_PROP_FLAGS4 ,USEROBJ_FLAGS, NULL,NULL}, + { "exemptions" ,USER_PROP_EXEMPT ,USEROBJ_FLAGS, NULL,NULL}, + { "restrictions" ,USER_PROP_REST ,USEROBJ_FLAGS, NULL,NULL}, + { "credits" ,USER_PROP_CDT ,USEROBJ_FLAGS, NULL,NULL}, + { "free_credits" ,USER_PROP_FREECDT ,USEROBJ_FLAGS, NULL,NULL}, + { "minutes" ,USER_PROP_MIN ,USEROBJ_FLAGS, NULL,NULL}, + { "extra_time" ,USER_PROP_TEXTRA ,USEROBJ_FLAGS, NULL,NULL}, + { "expiration_date" ,USER_PROP_EXPIRE ,USEROBJ_FLAGS, NULL,NULL}, + {0} +}; + +static JSClass js_user_class = { + "User" /* name */ + ,JSCLASS_HAS_PRIVATE /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,js_user_get /* getProperty */ + ,js_user_set /* setProperty */ + ,JS_EnumerateStub /* enumerate */ + ,JS_ResolveStub /* resolve */ + ,JS_ConvertStub /* convert */ + ,JS_FinalizeStub /* finalize */ +}; + +static JSClass js_user_stats_class = { + "UserStats" /* name */ + ,JSCLASS_HAS_PRIVATE /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,js_user_get /* getProperty */ + ,js_user_set /* setProperty */ + ,JS_EnumerateStub /* enumerate */ + ,JS_ResolveStub /* resolve */ + ,JS_ConvertStub /* convert */ + ,JS_FinalizeStub /* finalize */ +}; + + +static JSClass js_user_security_class = { + "UserSecurity" /* name */ + ,JSCLASS_HAS_PRIVATE /* flags */ + ,JS_PropertyStub /* addProperty */ + ,JS_PropertyStub /* delProperty */ + ,js_user_get /* getProperty */ + ,js_user_set /* setProperty */ + ,JS_EnumerateStub /* enumerate */ + ,JS_ResolveStub /* resolve */ + ,JS_ConvertStub /* convert */ + ,JS_FinalizeStub /* finalize */ +}; + +JSObject* DLLCALL js_CreateUserObject(scfg_t* cfg, JSContext* cx, JSObject* parent, char* name, user_t* user) +{ + JSObject* userobj; + JSObject* statsobj; + JSObject* securityobj; + + userobj = JS_DefineObject(cx, parent, name, &js_user_class, NULL, 0); + + if(userobj==NULL) + return(NULL); + + JS_SetPrivate(cx, userobj, user); /* Store a pointer to user_t */ + + JS_DefineProperties(cx, userobj, js_user_properties); + + /* user.stats */ + statsobj = JS_DefineObject(cx, userobj, "stats" + ,&js_user_stats_class, NULL, 0); + + if(statsobj==NULL) + return(NULL); + + JS_SetPrivate(cx, statsobj, user); /* Store a pointer to user_t */ + + JS_DefineProperties(cx, statsobj, js_user_stats_properties); + + /* user.security */ + securityobj = JS_DefineObject(cx, userobj, "security" + ,&js_user_security_class, NULL, 0); + + if(securityobj==NULL) + return(NULL); + + JS_SetPrivate(cx, securityobj, user); /* Store a pointer to user_t */ + + JS_DefineProperties(cx, securityobj, js_user_security_properties); + + return(userobj); +} + +#endif /* JAVSCRIPT */ \ No newline at end of file