Annotation of sbbs/src/sbbs3/js_system.c, revision 1.1.1.2

1.1       root        1: /* js_system.c */
                      2: 
                      3: /* Synchronet JavaScript "system" Object */
                      4: 
1.1.1.2 ! root        5: /* $Id: js_system.c,v 1.135 2011/08/25 19:23:31 rswindell Exp $ */
1.1       root        6: 
                      7: /****************************************************************************
                      8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                     10:  *                                                                                                                                                     *
1.1.1.2 ! root       11:  * Copyright 2011 Rob Swindell - http://www.synchro.net/copyright.html         *
1.1       root       12:  *                                                                                                                                                     *
                     13:  * This program is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU General Public License                         *
                     15:  * as published by the Free Software Foundation; either version 2                      *
                     16:  * of the License, or (at your option) any later version.                                      *
                     17:  * See the GNU General Public License for more details: gpl.txt or                     *
                     18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
                     19:  *                                                                                                                                                     *
                     20:  * Anonymous FTP access to the most recent released source is available at     *
                     21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     22:  *                                                                                                                                                     *
                     23:  * Anonymous CVS access to the development source and modification history     *
                     24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     26:  *     (just hit return, no password is necessary)                                                     *
                     27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     28:  *                                                                                                                                                     *
                     29:  * For Synchronet coding style and modification guidelines, see                                *
                     30:  * http://www.synchro.net/source.html                                                                          *
                     31:  *                                                                                                                                                     *
                     32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     33:  * format) via e-mail to [email protected]                                                                      *
                     34:  *                                                                                                                                                     *
                     35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     36:  ****************************************************************************/
                     37: 
                     38: #include "sbbs.h"
1.1.1.2 ! root       39: #include "js_request.h"
1.1       root       40: 
                     41: #ifdef JAVASCRIPT
                     42: 
                     43: /* System Object Properites */
                     44: enum {
                     45:         SYS_PROP_NAME
                     46:        ,SYS_PROP_OP
                     47:        ,SYS_PROP_ID
                     48:        ,SYS_PROP_MISC
                     49:        ,SYS_PROP_PSNAME
                     50:        ,SYS_PROP_PSNUM
                     51:        ,SYS_PROP_INETADDR
                     52:        ,SYS_PROP_LOCATION
                     53:        ,SYS_PROP_TIMEZONE
                     54:        ,SYS_PROP_PWDAYS
                     55:        ,SYS_PROP_DELDAYS
                     56: 
                     57:        ,SYS_PROP_LASTUSER
                     58:        ,SYS_PROP_LASTUSERON
                     59:        ,SYS_PROP_FREEDISKSPACE
                     60:        ,SYS_PROP_FREEDISKSPACEK
                     61: 
                     62:        ,SYS_PROP_NODES
                     63:        ,SYS_PROP_LASTNODE
                     64: 
                     65:        ,SYS_PROP_NEW_PASS
                     66:        ,SYS_PROP_NEW_MAGIC
                     67:        ,SYS_PROP_NEW_LEVEL
                     68:        ,SYS_PROP_NEW_FLAGS1
                     69:        ,SYS_PROP_NEW_FLAGS2
                     70:        ,SYS_PROP_NEW_FLAGS3
                     71:        ,SYS_PROP_NEW_FLAGS4
                     72:        ,SYS_PROP_NEW_REST
                     73:        ,SYS_PROP_NEW_EXEMPT
                     74:        ,SYS_PROP_NEW_CDT
                     75:        ,SYS_PROP_NEW_MIN
                     76:        ,SYS_PROP_NEW_SHELL
                     77:        ,SYS_PROP_NEW_XEDIT
                     78:        ,SYS_PROP_NEW_MISC
                     79:        ,SYS_PROP_NEW_PROT
                     80:        ,SYS_PROP_NEW_EXPIRE
                     81:        ,SYS_PROP_NEW_UQ
                     82: 
                     83:        ,SYS_PROP_EXPIRED_LEVEL
                     84:        ,SYS_PROP_EXPIRED_FLAGS1
                     85:        ,SYS_PROP_EXPIRED_FLAGS2
                     86:        ,SYS_PROP_EXPIRED_FLAGS3
                     87:        ,SYS_PROP_EXPIRED_FLAGS4
                     88:        ,SYS_PROP_EXPIRED_REST
                     89:        ,SYS_PROP_EXPIRED_EXEMPT
                     90: 
                     91:        /* directories */
                     92:        ,SYS_PROP_NODE_DIR
                     93:        ,SYS_PROP_CTRL_DIR
                     94:        ,SYS_PROP_DATA_DIR
                     95:        ,SYS_PROP_TEXT_DIR
                     96:        ,SYS_PROP_TEMP_DIR
                     97:        ,SYS_PROP_EXEC_DIR
                     98:        ,SYS_PROP_MODS_DIR
                     99:        ,SYS_PROP_LOGS_DIR
                    100: 
                    101:        /* msclock() access */
                    102:        ,SYS_PROP_CLOCK
                    103:        ,SYS_PROP_CLOCK_PER_SEC
                    104:        ,SYS_PROP_TIMER
                    105: 
                    106:        /* filenames */
                    107:        ,SYS_PROP_DEVNULL
                    108:        ,SYS_PROP_TEMP_PATH
                    109:        ,SYS_PROP_CMD_SHELL
                    110: 
                    111:        /* last */
                    112:        ,SYS_PROP_LOCAL_HOSTNAME
                    113: };
                    114: 
                    115: static JSBool js_system_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                    116: {
                    117:        char            str[128];
                    118:        char*           p=NULL;
                    119:     jsint       tiny;
                    120:        JSString*       js_str;
                    121:        ulong           val;
                    122:        scfg_t*         cfg;
1.1.1.2 ! root      123:        jsrefcount      rc;
1.1       root      124: 
                    125:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    126:                return(JS_FALSE);
                    127: 
                    128:     tiny = JSVAL_TO_INT(id);
                    129: 
                    130:        switch(tiny) {
                    131:                case SYS_PROP_NAME:
                    132:                p=cfg->sys_name;
                    133:                        break;
                    134:                case SYS_PROP_OP:
                    135:                        p=cfg->sys_op;
                    136:                        break;
                    137:                case SYS_PROP_ID:
                    138:                        p=cfg->sys_id;
                    139:                        break;
                    140:                case SYS_PROP_MISC:
                    141:                        JS_NewNumberValue(cx,cfg->sys_misc,vp);
                    142:                        break;
                    143:                case SYS_PROP_PSNAME:
                    144:                        p=cfg->sys_psname;
                    145:                        break;
                    146:                case SYS_PROP_PSNUM:
                    147:                        *vp = INT_TO_JSVAL(cfg->sys_psnum);
                    148:                        break;
                    149:                case SYS_PROP_INETADDR:
                    150:                        p=cfg->sys_inetaddr;
                    151:                        break;
                    152:                case SYS_PROP_LOCATION:
                    153:                        p=cfg->sys_location;
                    154:                        break;
                    155:                case SYS_PROP_TIMEZONE:
                    156:                        sys_timezone(cfg);
                    157:                        *vp = INT_TO_JSVAL(cfg->sys_timezone);
                    158:                        break;
                    159:                case SYS_PROP_NODES:
                    160:                        *vp = INT_TO_JSVAL(cfg->sys_nodes);
                    161:                        break;
                    162:                case SYS_PROP_LASTNODE:
                    163:                        *vp = INT_TO_JSVAL(cfg->sys_lastnode);
                    164:                        break;
                    165:                case SYS_PROP_PWDAYS:
                    166:                        *vp = INT_TO_JSVAL(cfg->sys_pwdays);
                    167:                        break;
                    168:                case SYS_PROP_DELDAYS:
                    169:                        *vp = INT_TO_JSVAL(cfg->sys_deldays);
                    170:                        break;
                    171:                case SYS_PROP_LASTUSER:
                    172:                        *vp = INT_TO_JSVAL(lastuser(cfg));
                    173:                        break;
                    174:                case SYS_PROP_LASTUSERON:
                    175:                        p=lastuseron;
                    176:                        break;
                    177:                case SYS_PROP_FREEDISKSPACE:
                    178:                case SYS_PROP_FREEDISKSPACEK:
1.1.1.2 ! root      179:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root      180:                        if(tiny==SYS_PROP_FREEDISKSPACE)
                    181:                                val = getfreediskspace(cfg->temp_dir,0);
                    182:                        else
                    183:                                val = getfreediskspace(cfg->temp_dir,1024);
1.1.1.2 ! root      184:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      185:                        JS_NewNumberValue(cx,val,vp);
                    186:                        break;
                    187: 
                    188:                case SYS_PROP_NEW_PASS:
                    189:                        p=cfg->new_pass;
                    190:                        break;
                    191:                case SYS_PROP_NEW_MAGIC:
                    192:                        p=cfg->new_magic;
                    193:                        break;
                    194:                case SYS_PROP_NEW_LEVEL:
                    195:                        *vp = INT_TO_JSVAL(cfg->new_level);
                    196:                        break;
                    197:                case SYS_PROP_NEW_FLAGS1:
                    198:                        *vp = INT_TO_JSVAL(cfg->new_flags1);
                    199:                        break;
                    200:                case SYS_PROP_NEW_FLAGS2:
                    201:                        *vp = INT_TO_JSVAL(cfg->new_flags2);
                    202:                        break;
                    203:                case SYS_PROP_NEW_FLAGS3:
                    204:                        *vp = INT_TO_JSVAL(cfg->new_flags3);
                    205:                        break;
                    206:                case SYS_PROP_NEW_FLAGS4:
                    207:                        *vp = INT_TO_JSVAL(cfg->new_flags4);
                    208:                        break;
                    209:                case SYS_PROP_NEW_REST:
                    210:                        *vp = INT_TO_JSVAL(cfg->new_rest);
                    211:                        break;
                    212:                case SYS_PROP_NEW_EXEMPT:
                    213:                        *vp = INT_TO_JSVAL(cfg->new_exempt);
                    214:                        break;
                    215:                case SYS_PROP_NEW_CDT:
                    216:                        JS_NewNumberValue(cx,cfg->new_cdt,vp);
                    217:                        break;
                    218:                case SYS_PROP_NEW_MIN:
                    219:                        JS_NewNumberValue(cx,cfg->new_min,vp);
                    220:                        break;
                    221:                case SYS_PROP_NEW_SHELL:
1.1.1.2 ! root      222:                        if(cfg->new_shell<cfg->total_shells)
        !           223:                                p=cfg->shell[cfg->new_shell]->code;
1.1       root      224:                        break;
                    225:                case SYS_PROP_NEW_XEDIT:
                    226:                        p=cfg->new_xedit;
                    227:                        break;
                    228:                case SYS_PROP_NEW_MISC:
                    229:                        JS_NewNumberValue(cx,cfg->new_misc,vp);
                    230:                        break;
                    231:                case SYS_PROP_NEW_PROT:
                    232:                        sprintf(str,"%c",cfg->new_prot);
                    233:                        p=str;
                    234:                        break;
                    235:                case SYS_PROP_NEW_EXPIRE:
                    236:                        JS_NewNumberValue(cx,cfg->new_expire,vp);
                    237:                        break;
                    238:                case SYS_PROP_NEW_UQ:
                    239:                        JS_NewNumberValue(cx,cfg->uq,vp);
                    240:                        break;
                    241: 
                    242:                case SYS_PROP_EXPIRED_LEVEL:
                    243:                        *vp = INT_TO_JSVAL(cfg->expired_level);
                    244:                        break;
                    245:                case SYS_PROP_EXPIRED_FLAGS1:
                    246:                        *vp = INT_TO_JSVAL(cfg->expired_flags1);
                    247:                        break;
                    248:                case SYS_PROP_EXPIRED_FLAGS2:
                    249:                        *vp = INT_TO_JSVAL(cfg->expired_flags2);
                    250:                        break;
                    251:                case SYS_PROP_EXPIRED_FLAGS3:
                    252:                        *vp = INT_TO_JSVAL(cfg->expired_flags3);
                    253:                        break;
                    254:                case SYS_PROP_EXPIRED_FLAGS4:
                    255:                        *vp = INT_TO_JSVAL(cfg->expired_flags4);
                    256:                        break;
                    257:                case SYS_PROP_EXPIRED_REST:
                    258:                        *vp = INT_TO_JSVAL(cfg->expired_rest);
                    259:                        break;
                    260:                case SYS_PROP_EXPIRED_EXEMPT:
                    261:                        *vp = INT_TO_JSVAL(cfg->expired_exempt);
                    262:                        break;
                    263:                case SYS_PROP_NODE_DIR:
                    264:                        p=cfg->node_dir;
                    265:                        break;
                    266:                case SYS_PROP_CTRL_DIR:
                    267:                        p=cfg->ctrl_dir;
                    268:                        break;
                    269:                case SYS_PROP_DATA_DIR:
                    270:                        p=cfg->data_dir;
                    271:                        break;
                    272:                case SYS_PROP_TEXT_DIR:
                    273:                        p=cfg->text_dir;
                    274:                        break;
                    275:                case SYS_PROP_TEMP_DIR:
                    276:                        p=cfg->temp_dir;
                    277:                        break;
                    278:                case SYS_PROP_EXEC_DIR:
                    279:                        p=cfg->exec_dir;
                    280:                        break;
                    281:                case SYS_PROP_MODS_DIR:
                    282:                        p=cfg->mods_dir;
                    283:                        break;
                    284:                case SYS_PROP_LOGS_DIR:
                    285:                        p=cfg->logs_dir;
                    286:                        break;
                    287: 
                    288:                case SYS_PROP_DEVNULL:
                    289:                        p=_PATH_DEVNULL;
                    290:                        break;
                    291:                case SYS_PROP_TEMP_PATH:
                    292:                        p=_PATH_TMP;
                    293:                        break;
                    294: 
                    295:                case SYS_PROP_CMD_SHELL:
1.1.1.2 ! root      296:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root      297:                        p=os_cmdshell();
1.1.1.2 ! root      298:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      299:                        break;
                    300: 
                    301:                case SYS_PROP_CLOCK:
                    302:                        JS_NewNumberValue(cx,msclock(),vp);
                    303:                        break;
                    304:                case SYS_PROP_CLOCK_PER_SEC:
                    305:                        JS_NewNumberValue(cx,MSCLOCKS_PER_SEC,vp);
                    306:                        break;
                    307:                case SYS_PROP_TIMER:
                    308:                        JS_NewNumberValue(cx,xp_timer(),vp);
                    309:                        break;
                    310: 
                    311:                case SYS_PROP_LOCAL_HOSTNAME:
1.1.1.2 ! root      312:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root      313:                        gethostname(str,sizeof(str));
1.1.1.2 ! root      314:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      315:                        p=str;
                    316:                        break;
                    317:        }
                    318: 
                    319:        if(p!=NULL) {   /* string property */
                    320:                if((js_str=JS_NewStringCopyZ(cx, p))==NULL)
                    321:                        return(JS_FALSE);
                    322:                *vp = STRING_TO_JSVAL(js_str);
                    323:        }
                    324: 
                    325:        return(JS_TRUE);
                    326: }
                    327: 
                    328: static JSBool js_system_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                    329: {
                    330:     jsint       tiny;
                    331:        scfg_t*         cfg;
                    332: 
                    333:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    334:                return(JS_FALSE);
                    335: 
                    336:     tiny = JSVAL_TO_INT(id);
                    337: 
                    338:        switch(tiny) {
                    339:                case SYS_PROP_MISC:
                    340:                        JS_ValueToInt32(cx, *vp, (int32*)&cfg->sys_misc);
                    341:                        break;
                    342:        }
                    343: 
                    344:        return(TRUE);
                    345: }
                    346: 
                    347: 
                    348: #define SYSOBJ_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
                    349: 
                    350: static jsSyncPropertySpec js_system_properties[] = {
                    351: /*              name,                                          tinyid,                         flags,                          ver     */
                    352: 
                    353:        {       "name",                                         SYS_PROP_NAME,          SYSOBJ_FLAGS,           310  },
                    354:        {       "operator",                                     SYS_PROP_OP,            SYSOBJ_FLAGS,           310  },
                    355:        {       "qwk_id",                                       SYS_PROP_ID,            SYSOBJ_FLAGS,           310  },
                    356:        {       "settings",                                     SYS_PROP_MISC,          JSPROP_ENUMERATE,       310  },
                    357:        {       "psname",                                       SYS_PROP_PSNAME,        SYSOBJ_FLAGS,           310  },
                    358:        {       "psnum",                                        SYS_PROP_PSNUM,         SYSOBJ_FLAGS,           310  },
                    359:        {       "inetaddr",                                     SYS_PROP_INETADDR,      JSPROP_READONLY,        310  }, /* alias */
                    360:        {       "inet_addr",                            SYS_PROP_INETADDR,      SYSOBJ_FLAGS,           311  },
                    361:        {       "location",                                     SYS_PROP_LOCATION,      SYSOBJ_FLAGS,           310  },
                    362:        {       "timezone",                                     SYS_PROP_TIMEZONE,      SYSOBJ_FLAGS,           310  },
                    363:        {       "pwdays",                                       SYS_PROP_PWDAYS,        SYSOBJ_FLAGS,           310  },
                    364:        {       "deldays",                                      SYS_PROP_DELDAYS,       SYSOBJ_FLAGS,           310  },
                    365: 
                    366:        {       "lastuser",                                     SYS_PROP_LASTUSER               ,SYSOBJ_FLAGS,  311  },
                    367:        {       "lastuseron",                           SYS_PROP_LASTUSERON             ,SYSOBJ_FLAGS,  310  },
                    368:        {       "freediskspace",                        SYS_PROP_FREEDISKSPACE  ,SYSOBJ_FLAGS,  310  },
                    369:        {       "freediskspacek",                       SYS_PROP_FREEDISKSPACEK ,SYSOBJ_FLAGS,  310  },
                    370: 
                    371:        {       "nodes",                                        SYS_PROP_NODES,         SYSOBJ_FLAGS,           310  },
                    372:        {       "lastnode",                                     SYS_PROP_LASTNODE,      SYSOBJ_FLAGS,           310  },
                    373: 
                    374:        {       "newuser_password",                     SYS_PROP_NEW_PASS               ,SYSOBJ_FLAGS,  310  },
                    375:        {       "newuser_magic_word",           SYS_PROP_NEW_MAGIC              ,SYSOBJ_FLAGS,  310  },
                    376:        {       "newuser_level",                        SYS_PROP_NEW_LEVEL              ,SYSOBJ_FLAGS,  310  },
                    377:        {       "newuser_flags1",                       SYS_PROP_NEW_FLAGS1             ,SYSOBJ_FLAGS,  310  },
                    378:        {       "newuser_flags2",                       SYS_PROP_NEW_FLAGS2             ,SYSOBJ_FLAGS,  310  },
                    379:        {       "newuser_flags3",                       SYS_PROP_NEW_FLAGS3             ,SYSOBJ_FLAGS,  310  },
                    380:        {       "newuser_flags4",                       SYS_PROP_NEW_FLAGS4             ,SYSOBJ_FLAGS,  310  },
                    381:        {       "newuser_restrictions",         SYS_PROP_NEW_REST               ,SYSOBJ_FLAGS,  310  },
                    382:        {       "newuser_exemptions",           SYS_PROP_NEW_EXEMPT             ,SYSOBJ_FLAGS,  310  },
                    383:        {       "newuser_credits",                      SYS_PROP_NEW_CDT                ,SYSOBJ_FLAGS,  310  },
                    384:        {       "newuser_minutes",                      SYS_PROP_NEW_MIN                ,SYSOBJ_FLAGS,  310  },
                    385:        {       "newuser_command_shell",        SYS_PROP_NEW_SHELL              ,SYSOBJ_FLAGS,  310  },
                    386:        {       "newuser_editor",                       SYS_PROP_NEW_XEDIT              ,SYSOBJ_FLAGS,  310  },
                    387:        {       "newuser_settings",                     SYS_PROP_NEW_MISC               ,SYSOBJ_FLAGS,  310  },
                    388:        {       "newuser_download_protocol",SYS_PROP_NEW_PROT           ,SYSOBJ_FLAGS,  310  },
                    389:        {       "newuser_expiration_days",      SYS_PROP_NEW_EXPIRE             ,SYSOBJ_FLAGS,  310  },
                    390:        {       "newuser_questions",            SYS_PROP_NEW_UQ                 ,SYSOBJ_FLAGS,  310  },
                    391: 
                    392:        {       "expired_level",                        SYS_PROP_EXPIRED_LEVEL  ,SYSOBJ_FLAGS,  310  },
                    393:        {       "expired_flags1",                       SYS_PROP_EXPIRED_FLAGS1 ,SYSOBJ_FLAGS,  310  },
                    394:        {       "expired_flags2",                       SYS_PROP_EXPIRED_FLAGS2 ,SYSOBJ_FLAGS,  310  },
                    395:        {       "expired_flags3",                       SYS_PROP_EXPIRED_FLAGS3 ,SYSOBJ_FLAGS,  310  },
                    396:        {       "expired_flags4",                       SYS_PROP_EXPIRED_FLAGS4 ,SYSOBJ_FLAGS,  310  },
                    397:        {       "expired_restrictions",         SYS_PROP_EXPIRED_REST   ,SYSOBJ_FLAGS,  310  },
                    398:        {       "expired_exemptions",           SYS_PROP_EXPIRED_EXEMPT ,SYSOBJ_FLAGS,  310  }, 
                    399: 
                    400:        /* directories */
                    401:        {       "node_dir",                                     SYS_PROP_NODE_DIR               ,SYSOBJ_FLAGS,  310  }, 
                    402:        {       "ctrl_dir",                                     SYS_PROP_CTRL_DIR               ,SYSOBJ_FLAGS,  310  }, 
                    403:        {       "data_dir",                                     SYS_PROP_DATA_DIR               ,SYSOBJ_FLAGS,  310  }, 
                    404:        {       "text_dir",                                     SYS_PROP_TEXT_DIR               ,SYSOBJ_FLAGS,  310  }, 
                    405:        {       "temp_dir",                                     SYS_PROP_TEMP_DIR               ,SYSOBJ_FLAGS,  310  }, 
                    406:        {       "exec_dir",                                     SYS_PROP_EXEC_DIR               ,SYSOBJ_FLAGS,  310  }, 
                    407:        {       "mods_dir",                                     SYS_PROP_MODS_DIR               ,SYSOBJ_FLAGS,  310  }, 
                    408:        {       "logs_dir",                                     SYS_PROP_LOGS_DIR               ,SYSOBJ_FLAGS,  310  }, 
                    409: 
                    410:        /* filenames */
                    411:        {       "devnull",                                      SYS_PROP_DEVNULL                ,SYSOBJ_FLAGS,  311  },
                    412:        {       "temp_path",                            SYS_PROP_TEMP_PATH              ,SYSOBJ_FLAGS,  312      },
                    413:        {       "cmd_shell",                            SYS_PROP_CMD_SHELL              ,SYSOBJ_FLAGS,  314      },
                    414: 
                    415:        /* clock access */
                    416:        {       "clock_ticks",                          SYS_PROP_CLOCK                  ,SYSOBJ_FLAGS,  311  },
                    417:        {       "clock_ticks_per_second",       SYS_PROP_CLOCK_PER_SEC  ,SYSOBJ_FLAGS,  311  },
                    418:        {       "timer",                                        SYS_PROP_TIMER                  ,SYSOBJ_FLAGS,  314      },
                    419: 
                    420:        /* last */
                    421:        {       "local_host_name",                      SYS_PROP_LOCAL_HOSTNAME ,SYSOBJ_FLAGS,  311  },
                    422:        {0}
                    423: };
                    424: 
                    425: #ifdef BUILD_JSDOCS
                    426: static char* sys_prop_desc[] = {
                    427:         "BBS name"
                    428:        ,"operator name"
                    429:        ,"system QWK-ID (for QWK packets)"
                    430:        ,"settings bitfield (see <tt>SS_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
                    431:        ,"PostLink name"
                    432:        ,"PostLink system number"
                    433:        ,"Internet address (host or domain name)"
                    434:        ,"location (city, state)"
                    435:        ,"timezone (use <i>system.zonestr()</i> to get string representation)"
                    436:        ,"days between forced password changes"
                    437:        ,"days to preserve deleted user records"
                    438: 
                    439:        ,"last user record number in user database (includes deleted and inactive user records)"
                    440:        ,"name of last user to logoff"
                    441:        ,"amount of free disk space (in bytes)"
                    442:        ,"amount of free disk space (in kilobytes)"
                    443: 
                    444:        ,"total number of BBS nodes"
                    445:        ,"last displayable node number"
                    446: 
                    447:        ,"new user password"
                    448:        ,"new user magic word"
                    449:        ,"new user level"
                    450:        ,"new user flag set #1"
                    451:        ,"new user flag set #2"
                    452:        ,"new user flag set #3"
                    453:        ,"new user flag set #4"
                    454:        ,"new user restriction flags"
                    455:        ,"new user exemption flags"
                    456:        ,"new user credits"
                    457:        ,"new user extra minutes"
                    458:        ,"new user command shell"
                    459:        ,"new user external editor"
                    460:        ,"new user settings"
                    461:        ,"new user file transfer protocol (command key)"
                    462:        ,"new user expiration days"
                    463:        ,"new user questions bitfield (see <tt>UQ_*</tt> in <tt>sbbsdefs.js</tt> for bit definitions)"
                    464: 
                    465:        ,"expired user level"
                    466:        ,"expired user flag set #1"
                    467:        ,"expired user flag set #2"
                    468:        ,"expired user flag set #3"
                    469:        ,"expired user flag set #4"
                    470:        ,"expired user restriction flags"
                    471:        ,"expired user exemption flags"
                    472: 
                    473:        /* directories */
                    474:        ,"node directory"
                    475:        ,"control file directory"
                    476:        ,"data file directory"
                    477:        ,"text file directory"
                    478:        ,"temporary file directory"
                    479:        ,"executable file directory"
                    480:        ,"modified modules directory (optional)"
                    481:        ,"log file directory"
                    482: 
                    483:        /* filenames */
                    484:        ,"platform-specific \"null\" device filename"
                    485:        ,"platform-specific temporary file directory"
                    486:        ,"platform-specific command processor/shell"
                    487: 
                    488:        /* clock */
                    489:        ,"amount of elapsed processor time in clock 'ticks'"
                    490:        ,"number of clock ticks per second"
                    491:        ,"high-resolution timer, in seconds (fractional seconds supported)"
                    492: 
                    493:        /* INSERT new tabled properties here */
                    494:        ,"private host name that uniquely identifies this system on the local network"
                    495: 
                    496:        /* Manually created (non-tabled) properties */
                    497:        ,"public host name that uniquely identifies this system on the Internet (usually the same as <i>system.inet_addr</i>)"
                    498:        ,"Synchronet version number (e.g. '3.10')"
                    499:        ,"Synchronet revision letter (e.g. 'k')"
                    500:        ,"Synchronet alpha/beta designation (e.g. ' beta')"
                    501:        ,"Synchronet full version information (e.g. '3.10k Beta Debug')"
                    502:        ,"Synchronet version notice (includes version and platform)"
                    503:        ,"Synchronet version number in decimal (e.g. 31301 for v3.13b)"
                    504:        ,"Synchronet version number in hexadecimal (e.g. 0x31301 for v3.13b)"
                    505:        ,"platform description (e.g. 'Win32', 'Linux', 'FreeBSD')"
1.1.1.2 ! root      506:        ,"architecture description (e.g. 'i386', 'i686', 'x86_64')"
1.1       root      507:        ,"socket library version information"
                    508:        ,"message base library version information"
                    509:        ,"compiler used to build Synchronet"
                    510:        ,"date and time compiled"
                    511:        ,"Synchronet copyright display"
                    512:        ,"JavaScript engine version information"
                    513:        ,"operating system version information"
                    514:        ,"time/date system was brought online (in time_t format)"
                    515: 
                    516:        ,"array of FidoNet Technology Network (FTN) addresses associated with this system"
                    517:        ,NULL
                    518: };
                    519: #endif
                    520: 
                    521: 
                    522: /* System Stats Propertiess */
                    523: enum {
                    524:         SYSSTAT_PROP_LOGONS
                    525:        ,SYSSTAT_PROP_LTODAY
                    526:        ,SYSSTAT_PROP_TIMEON
                    527:        ,SYSSTAT_PROP_TTODAY
                    528:        ,SYSSTAT_PROP_ULS
                    529:        ,SYSSTAT_PROP_ULB
                    530:        ,SYSSTAT_PROP_DLS
                    531:        ,SYSSTAT_PROP_DLB
                    532:        ,SYSSTAT_PROP_PTODAY
                    533:        ,SYSSTAT_PROP_ETODAY
                    534:        ,SYSSTAT_PROP_FTODAY
                    535:        ,SYSSTAT_PROP_NUSERS
                    536: 
                    537:        ,SYSSTAT_PROP_TOTALUSERS
                    538:        ,SYSSTAT_PROP_TOTALFILES
                    539:        ,SYSSTAT_PROP_TOTALMSGS
                    540:        ,SYSSTAT_PROP_TOTALMAIL
                    541:        ,SYSSTAT_PROP_FEEDBACK
                    542: };
                    543: 
                    544: static JSBool js_sysstats_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                    545: {
                    546:     jsint       tiny;
                    547:        scfg_t*         cfg;
                    548:        stats_t         stats;
                    549:        uint            i;
                    550:        ulong           l;
1.1.1.2 ! root      551:        jsrefcount      rc;
1.1       root      552: 
                    553:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    554:                return(JS_FALSE);
                    555: 
                    556:     tiny = JSVAL_TO_INT(id);
                    557: 
1.1.1.2 ! root      558:        rc=JS_SUSPENDREQUEST(cx);
        !           559:        if(!getstats(cfg, 0, &stats)) {
        !           560:                JS_RESUMEREQUEST(cx, rc);
1.1       root      561:                return(FALSE);
1.1.1.2 ! root      562:        }
        !           563:        JS_RESUMEREQUEST(cx, rc);
1.1       root      564: 
                    565:        switch(tiny) {
                    566:                case SYSSTAT_PROP_LOGONS:
                    567:                        JS_NewNumberValue(cx,stats.logons,vp);
                    568:                        break;
                    569:                case SYSSTAT_PROP_LTODAY:
                    570:                        JS_NewNumberValue(cx,stats.ltoday,vp);
                    571:                        break;
                    572:                case SYSSTAT_PROP_TIMEON:
                    573:                        JS_NewNumberValue(cx,stats.timeon,vp);
                    574:                        break;
                    575:                case SYSSTAT_PROP_TTODAY:
                    576:                        JS_NewNumberValue(cx,stats.ttoday,vp);
                    577:                        break;
                    578:                case SYSSTAT_PROP_ULS:
                    579:                        JS_NewNumberValue(cx,stats.uls,vp);
                    580:                        break;
                    581:                case SYSSTAT_PROP_ULB:
                    582:                        JS_NewNumberValue(cx,stats.ulb,vp);
                    583:                        break;
                    584:                case SYSSTAT_PROP_DLS:
                    585:                        JS_NewNumberValue(cx,stats.dls,vp);
                    586:                        break;
                    587:                case SYSSTAT_PROP_DLB:
                    588:                        JS_NewNumberValue(cx,stats.dlb,vp);
                    589:                        break;
                    590:                case SYSSTAT_PROP_PTODAY:
                    591:                        JS_NewNumberValue(cx,stats.ptoday,vp);
                    592:                        break;
                    593:                case SYSSTAT_PROP_ETODAY:
                    594:                        JS_NewNumberValue(cx,stats.etoday,vp);
                    595:                        break;
                    596:                case SYSSTAT_PROP_FTODAY:
                    597:                        JS_NewNumberValue(cx,stats.ftoday,vp);
                    598:                        break;
                    599:                case SYSSTAT_PROP_NUSERS:
                    600:                        JS_NewNumberValue(cx,stats.nusers,vp);
                    601:                        break;
                    602: 
                    603:                case SYSSTAT_PROP_TOTALUSERS:
1.1.1.2 ! root      604:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root      605:                        *vp = INT_TO_JSVAL(total_users(cfg));
1.1.1.2 ! root      606:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      607:                        break;
                    608:                case SYSSTAT_PROP_TOTALMSGS:
                    609:                        l=0;
1.1.1.2 ! root      610:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root      611:                        for(i=0;i<cfg->total_subs;i++)
                    612:                                l+=getposts(cfg,i); 
1.1.1.2 ! root      613:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      614:                        JS_NewNumberValue(cx,l,vp); 
                    615:                        break;
                    616:                case SYSSTAT_PROP_TOTALFILES:
                    617:                        l=0;
1.1.1.2 ! root      618:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root      619:                        for(i=0;i<cfg->total_dirs;i++)
                    620:                                l+=getfiles(cfg,i);
1.1.1.2 ! root      621:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      622:                        JS_NewNumberValue(cx,l,vp);
                    623:                        break;
                    624:                case SYSSTAT_PROP_TOTALMAIL:
1.1.1.2 ! root      625:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root      626:                        *vp = INT_TO_JSVAL(getmail(cfg, 0,0));
1.1.1.2 ! root      627:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      628:                        break;
                    629:                case SYSSTAT_PROP_FEEDBACK:
1.1.1.2 ! root      630:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root      631:                        *vp = INT_TO_JSVAL(getmail(cfg, 1,0));
1.1.1.2 ! root      632:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      633:                        break;
                    634:        }
                    635: 
                    636:        return(TRUE);
                    637: }
                    638: 
                    639: #define SYSSTAT_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
                    640: 
                    641: static jsSyncPropertySpec js_sysstats_properties[] = {
                    642: /*              name,                                          tinyid,                                         flags,                  ver     */
                    643: 
                    644:        {       "total_logons",                         SYSSTAT_PROP_LOGONS,            SYSSTAT_FLAGS,  310 },
                    645:        {       "logons_today",                         SYSSTAT_PROP_LTODAY,            SYSSTAT_FLAGS,  310 },
                    646:        {       "total_timeon",                         SYSSTAT_PROP_TIMEON,            SYSSTAT_FLAGS,  310 },
                    647:        {       "timeon_today",                         SYSSTAT_PROP_TTODAY,            SYSSTAT_FLAGS,  310 },
                    648:        {       "total_files",                          SYSSTAT_PROP_TOTALFILES,        SYSSTAT_FLAGS,  310 },
                    649:        {       "files_uploaded_today",         SYSSTAT_PROP_ULS,                       SYSSTAT_FLAGS,  310 },
                    650:        {       "bytes_uploaded_today",         SYSSTAT_PROP_ULB,                       SYSSTAT_FLAGS,  310 },
                    651:        {       "files_downloaded_today",       SYSSTAT_PROP_DLS,                       SYSSTAT_FLAGS,  310 },
                    652:        {       "bytes_downloaded_today",       SYSSTAT_PROP_DLB,                       SYSSTAT_FLAGS,  310 },
                    653:        {       "total_messages",                       SYSSTAT_PROP_TOTALMSGS,         SYSSTAT_FLAGS,  310 },
                    654:        {       "messages_posted_today",        SYSSTAT_PROP_PTODAY,            SYSSTAT_FLAGS,  310 },
                    655:        {       "total_email",                          SYSSTAT_PROP_TOTALMAIL,         SYSSTAT_FLAGS,  310 },
                    656:        {       "email_sent_today",                     SYSSTAT_PROP_ETODAY,            SYSSTAT_FLAGS,  310 },
                    657:        {       "total_feedback",                       SYSSTAT_PROP_FEEDBACK,          SYSSTAT_FLAGS,  310 },
                    658:        {       "feedback_sent_today",          SYSSTAT_PROP_FTODAY,            SYSSTAT_FLAGS,  310 },
                    659:        {       "total_users",                          SYSSTAT_PROP_TOTALUSERS,        SYSSTAT_FLAGS,  310 },
                    660:        {       "new_users_today",                      SYSSTAT_PROP_NUSERS,            SYSSTAT_FLAGS,  310 },
                    661:        {0}
                    662: };
                    663: 
                    664: #ifdef BUILD_JSDOCS
                    665: static char* sysstat_prop_desc[] = {
                    666:         "total logons"
                    667:        ,"logons today"
                    668:        ,"total time used"
                    669:        ,"time used today"
                    670:        ,"total files in file bases"
                    671:        ,"files uploaded today"
                    672:        ,"bytes uploaded today"
                    673:        ,"files downloaded today"
                    674:        ,"bytes downloaded today"
                    675:        ,"total messages in message bases"
                    676:        ,"messages posted today"
                    677:        ,"total messages in mail base"
                    678:        ,"email sent today"
                    679:        ,"total feedback messages waiting"
                    680:        ,"feedback sent today"
                    681:        ,"total user records (does not include deleted or inactive user records)"
                    682:        ,"new users today"
                    683:        ,NULL
                    684: };
                    685: #endif
                    686: 
1.1.1.2 ! root      687: static JSBool js_sysstats_resolve(JSContext *cx, JSObject *obj, jsval id)
        !           688: {
        !           689:        char*                   name=NULL;
        !           690: 
        !           691:        if(id != JSVAL_NULL)
        !           692:                name=JS_GetStringBytes(JSVAL_TO_STRING(id));
        !           693: 
        !           694:        return(js_SyncResolve(cx, obj, name, js_sysstats_properties, NULL, NULL, 0));
        !           695: }
        !           696: 
        !           697: static JSBool js_sysstats_enumerate(JSContext *cx, JSObject *obj)
        !           698: {
        !           699:        return(js_sysstats_resolve(cx, obj, JSVAL_NULL));
        !           700: }
1.1       root      701: 
                    702: static JSClass js_sysstats_class = {
                    703:      "Stats"                           /* name                 */
                    704:     ,JSCLASS_HAS_PRIVATE       /* flags                */
                    705:        ,JS_PropertyStub                /* addProperty  */
                    706:        ,JS_PropertyStub                /* delProperty  */
                    707:        ,js_sysstats_get                /* getProperty  */
                    708:        ,JS_PropertyStub                /* setProperty  */
1.1.1.2 ! root      709:        ,js_sysstats_enumerate  /* enumerate    */
        !           710:        ,js_sysstats_resolve    /* resolve              */
1.1       root      711:        ,JS_ConvertStub                 /* convert              */
                    712:        ,JS_FinalizeStub                /* finalize             */
                    713: };
                    714: 
                    715: static JSBool
                    716: js_alias(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    717: {
                    718:        char*           p;
                    719:        char            buf[128];
                    720:        JSString*       js_str;
                    721:        scfg_t*         cfg;
1.1.1.2 ! root      722:        jsrefcount      rc;
1.1       root      723: 
                    724:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    725:                return(JS_FALSE);
                    726: 
                    727:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL) {
                    728:                *rval = INT_TO_JSVAL(0);
                    729:                return(JS_TRUE);
                    730:        }
                    731: 
                    732:        if((p=JS_GetStringBytes(js_str))==NULL) {
                    733:                *rval = INT_TO_JSVAL(0);
                    734:                return(JS_TRUE);
                    735:        }
                    736: 
1.1.1.2 ! root      737:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      738:        p=alias(cfg,p,buf);
1.1.1.2 ! root      739:        JS_RESUMEREQUEST(cx, rc);
1.1       root      740: 
                    741:        if((js_str = JS_NewStringCopyZ(cx, p))==NULL)
                    742:                return(JS_FALSE);
                    743: 
                    744:        *rval = STRING_TO_JSVAL(js_str);
                    745:        return(JS_TRUE);
                    746: }
                    747: 
                    748: static JSBool
                    749: js_username(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    750: {
                    751:        int32           val;
                    752:        char            buf[128];
                    753:        JSString*       js_str;
                    754:        scfg_t*         cfg;
1.1.1.2 ! root      755:        char*           cstr;
        !           756:        jsrefcount      rc;
1.1       root      757: 
                    758:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    759:                return(JS_FALSE);
                    760: 
                    761:        val=0;
                    762:        JS_ValueToInt32(cx,argv[0],&val);
                    763: 
1.1.1.2 ! root      764:        rc=JS_SUSPENDREQUEST(cx);
        !           765:        cstr=username(cfg,val,buf);
        !           766:        JS_RESUMEREQUEST(cx, rc);
        !           767:        if((js_str = JS_NewStringCopyZ(cx, cstr))==NULL)
1.1       root      768:                return(JS_FALSE);
                    769: 
                    770:        *rval = STRING_TO_JSVAL(js_str);
                    771:        return(JS_TRUE);
                    772: }
                    773: 
                    774: static JSBool
                    775: js_matchuser(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    776: {
                    777:        char*           p;
                    778:        JSString*       js_str;
                    779:        scfg_t*         cfg;
                    780:        BOOL            sysop_alias=TRUE;
1.1.1.2 ! root      781:        jsrefcount      rc;
1.1       root      782: 
                    783:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    784:                return(JS_FALSE);
                    785: 
                    786:        if((js_str=JS_ValueToString(cx, argv[0]))==NULL) {
                    787:                *rval = INT_TO_JSVAL(0);
                    788:                return(JS_TRUE);
                    789:        }
                    790: 
                    791:        if(argc>1)
                    792:                JS_ValueToBoolean(cx,argv[1],&sysop_alias);
                    793: 
                    794:        if((p=JS_GetStringBytes(js_str))==NULL) {
                    795:                *rval = INT_TO_JSVAL(0);
                    796:                return(JS_TRUE);
                    797:        }
                    798: 
1.1.1.2 ! root      799:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      800:        *rval = INT_TO_JSVAL(matchuser(cfg,p,sysop_alias));
1.1.1.2 ! root      801:        JS_RESUMEREQUEST(cx, rc);
1.1       root      802:        return(JS_TRUE);
                    803: }
                    804: 
                    805: static JSBool
                    806: js_matchuserdata(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    807: {
                    808:        char*           p;
                    809:        JSString*       js_str;
                    810:        int32           offset=0;
                    811:        int32           usernumber=0;
                    812:        int                     len;
                    813:        scfg_t*         cfg;
1.1.1.2 ! root      814:        jsrefcount      rc;
        !           815:        BOOL            match_next=FALSE;
        !           816:        int             argnum=2;
1.1       root      817: 
                    818:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    819:                return(JS_FALSE);
                    820: 
                    821:        JS_ValueToInt32(cx,argv[0],&offset);
1.1.1.2 ! root      822:        rc=JS_SUSPENDREQUEST(cx);
        !           823:        len=user_rec_len(offset);
        !           824:        JS_RESUMEREQUEST(cx, rc);
        !           825:        if(len<0) {
        !           826:                JS_ReportError(cx,"Invalid user data offset: %d", offset);
1.1       root      827:                return(JS_FALSE);
1.1.1.2 ! root      828:        }
1.1       root      829: 
                    830:        if((js_str=JS_ValueToString(cx, argv[1]))==NULL) {
                    831:                *rval = INT_TO_JSVAL(0);
                    832:                return(JS_TRUE);
                    833:        }
                    834: 
1.1.1.2 ! root      835:        if(JSVAL_IS_NUMBER(argv[argnum]))
        !           836:                JS_ValueToInt32(cx, argv[argnum++], &usernumber);
        !           837:        if(JSVAL_IS_BOOLEAN(argv[argnum]))
        !           838:                JS_ValueToBoolean(cx, argv[argnum], &match_next);
        !           839:                
1.1       root      840:        if((p=JS_GetStringBytes(js_str))==NULL) {
                    841:                *rval = INT_TO_JSVAL(0);
                    842:                return(JS_TRUE);
                    843:        }
1.1.1.2 ! root      844:        
        !           845:        rc=JS_SUSPENDREQUEST(cx);
        !           846:        *rval = INT_TO_JSVAL(userdatdupe(cfg,usernumber,offset,len,p,FALSE,match_next));
        !           847:        JS_RESUMEREQUEST(cx, rc);
1.1       root      848:        return(JS_TRUE);
                    849: }
                    850: 
                    851: static JSBool
                    852: js_trashcan(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    853: {
                    854:        char*           str;
                    855:        char*           can;
                    856:        JSString*       js_str;
                    857:        JSString*       js_can;
                    858:        scfg_t*         cfg;
1.1.1.2 ! root      859:        jsrefcount      rc;
1.1       root      860: 
                    861:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    862:                return(JS_FALSE);
                    863: 
                    864:        if((js_can=JS_ValueToString(cx, argv[0]))==NULL) {
                    865:                *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
                    866:                return(JS_TRUE);
                    867:        }
                    868: 
                    869:        if((js_str=JS_ValueToString(cx, argv[1]))==NULL) {
                    870:                *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
                    871:                return(JS_TRUE);
                    872:        }
                    873: 
                    874:        if((can=JS_GetStringBytes(js_can))==NULL) {
                    875:                *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
                    876:                return(JS_TRUE);
                    877:        }
                    878: 
                    879:        if((str=JS_GetStringBytes(js_str))==NULL) {
                    880:                *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
                    881:                return(JS_TRUE);
                    882:        }
                    883: 
1.1.1.2 ! root      884:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      885:        *rval = BOOLEAN_TO_JSVAL(trashcan(cfg,str,can));        /* user args are reversed */
1.1.1.2 ! root      886:        JS_RESUMEREQUEST(cx, rc);
1.1       root      887:        return(JS_TRUE);
                    888: }
                    889: 
                    890: static JSBool
                    891: js_findstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    892: {
                    893:        char*           str;
                    894:        char*           fname;
                    895:        JSString*       js_str;
                    896:        JSString*       js_fname;
1.1.1.2 ! root      897:        jsrefcount      rc;
1.1       root      898: 
                    899:        if((js_fname=JS_ValueToString(cx, argv[0]))==NULL) {
                    900:                *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
                    901:                return(JS_TRUE);
                    902:        }
                    903: 
                    904:        if((js_str=JS_ValueToString(cx, argv[1]))==NULL) {
                    905:                *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
                    906:                return(JS_TRUE);
                    907:        }
                    908: 
                    909:        if((fname=JS_GetStringBytes(js_fname))==NULL) {
                    910:                *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
                    911:                return(JS_TRUE);
                    912:        }
                    913: 
                    914:        if((str=JS_GetStringBytes(js_str))==NULL) {
                    915:                *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
                    916:                return(JS_TRUE);
                    917:        }
                    918: 
1.1.1.2 ! root      919:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      920:        *rval = BOOLEAN_TO_JSVAL(findstr(str,fname));   /* user args are reversed */
1.1.1.2 ! root      921:        JS_RESUMEREQUEST(cx, rc);
1.1       root      922:        return(JS_TRUE);
                    923: }
                    924: 
                    925: static JSBool
                    926: js_zonestr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    927: {
                    928:        JSString*       js_str;
                    929:        short           zone;
                    930:        int32           val=0;
                    931:        scfg_t*         cfg;
1.1.1.2 ! root      932:        jsrefcount      rc;
        !           933:        char*           cstr;
1.1       root      934: 
                    935:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    936:                return(JS_FALSE);
                    937: 
                    938:        if(argc<1)
                    939:                zone=sys_timezone(cfg);
                    940:        else {
                    941:                JS_ValueToInt32(cx,argv[0],&val);
                    942:                zone=(short)val;
                    943:        }
                    944: 
1.1.1.2 ! root      945:        rc=JS_SUSPENDREQUEST(cx);
        !           946:        cstr=smb_zonestr(zone,NULL);
        !           947:        JS_RESUMEREQUEST(cx, rc);
        !           948:        if((js_str = JS_NewStringCopyZ(cx, cstr))==NULL)
1.1       root      949:                return(JS_FALSE);
                    950: 
                    951:        *rval = STRING_TO_JSVAL(js_str);
                    952:        return(JS_TRUE);
                    953: }
                    954: 
                    955: /* Returns a ctime()-like string in the system-preferred time format */
                    956: static JSBool
                    957: js_timestr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    958: {
                    959:        char            str[128];
                    960:        int32           i=0;
                    961:        time_t          t;
                    962:        JSString*       js_str;
                    963:        scfg_t*         cfg;
1.1.1.2 ! root      964:        jsrefcount      rc;
1.1       root      965: 
                    966:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    967:                return(JS_FALSE);
                    968: 
                    969:        if(argc<1)
                    970:                i=time(NULL);   /* use current time */
                    971:        else
                    972:                JS_ValueToInt32(cx,argv[0],&i);
                    973:        t=i;
1.1.1.2 ! root      974:        rc=JS_SUSPENDREQUEST(cx);
        !           975:        timestr(cfg,t,str);
        !           976:        JS_RESUMEREQUEST(cx, rc);
1.1       root      977:        if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
                    978:                return(JS_FALSE);
                    979: 
                    980:        *rval = STRING_TO_JSVAL(js_str);
                    981:        return(JS_TRUE);
                    982: }
                    983: 
                    984: /* Returns a mm/dd/yy or dd/mm/yy formated string */
                    985: static JSBool
                    986: js_datestr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    987: {
                    988:        char            str[128];
                    989:        time_t          t;
                    990:        JSString*       js_str;
                    991:        scfg_t*         cfg;
                    992: 
                    993:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                    994:                return(JS_FALSE);
                    995: 
                    996:        if(argc<1)
                    997:                t=time(NULL);   /* use current time */
                    998:        else {
                    999:                if(JSVAL_IS_STRING(argv[0])) {  /* convert from string to time_t? */
1.1.1.2 ! root     1000:                        JS_NewNumberValue(cx,dstrtounix(cfg,JS_GetStringBytes(JS_ValueToString(cx, argv[0]))),rval);
1.1       root     1001:                        return(JS_TRUE);
                   1002:                }
                   1003:                JS_ValueToInt32(cx,argv[0],(int32*)&t);
                   1004:        }
                   1005:        unixtodstr(cfg,t,str);
                   1006:        if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
                   1007:                return(JS_FALSE);
                   1008: 
                   1009:        *rval = STRING_TO_JSVAL(js_str);
                   1010:        return(JS_TRUE);
                   1011: }
                   1012: 
                   1013: static JSBool
                   1014: js_secondstr(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1015: {
                   1016:        char            str[128];
                   1017:        int32           t=0;
                   1018:        JSString*       js_str;
                   1019: 
                   1020:        *rval = JSVAL_NULL;
                   1021: 
                   1022:        if(argc<1)
                   1023:                return(JS_TRUE);
                   1024: 
                   1025:        JS_ValueToInt32(cx,argv[0],&t);
                   1026:        sectostr(t,str);
                   1027:        if((js_str = JS_NewStringCopyZ(cx, str))==NULL)
                   1028:                return(JS_FALSE);
                   1029: 
                   1030:        *rval = STRING_TO_JSVAL(js_str);
                   1031:        return(JS_TRUE);
                   1032: }
                   1033: 
                   1034: static JSBool
                   1035: js_spamlog(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1036: {
                   1037:        uintN           i;
                   1038:        char*           p;
                   1039:        char*           prot=NULL;
                   1040:        char*           action=NULL;
                   1041:        char*           reason=NULL;
                   1042:        char*           host=NULL;
                   1043:        char*           ip_addr=NULL;
                   1044:        char*           to=NULL;
                   1045:        char*           from=NULL;
                   1046:        scfg_t*         cfg;
1.1.1.2 ! root     1047:        jsrefcount      rc;
1.1       root     1048: 
                   1049:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                   1050:                return(JS_FALSE);
                   1051: 
                   1052:        for(i=0;i<argc;i++) {
                   1053:                if(!JSVAL_IS_STRING(argv[i]))
                   1054:                        continue;
                   1055:                p=JS_GetStringBytes(JS_ValueToString(cx, argv[i]));
                   1056:                if(p==NULL)
                   1057:                        continue;
                   1058:                if(prot==NULL)
                   1059:                        prot=p;
                   1060:                else if(action==NULL)
                   1061:                        action=p;
                   1062:                else if(reason==NULL)
                   1063:                        reason=p;
                   1064:                else if(host==NULL)
                   1065:                        host=p;
                   1066:                else if(ip_addr==NULL)
                   1067:                        ip_addr=p;
                   1068:                else if(to==NULL)
                   1069:                        to=p;
                   1070:                else if(from==NULL)
                   1071:                        from=p;
                   1072:        }
1.1.1.2 ! root     1073:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1074:        *rval = BOOLEAN_TO_JSVAL(spamlog(cfg,prot,action,reason,host,ip_addr,to,from));
1.1.1.2 ! root     1075:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1076:        return(JS_TRUE);
                   1077: }
                   1078: 
                   1079: static JSBool
                   1080: js_hacklog(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1081: {
                   1082:        uintN           i;
                   1083:        int32           i32=0;
                   1084:        char*           p;
                   1085:        char*           prot=NULL;
                   1086:        char*           user=NULL;
                   1087:        char*           text=NULL;
                   1088:        char*           host=NULL;
                   1089:        SOCKADDR_IN     addr;
                   1090:        scfg_t*         cfg;
1.1.1.2 ! root     1091:        jsrefcount      rc;
1.1       root     1092: 
                   1093:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                   1094:                return(JS_FALSE);
                   1095: 
                   1096:        memset(&addr,0,sizeof(addr));
                   1097:        for(i=0;i<argc;i++) {
                   1098:                if(JSVAL_IS_NUMBER(argv[i])) {
                   1099:                        JS_ValueToInt32(cx,argv[i],&i32);
                   1100:                        if(addr.sin_addr.s_addr==0)
                   1101:                                addr.sin_addr.s_addr=i32;
                   1102:                        else
                   1103:                                addr.sin_port=(ushort)i32;
                   1104:                        continue;
                   1105:                }
                   1106:                if(!JSVAL_IS_STRING(argv[i]))
                   1107:                        continue;
                   1108:                p=JS_GetStringBytes(JS_ValueToString(cx, argv[i]));
                   1109:                if(p==NULL)
                   1110:                        continue;
                   1111:                if(prot==NULL)
                   1112:                        prot=p;
                   1113:                else if(user==NULL)
                   1114:                        user=p;
                   1115:                else if(text==NULL)
                   1116:                        text=p;
                   1117:                else if(host==NULL)
                   1118:                        host=p;
                   1119:        }
1.1.1.2 ! root     1120:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1121:        *rval = BOOLEAN_TO_JSVAL(hacklog(cfg,prot,user,text,host,&addr));
1.1.1.2 ! root     1122:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1123:        return(JS_TRUE);
                   1124: }
                   1125: 
                   1126: static JSBool
                   1127: js_filter_ip(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1128: {
                   1129:        uintN           i;
                   1130:        char*           p;
                   1131:        char*           prot=NULL;
                   1132:        char*           reason=NULL;
                   1133:        char*           host=NULL;
                   1134:        char*           ip_addr=NULL;
                   1135:        char*           from=NULL;
                   1136:        char*           fname=NULL;
                   1137:        scfg_t*         cfg;
1.1.1.2 ! root     1138:        jsrefcount      rc;
1.1       root     1139: 
                   1140:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                   1141:                return(JS_FALSE);
                   1142: 
                   1143:        for(i=0;i<argc;i++) {
                   1144:                if(!JSVAL_IS_STRING(argv[i]))
                   1145:                        continue;
                   1146:                p=JS_GetStringBytes(JS_ValueToString(cx, argv[i]));
                   1147:                if(p==NULL)
                   1148:                        continue;
                   1149:                if(prot==NULL)
                   1150:                        prot=p;
                   1151:                else if(reason==NULL)
                   1152:                        reason=p;
                   1153:                else if(host==NULL)
                   1154:                        host=p;
                   1155:                else if(ip_addr==NULL)
                   1156:                        ip_addr=p;
                   1157:                else if(from==NULL)
                   1158:                        from=p;
                   1159:                else if(fname==NULL)
                   1160:                        fname=p;
                   1161:        }
1.1.1.2 ! root     1162:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1163:        *rval = BOOLEAN_TO_JSVAL(filter_ip(cfg,prot,reason,host,ip_addr,from,fname));
1.1.1.2 ! root     1164:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1165:        return(JS_TRUE);
                   1166: }
                   1167: 
                   1168: static JSBool
                   1169: js_get_node_message(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1170: {
                   1171:        char*           buf;
                   1172:        int32           node_num;
                   1173:        JSString*       js_str;
                   1174:        scfg_t*         cfg;
1.1.1.2 ! root     1175:        jsrefcount      rc;
1.1       root     1176: 
                   1177:        *rval = JSVAL_NULL;
                   1178: 
                   1179:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                   1180:                return(JS_FALSE);
                   1181: 
                   1182:        node_num=cfg->node_num;
                   1183:        if(argc) 
                   1184:                JS_ValueToInt32(cx,argv[0],&node_num);
                   1185:        if(node_num<1)
                   1186:                node_num=1;
                   1187: 
1.1.1.2 ! root     1188:        rc=JS_SUSPENDREQUEST(cx);
        !          1189:        buf=getnmsg(cfg,node_num);
        !          1190:        JS_RESUMEREQUEST(cx, rc);
        !          1191:        if(buf==NULL)
1.1       root     1192:                return(JS_TRUE);
                   1193: 
                   1194:        js_str=JS_NewStringCopyZ(cx, buf);
                   1195:        free(buf);
                   1196: 
                   1197:        if(js_str==NULL)
                   1198:                return(JS_FALSE);
                   1199:        *rval = STRING_TO_JSVAL(js_str);
                   1200:        return(JS_TRUE);
                   1201: }
                   1202: 
                   1203: static JSBool
                   1204: js_put_node_message(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1205: {
                   1206:        int32           node=1;
                   1207:        JSString*       js_msg;
                   1208:        char*           msg;
                   1209:        scfg_t*         cfg;
1.1.1.2 ! root     1210:        jsrefcount      rc;
1.1       root     1211: 
                   1212:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                   1213:                return(JS_FALSE);
                   1214: 
                   1215:        JS_ValueToInt32(cx,argv[0],&node);
                   1216:        if(node<1)
                   1217:                node=1;
                   1218: 
                   1219:        if((js_msg=JS_ValueToString(cx, argv[1]))==NULL) 
                   1220:                return(JS_FALSE);
                   1221: 
                   1222:        if((msg=JS_GetStringBytes(js_msg))==NULL) 
                   1223:                return(JS_FALSE);
                   1224: 
1.1.1.2 ! root     1225:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1226:        *rval = BOOLEAN_TO_JSVAL(putnmsg(cfg,node,msg)==0);
1.1.1.2 ! root     1227:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1228: 
                   1229:        return(JS_TRUE);
                   1230: }
                   1231: 
                   1232: static JSBool
                   1233: js_get_telegram(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1234: {
                   1235:        char*           buf;
                   1236:        int32           usernumber=1;
                   1237:        JSString*       js_str;
                   1238:        scfg_t*         cfg;
1.1.1.2 ! root     1239:        jsrefcount      rc;
1.1       root     1240: 
                   1241:        *rval = JSVAL_NULL;
                   1242: 
                   1243:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                   1244:                return(JS_FALSE);
                   1245: 
                   1246:        JS_ValueToInt32(cx,argv[0],&usernumber);
                   1247:        if(usernumber<1)
                   1248:                usernumber=1;
                   1249: 
1.1.1.2 ! root     1250:        rc=JS_SUSPENDREQUEST(cx);
        !          1251:        buf=getsmsg(cfg,usernumber);
        !          1252:        JS_RESUMEREQUEST(cx, rc);
        !          1253:        if(buf==NULL)
1.1       root     1254:                return(JS_TRUE);
                   1255: 
                   1256:        js_str=JS_NewStringCopyZ(cx, buf);
                   1257:        free(buf);
                   1258: 
                   1259:        if(js_str==NULL)
                   1260:                return(JS_FALSE);
                   1261:        *rval = STRING_TO_JSVAL(js_str);
                   1262:        return(JS_TRUE);
                   1263: }
                   1264: 
                   1265: static JSBool
                   1266: js_put_telegram(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1267: {
                   1268:        int32           usernumber=1;
                   1269:        JSString*       js_msg;
                   1270:        char*           msg;
                   1271:        scfg_t*         cfg;
1.1.1.2 ! root     1272:        jsrefcount      rc;
1.1       root     1273: 
                   1274:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                   1275:                return(JS_FALSE);
                   1276: 
                   1277:        JS_ValueToInt32(cx,argv[0],&usernumber);
                   1278:        if(usernumber<1)
                   1279:                usernumber=1;
                   1280: 
                   1281:        if((js_msg=JS_ValueToString(cx, argv[1]))==NULL) 
                   1282:                return(JS_FALSE);
                   1283: 
                   1284:        if((msg=JS_GetStringBytes(js_msg))==NULL) 
                   1285:                return(JS_FALSE);
                   1286: 
1.1.1.2 ! root     1287:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1288:        *rval = BOOLEAN_TO_JSVAL(putsmsg(cfg,usernumber,msg)==0);
1.1.1.2 ! root     1289:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1290: 
                   1291:        return(JS_TRUE);
                   1292: }
                   1293: 
                   1294: static JSBool
                   1295: js_new_user(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1296: {
                   1297:        char*           alias;
                   1298:        int                     i;
1.1.1.2 ! root     1299:        uintN           n;
1.1       root     1300:        scfg_t*         cfg;
                   1301:        user_t          user;
                   1302:        JSObject*       userobj;
1.1.1.2 ! root     1303:        jsrefcount      rc;
        !          1304:        client_t*       client=NULL;
1.1       root     1305: 
                   1306:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                   1307:                return(JS_FALSE);
                   1308: 
                   1309:        alias=JS_GetStringBytes(JS_ValueToString(cx,argv[0]));
                   1310: 
1.1.1.2 ! root     1311:        rc=JS_SUSPENDREQUEST(cx);
        !          1312:        if(!check_name(cfg,alias)) {
        !          1313:                JS_RESUMEREQUEST(cx, rc);
        !          1314:                JS_ReportError(cx,"Invalid or duplicate user alias: %s", alias);
        !          1315:                return JS_FALSE;
        !          1316:        }
        !          1317: 
1.1       root     1318:        memset(&user,0,sizeof(user));
1.1.1.2 ! root     1319:        for(n=0;n<argc;n++) {
        !          1320:                if(JSVAL_IS_OBJECT(argv[n])) {
        !          1321:                        JSClass*        cl;
        !          1322:                        JSObject*       objarg = JSVAL_TO_OBJECT(argv[n]);
        !          1323:                        if((cl=JS_GetClass(cx,objarg))!=NULL && strcmp(cl->name,"Client")==0) {
        !          1324:                                client=JS_GetPrivate(cx,objarg);
        !          1325:                                continue;
        !          1326:                        }
        !          1327:                }
        !          1328:        }
        !          1329:        if(client!=NULL) {
        !          1330:                SAFECOPY(user.modem,client->protocol);
        !          1331:                SAFECOPY(user.comp,client->host);
        !          1332:                SAFECOPY(user.note,client->addr);
        !          1333:        }
1.1       root     1334: 
                   1335:        user.sex=' ';
                   1336:        SAFECOPY(user.alias,alias);
                   1337: 
                   1338:        /* statistics */
                   1339:        user.firston=user.laston=user.pwmod=time(NULL);
                   1340: 
                   1341:        /* security */
                   1342:        user.level=cfg->new_level;
                   1343:        user.flags1=cfg->new_flags1;
                   1344:        user.flags2=cfg->new_flags2;
                   1345:        user.flags3=cfg->new_flags3;
                   1346:        user.flags4=cfg->new_flags4;
                   1347:        user.rest=cfg->new_rest;
                   1348:        user.exempt=cfg->new_exempt;
                   1349: 
                   1350:        user.cdt=cfg->new_cdt;
                   1351:        user.min=cfg->new_min;
                   1352:        user.freecdt=cfg->level_freecdtperday[user.level];
                   1353:        if(cfg->new_expire)
                   1354:                user.expire=user.firston+((long)cfg->new_expire*24L*60L*60L);
                   1355:        else
                   1356:                user.expire=0;
                   1357: 
                   1358:        /* settings */
                   1359:        if(cfg->total_fcomps)
                   1360:                strcpy(user.tmpext,cfg->fcomp[0]->ext);
                   1361:        else
                   1362:                strcpy(user.tmpext,"ZIP");
                   1363: 
                   1364:        user.shell=cfg->new_shell;
                   1365:        user.misc=cfg->new_misc|(AUTOTERM|COLOR);
                   1366:        user.prot=cfg->new_prot;
                   1367:        user.qwk=QWK_DEFAULT;
                   1368: 
                   1369:        for(i=0;i<cfg->total_xedits;i++)
1.1.1.2 ! root     1370:                if(!stricmp(cfg->xedit[i]->code,cfg->new_xedit) && chk_ar(cfg,cfg->xedit[i]->ar,&user,/* client: */NULL))
1.1       root     1371:                        break;
                   1372:        if(i<cfg->total_xedits)
                   1373:                user.xedit=i+1;
                   1374: 
                   1375:        i=newuserdat(cfg,&user);
1.1.1.2 ! root     1376:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1377: 
                   1378:        if(i==0) {
1.1.1.2 ! root     1379:                userobj=js_CreateUserObject(cx, obj, cfg, NULL, &user, /* client: */NULL, /* global_user: */FALSE);
1.1       root     1380:                *rval = OBJECT_TO_JSVAL(userobj);
                   1381:        } else
                   1382:                *rval = INT_TO_JSVAL(i);
                   1383: 
                   1384:        return(JS_TRUE);
                   1385: }
                   1386: 
                   1387: static JSBool
                   1388: js_exec(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1389: {
1.1.1.2 ! root     1390:        jsrefcount      rc;
        !          1391: 
        !          1392:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1393:        *rval = INT_TO_JSVAL(system(JS_GetStringBytes(JS_ValueToString(cx, argv[0]))));
1.1.1.2 ! root     1394:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1395:        
                   1396:        return(JS_TRUE);
                   1397: }
                   1398: 
                   1399: static JSBool
                   1400: js_popen(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1401: {
                   1402:        char            str[1024];
                   1403:        char*           cmd;
                   1404:        FILE*           fp;
                   1405:        jsint           line=0;
                   1406:        jsval           val;
                   1407:        JSObject*       array;
                   1408:        JSString*       js_str;
1.1.1.2 ! root     1409:        jsrefcount      rc;
1.1       root     1410: 
                   1411:        if(argc<1)
                   1412:                return(JS_TRUE);
                   1413: 
                   1414:        if((array=JS_NewArrayObject(cx,0,NULL))==NULL)
                   1415:                return(JS_FALSE);
                   1416: 
                   1417:        cmd=JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
1.1.1.2 ! root     1418:        rc=JS_SUSPENDREQUEST(cx);
        !          1419:        if((fp=popen(cmd,"r"))==NULL) {
        !          1420:                JS_RESUMEREQUEST(cx, rc);
1.1       root     1421:                return(JS_TRUE);
1.1.1.2 ! root     1422:        }
1.1       root     1423:        while(!feof(fp)) {
                   1424:                if(fgets(str,sizeof(str),fp)==NULL)
                   1425:                        break;
1.1.1.2 ! root     1426:                JS_RESUMEREQUEST(cx, rc);
        !          1427:                if((js_str=JS_NewStringCopyZ(cx,str))==NULL) {
        !          1428:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1429:                        break;
1.1.1.2 ! root     1430:                }
1.1       root     1431:                val=STRING_TO_JSVAL(js_str);
1.1.1.2 ! root     1432:         if(!JS_SetElement(cx, array, line++, &val)) {
        !          1433:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1434:                        break;
1.1.1.2 ! root     1435:                }
        !          1436:                rc=JS_SUSPENDREQUEST(cx);
1.1       root     1437:        }
                   1438:        pclose(fp);
1.1.1.2 ! root     1439:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1440: 
                   1441:     *rval = OBJECT_TO_JSVAL(array);
                   1442: 
                   1443:     return(JS_TRUE);
                   1444: }
                   1445: 
                   1446: static JSBool
                   1447: js_chksyspass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1448: {
                   1449:        scfg_t*         cfg;
                   1450: 
                   1451:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
                   1452:                return(JS_FALSE);
                   1453: 
                   1454:        *rval = BOOLEAN_TO_JSVAL(stricmp(JS_GetStringBytes(JS_ValueToString(cx, argv[0]))
                   1455:                                                                ,cfg->sys_pass)==0);
                   1456:        
                   1457:        return(JS_TRUE);
                   1458: }
                   1459: 
1.1.1.2 ! root     1460: static JSBool 
        !          1461: js_chkname(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1462: {
        !          1463:        char*   str;
        !          1464:        scfg_t* cfg;
        !          1465:        jsrefcount      rc;
        !          1466: 
        !          1467:        str = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
        !          1468:        if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
        !          1469:                return(JS_FALSE);
        !          1470: 
        !          1471:        rc=JS_SUSPENDREQUEST(cx);
        !          1472:        *rval = BOOLEAN_TO_JSVAL(check_name(cfg,str));
        !          1473:        JS_RESUMEREQUEST(cx, rc);
        !          1474: 
        !          1475:        return(JS_TRUE);
        !          1476: }
        !          1477: 
        !          1478: static JSBool 
        !          1479: js_chkpid(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1480: {
        !          1481:        int32           pid=0;
        !          1482:        jsrefcount      rc;
        !          1483: 
        !          1484:        *rval = JSVAL_FALSE;
        !          1485: 
        !          1486:        if(argc<1)
        !          1487:                return(JS_TRUE);
        !          1488: 
        !          1489:        JS_ValueToInt32(cx,argv[0],&pid);
        !          1490: 
        !          1491:        rc=JS_SUSPENDREQUEST(cx);
        !          1492:        *rval = BOOLEAN_TO_JSVAL(check_pid(pid));
        !          1493:        JS_RESUMEREQUEST(cx, rc);
        !          1494: 
        !          1495:        return(JS_TRUE);
        !          1496: }
        !          1497: 
        !          1498: static JSBool 
        !          1499: js_killpid(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
        !          1500: {
        !          1501:        int32           pid=0;
        !          1502:        jsrefcount      rc;
        !          1503: 
        !          1504:        *rval = JSVAL_FALSE;
        !          1505: 
        !          1506:        if(argc<1)
        !          1507:                return(JS_TRUE);
        !          1508: 
        !          1509:        JS_ValueToInt32(cx,argv[0],&pid);
        !          1510: 
        !          1511:        rc=JS_SUSPENDREQUEST(cx);
        !          1512:        *rval = BOOLEAN_TO_JSVAL(terminate_pid(pid));
        !          1513:        JS_RESUMEREQUEST(cx, rc);
        !          1514: 
        !          1515:        return(JS_TRUE);
        !          1516: }
1.1       root     1517: 
                   1518: 
                   1519: static jsSyncMethodSpec js_system_functions[] = {
                   1520:        {"username",            js_username,            1,      JSTYPE_STRING,  JSDOCSTR("number")
                   1521:        ,JSDOCSTR("returns name of user in specified user record <i>number</i>, or empty string if not found")
                   1522:        ,311
                   1523:        },
                   1524:        {"alias",                       js_alias,                       1,      JSTYPE_STRING,  JSDOCSTR("alias")
                   1525:        ,JSDOCSTR("returns name of user that matches alias (if found in <tt>ctrl/alias.cfg</tt>)")
                   1526:        ,310
                   1527:        },              
                   1528:        {"matchuser",           js_matchuser,           1,      JSTYPE_NUMBER,  JSDOCSTR("username [,sysop_alias=<tt>true</tt>]")
                   1529:        ,JSDOCSTR("exact user name matching, returns number of user whose name/alias matches <i>username</i> "
                   1530:                " or 0 if not found, matches well-known sysop aliases by default")
                   1531:        ,310
                   1532:        },              
1.1.1.2 ! root     1533:        {"matchuserdata",       js_matchuserdata,       2,      JSTYPE_NUMBER,  JSDOCSTR("field, data [,usernumber, match_next=<tt>false</tt>]")
        !          1534:        ,JSDOCSTR("search user database for data in a specific field (see <tt>U_*</tt> in <tt>sbbsdefs.js</tt>), "
        !          1535:                "returns first matching user record number, optional <i>usernumber</i> specifies user record to skip, "
        !          1536:                "or record at which to begin searching if optional <i>match_next</i> is <tt>true</tt>")
1.1       root     1537:        ,310
                   1538:        },
1.1.1.2 ! root     1539:        {"trashcan",            js_trashcan,            2,      JSTYPE_BOOLEAN, JSDOCSTR("basename, find_string")
        !          1540:        ,JSDOCSTR("search <tt>text/<i>basename</i>.can</tt> for pseudo-regexp")
1.1       root     1541:        ,310
                   1542:        },              
                   1543:        {"findstr",                     js_findstr,                     2,      JSTYPE_BOOLEAN, JSDOCSTR("path/filename, find_string")
                   1544:        ,JSDOCSTR("search any file for pseudo-regexp")
                   1545:        ,310
                   1546:        },              
                   1547:        {"zonestr",                     js_zonestr,                     0,      JSTYPE_STRING,  JSDOCSTR("[timezone=<i>local</i>]")
                   1548:        ,JSDOCSTR("convert time zone integer to string, defaults to system timezone if <i>timezone</i> not specified")
                   1549:        ,310
                   1550:        },              
                   1551:        {"timestr",                     js_timestr,                     0,      JSTYPE_STRING,  JSDOCSTR("[time=<i>current</i>]")
                   1552:        ,JSDOCSTR("convert time_t integer into a time string, "
                   1553:                "defaults to current time if <i>time</i> not specified")
                   1554:        ,310
                   1555:        },              
                   1556:        {"datestr",                     js_datestr,                     0,      JSTYPE_STRING,  JSDOCSTR("[time=<i>current</i>]")
                   1557:        ,JSDOCSTR("convert time_t integer into a date string (in either <tt>MM/DD/YY</tt> or <tt>DD/MM/YY</tt> format), "
1.1.1.2 ! root     1558:                "defaults to current date if <i>time</i> not specified. "
        !          1559:                "If <i>time</i> is a string in the appropriate format, returns the time_t.")
1.1       root     1560:        ,310
                   1561:        },              
                   1562:        {"secondstr",           js_secondstr,           0,      JSTYPE_STRING,  JSDOCSTR("seconds")
                   1563:        ,JSDOCSTR("convert elapsed time in seconds into a string in <tt>hh:mm:ss</tt> format")
                   1564:        ,310
                   1565:        },              
                   1566:        {"spamlog",                     js_spamlog,                     6,      JSTYPE_BOOLEAN, JSDOCSTR("[protocol, action, reason, host, ip, to, from]")
                   1567:        ,JSDOCSTR("log a suspected SPAM attempt")
                   1568:        ,310
                   1569:        },              
                   1570:        {"hacklog",                     js_hacklog,                     5,      JSTYPE_BOOLEAN, JSDOCSTR("[protocol, user, text, host, ip, port]")
                   1571:        ,JSDOCSTR("log a suspected hack attempt")
                   1572:        ,310
                   1573:        },
                   1574:        {"filter_ip",           js_filter_ip,           4,      JSTYPE_BOOLEAN, JSDOCSTR("[protocol, reason, host, ip, username]")
                   1575:        ,JSDOCSTR("add an IP address (with comment) to the system's IP filter file")
                   1576:        ,311
                   1577:        },              
                   1578:        {"get_node_message",js_get_node_message,0,      JSTYPE_STRING,  JSDOCSTR("node_number")
                   1579:        ,JSDOCSTR("read any messages waiting for the specified node and return in a single string")
                   1580:        ,311
                   1581:        },              
                   1582:        {"put_node_message",js_put_node_message,2,      JSTYPE_BOOLEAN, JSDOCSTR("node_number, message_text")
                   1583:        ,JSDOCSTR("send a node a short text message, delivered immediately")
                   1584:        ,310
                   1585:        },              
                   1586:        {"get_telegram",        js_get_telegram,        1,      JSTYPE_STRING,  JSDOCSTR("user_number")
                   1587:        ,JSDOCSTR("returns any short text messages waiting for the specified user")
                   1588:        ,311
                   1589:        },              
                   1590:        {"put_telegram",        js_put_telegram,        2,      JSTYPE_BOOLEAN, JSDOCSTR("user_number, message_text")
                   1591:        ,JSDOCSTR("sends a user a short text message, delivered immediately or during next logon")
                   1592:        ,310
                   1593:        },              
                   1594:        {"newuser",                     js_new_user,            1,      JSTYPE_ALIAS },
1.1.1.2 ! root     1595:        {"new_user",            js_new_user,            1,      JSTYPE_OBJECT,  JSDOCSTR("name/alias [,client object]")
        !          1596:        ,JSDOCSTR("creates a new user record, returns a new <a href=#User>User</a> object representing the new user account, on success.<br>"
        !          1597:        "returns an numeric error code on failure (optional <i>client</i> object argument added in v3.15a)")
1.1       root     1598:        ,310
                   1599:        },
                   1600:        {"exec",                        js_exec,                        1,      JSTYPE_NUMBER,  JSDOCSTR("command-line")
                   1601:        ,JSDOCSTR("executes a native system/shell command-line, returns <i>0</i> on success")
                   1602:        ,311
                   1603:        },
                   1604:        {"popen",                       js_popen,                       0,      JSTYPE_ARRAY,   JSDOCSTR("command-line")
                   1605:        ,JSDOCSTR("executes a native system/shell command-line, returns array of captured output lines on success "
                   1606:                "(<b>only functional on UNIX systems</b>)")
                   1607:        ,311
                   1608:        },
                   1609:        {"check_syspass",       js_chksyspass,          1,      JSTYPE_BOOLEAN, JSDOCSTR("password")
1.1.1.2 ! root     1610:        ,JSDOCSTR("compares the supplied <i>password</i> against the system password and returns <i>true</i> if it matches")
1.1       root     1611:        ,311
                   1612:        },
1.1.1.2 ! root     1613:        {"check_name",          js_chkname,                     1,      JSTYPE_BOOLEAN, JSDOCSTR("name/alias")
        !          1614:        ,JSDOCSTR("checks that the provided name/alias string is suitable for a new user account, "
        !          1615:                "returns <i>true</i> if it is valid")
        !          1616:        ,315
        !          1617:        },
        !          1618:        {"check_pid",           js_chkpid,                      1,      JSTYPE_BOOLEAN, JSDOCSTR("process-ID")
        !          1619:        ,JSDOCSTR("checks that the provided process ID is a valid executing process on the system, "
        !          1620:                "returns <i>true</i> if it is valid")
        !          1621:        ,315
        !          1622:        },
        !          1623:        {"terminate_pid",       js_killpid,                     1,      JSTYPE_BOOLEAN, JSDOCSTR("process-ID")
        !          1624:        ,JSDOCSTR("terminates executing process on the system with the specified process ID, "
        !          1625:                "returns <i>true</i> on success")
        !          1626:        ,315
        !          1627:        },
1.1       root     1628:        {0}
                   1629: };
                   1630: 
                   1631: 
                   1632: /* node properties */
                   1633: enum {
                   1634:        /* raw node_t fields */
                   1635:         NODE_PROP_STATUS
                   1636:        ,NODE_PROP_ERRORS
                   1637:        ,NODE_PROP_ACTION
                   1638:        ,NODE_PROP_USERON
                   1639:        ,NODE_PROP_CONNECTION
                   1640:        ,NODE_PROP_MISC
                   1641:        ,NODE_PROP_AUX
                   1642:        ,NODE_PROP_EXTAUX
1.1.1.2 ! root     1643:        ,NODE_PROP_DIR
1.1       root     1644: };
                   1645: 
                   1646: #ifdef BUILD_JSDOCS
                   1647: static char* node_prop_desc[] = {
                   1648:         "status (see <tt>nodedefs.js</tt> for valid values)"
                   1649:        ,"error counter"
                   1650:        ,"current user action (see <tt>nodedefs.js</tt>)"
                   1651:        ,"current user number"
                   1652:        ,"connection speed (<tt>0xffff</tt> = Telnet or RLogin)"
                   1653:        ,"miscellaneous bitfield (see <tt>nodedefs.js</tt>)"
                   1654:        ,"auxillary value"
                   1655:        ,"extended auxillary value"
1.1.1.2 ! root     1656:        ,"node directory"
1.1       root     1657:        ,NULL
                   1658: };
                   1659: #endif
                   1660: 
                   1661: 
                   1662: static JSBool js_node_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                   1663: {
                   1664:        uint            node_num;
                   1665:     jsint       tiny;
                   1666:        node_t          node;
                   1667:        scfg_t*         cfg;
                   1668:        JSObject*       sysobj;
                   1669:        JSObject*       node_list;
1.1.1.2 ! root     1670:        jsrefcount      rc;
        !          1671:        JSString*       js_str;
1.1       root     1672: 
                   1673:        tiny = JSVAL_TO_INT(id);
                   1674: 
                   1675:        if((node_list=JS_GetParent(cx, obj))==NULL)
                   1676:                return(JS_FALSE);
                   1677: 
                   1678:        if((sysobj=JS_GetParent(cx, node_list))==NULL)
                   1679:                return(JS_FALSE);
                   1680: 
                   1681:        if((cfg=(scfg_t*)JS_GetPrivate(cx,sysobj))==NULL)
                   1682:                return(JS_FALSE);
                   1683: 
                   1684:        node_num=(uint)JS_GetPrivate(cx,obj)>>1;
                   1685: 
1.1.1.2 ! root     1686:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1687:        memset(&node,0,sizeof(node));
1.1.1.2 ! root     1688:        if(getnodedat(cfg, node_num, &node, NULL)) {
        !          1689:                JS_RESUMEREQUEST(cx, rc);
1.1       root     1690:                return(JS_TRUE);
1.1.1.2 ! root     1691:        }
        !          1692:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1693:        
                   1694:     switch(tiny) {
                   1695:                case NODE_PROP_STATUS:
                   1696:                        *vp = INT_TO_JSVAL((int)node.status);
                   1697:                        break;
                   1698:                case NODE_PROP_ERRORS:  
                   1699:                        *vp = INT_TO_JSVAL((int)node.errors);
                   1700:                        break;
                   1701:                case NODE_PROP_ACTION:  
                   1702:                        *vp = INT_TO_JSVAL((int)node.action);
                   1703:                        break;
                   1704:                case NODE_PROP_USERON:  
                   1705:                        *vp = INT_TO_JSVAL((int)node.useron);
                   1706:                        break;
                   1707:                case NODE_PROP_CONNECTION:
                   1708:                        *vp = INT_TO_JSVAL((int)node.connection);
                   1709:                        break;
                   1710:                case NODE_PROP_MISC:            
                   1711:                        *vp = INT_TO_JSVAL((int)node.misc);
                   1712:                        break;
                   1713:                case NODE_PROP_AUX:             
                   1714:                        *vp = INT_TO_JSVAL((int)node.aux);
                   1715:                        break;
                   1716:                case NODE_PROP_EXTAUX:  
                   1717:                        JS_NewNumberValue(cx,node.extaux,vp);
                   1718:                        break;
1.1.1.2 ! root     1719:                case NODE_PROP_DIR:
        !          1720:                        if((js_str=JS_NewStringCopyZ(cx, cfg->node_path[node_num-1]))==NULL)
        !          1721:                                return(JS_FALSE);
        !          1722:                        *vp = STRING_TO_JSVAL(js_str);
        !          1723:                        break;
1.1       root     1724:        }
                   1725:        return(JS_TRUE);
                   1726: }
                   1727: 
                   1728: static JSBool js_node_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                   1729: {
                   1730:        uint            node_num;
                   1731:        int                     file;
                   1732:        jsint           val=0;
                   1733:     jsint       tiny;
                   1734:        node_t          node;
                   1735:        scfg_t*         cfg;
                   1736:        JSObject*       sysobj;
                   1737:        JSObject*       node_list;
1.1.1.2 ! root     1738:        jsrefcount      rc;
1.1       root     1739: 
                   1740:        if((node_list=JS_GetParent(cx, obj))==NULL)
                   1741:                return(JS_FALSE);
                   1742: 
                   1743:        if((sysobj=JS_GetParent(cx, node_list))==NULL)
                   1744:                return(JS_FALSE);
                   1745: 
                   1746:        if((cfg=(scfg_t*)JS_GetPrivate(cx,sysobj))==NULL)
                   1747:                return(JS_FALSE);
                   1748: 
                   1749:        node_num=(uint)JS_GetPrivate(cx,obj)>>1;
                   1750: 
1.1.1.2 ! root     1751:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1752:        memset(&node,0,sizeof(node));
1.1.1.2 ! root     1753:        if(getnodedat(cfg, node_num, &node, &file)) {
        !          1754:                JS_RESUMEREQUEST(cx, rc);
1.1       root     1755:                return(JS_TRUE);
1.1.1.2 ! root     1756:        }
1.1       root     1757: 
1.1.1.2 ! root     1758:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1759:        if(JSVAL_IS_NUMBER(*vp))
                   1760:                JS_ValueToInt32(cx, *vp, &val);
                   1761: 
                   1762:        tiny = JSVAL_TO_INT(id);
1.1.1.2 ! root     1763:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1764:        
                   1765:     switch(tiny) {
                   1766:                case NODE_PROP_STATUS:
                   1767:                        node.status=(BYTE)val;
                   1768:                        break;
                   1769:                case NODE_PROP_ERRORS:  
                   1770:                        node.errors=(BYTE)val;
                   1771:                        break;
                   1772:                case NODE_PROP_ACTION:  
                   1773:                        node.action=(BYTE)val;
                   1774:                        break;
                   1775:                case NODE_PROP_USERON:  
                   1776:                        node.useron=(WORD)val;
                   1777:                        break;
                   1778:                case NODE_PROP_CONNECTION:
                   1779:                        node.connection=(WORD)val;
                   1780:                        break;
                   1781:                case NODE_PROP_MISC:            
                   1782:                        node.misc=(WORD)val;
                   1783:                        break;
                   1784:                case NODE_PROP_AUX:             
                   1785:                        node.aux=(WORD)val;
                   1786:                        break;
                   1787:                case NODE_PROP_EXTAUX:  
                   1788:                        node.extaux=val;
                   1789:                        break;
                   1790:        }
                   1791:        putnodedat(cfg,node_num,&node,file);
1.1.1.2 ! root     1792:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1793: 
                   1794:        return(JS_TRUE);
                   1795: }
                   1796: 
                   1797: static jsSyncPropertySpec js_node_properties[] = {
                   1798: /*              name,                                          tinyid,                                 flags,                          ver     */
                   1799: 
                   1800: /* raw node_t fields */
                   1801:        {       "status",                                       NODE_PROP_STATUS,               JSPROP_ENUMERATE,       310 },
                   1802:        {       "errors",                                       NODE_PROP_ERRORS,               JSPROP_ENUMERATE,       310 },
                   1803:        {       "action",                                       NODE_PROP_ACTION,               JSPROP_ENUMERATE,       310 },
                   1804:        {       "useron",                                       NODE_PROP_USERON,               JSPROP_ENUMERATE,       310 },
                   1805:        {       "connection",                           NODE_PROP_CONNECTION,   JSPROP_ENUMERATE,       310 },
                   1806:        {       "misc",                                         NODE_PROP_MISC,                 JSPROP_ENUMERATE,       310 },
                   1807:        {       "aux",                                          NODE_PROP_AUX,                  JSPROP_ENUMERATE,       310 },
                   1808:        {       "extaux",                                       NODE_PROP_EXTAUX,               JSPROP_ENUMERATE,       310 },
1.1.1.2 ! root     1809:        {       "dir",                                          NODE_PROP_DIR,                  JSPROP_ENUMERATE|JSPROP_READONLY,       315 },
1.1       root     1810:        {0}
                   1811: };
                   1812: 
1.1.1.2 ! root     1813: static JSBool js_node_resolve(JSContext *cx, JSObject *obj, jsval id)
        !          1814: {
        !          1815:        char*                   name=NULL;
        !          1816: 
        !          1817:        if(id != JSVAL_NULL)
        !          1818:                name=JS_GetStringBytes(JSVAL_TO_STRING(id));
        !          1819: 
        !          1820:        return(js_SyncResolve(cx, obj, name, js_node_properties, NULL, NULL, 0));
        !          1821: }
        !          1822: 
        !          1823: static JSBool js_node_enumerate(JSContext *cx, JSObject *obj)
        !          1824: {
        !          1825:        return(js_node_resolve(cx, obj, JSVAL_NULL));
        !          1826: }
        !          1827: 
1.1       root     1828: static JSClass js_node_class = {
                   1829:      "Node"                                    /* name                 */
                   1830:     ,JSCLASS_HAS_PRIVATE       /* flags                */
                   1831:        ,JS_PropertyStub                /* addProperty  */
                   1832:        ,JS_PropertyStub                /* delProperty  */
                   1833:        ,js_node_get                    /* getProperty  */
                   1834:        ,js_node_set                    /* setProperty  */
1.1.1.2 ! root     1835:        ,js_node_enumerate              /* enumerate    */
        !          1836:        ,js_node_resolve                /* resolve              */
1.1       root     1837:        ,JS_ConvertStub                 /* convert              */
                   1838:        ,JS_FinalizeStub                /* finalize             */
                   1839: };
                   1840: 
1.1.1.2 ! root     1841: #define LAZY_INTEGER(PropName, PropValue) \
        !          1842:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !          1843:                JS_NewNumberValue(cx,(PropValue),&val); \
        !          1844:                JS_DefineProperty(cx, obj, (PropName), val, NULL,NULL,JSPROP_ENUMERATE); \
        !          1845:                if(name) return(JS_TRUE); \
        !          1846:        }
        !          1847: 
        !          1848: #define LAZY_STRING(PropName, PropValue) \
        !          1849:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !          1850:                if((js_str=JS_NewStringCopyZ(cx, (PropValue)))!=NULL) { \
        !          1851:                        JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, JSPROP_ENUMERATE); \
        !          1852:                        if(name) return(JS_TRUE); \
        !          1853:                } \
        !          1854:                else if(name) return(JS_TRUE); \
        !          1855:        }
        !          1856: 
        !          1857: #define LAZY_STRFUNC(PropName, Function, PropValue) \
        !          1858:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !          1859:                Function; \
        !          1860:                if((js_str=JS_NewStringCopyZ(cx, (PropValue)))!=NULL) { \
        !          1861:                        JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, JSPROP_ENUMERATE); \
        !          1862:                        if(name) return(JS_TRUE); \
        !          1863:                } \
        !          1864:                else if(name) return(JS_TRUE); \
        !          1865:        }
        !          1866: 
        !          1867: #define LAZY_STRFUNC_TRUNCSP(PropName, Function, PropValue) \
        !          1868:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !          1869:                Function; \
        !          1870:                if((js_str=JS_NewStringCopyZ(cx, truncsp(PropValue)))!=NULL) { \
        !          1871:                        JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, JSPROP_ENUMERATE); \
        !          1872:                        if(name) return(JS_TRUE); \
        !          1873:                } \
        !          1874:                else if(name) return(JS_TRUE); \
        !          1875:        }
        !          1876: 
        !          1877: static JSBool js_system_resolve(JSContext *cx, JSObject *obj, jsval id)
1.1       root     1878: {
1.1.1.2 ! root     1879:        char*           name=NULL;
1.1       root     1880:        jsval           val;
1.1.1.2 ! root     1881:        char            str[256];
1.1       root     1882:        JSString*       js_str;
1.1.1.2 ! root     1883:        JSObject*       newobj;
        !          1884:        JSObject*       nodeobj;
        !          1885:        scfg_t*         cfg;
        !          1886:        uint            i;
1.1       root     1887: 
1.1.1.2 ! root     1888:        if(id != JSVAL_NULL)
        !          1889:                name=JS_GetStringBytes(JSVAL_TO_STRING(id));
1.1       root     1890: 
                   1891:        /****************************/
                   1892:        /* static string properties */
1.1.1.2 ! root     1893:        LAZY_STRING("version", VERSION);
        !          1894:        LAZY_STRFUNC("revision", sprintf(str,"%c",REVISION), str);
        !          1895:        LAZY_STRFUNC_TRUNCSP("beta_version", SAFECOPY(str, beta_version), str);
        !          1896: 
        !          1897:        if(name==NULL || strcmp(name, "full_version")==0) {
        !          1898:                sprintf(str,"%s%c%s",VERSION,REVISION,beta_version);
        !          1899:                truncsp(str);
1.1       root     1900: #if defined(_DEBUG)
1.1.1.2 ! root     1901:                strcat(str," Debug");
1.1       root     1902: #endif
1.1.1.2 ! root     1903:                if((js_str=JS_NewStringCopyZ(cx, str))!=NULL) {
        !          1904:                        val = STRING_TO_JSVAL(js_str);
        !          1905:                        JS_SetProperty(cx, obj, "full_version", &val);
        !          1906:                        if(name) return(JS_TRUE);
        !          1907:                }
        !          1908:                else if(name) return(JS_TRUE);
        !          1909:        }
1.1       root     1910: 
1.1.1.2 ! root     1911:        LAZY_STRING("version_notice", VERSION_NOTICE);
1.1       root     1912: 
                   1913:        /* Numeric version properties */
1.1.1.2 ! root     1914:        LAZY_INTEGER("version_num", VERSION_NUM);
        !          1915:        LAZY_INTEGER("version_hex", VERSION_HEX);
1.1       root     1916: 
1.1.1.2 ! root     1917:        LAZY_STRING("platform", PLATFORM_DESC);
        !          1918:        LAZY_STRING("architecture", ARCHITECTURE_DESC);
        !          1919:        LAZY_STRFUNC("msgbase_lib", sprintf(str,"SMBLIB %s",smb_lib_ver()), str);
        !          1920:        LAZY_STRFUNC("compiled_with", DESCRIBE_COMPILER(str), str);
        !          1921:        LAZY_STRFUNC("compiled_when", sprintf(str,"%s %.5s",__DATE__,__TIME__), str);
        !          1922:        LAZY_STRING("copyright", COPYRIGHT_NOTICE);
        !          1923:        LAZY_STRING("js_version", (char *)JS_GetImplementationVersion());
        !          1924:        LAZY_STRING("os_version", os_version(str));
1.1       root     1925: 
1.1.1.2 ! root     1926:        /* fido_addr_list property */
        !          1927:        if(name==NULL || strcmp(name, "fido_addr_list")==0) {
        !          1928:                if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
        !          1929:                        return(JS_FALSE);
1.1       root     1930: 
1.1.1.2 ! root     1931:                if((newobj=JS_NewArrayObject(cx, 0, NULL))==NULL)
        !          1932:                        return(JS_FALSE);
1.1       root     1933: 
1.1.1.2 ! root     1934:                if(!JS_SetParent(cx, newobj, obj))
        !          1935:                        return(JS_FALSE);
1.1       root     1936: 
1.1.1.2 ! root     1937:                if(!JS_DefineProperty(cx, obj, "fido_addr_list", OBJECT_TO_JSVAL(newobj)
        !          1938:                        , NULL, NULL, JSPROP_ENUMERATE))
        !          1939:                        return(JS_FALSE);
1.1       root     1940: 
1.1.1.2 ! root     1941:                for(i=0;i<cfg->total_faddrs;i++) {
        !          1942:                        val=STRING_TO_JSVAL(JS_NewStringCopyZ(cx,smb_faddrtoa(&cfg->faddr[i],str)));
        !          1943:                        JS_SetElement(cx, newobj, i, &val);
        !          1944:                }
        !          1945:                if(name) return(JS_TRUE);
        !          1946:        }
1.1       root     1947: 
1.1.1.2 ! root     1948:        if(name==NULL || strcmp(name, "stats")==0) {
        !          1949:                if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
        !          1950:                        return(JS_FALSE);
1.1       root     1951: 
1.1.1.2 ! root     1952:                newobj = JS_DefineObject(cx, obj, "stats", &js_sysstats_class, NULL
        !          1953:                        ,JSPROP_ENUMERATE|JSPROP_READONLY);
1.1       root     1954: 
1.1.1.2 ! root     1955:                if(newobj==NULL)
        !          1956:                        return(JS_FALSE);
1.1       root     1957: 
1.1.1.2 ! root     1958:                JS_SetPrivate(cx, newobj, cfg); /* Store a pointer to scfg_t */
        !          1959:        }
1.1       root     1960: 
1.1.1.2 ! root     1961:        /* node_list property */
        !          1962:        if(name==NULL || strcmp(name, "node_list")==0) {
        !          1963:                if((cfg=(scfg_t*)JS_GetPrivate(cx,obj))==NULL)
        !          1964:                        return(JS_FALSE);
1.1       root     1965: 
1.1.1.2 ! root     1966:                if((newobj=JS_NewArrayObject(cx, 0, NULL))==NULL) 
        !          1967:                        return(JS_FALSE);
1.1       root     1968: 
1.1.1.2 ! root     1969:                if(!JS_SetParent(cx, newobj, obj))
        !          1970:                        return(JS_FALSE);
1.1       root     1971: 
1.1.1.2 ! root     1972:                if(!JS_DefineProperty(cx, obj, "node_list", OBJECT_TO_JSVAL(newobj)
        !          1973:                        , NULL, NULL, JSPROP_ENUMERATE))
        !          1974:                        return(JS_FALSE);
1.1       root     1975: 
1.1.1.2 ! root     1976:                for(i=0;i<cfg->sys_nodes && i<cfg->sys_lastnode;i++) {
        !          1977: 
        !          1978:                        nodeobj = JS_NewObject(cx, &js_node_class, NULL, newobj);
        !          1979: 
        !          1980:                        if(nodeobj==NULL)
        !          1981:                                return(JS_FALSE);
        !          1982: 
        !          1983:                        /* Store node number */
        !          1984:                        /* We have to shift it to make it look like a pointer to JS. :-( */
        !          1985:                        if(!JS_SetPrivate(cx, nodeobj, (char*)((i+1)<<1)))
        !          1986:                                return(JS_FALSE);
        !          1987: 
        !          1988:        #ifdef BUILD_JSDOCS
        !          1989:                        if(i==0) {
        !          1990:                                js_DescribeSyncObject(cx,nodeobj,"BBS node listing",310);
        !          1991:                                js_CreateArrayOfStrings(cx, nodeobj, "_property_desc_list", node_prop_desc, JSPROP_READONLY);
        !          1992:                        }
        !          1993:        #endif
        !          1994: 
        !          1995:                        val=OBJECT_TO_JSVAL(nodeobj);
        !          1996:                        if(!JS_SetElement(cx, newobj, i, &val))
        !          1997:                                return(JS_FALSE);
        !          1998:                }
        !          1999:                if(name) return(JS_TRUE);
1.1       root     2000:        }
                   2001: 
                   2002: 
1.1.1.2 ! root     2003:        return(js_SyncResolve(cx, obj, name, js_system_properties, js_system_functions, NULL, 0));
        !          2004: }
1.1       root     2005: 
1.1.1.2 ! root     2006: static JSBool js_system_enumerate(JSContext *cx, JSObject *obj)
        !          2007: {
        !          2008:        return(js_node_resolve(cx, obj, JSVAL_NULL));
        !          2009: }
1.1       root     2010: 
1.1.1.2 ! root     2011: static JSClass js_system_class = {
        !          2012:      "System"                          /* name                 */
        !          2013:     ,JSCLASS_HAS_PRIVATE       /* flags                */
        !          2014:        ,JS_PropertyStub                /* addProperty  */
        !          2015:        ,JS_PropertyStub                /* delProperty  */
        !          2016:        ,js_system_get                  /* getProperty  */
        !          2017:        ,js_system_set                  /* setProperty  */
        !          2018:        ,js_system_enumerate    /* enumerate    */
        !          2019:        ,js_system_resolve              /* resolve              */
        !          2020:        ,JS_ConvertStub                 /* convert              */
        !          2021:        ,JS_FinalizeStub                /* finalize             */
        !          2022: };
1.1       root     2023: 
1.1.1.2 ! root     2024: JSObject* DLLCALL js_CreateSystemObject(JSContext* cx, JSObject* parent
        !          2025:                                                                                ,scfg_t* cfg, time_t uptime, char* host_name, char* socklib_desc)
        !          2026: {
        !          2027:        jsval           val;
        !          2028:        JSObject*       sysobj;
        !          2029:        JSString*       js_str;
        !          2030:        char            str[256];
1.1       root     2031: 
1.1.1.2 ! root     2032:        sysobj = JS_DefineObject(cx, parent, "system", &js_system_class, NULL
        !          2033:                ,JSPROP_ENUMERATE|JSPROP_READONLY);
1.1       root     2034: 
1.1.1.2 ! root     2035:        if(sysobj==NULL)
1.1       root     2036:                return(NULL);
                   2037: 
1.1.1.2 ! root     2038:        if(!JS_SetPrivate(cx, sysobj, cfg))     /* Store a pointer to scfg_t */
1.1       root     2039:                return(NULL);
                   2040: 
1.1.1.2 ! root     2041:        /****************************/
        !          2042:        /* static string properties */
        !          2043:        if((js_str=JS_NewStringCopyZ(cx, host_name))==NULL)
        !          2044:                return(NULL);
        !          2045:        val = STRING_TO_JSVAL(js_str);
        !          2046:        if(!JS_SetProperty(cx, sysobj, "host_name", &val))
        !          2047:                return(NULL);
1.1       root     2048: 
1.1.1.2 ! root     2049:        if((js_str=JS_NewStringCopyZ(cx, socklib_version(str, socklib_desc)))==NULL)
        !          2050:                return(NULL);
        !          2051:        val = STRING_TO_JSVAL(js_str);
        !          2052:        if(!JS_SetProperty(cx, sysobj, "socket_lib", &val))
        !          2053:                return(NULL);
1.1       root     2054: 
1.1.1.2 ! root     2055:        /***********************/
1.1       root     2056: 
1.1.1.2 ! root     2057:        JS_NewNumberValue(cx,uptime,&val);
        !          2058:        if(!JS_SetProperty(cx, sysobj, "uptime", &val))
        !          2059:                return(NULL);
1.1       root     2060: 
                   2061: #ifdef BUILD_JSDOCS
1.1.1.2 ! root     2062:        js_DescribeSyncObject(cx,sysobj,"Global system-related properties and methods",310);
        !          2063:        js_CreateArrayOfStrings(cx, sysobj, "_property_desc_list", sys_prop_desc, JSPROP_READONLY);
1.1       root     2064: #endif
                   2065: 
1.1.1.2 ! root     2066: #ifdef BUILD_JSDOCS
        !          2067:        {
        !          2068:                JSObject*       statsobj;
        !          2069: 
        !          2070:                js_DescribeSyncObject(cx,statsobj,"System statistics",310);
        !          2071:                js_CreateArrayOfStrings(cx, statsobj, "_property_desc_list", sysstat_prop_desc, JSPROP_READONLY);
        !          2072:        }
        !          2073: #endif
1.1       root     2074: 
                   2075:        return(sysobj);
                   2076: }
                   2077: 
                   2078: #endif /* JAVSCRIPT */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.