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

1.1       root        1: /* js_msgbase.c */
                      2: 
                      3: /* Synchronet JavaScript "MsgBase" Object */
                      4: 
1.1.1.2 ! root        5: /* $Id: js_msgbase.c,v 1.155 2011/08/30 22:51:21 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: 
1.1.1.2 ! root       43: static scfg_t*                 scfg=NULL;
1.1       root       44: 
                     45: typedef struct
                     46: {
                     47:        smb_t   smb;
                     48:        int             status;
                     49:        BOOL    debug;
                     50: 
                     51: } private_t;
                     52: 
1.1.1.2 ! root       53: typedef struct
        !            54: {
        !            55:        private_t       *p;
        !            56:        BOOL            expand_fields;
        !            57:        smbmsg_t        msg;
        !            58: 
        !            59: } privatemsg_t;
        !            60: 
1.1       root       61: static const char* getprivate_failure = "line %d %s JS_GetPrivate failed";
                     62: 
                     63: /* Destructor */
                     64: 
                     65: static void js_finalize_msgbase(JSContext *cx, JSObject *obj)
                     66: {
                     67:        private_t* p;
                     68:        
                     69:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
                     70:                return;
                     71: 
                     72:        if(SMB_IS_OPEN(&(p->smb)))
                     73:                smb_close(&(p->smb));
                     74: 
                     75:        free(p);
                     76: 
                     77:        JS_SetPrivate(cx, obj, NULL);
                     78: }
                     79: 
                     80: /* Methods */
                     81: 
                     82: static JSBool
                     83: js_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                     84: {
                     85:        private_t* p;
1.1.1.2 ! root       86:        jsrefcount      rc;
1.1       root       87:        
                     88:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                     89:                JS_ReportError(cx,getprivate_failure,WHERE);
                     90:                return(JS_FALSE);
                     91:        }
                     92: 
                     93:        *rval = JSVAL_FALSE;
                     94: 
                     95:        if(p->smb.subnum==INVALID_SUB 
                     96:                && strchr(p->smb.file,'/')==NULL
                     97:                && strchr(p->smb.file,'\\')==NULL) {
                     98:                JS_ReportError(cx,"Unrecognized msgbase code: %s",p->smb.file);
                     99:                return(JS_TRUE);
                    100:        }
                    101: 
1.1.1.2 ! root      102:        rc=JS_SUSPENDREQUEST(cx);
        !           103:        if((p->status=smb_open(&(p->smb)))!=SMB_SUCCESS) {
        !           104:                JS_RESUMEREQUEST(cx, rc);
1.1       root      105:                return(JS_TRUE);
1.1.1.2 ! root      106:        }
        !           107:        JS_RESUMEREQUEST(cx, rc);
1.1       root      108: 
                    109:        *rval = JSVAL_TRUE;
                    110:        return(JS_TRUE);
                    111: }
                    112: 
                    113: 
                    114: static JSBool
                    115: js_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    116: {
                    117:        private_t* p;
1.1.1.2 ! root      118:        jsrefcount      rc;
1.1       root      119:        
                    120:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    121:                JS_ReportError(cx,getprivate_failure,WHERE);
                    122:                return(JS_FALSE);
                    123:        }
                    124: 
1.1.1.2 ! root      125:        rc=JS_SUSPENDREQUEST(cx);
1.1       root      126:        smb_close(&(p->smb));
1.1.1.2 ! root      127:        JS_RESUMEREQUEST(cx, rc);
1.1       root      128: 
                    129:        return(JS_TRUE);
                    130: }
                    131: 
                    132: static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg)
                    133: {
                    134:        char*           cp;
                    135:        char            to[256];
                    136:        ushort          nettype=NET_UNKNOWN;
                    137:        ushort          agent;
                    138:        int32           i32;
                    139:        jsval           val;
                    140: 
                    141:        if(JS_GetProperty(cx, hdr, "to", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    142:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    143:                        return(FALSE);
                    144:        } else {
                    145:                if(p->smb.status.attr&SMB_EMAIL)        /* e-mail */
                    146:                        return(FALSE);                                  /* "to" property required */
                    147:                cp="All";
                    148:        }
1.1.1.2 ! root      149: 
1.1       root      150:        if((p->status=smb_hfield_str(msg, RECIPIENT, cp))!=SMB_SUCCESS)
                    151:                return(FALSE);
                    152:        if(!(p->smb.status.attr&SMB_EMAIL)) {
                    153:                SAFECOPY(to,cp);
                    154:                strlwr(to);
                    155:                msg->idx.to=crc16(to,0);
                    156:        }
                    157: 
                    158:        if(JS_GetProperty(cx, hdr, "to_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    159:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    160:                        return(FALSE);
                    161:                if((p->status=smb_hfield_str(msg, RECIPIENTEXT, cp))!=SMB_SUCCESS)
                    162:                        return(FALSE);
                    163:                if(p->smb.status.attr&SMB_EMAIL)
                    164:                        msg->idx.to=atoi(cp);
                    165:        }
                    166: 
                    167:        if(JS_GetProperty(cx, hdr, "to_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    168:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    169:                        return(FALSE);
                    170:                if((p->status=smb_hfield_str(msg, RECIPIENTORG, cp))!=SMB_SUCCESS)
                    171:                        return(FALSE);
                    172:        }
                    173: 
                    174:        if(JS_GetProperty(cx, hdr, "to_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    175:                JS_ValueToInt32(cx,val,&i32);
                    176:                nettype=(ushort)i32;
                    177:        }
                    178: 
                    179:        if(JS_GetProperty(cx, hdr, "to_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    180:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    181:                        return(FALSE);
                    182:                if((p->status=smb_hfield_netaddr(msg, RECIPIENTNETADDR, cp, &nettype))!=SMB_SUCCESS)
                    183:                        return(FALSE);
                    184:        }
                    185: 
                    186:        if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
                    187:                if(p->smb.status.attr&SMB_EMAIL)
                    188:                        msg->idx.to=0;
                    189:                if((p->status=smb_hfield_bin(msg, RECIPIENTNETTYPE, nettype))!=SMB_SUCCESS)
                    190:                        return(FALSE);
                    191:        }
                    192: 
                    193:        if(JS_GetProperty(cx, hdr, "to_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    194:                JS_ValueToInt32(cx,val,&i32);
                    195:                agent=(ushort)i32;
                    196:                if((p->status=smb_hfield_bin(msg, RECIPIENTAGENT, agent))!=SMB_SUCCESS)
                    197:                        return(FALSE);
                    198:        }
                    199: 
                    200:        return(TRUE);
                    201: }
                    202: 
                    203: static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg
                    204:                                                                ,BOOL recipient)
                    205: {
                    206:        char*           cp;
                    207:        char            from[256];
                    208:        ushort          nettype=NET_UNKNOWN;
                    209:        ushort          type;
                    210:        ushort          agent;
                    211:        int32           i32;
                    212:        jsval           val;
                    213:        JSObject*       array;
                    214:        JSObject*       field;
                    215:        jsuint          i,len;
                    216: 
                    217:        if(hdr==NULL)
                    218:                return(FALSE);
                    219: 
                    220:        if(recipient && !parse_recipient_object(cx,p,hdr,msg))
                    221:                return(FALSE);
                    222: 
                    223:        /* Required Header Fields */
                    224:        if(JS_GetProperty(cx, hdr, "subject", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    225:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    226:                        return(FALSE);
                    227:        } else
                    228:                cp="";
                    229:        if((p->status=smb_hfield_str(msg, SUBJECT, cp))!=SMB_SUCCESS)
                    230:                return(FALSE);
                    231:        msg->idx.subj=smb_subject_crc(cp);
                    232: 
                    233:        if(JS_GetProperty(cx, hdr, "from", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    234:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    235:                        return(FALSE);
                    236:        } else
                    237:                return(FALSE);  /* "from" property required */
                    238:        if((p->status=smb_hfield_str(msg, SENDER, cp))!=SMB_SUCCESS)
                    239:                return(FALSE);
                    240:        if(!(p->smb.status.attr&SMB_EMAIL)) {
                    241:                SAFECOPY(from,cp);
                    242:                strlwr(from);
                    243:                msg->idx.from=crc16(from,0);
                    244:        }
                    245: 
                    246:        /* Optional Header Fields */
                    247:        if(JS_GetProperty(cx, hdr, "from_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    248:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    249:                        return(FALSE);
                    250:                if((p->status=smb_hfield_str(msg, SENDEREXT, cp))!=SMB_SUCCESS)
                    251:                        return(FALSE);
                    252:                if(p->smb.status.attr&SMB_EMAIL)
                    253:                        msg->idx.from=atoi(cp);
                    254:        }
                    255: 
                    256:        if(JS_GetProperty(cx, hdr, "from_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    257:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    258:                        return(FALSE);
                    259:                if((p->status=smb_hfield_str(msg, SENDERORG, cp))!=SMB_SUCCESS)
                    260:                        return(FALSE);
                    261:        }
                    262: 
                    263:        if(JS_GetProperty(cx, hdr, "from_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    264:                JS_ValueToInt32(cx,val,&i32);
                    265:                nettype=(ushort)i32;
                    266:        }
                    267: 
                    268:        if(JS_GetProperty(cx, hdr, "from_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    269:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    270:                        return(FALSE);
                    271:                if((p->status=smb_hfield_netaddr(msg, SENDERNETADDR, cp, &nettype))!=SMB_SUCCESS)
                    272:                        return(FALSE);
                    273:        }
                    274:        
                    275:        if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
                    276:                if(p->smb.status.attr&SMB_EMAIL)
                    277:                        msg->idx.from=0;
                    278:                if((p->status=smb_hfield_bin(msg, SENDERNETTYPE, nettype))!=SMB_SUCCESS)
                    279:                        return(FALSE);
                    280:        }
                    281: 
                    282:        if(JS_GetProperty(cx, hdr, "from_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    283:                JS_ValueToInt32(cx,val,&i32);
                    284:                agent=(ushort)i32;
                    285:                if((p->status=smb_hfield_bin(msg, SENDERAGENT, agent))!=SMB_SUCCESS)
                    286:                        return(FALSE);
                    287:        }
                    288: 
                    289:        if(JS_GetProperty(cx, hdr, "from_ip_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    290:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    291:                        return(FALSE);
                    292:                if((p->status=smb_hfield_str(msg, SENDERIPADDR, cp))!=SMB_SUCCESS)
                    293:                        return(FALSE);
                    294:        }
                    295: 
                    296:        if(JS_GetProperty(cx, hdr, "from_host_name", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    297:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    298:                        return(FALSE);
                    299:                if((p->status=smb_hfield_str(msg, SENDERHOSTNAME, cp))!=SMB_SUCCESS)
                    300:                        return(FALSE);
                    301:        }
                    302: 
                    303:        if(JS_GetProperty(cx, hdr, "from_protocol", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    304:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    305:                        return(FALSE);
                    306:                if((p->status=smb_hfield_str(msg, SENDERPROTOCOL, cp))!=SMB_SUCCESS)
                    307:                        return(FALSE);
                    308:        }
                    309: 
                    310:        if(JS_GetProperty(cx, hdr, "from_port", &val) && !JSVAL_NULL_OR_VOID(val)) {
1.1.1.2 ! root      311:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
        !           312:                        return(FALSE);
        !           313:                if((p->status=smb_hfield_str(msg, SENDERPORT, cp))!=SMB_SUCCESS)
1.1       root      314:                        return(FALSE);
                    315:        }
                    316: 
                    317:        if(JS_GetProperty(cx, hdr, "replyto", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    318:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    319:                        return(FALSE);
                    320:                if((p->status=smb_hfield_str(msg, REPLYTO, cp))!=SMB_SUCCESS)
                    321:                        return(FALSE);
                    322:        }
                    323: 
                    324:        if(JS_GetProperty(cx, hdr, "replyto_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    325:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    326:                        return(FALSE);
                    327:                if((p->status=smb_hfield_str(msg, REPLYTOEXT, cp))!=SMB_SUCCESS)
                    328:                        return(FALSE);
                    329:        }
                    330: 
                    331:        if(JS_GetProperty(cx, hdr, "replyto_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    332:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    333:                        return(FALSE);
                    334:                if((p->status=smb_hfield_str(msg, REPLYTOORG, cp))!=SMB_SUCCESS)
                    335:                        return(FALSE);
                    336:        }
                    337: 
                    338:        nettype=NET_UNKNOWN;
                    339:        if(JS_GetProperty(cx, hdr, "replyto_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    340:                JS_ValueToInt32(cx,val,&i32);
                    341:                nettype=(ushort)i32;
                    342:        }
                    343:        if(JS_GetProperty(cx, hdr, "replyto_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    344:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    345:                        return(FALSE);
                    346:                if((p->status=smb_hfield_netaddr(msg, REPLYTONETADDR, cp, &nettype))!=SMB_SUCCESS)
                    347:                        return(FALSE);
                    348:        }
                    349:        if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
                    350:                if((p->status=smb_hfield_bin(msg, REPLYTONETTYPE, nettype))!=SMB_SUCCESS)
                    351:                        return(FALSE);
                    352:        }
                    353: 
                    354:        if(JS_GetProperty(cx, hdr, "replyto_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    355:                JS_ValueToInt32(cx,val,&i32);
                    356:                agent=(ushort)i32;
                    357:                if((p->status=smb_hfield_bin(msg, REPLYTOAGENT, agent))!=SMB_SUCCESS)
                    358:                        return(FALSE);
                    359:        }
                    360: 
                    361:        /* RFC822 headers */
                    362:        if(JS_GetProperty(cx, hdr, "id", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    363:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    364:                        return(FALSE);
                    365:                if((p->status=smb_hfield_str(msg, RFC822MSGID, cp))!=SMB_SUCCESS)
                    366:                        return(FALSE);
                    367:        }
                    368: 
                    369:        if(JS_GetProperty(cx, hdr, "reply_id", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    370:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    371:                        return(FALSE);
                    372:                if((p->status=smb_hfield_str(msg, RFC822REPLYID, cp))!=SMB_SUCCESS)
                    373:                        return(FALSE);
                    374:        }
                    375: 
                    376:        /* SMTP headers */
                    377:        if(JS_GetProperty(cx, hdr, "reverse_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    378:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    379:                        return(FALSE);
                    380:                if((p->status=smb_hfield_str(msg, SMTPREVERSEPATH, cp))!=SMB_SUCCESS)
                    381:                        return(FALSE);
                    382:        }
                    383: 
                    384:        if(JS_GetProperty(cx, hdr, "forward_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    385:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    386:                        return(FALSE);
                    387:                if((p->status=smb_hfield_str(msg, SMTPFORWARDPATH, cp))!=SMB_SUCCESS)
                    388:                        return(FALSE);
                    389:        }
                    390: 
                    391:        /* USENET headers */
                    392:        if(JS_GetProperty(cx, hdr, "path", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    393:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    394:                        return(FALSE);
                    395:                if((p->status=smb_hfield_str(msg, USENETPATH, cp))!=SMB_SUCCESS)
                    396:                        return(FALSE);
                    397:        }
                    398: 
                    399:        if(JS_GetProperty(cx, hdr, "newsgroups", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    400:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    401:                        return(FALSE);
                    402:                if((p->status=smb_hfield_str(msg, USENETNEWSGROUPS, cp))!=SMB_SUCCESS)
                    403:                        return(FALSE);
                    404:        }
                    405: 
                    406:        /* FTN headers */
                    407:        if(JS_GetProperty(cx, hdr, "ftn_msgid", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    408:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    409:                        return(FALSE);
                    410:                if((p->status=smb_hfield_str(msg, FIDOMSGID, cp))!=SMB_SUCCESS)
                    411:                        return(FALSE);
                    412:        }
                    413: 
                    414:        if(JS_GetProperty(cx, hdr, "ftn_reply", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    415:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    416:                        return(FALSE);
                    417:                if((p->status=smb_hfield_str(msg, FIDOREPLYID, cp))!=SMB_SUCCESS)
                    418:                        return(FALSE);
                    419:        }
                    420: 
                    421:        if(JS_GetProperty(cx, hdr, "ftn_area", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    422:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    423:                        return(FALSE);
                    424:                if((p->status=smb_hfield_str(msg, FIDOAREA, cp))!=SMB_SUCCESS)
                    425:                        return(FALSE);
                    426:        }
                    427: 
                    428:        if(JS_GetProperty(cx, hdr, "ftn_flags", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    429:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    430:                        return(FALSE);
                    431:                if((p->status=smb_hfield_str(msg, FIDOFLAGS, cp))!=SMB_SUCCESS)
                    432:                        return(FALSE);
                    433:        }
                    434: 
                    435:        if(JS_GetProperty(cx, hdr, "ftn_pid", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    436:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    437:                        return(FALSE);
                    438:                if((p->status=smb_hfield_str(msg, FIDOPID, cp))!=SMB_SUCCESS)
                    439:                        return(FALSE);
                    440:        }
                    441: 
                    442:        if(JS_GetProperty(cx, hdr, "ftn_tid", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    443:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    444:                        return(FALSE);
                    445:                if((p->status=smb_hfield_str(msg, FIDOTID, cp))!=SMB_SUCCESS)
                    446:                        return(FALSE);
                    447:        }
                    448: 
                    449:        if(JS_GetProperty(cx, hdr, "date", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    450:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    451:                        return(FALSE);
                    452:                msg->hdr.when_written=rfc822date(cp);
                    453:        }
                    454:        
                    455:        /* Numeric Header Fields */
                    456:        if(JS_GetProperty(cx, hdr, "attr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    457:                JS_ValueToInt32(cx,val,&i32);
                    458:                msg->hdr.attr=(ushort)i32;
                    459:                msg->idx.attr=msg->hdr.attr;
                    460:        }
                    461:        if(JS_GetProperty(cx, hdr, "auxattr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    462:                JS_ValueToInt32(cx,val,&i32);
                    463:                msg->hdr.auxattr=i32;
                    464:        }
                    465:        if(JS_GetProperty(cx, hdr, "netattr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    466:                JS_ValueToInt32(cx,val,&i32);
                    467:                msg->hdr.netattr=i32;
                    468:        }
                    469:        if(JS_GetProperty(cx, hdr, "when_written_time", &val) && !JSVAL_NULL_OR_VOID(val))  {
                    470:                JS_ValueToInt32(cx,val,&i32);
                    471:                msg->hdr.when_written.time=i32;
                    472:        }
                    473:        if(JS_GetProperty(cx, hdr, "when_written_zone", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    474:                JS_ValueToInt32(cx,val,&i32);
                    475:                msg->hdr.when_written.zone=(short)i32;
                    476:        }
                    477:        if(JS_GetProperty(cx, hdr, "when_imported_time", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    478:                JS_ValueToInt32(cx,val,&i32);
                    479:                msg->hdr.when_imported.time=i32;
                    480:        }
                    481:        if(JS_GetProperty(cx, hdr, "when_imported_zone", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    482:                JS_ValueToInt32(cx,val,&i32);
                    483:                msg->hdr.when_imported.zone=(short)i32;
                    484:        }
                    485: 
                    486:        if((JS_GetProperty(cx, hdr, "thread_orig", &val) 
                    487:                || JS_GetProperty(cx, hdr, "thread_back", &val)) && !JSVAL_NULL_OR_VOID(val)) {
                    488:                JS_ValueToInt32(cx,val,&i32);
                    489:                msg->hdr.thread_back=i32;
                    490:        }
                    491:        if(JS_GetProperty(cx, hdr, "thread_next", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    492:                JS_ValueToInt32(cx,val,&i32);
                    493:                msg->hdr.thread_next=i32;
                    494:        }
                    495:        if(JS_GetProperty(cx, hdr, "thread_first", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    496:                JS_ValueToInt32(cx,val,&i32);
                    497:                msg->hdr.thread_first=i32;
                    498:        }
                    499: 
                    500:        if(JS_GetProperty(cx, hdr, "field_list", &val) && JSVAL_IS_OBJECT(val)) {
                    501:                array=JSVAL_TO_OBJECT(val);
                    502:                len=0;
                    503:                if(!JS_GetArrayLength(cx, array, &len))
                    504:                        return(FALSE);
                    505: 
                    506:                for(i=0;i<len;i++) {
                    507:                        if(!JS_GetElement(cx, array, i, &val))
                    508:                                continue;
                    509:                        if(!JSVAL_IS_OBJECT(val))
                    510:                                continue;
                    511:                        field=JSVAL_TO_OBJECT(val);
                    512:                        if(!JS_GetProperty(cx, field, "type", &val))
                    513:                                continue;
                    514:                        if(JSVAL_IS_STRING(val))
                    515:                                type=smb_hfieldtypelookup(JS_GetStringBytes(JS_ValueToString(cx,val)));
                    516:                        else {
                    517:                                JS_ValueToInt32(cx,val,&i32);
                    518:                                type=(ushort)i32;
                    519:                        }
                    520:                        if(!JS_GetProperty(cx, field, "data", &val))
                    521:                                continue;
                    522:                        if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    523:                                return(FALSE);
                    524:                        if((p->status=smb_hfield_str(msg, type, cp))!=SMB_SUCCESS)
                    525:                                return(FALSE);
                    526:                }
                    527:        }
                    528: 
                    529:        if(msg->hdr.number==0 && JS_GetProperty(cx, hdr, "number", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    530:                JS_ValueToInt32(cx,val,&i32);
                    531:                msg->hdr.number=i32;
                    532:        }
                    533: 
                    534:        return(TRUE);
                    535: }
                    536: 
                    537: /* obj must've been previously returned from get_msg_header() */
                    538: BOOL DLLCALL js_ParseMsgHeaderObject(JSContext* cx, JSObject* obj, smbmsg_t* msg)
                    539: {
                    540:        private_t*      p;
                    541: 
                    542:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    543:                JS_ReportError(cx,getprivate_failure,WHERE);
                    544:                return(FALSE);
                    545:        }
                    546: 
                    547:        if(!parse_header_object(cx, p, obj, msg, /* recipient */ TRUE)) {
                    548:                smb_freemsgmem(msg);
                    549:                return(FALSE);
                    550:        }
                    551: 
                    552:        return(TRUE);
                    553: }
                    554: 
1.1.1.2 ! root      555: static BOOL msg_offset_by_id(private_t* p, char* id, int32_t* offset)
1.1       root      556: {
                    557:        smbmsg_t msg;
                    558: 
                    559:        if((p->status=smb_getmsgidx_by_msgid(&(p->smb),&msg,id))!=SMB_SUCCESS)
                    560:                return(FALSE);
                    561: 
                    562:        *offset = msg.offset;
                    563:        return(TRUE);
                    564: }
                    565: 
                    566: static JSBool
                    567: js_get_msg_index(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    568: {
                    569:        uintN           n;
                    570:        jsval           val;
                    571:        smbmsg_t        msg;
                    572:        JSObject*       idxobj;
                    573:        JSBool          by_offset=JS_FALSE;
                    574:        private_t*      p;
1.1.1.2 ! root      575:        jsrefcount      rc;
        !           576:        JSObject*       proto;
1.1       root      577: 
                    578:        *rval = JSVAL_NULL;
                    579:        
                    580:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    581:                JS_ReportError(cx,getprivate_failure,WHERE);
                    582:                return(JS_FALSE);
                    583:        }
                    584: 
                    585:        if(!SMB_IS_OPEN(&(p->smb)))
                    586:                return(JS_TRUE);
                    587: 
                    588:        memset(&msg,0,sizeof(msg));
                    589: 
                    590:        for(n=0;n<argc;n++) {
1.1.1.2 ! root      591:                if(JSVAL_IS_BOOLEAN(argv[n])) {
1.1       root      592:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
1.1.1.2 ! root      593:                }
1.1       root      594:                else if(JSVAL_IS_NUM(argv[n])) {
                    595:                        if(by_offset)                                                   /* Get by offset */
                    596:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                    597:                        else                                                                    /* Get by number */
                    598:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                    599: 
1.1.1.2 ! root      600:                        rc=JS_SUSPENDREQUEST(cx);
        !           601:                        if((p->status=smb_getmsgidx(&(p->smb), &msg))!=SMB_SUCCESS) {
        !           602:                                JS_RESUMEREQUEST(cx, rc);
1.1       root      603:                                return(JS_TRUE);
1.1.1.2 ! root      604:                        }
        !           605:                        JS_RESUMEREQUEST(cx, rc);
1.1       root      606: 
                    607:                        break;
                    608:                }
                    609:        }
                    610: 
1.1.1.2 ! root      611:        if(JS_GetProperty(cx, JS_GetGlobalObject(cx), "MsgBase", &val) && !JSVAL_NULL_OR_VOID(val)) {
        !           612:                JS_ValueToObject(cx,val,&proto);
        !           613:                if(JS_GetProperty(cx, proto, "IndexPrototype", &val) && !JSVAL_NULL_OR_VOID(val))
        !           614:                        JS_ValueToObject(cx,val,&proto);
        !           615:                else
        !           616:                        proto=NULL;
        !           617:        }
        !           618:        else
        !           619:                proto=NULL;
        !           620: 
        !           621:        if((idxobj=JS_NewObject(cx,NULL,proto,obj))==NULL)
1.1       root      622:                return(JS_TRUE);
                    623: 
                    624:        JS_NewNumberValue(cx, msg.idx.number    ,&val);
                    625:        JS_DefineProperty(cx, idxobj, "number"  ,val
                    626:                ,NULL,NULL,JSPROP_ENUMERATE);
                    627: 
                    628:        JS_NewNumberValue(cx, msg.idx.to                ,&val);
                    629:        JS_DefineProperty(cx, idxobj, "to"              ,val
                    630:                ,NULL,NULL,JSPROP_ENUMERATE);
                    631: 
                    632:        JS_NewNumberValue(cx, msg.idx.from              ,&val);
                    633:        JS_DefineProperty(cx, idxobj, "from"    ,val
                    634:                ,NULL,NULL,JSPROP_ENUMERATE);
                    635: 
                    636:        JS_NewNumberValue(cx, msg.idx.subj              ,&val);
                    637:        JS_DefineProperty(cx, idxobj, "subject" ,val
                    638:                ,NULL,NULL,JSPROP_ENUMERATE);
                    639: 
                    640:        JS_NewNumberValue(cx, msg.idx.attr              ,&val);
                    641:        JS_DefineProperty(cx, idxobj, "attr"    ,val
                    642:                ,NULL,NULL,JSPROP_ENUMERATE);
                    643: 
                    644:        JS_NewNumberValue(cx, msg.offset                ,&val);
                    645:        JS_DefineProperty(cx, idxobj, "offset"  ,val
                    646:                ,NULL,NULL,JSPROP_ENUMERATE);
                    647: 
                    648:        JS_NewNumberValue(cx, msg.idx.time              ,&val);
                    649:        JS_DefineProperty(cx, idxobj, "time"    ,val
                    650:                ,NULL,NULL,JSPROP_ENUMERATE);
                    651: 
                    652:        *rval = OBJECT_TO_JSVAL(idxobj);
                    653: 
                    654:        return(JS_TRUE);
                    655: }
                    656: 
1.1.1.2 ! root      657: #define LAZY_INTEGER(PropName, PropValue, flags) \
        !           658:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !           659:                JS_NewNumberValue(cx,(PropValue),&v); \
        !           660:                JS_DefineProperty(cx, obj, (PropName), v, NULL,NULL,flags); \
        !           661:                if(name) return(JS_TRUE); \
        !           662:        }
        !           663: 
        !           664: #define LAZY_INTEGER_EXPAND(PropName, PropValue, flags) \
        !           665:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !           666:                if(p->expand_fields || (PropValue)) { \
        !           667:                        JS_NewNumberValue(cx,(PropValue),&v); \
        !           668:                        JS_DefineProperty(cx, obj, (PropName), v, NULL,NULL,flags); \
        !           669:                        if(name) return(JS_TRUE); \
        !           670:                } \
        !           671:                else if(name) return(JS_TRUE); \
        !           672:        }
        !           673: 
        !           674: #define LAZY_INTEGER_COND(PropName, Condition, PropValue, flags) \
        !           675:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !           676:                if(Condition) { \
        !           677:                        JS_NewNumberValue(cx,(PropValue),&v); \
        !           678:                        JS_DefineProperty(cx, obj, (PropName), v, NULL,NULL,flags); \
        !           679:                        if(name) return(JS_TRUE); \
        !           680:                } \
        !           681:                else if(name) return(JS_TRUE); \
        !           682:        }
        !           683: 
        !           684: #define LAZY_STRING(PropName, PropValue, flags) \
        !           685:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !           686:                if((js_str=JS_NewStringCopyZ(cx, (PropValue)))!=NULL) { \
        !           687:                        JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, flags); \
        !           688:                        if(name) return(JS_TRUE); \
        !           689:                } \
        !           690:                else if(name) return(JS_TRUE); \
        !           691:        }
        !           692: 
        !           693: #define LAZY_STRING_TRUNCSP(PropName, PropValue, flags) \
        !           694:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !           695:                if((js_str=JS_NewStringCopyZ(cx, truncsp(PropValue)))!=NULL) { \
        !           696:                        JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, flags); \
        !           697:                        if(name) return(JS_TRUE); \
        !           698:                } \
        !           699:                else if(name) return(JS_TRUE); \
        !           700:        }
        !           701: 
        !           702: #define LAZY_STRING_COND(PropName, Condition, PropValue, flags) \
        !           703:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !           704:                if((Condition) && (js_str=JS_NewStringCopyZ(cx, (PropValue)))!=NULL) { \
        !           705:                        JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, flags); \
        !           706:                        if(name) return(JS_TRUE); \
        !           707:                } \
        !           708:                else if(name) return(JS_TRUE); \
        !           709:        }
        !           710: 
        !           711: #define LAZY_STRING_TRUNCSP_NULL(PropName, PropValue, flags) \
        !           712:        if(name==NULL || strcmp(name, (PropName))==0) { \
        !           713:                if((PropValue) != NULL && (js_str=JS_NewStringCopyZ(cx, truncsp(PropValue)))!=NULL) { \
        !           714:                        JS_DefineProperty(cx, obj, PropName, STRING_TO_JSVAL(js_str), NULL, NULL, flags); \
        !           715:                        if(name) return(JS_TRUE); \
        !           716:                } \
        !           717:                else if(name) return(JS_TRUE); \
        !           718:        }
        !           719: 
        !           720: static JSBool js_get_msg_header_resolve(JSContext *cx, JSObject *obj, jsval id)
        !           721: {
        !           722:        char                    date[128];
        !           723:        char                    msg_id[256];
        !           724:        char                    reply_id[256];
        !           725:        char                    tmp[128];
        !           726:        char*                   val;
        !           727:        int                             i;
        !           728:        smbmsg_t                remsg;
        !           729:        JSObject*               array;
        !           730:        JSObject*               field;
        !           731:        JSString*               js_str;
        !           732:        jsint                   items;
        !           733:        jsval                   v;
        !           734:        privatemsg_t*   p;
        !           735:        char*                   name=NULL;
        !           736:        jsrefcount              rc;
        !           737: 
        !           738:        if(id != JSVAL_NULL)
        !           739:                name=JS_GetStringBytes(JSVAL_TO_STRING(id));
        !           740: 
        !           741:        /* If we have already enumerated, we're done here... */
        !           742:        if((p=(privatemsg_t*)JS_GetPrivate(cx,obj))==NULL)
        !           743:                return(JS_TRUE);
        !           744: 
        !           745:        if((p->msg).hdr.number==0) /* No valid message number/id/offset specified */
        !           746:                return(JS_TRUE);
        !           747: 
        !           748:        LAZY_INTEGER("number", p->msg.hdr.number, JSPROP_ENUMERATE);
        !           749:        LAZY_INTEGER("offset", p->msg.offset, JSPROP_ENUMERATE);
        !           750:        LAZY_STRING_TRUNCSP("to",p->msg.to, JSPROP_ENUMERATE);
        !           751:        LAZY_STRING_TRUNCSP("from",p->msg.from, JSPROP_ENUMERATE);
        !           752:        LAZY_STRING_TRUNCSP("subject",p->msg.subj, JSPROP_ENUMERATE);
        !           753:        LAZY_STRING_TRUNCSP_NULL("summary", p->msg.summary, JSPROP_ENUMERATE);
        !           754:        LAZY_STRING_TRUNCSP_NULL("to_ext", p->msg.to_ext, JSPROP_ENUMERATE);
        !           755:        LAZY_STRING_TRUNCSP_NULL("from_ext", p->msg.from_ext, JSPROP_ENUMERATE);
        !           756:        LAZY_STRING_TRUNCSP_NULL("from_org", p->msg.from_org, JSPROP_ENUMERATE);
        !           757:        LAZY_STRING_TRUNCSP_NULL("replyto", p->msg.replyto, JSPROP_ENUMERATE);
        !           758:        LAZY_STRING_TRUNCSP_NULL("replyto_ext", p->msg.replyto_ext, JSPROP_ENUMERATE);
        !           759:        LAZY_STRING_TRUNCSP_NULL("reverse_path", p->msg.reverse_path, JSPROP_ENUMERATE);
        !           760:        LAZY_STRING_TRUNCSP_NULL("forward_path", p->msg.forward_path, JSPROP_ENUMERATE);
        !           761:        LAZY_INTEGER_EXPAND("to_agent", p->msg.to_agent, JSPROP_ENUMERATE);
        !           762:        LAZY_INTEGER_EXPAND("from_agent", p->msg.from_agent, JSPROP_ENUMERATE);
        !           763:        LAZY_INTEGER_EXPAND("replyto_agent", p->msg.replyto_agent, JSPROP_ENUMERATE);
        !           764:        LAZY_INTEGER_EXPAND("to_net_type", p->msg.to_net.type, JSPROP_ENUMERATE);
        !           765:        LAZY_STRING_COND("to_net_addr", p->msg.to_net.type && p->msg.to_net.addr, smb_netaddrstr(&(p->msg).to_net,tmp), JSPROP_ENUMERATE);
        !           766:        LAZY_INTEGER_EXPAND("from_net_type", p->msg.from_net.type, JSPROP_ENUMERATE);
        !           767:        /* exception here because p->msg.from_net is NULL */
        !           768:        LAZY_STRING_COND("from_net_addr", p->msg.from_net.type && p->msg.from_net.addr, smb_netaddrstr(&(p->msg).from_net,tmp), JSPROP_ENUMERATE);
        !           769:        LAZY_INTEGER_EXPAND("replyto_net_type", p->msg.replyto_net.type, JSPROP_ENUMERATE);
        !           770:        LAZY_STRING_COND("replyto_net_addr", p->msg.replyto_net.type && p->msg.replyto_net.addr, smb_netaddrstr(&(p->msg).replyto_net,tmp), JSPROP_ENUMERATE);
        !           771:        LAZY_STRING_COND("from_ip_addr", (val=smb_get_hfield(&(p->msg),SENDERIPADDR,NULL))!=NULL, val, JSPROP_ENUMERATE);
        !           772:        LAZY_STRING_COND("from_host_name", (val=smb_get_hfield(&(p->msg),SENDERHOSTNAME,NULL))!=NULL, val, JSPROP_ENUMERATE);
        !           773:        LAZY_STRING_COND("from_protocol", (val=smb_get_hfield(&(p->msg),SENDERPROTOCOL,NULL))!=NULL, val, JSPROP_ENUMERATE);
        !           774:        LAZY_STRING_COND("from_port", (val=smb_get_hfield(&(p->msg),SENDERPORT,NULL))!=NULL, val, JSPROP_ENUMERATE);
        !           775:        LAZY_INTEGER_EXPAND("forwarded", p->msg.forwarded, JSPROP_ENUMERATE);
        !           776:        LAZY_INTEGER_EXPAND("expiration", p->msg.expiration, JSPROP_ENUMERATE);
        !           777:        LAZY_INTEGER_EXPAND("priority", p->msg.priority, JSPROP_ENUMERATE);
        !           778:        LAZY_INTEGER_EXPAND("cost", p->msg.cost, JSPROP_ENUMERATE);
        !           779: 
        !           780:        /* Fixed length portion of msg header */
        !           781:        LAZY_INTEGER("type", p->msg.hdr.type, JSPROP_ENUMERATE);
        !           782:        LAZY_INTEGER("version", p->msg.hdr.version, JSPROP_ENUMERATE);
        !           783:        LAZY_INTEGER("attr", p->msg.hdr.attr, JSPROP_ENUMERATE);
        !           784:        LAZY_INTEGER("auxattr", p->msg.hdr.auxattr, JSPROP_ENUMERATE);
        !           785:        LAZY_INTEGER("netattr", p->msg.hdr.netattr, JSPROP_ENUMERATE);
        !           786:        LAZY_INTEGER("when_written_time", p->msg.hdr.when_written.time, JSPROP_ENUMERATE);
        !           787:        LAZY_INTEGER("when_written_zone", p->msg.hdr.when_written.zone, JSPROP_ENUMERATE);
        !           788:        LAZY_INTEGER("when_written_zone_offset", smb_tzutc(p->msg.hdr.when_written.zone), JSPROP_ENUMERATE|JSPROP_READONLY);
        !           789:        LAZY_INTEGER("when_imported_time", p->msg.hdr.when_imported.time, JSPROP_ENUMERATE);
        !           790:        LAZY_INTEGER("when_imported_zone", p->msg.hdr.when_imported.zone, JSPROP_ENUMERATE);
        !           791:        LAZY_INTEGER("when_imported_zone_offset", smb_tzutc(p->msg.hdr.when_imported.zone), JSPROP_ENUMERATE|JSPROP_READONLY);
        !           792:        LAZY_INTEGER("thread_back", p->msg.hdr.thread_back, JSPROP_ENUMERATE);
        !           793:        LAZY_INTEGER("thread_orig", p->msg.hdr.thread_back, JSPROP_ENUMERATE);
        !           794:        LAZY_INTEGER("thread_next", p->msg.hdr.thread_next, JSPROP_ENUMERATE);
        !           795:        LAZY_INTEGER("thread_first", p->msg.hdr.thread_first, JSPROP_ENUMERATE);
        !           796:        LAZY_INTEGER("delivery_attempts", p->msg.hdr.delivery_attempts, JSPROP_ENUMERATE);
        !           797:        LAZY_INTEGER("last_downloaded", p->msg.hdr.last_downloaded, JSPROP_ENUMERATE);
        !           798:        LAZY_INTEGER("times_downloaded", p->msg.hdr.times_downloaded, JSPROP_ENUMERATE);
        !           799:        LAZY_INTEGER("data_length", smb_getmsgdatlen(&(p->msg)), JSPROP_ENUMERATE);
        !           800:        LAZY_STRING("date", msgdate((p->msg).hdr.when_written,date), JSPROP_ENUMERATE);
        !           801: 
        !           802:        if(name==NULL || strcmp(name,"reply_id")==0) {
        !           803:                /* Reply-ID (References) */
        !           804:                if((p->msg).reply_id!=NULL)
        !           805:                        val=(p->msg).reply_id;
        !           806:                else {
        !           807:                        reply_id[0]=0;
        !           808:                        if(p->expand_fields && (p->msg).hdr.thread_back) {
        !           809:                                rc=JS_SUSPENDREQUEST(cx);
        !           810:                                memset(&remsg,0,sizeof(remsg));
        !           811:                                remsg.hdr.number=(p->msg).hdr.thread_back;
        !           812:                                if(smb_getmsgidx(&(p->p->smb), &remsg))
        !           813:                                        SAFEPRINTF(reply_id,"<%s>",p->p->smb.last_error);
        !           814:                                else
        !           815:                                        get_msgid(scfg,p->p->smb.subnum,&remsg,reply_id,sizeof(reply_id));
        !           816:                                JS_RESUMEREQUEST(cx, rc);
        !           817:                        }
        !           818:                        val=reply_id;
        !           819:                }
        !           820:                if(val[0] && (js_str=JS_NewStringCopyZ(cx,truncsp(val)))!=NULL) {
        !           821:                        JS_DefineProperty(cx, obj, "reply_id"
        !           822:                                , STRING_TO_JSVAL(js_str)
        !           823:                                ,NULL,NULL,JSPROP_ENUMERATE);
        !           824:                        if (name)
        !           825:                                return(JS_TRUE);
        !           826:                }
        !           827:                else if (name)
        !           828:                        return(JS_TRUE);
        !           829:        }
        !           830: 
        !           831:        /* Message-ID */
        !           832:        if(name==NULL || strcmp(name,"id")==0) {
        !           833:                if(p->expand_fields || (p->msg).id!=NULL) {
        !           834:                        get_msgid(scfg,p->p->smb.subnum,&(p->msg),msg_id,sizeof(msg_id));
        !           835:                        val=msg_id;
        !           836:                        if((js_str=JS_NewStringCopyZ(cx,truncsp(val)))!=NULL) {
        !           837:                                JS_DefineProperty(cx, obj, "id"
        !           838:                                        ,STRING_TO_JSVAL(js_str)
        !           839:                                        ,NULL,NULL,JSPROP_ENUMERATE);
        !           840:                                if (name)
        !           841:                                        return(JS_TRUE);
        !           842:                        }
        !           843:                        else if (name)
        !           844:                                return(JS_TRUE);
        !           845:                }
        !           846:                else if (name)
        !           847:                        return(JS_TRUE);
        !           848:        }
        !           849: 
        !           850:        /* USENET Fields */
        !           851:        LAZY_STRING_TRUNCSP_NULL("path", p->msg.path, JSPROP_ENUMERATE);
        !           852:        LAZY_STRING_TRUNCSP_NULL("newsgroups", p->msg.newsgroups, JSPROP_ENUMERATE);
        !           853: 
        !           854:        /* FidoNet Header Fields */
        !           855:        LAZY_STRING_TRUNCSP_NULL("ftn_msgid", p->msg.ftn_msgid, JSPROP_ENUMERATE);
        !           856:        LAZY_STRING_TRUNCSP_NULL("ftn_reply", p->msg.ftn_reply, JSPROP_ENUMERATE);
        !           857:        LAZY_STRING_TRUNCSP_NULL("ftn_pid", p->msg.ftn_pid, JSPROP_ENUMERATE);
        !           858:        LAZY_STRING_TRUNCSP_NULL("ftn_tid", p->msg.ftn_tid, JSPROP_ENUMERATE);
        !           859:        LAZY_STRING_TRUNCSP_NULL("ftn_area", p->msg.ftn_area, JSPROP_ENUMERATE);
        !           860:        LAZY_STRING_TRUNCSP_NULL("ftn_flags", p->msg.ftn_flags, JSPROP_ENUMERATE);
        !           861: 
        !           862:        if(name==NULL || strcmp(name,"field_list")==0) {
        !           863:                /* Create hdr.field_list[] with repeating header fields (including type and data) */
        !           864:                if((array=JS_NewArrayObject(cx,0,NULL))!=NULL) {
        !           865:                        JS_DefineProperty(cx,obj,"field_list",OBJECT_TO_JSVAL(array)
        !           866:                                ,NULL,NULL,JSPROP_ENUMERATE);
        !           867:                        items=0;
        !           868:                        for(i=0;i<(p->msg).total_hfields;i++) {
        !           869:                                switch((p->msg).hfield[i].type) {
        !           870:                                        case SMB_COMMENT:
        !           871:                                        case SMB_CARBONCOPY:
        !           872:                                        case SMB_GROUP:
        !           873:                                        case FILEATTACH:
        !           874:                                        case DESTFILE:
        !           875:                                        case FILEATTACHLIST:
        !           876:                                        case DESTFILELIST:
        !           877:                                        case FILEREQUEST:
        !           878:                                        case FILEPASSWORD:
        !           879:                                        case FILEREQUESTLIST:
        !           880:                                        case FILEPASSWORDLIST:
        !           881:                                        case FIDOCTRL:
        !           882:                                        case FIDOSEENBY:
        !           883:                                        case FIDOPATH:
        !           884:                                        case RFC822HEADER:
        !           885:                                        case UNKNOWNASCII:
        !           886:                                                /* only support these header field types */
        !           887:                                                break;
        !           888:                                        default:
        !           889:                                                /* dupe or possibly binary header field */
        !           890:                                                continue;
        !           891:                                }
        !           892:                                if((field=JS_NewObject(cx,NULL,NULL,array))==NULL)
        !           893:                                        continue;
        !           894:                                JS_DefineProperty(cx,field,"type"
        !           895:                                        ,INT_TO_JSVAL((p->msg).hfield[i].type)
        !           896:                                        ,NULL,NULL,JSPROP_ENUMERATE);
        !           897:                                if((js_str=JS_NewStringCopyN(cx,(p->msg).hfield_dat[i],(p->msg).hfield[i].length))==NULL)
        !           898:                                        break;
        !           899:                                JS_DefineProperty(cx,field,"data"
        !           900:                                        ,STRING_TO_JSVAL(js_str)
        !           901:                                        ,NULL,NULL,JSPROP_ENUMERATE);
        !           902:                                JS_DefineElement(cx,array,items,OBJECT_TO_JSVAL(field)
        !           903:                                        ,NULL,NULL,JSPROP_ENUMERATE);
        !           904:                                items++;
        !           905:                        }
        !           906:                        if (name)
        !           907:                                return(JS_TRUE);
        !           908:                }
        !           909:                else if (name)
        !           910:                        return(JS_TRUE);
        !           911:        }
        !           912: 
        !           913:        /* DO NOT RETURN JS_FALSE on unknown names */
        !           914:        /* Doing so will preven toString() among others from working. */
        !           915:        
        !           916:        return(JS_TRUE);
        !           917: }
        !           918: 
        !           919: static JSBool js_get_msg_header_enumerate(JSContext *cx, JSObject *obj)
        !           920: {
        !           921:        privatemsg_t* p;
        !           922: 
        !           923:        js_get_msg_header_resolve(cx, obj, JSVAL_NULL);
        !           924: 
        !           925:        if((p=(privatemsg_t*)JS_GetPrivate(cx,obj))==NULL)
        !           926:                return(JS_TRUE);
        !           927: 
        !           928:        smb_freemsgmem(&(p->msg));
        !           929:        free(p);
        !           930: 
        !           931:        JS_SetPrivate(cx, obj, NULL);
        !           932: 
        !           933:        return(JS_TRUE);
        !           934: }
        !           935: 
        !           936: static void js_get_msg_header_finalize(JSContext *cx, JSObject *obj)
        !           937: {
        !           938:        privatemsg_t* p;
        !           939: 
        !           940:        if((p=(privatemsg_t*)JS_GetPrivate(cx,obj))==NULL)
        !           941:                return;
        !           942: 
        !           943:        smb_freemsgmem(&(p->msg));
        !           944:        free(p);
        !           945: 
        !           946:        JS_SetPrivate(cx, obj, NULL);
        !           947: }
        !           948: 
1.1       root      949: static JSClass js_msghdr_class = {
                    950:      "MsgHeader"                       /* name                 */
                    951:     ,JSCLASS_HAS_PRIVATE       /* flags                */
                    952:        ,JS_PropertyStub                /* addProperty  */
                    953:        ,JS_PropertyStub                /* delProperty  */
                    954:        ,JS_PropertyStub                /* getProperty  */
                    955:        ,JS_PropertyStub                /* setProperty  */
1.1.1.2 ! root      956:        ,js_get_msg_header_enumerate            /* enumerate    */
        !           957:        ,js_get_msg_header_resolve                      /* resolve              */
1.1       root      958:        ,JS_ConvertStub                 /* convert              */
1.1.1.2 ! root      959:        ,js_get_msg_header_finalize             /* finalize             */
1.1       root      960: };
                    961: 
                    962: static JSBool
                    963: js_get_msg_header(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    964: {
                    965:        uintN           n;
                    966:        JSObject*       hdrobj;
                    967:        JSBool          by_offset=JS_FALSE;
1.1.1.2 ! root      968:        jsrefcount      rc;
        !           969:        char*           cstr;
        !           970:        privatemsg_t*   p;
        !           971:        JSObject*       proto;
        !           972:        jsval           val;
1.1       root      973: 
                    974:        *rval = JSVAL_NULL;
1.1.1.2 ! root      975: 
        !           976:        if((p=(privatemsg_t*)malloc(sizeof(privatemsg_t)))==NULL) {
        !           977:                JS_ReportError(cx,"malloc failed");
        !           978:                return(JS_FALSE);
        !           979:        }
        !           980: 
        !           981:        memset(p,0,sizeof(privatemsg_t));
        !           982: 
        !           983:        if((p->p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
1.1       root      984:                JS_ReportError(cx,getprivate_failure,WHERE);
                    985:                return(JS_FALSE);
                    986:        }
                    987: 
1.1.1.2 ! root      988:        if(!SMB_IS_OPEN(&(p->p->smb))) {
        !           989:                free(p);
1.1       root      990:                return(JS_TRUE);
1.1.1.2 ! root      991:        }
1.1       root      992: 
                    993:        /* Parse boolean arguments first */
1.1.1.2 ! root      994:        p->expand_fields=JS_TRUE;       /* This parameter defaults to true */
1.1       root      995:        for(n=0;n<argc;n++) {
                    996:                if(!JSVAL_IS_BOOLEAN(argv[n]))
                    997:                        continue;
                    998:                if(n)
1.1.1.2 ! root      999:                        p->expand_fields=JSVAL_TO_BOOLEAN(argv[n]);
1.1       root     1000:                else
                   1001:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                   1002:        }
                   1003: 
                   1004:        /* Now parse message offset/id and get message */
                   1005:        for(n=0;n<argc;n++) {
                   1006:                if(JSVAL_IS_NUM(argv[n])) {
                   1007:                        if(by_offset)                                                   /* Get by offset */
1.1.1.2 ! root     1008:                                JS_ValueToInt32(cx,argv[n],(int32*)&(p->msg).offset);
1.1       root     1009:                        else                                                                    /* Get by number */
1.1.1.2 ! root     1010:                                JS_ValueToInt32(cx,argv[n],(int32*)&(p->msg).hdr.number);
1.1       root     1011: 
1.1.1.2 ! root     1012:                        rc=JS_SUSPENDREQUEST(cx);
        !          1013:                        if((p->p->status=smb_getmsgidx(&(p->p->smb), &(p->msg)))!=SMB_SUCCESS) {
        !          1014:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1015:                                return(JS_TRUE);
1.1.1.2 ! root     1016:                        }
1.1       root     1017: 
1.1.1.2 ! root     1018:                        if((p->p->status=smb_lockmsghdr(&(p->p->smb),&(p->msg)))!=SMB_SUCCESS) {
        !          1019:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1020:                                return(JS_TRUE);
1.1.1.2 ! root     1021:                        }
1.1       root     1022: 
1.1.1.2 ! root     1023:                        if((p->p->status=smb_getmsghdr(&(p->p->smb), &(p->msg)))!=SMB_SUCCESS) {
        !          1024:                                smb_unlockmsghdr(&(p->p->smb),&(p->msg)); 
        !          1025:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1026:                                return(JS_TRUE);
                   1027:                        }
                   1028: 
1.1.1.2 ! root     1029:                        smb_unlockmsghdr(&(p->p->smb),&(p->msg)); 
        !          1030:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1031:                        break;
                   1032:                } else if(JSVAL_IS_STRING(argv[n]))     {               /* Get by ID */
1.1.1.2 ! root     1033:                        cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
        !          1034:                        rc=JS_SUSPENDREQUEST(cx);
        !          1035:                        if((p->p->status=smb_getmsghdr_by_msgid(&(p->p->smb),&(p->msg)
        !          1036:                                        ,cstr))!=SMB_SUCCESS) {
        !          1037:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1038:                                return(JS_TRUE);        /* ID not found */
1.1.1.2 ! root     1039:                        }
        !          1040:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1041:                        break;
                   1042:                }
                   1043:        }
                   1044: 
1.1.1.2 ! root     1045:        if((p->msg).hdr.number==0) /* No valid message number/id/offset specified */
1.1       root     1046:                return(JS_TRUE);
                   1047: 
1.1.1.2 ! root     1048:        if(JS_GetProperty(cx, JS_GetGlobalObject(cx), "MsgBase", &val) && !JSVAL_NULL_OR_VOID(val)) {
        !          1049:                JS_ValueToObject(cx,val,&proto);
        !          1050:                if(JS_GetProperty(cx, proto, "HeaderPrototype", &val) && !JSVAL_NULL_OR_VOID(val))
        !          1051:                        JS_ValueToObject(cx,val,&proto);
        !          1052:                else
        !          1053:                        proto=NULL;
        !          1054:        }
        !          1055:        else
        !          1056:                proto=NULL;
        !          1057: 
        !          1058:        if((hdrobj=JS_NewObject(cx,&js_msghdr_class,proto,obj))==NULL) {
        !          1059:                smb_freemsgmem(&(p->msg));
1.1       root     1060:                return(JS_TRUE);
                   1061:        }
                   1062: 
                   1063:        if(!JS_SetPrivate(cx, hdrobj, p)) {
                   1064:                JS_ReportError(cx,"JS_SetPrivate failed");
1.1.1.2 ! root     1065:                free(p);
1.1       root     1066:                return(JS_FALSE);
                   1067:        }
                   1068: 
                   1069:        *rval = OBJECT_TO_JSVAL(hdrobj);
                   1070: 
                   1071:        return(JS_TRUE);
                   1072: }
                   1073: 
                   1074: static JSBool
                   1075: js_put_msg_header(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1076: {
                   1077:        uintN           n;
                   1078:        JSBool          by_offset=JS_FALSE;
                   1079:        JSBool          msg_specified=JS_FALSE;
                   1080:        smbmsg_t        msg;
                   1081:        JSObject*       hdr=NULL;
                   1082:        private_t*      p;
1.1.1.2 ! root     1083:        jsrefcount      rc;
        !          1084:        char*           cstr;
1.1       root     1085: 
                   1086:        *rval = JSVAL_FALSE;
                   1087: 
                   1088:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1089:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1090:                return(JS_FALSE);
                   1091:        }
                   1092: 
                   1093:        if(!SMB_IS_OPEN(&(p->smb)))
                   1094:                return(JS_TRUE);
                   1095: 
                   1096:        memset(&msg,0,sizeof(msg));
                   1097: 
                   1098:        for(n=0;n<argc;n++) {
                   1099:                if(JSVAL_IS_BOOLEAN(argv[n]))
                   1100:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                   1101:                else if(JSVAL_IS_NUM(argv[n])) {
                   1102:                        if(by_offset)                                                   /* Get by offset */
                   1103:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                   1104:                        else                                                                    /* Get by number */
                   1105:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                   1106:                        msg_specified=JS_TRUE;
                   1107:                        n++;
                   1108:                        break;
                   1109:                } else if(JSVAL_IS_STRING(argv[n]))     {               /* Get by ID */
1.1.1.2 ! root     1110:                        cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
        !          1111:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1112:                        if(!msg_offset_by_id(p
1.1.1.2 ! root     1113:                                        ,cstr
        !          1114:                                        ,&msg.offset)) {
        !          1115:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1116:                                return(JS_TRUE);        /* ID not found */
1.1.1.2 ! root     1117:                        }
        !          1118:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1119:                        msg_specified=JS_TRUE;
                   1120:                        n++;
                   1121:                        break;
                   1122:                }
                   1123:        }
                   1124: 
                   1125:        if(!msg_specified)
                   1126:                return(JS_TRUE);
                   1127: 
                   1128:        if(n==argc || !JSVAL_IS_OBJECT(argv[n])) /* no header supplied? */
                   1129:                return(JS_TRUE);
                   1130: 
                   1131:        hdr = JSVAL_TO_OBJECT(argv[n++]);
                   1132: 
1.1.1.2 ! root     1133:        rc=JS_SUSPENDREQUEST(cx);
        !          1134:        if((p->status=smb_getmsgidx(&(p->smb), &msg))!=SMB_SUCCESS) {
        !          1135:                JS_RESUMEREQUEST(cx, rc);
1.1       root     1136:                return(JS_TRUE);
1.1.1.2 ! root     1137:        }
1.1       root     1138: 
1.1.1.2 ! root     1139:        if((p->status=smb_lockmsghdr(&(p->smb),&msg))!=SMB_SUCCESS) {
        !          1140:                JS_RESUMEREQUEST(cx, rc);
1.1       root     1141:                return(JS_TRUE);
1.1.1.2 ! root     1142:        }
1.1       root     1143: 
                   1144:        do {
                   1145:                if((p->status=smb_getmsghdr(&(p->smb), &msg))!=SMB_SUCCESS)
                   1146:                        break;
                   1147: 
                   1148:                smb_freemsghdrmem(&msg);        /* prevent duplicate header fields */
                   1149: 
1.1.1.2 ! root     1150:                JS_RESUMEREQUEST(cx, rc);
1.1       root     1151:                if(!parse_header_object(cx, p, hdr, &msg, TRUE)) {
1.1.1.2 ! root     1152:                        SAFECOPY(p->smb.last_error,"Header parsing failure (required field missing?)");
1.1       root     1153:                        break;
                   1154:                }
1.1.1.2 ! root     1155:                rc=JS_SUSPENDREQUEST(cx);
1.1       root     1156: 
                   1157:                if((p->status=smb_putmsg(&(p->smb), &msg))!=SMB_SUCCESS)
                   1158:                        break;
                   1159: 
                   1160:                *rval = JSVAL_TRUE;
                   1161:        } while(0);
                   1162: 
                   1163:        smb_unlockmsghdr(&(p->smb),&msg); 
                   1164:        smb_freemsgmem(&msg);
1.1.1.2 ! root     1165:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1166: 
                   1167:        return(JS_TRUE);
                   1168: }
                   1169: 
                   1170: static JSBool
                   1171: js_remove_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1172: {
                   1173:        uintN           n;
                   1174:        JSBool          by_offset=JS_FALSE;
                   1175:        JSBool          msg_specified=JS_FALSE;
                   1176:        smbmsg_t        msg;
                   1177:        private_t*      p;
1.1.1.2 ! root     1178:        char*           cstr;
        !          1179:        jsrefcount      rc;
1.1       root     1180: 
                   1181:        *rval = JSVAL_FALSE;
                   1182: 
                   1183:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1184:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1185:                return(JS_FALSE);
                   1186:        }
                   1187: 
                   1188:        if(!SMB_IS_OPEN(&(p->smb)))
                   1189:                return(JS_TRUE);
                   1190: 
                   1191:        memset(&msg,0,sizeof(msg));
                   1192: 
                   1193:        for(n=0;n<argc;n++) {
                   1194:                if(JSVAL_IS_BOOLEAN(argv[n]))
                   1195:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                   1196:                else if(JSVAL_IS_NUM(argv[n])) {
                   1197:                        if(by_offset)                                                   /* Get by offset */
                   1198:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                   1199:                        else                                                                    /* Get by number */
                   1200:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                   1201:                        msg_specified=JS_TRUE;
                   1202:                        n++;
                   1203:                        break;
                   1204:                } else if(JSVAL_IS_STRING(argv[n]))     {               /* Get by ID */
1.1.1.2 ! root     1205:                        cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
        !          1206:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1207:                        if(!msg_offset_by_id(p
1.1.1.2 ! root     1208:                                        ,cstr
        !          1209:                                        ,&msg.offset)) {
        !          1210:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1211:                                return(JS_TRUE);        /* ID not found */
1.1.1.2 ! root     1212:                        }
        !          1213:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1214:                        msg_specified=JS_TRUE;
                   1215:                        n++;
                   1216:                        break;
                   1217:                }
                   1218:        }
                   1219: 
                   1220:        if(!msg_specified)
                   1221:                return(JS_TRUE);
                   1222: 
1.1.1.2 ! root     1223:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1224:        if((p->status=smb_getmsgidx(&(p->smb), &msg))==SMB_SUCCESS
                   1225:                && (p->status=smb_getmsghdr(&(p->smb), &msg))==SMB_SUCCESS) {
                   1226: 
                   1227:                msg.hdr.attr|=MSG_DELETE;
                   1228: 
                   1229:                if((p->status=smb_updatemsg(&(p->smb), &msg))==SMB_SUCCESS)
                   1230:                        *rval = JSVAL_TRUE;
                   1231:        }
                   1232: 
                   1233:        smb_freemsgmem(&msg);
1.1.1.2 ! root     1234:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1235: 
                   1236:        return(JS_TRUE);
                   1237: }
                   1238: 
                   1239: static char* get_msg_text(private_t* p, smbmsg_t* msg, BOOL strip_ctrl_a, BOOL rfc822, ulong mode)
                   1240: {
                   1241:        char*           buf;
                   1242: 
                   1243:        if((p->status=smb_getmsgidx(&(p->smb), msg))!=SMB_SUCCESS)
                   1244:                return(NULL);
                   1245: 
                   1246:        if((p->status=smb_lockmsghdr(&(p->smb),msg))!=SMB_SUCCESS)
                   1247:                return(NULL);
                   1248: 
                   1249:        if((p->status=smb_getmsghdr(&(p->smb), msg))!=SMB_SUCCESS) {
                   1250:                smb_unlockmsghdr(&(p->smb), msg); 
                   1251:                return(NULL);
                   1252:        }
                   1253: 
                   1254:        if((buf=smb_getmsgtxt(&(p->smb), msg, mode))==NULL) {
                   1255:                smb_unlockmsghdr(&(p->smb),msg); 
                   1256:                smb_freemsgmem(msg);
                   1257:                return(NULL);
                   1258:        }
                   1259: 
                   1260:        smb_unlockmsghdr(&(p->smb), msg); 
                   1261:        smb_freemsgmem(msg);
                   1262: 
1.1.1.2 ! root     1263:        if(strip_ctrl_a)
        !          1264:                remove_ctrl_a(buf, buf);
1.1       root     1265: 
                   1266:        if(rfc822) {    /* must escape lines starting with dot ('.') */
                   1267:                char* newbuf;
                   1268:                if((newbuf=malloc((strlen(buf)*2)+1))!=NULL) {
                   1269:                        int i,j;
                   1270:                        for(i=j=0;buf[i];i++) {
                   1271:                                if((i==0 || buf[i-1]=='\n') && buf[i]=='.')
                   1272:                                        newbuf[j++]='.';
                   1273:                                newbuf[j++]=buf[i]; 
                   1274:                        }
                   1275:                        newbuf[j]=0;
                   1276:                        free(buf);
                   1277:                        buf = newbuf;
                   1278:                }
                   1279:        }
                   1280: 
                   1281:        return(buf);
                   1282: }
                   1283: 
                   1284: static JSBool
                   1285: js_get_msg_body(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1286: {
                   1287:        char*           buf;
                   1288:        uintN           n;
                   1289:        smbmsg_t        msg;
                   1290:        JSBool          by_offset=JS_FALSE;
                   1291:        JSBool          strip_ctrl_a=JS_FALSE;
                   1292:        JSBool          tails=JS_TRUE;
                   1293:        JSBool          rfc822=JS_FALSE;
                   1294:        JSBool          msg_specified=JS_FALSE;
                   1295:        JSString*       js_str;
                   1296:        private_t*      p;
1.1.1.2 ! root     1297:        char*           cstr;
        !          1298:        jsrefcount      rc;
1.1       root     1299: 
                   1300:        *rval = JSVAL_NULL;
                   1301:        
                   1302:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1303:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1304:                return(JS_FALSE);
                   1305:        }
                   1306: 
                   1307:        if(!SMB_IS_OPEN(&(p->smb)))
                   1308:                return(JS_TRUE);
                   1309: 
                   1310:        memset(&msg,0,sizeof(msg));
                   1311: 
                   1312:        for(n=0;n<argc;n++) {
                   1313:                if(JSVAL_IS_BOOLEAN(argv[n]))
                   1314:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                   1315:                else if(JSVAL_IS_NUM(argv[n])) {
                   1316:                        if(by_offset)                                                   /* Get by offset */
                   1317:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                   1318:                        else                                                                    /* Get by number */
                   1319:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                   1320:                        msg_specified=JS_TRUE;
                   1321:                        n++;
                   1322:                        break;
                   1323:                } else if(JSVAL_IS_STRING(argv[n]))     {               /* Get by ID */
1.1.1.2 ! root     1324:                        cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
        !          1325:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1326:                        if(!msg_offset_by_id(p
1.1.1.2 ! root     1327:                                        ,cstr
        !          1328:                                        ,&msg.offset)) {
        !          1329:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1330:                                return(JS_TRUE);        /* ID not found */
1.1.1.2 ! root     1331:                        }
        !          1332:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1333:                        msg_specified=JS_TRUE;
                   1334:                        n++;
                   1335:                        break;
                   1336:                }
                   1337:        }
                   1338: 
                   1339:        if(!msg_specified)      /* No message number or id specified */
                   1340:                return(JS_TRUE);
                   1341: 
                   1342:        if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
                   1343:                strip_ctrl_a=JSVAL_TO_BOOLEAN(argv[n++]);
                   1344: 
                   1345:        if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
                   1346:                rfc822=JSVAL_TO_BOOLEAN(argv[n++]);
                   1347: 
                   1348:        if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
                   1349:                tails=JSVAL_TO_BOOLEAN(argv[n++]);
                   1350: 
1.1.1.2 ! root     1351:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1352:        buf = get_msg_text(p, &msg, strip_ctrl_a, rfc822, tails ? GETMSGTXT_TAILS : 0);
1.1.1.2 ! root     1353:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1354:        if(buf==NULL)
                   1355:                return(JS_TRUE);
                   1356: 
                   1357:        if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL)
                   1358:                *rval = STRING_TO_JSVAL(js_str);
                   1359: 
                   1360:        smb_freemsgtxt(buf);
                   1361: 
                   1362:        return(JS_TRUE);
                   1363: }
                   1364: 
                   1365: static JSBool
                   1366: js_get_msg_tail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1367: {
                   1368:        char*           buf;
                   1369:        uintN           n;
                   1370:        smbmsg_t        msg;
                   1371:        JSBool          by_offset=JS_FALSE;
                   1372:        JSBool          strip_ctrl_a=JS_FALSE;
                   1373:        JSBool          rfc822=JS_FALSE;
                   1374:        JSBool          msg_specified=JS_FALSE;
                   1375:        JSString*       js_str;
                   1376:        private_t*      p;
1.1.1.2 ! root     1377:        char*           cstr;
        !          1378:        jsrefcount      rc;
1.1       root     1379: 
                   1380:        *rval = JSVAL_NULL;
                   1381:        
                   1382:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1383:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1384:                return(JS_FALSE);
                   1385:        }
                   1386: 
                   1387:        if(!SMB_IS_OPEN(&(p->smb)))
                   1388:                return(JS_TRUE);
                   1389: 
                   1390:        memset(&msg,0,sizeof(msg));
                   1391: 
                   1392:        for(n=0;n<argc;n++) {
                   1393:                if(JSVAL_IS_BOOLEAN(argv[n]))
                   1394:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                   1395:                else if(JSVAL_IS_NUM(argv[n])) {
                   1396:                        if(by_offset)                                                   /* Get by offset */
                   1397:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                   1398:                        else                                                                    /* Get by number */
                   1399:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                   1400:                        msg_specified=JS_TRUE;
                   1401:                        n++;
                   1402:                        break;
                   1403:                } else if(JSVAL_IS_STRING(argv[n]))     {               /* Get by ID */
1.1.1.2 ! root     1404:                        cstr=JS_GetStringBytes(JSVAL_TO_STRING(argv[n]));
        !          1405:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1406:                        if(!msg_offset_by_id(p
1.1.1.2 ! root     1407:                                        ,cstr
        !          1408:                                        ,&msg.offset)) {
        !          1409:                                JS_RESUMEREQUEST(cx, rc);
1.1       root     1410:                                return(JS_TRUE);        /* ID not found */
1.1.1.2 ! root     1411:                        }
        !          1412:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1413:                        msg_specified=JS_TRUE;
                   1414:                        n++;
                   1415:                        break;
                   1416:                }
                   1417:        }
                   1418: 
                   1419:        if(!msg_specified)      /* No message number or id specified */
                   1420:                return(JS_TRUE);
                   1421: 
                   1422:        if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
                   1423:                strip_ctrl_a=JSVAL_TO_BOOLEAN(argv[n++]);
                   1424: 
                   1425:        if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
                   1426:                rfc822=JSVAL_TO_BOOLEAN(argv[n++]);
                   1427: 
1.1.1.2 ! root     1428:        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1429:        buf = get_msg_text(p, &msg, strip_ctrl_a, rfc822, GETMSGTXT_TAILS|GETMSGTXT_NO_BODY);
1.1.1.2 ! root     1430:        JS_RESUMEREQUEST(cx, rc);
1.1       root     1431:        if(buf==NULL)
                   1432:                return(JS_TRUE);
                   1433: 
                   1434:        if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL)
                   1435:                *rval = STRING_TO_JSVAL(js_str);
                   1436: 
                   1437:        smb_freemsgtxt(buf);
                   1438: 
                   1439:        return(JS_TRUE);
                   1440: }
                   1441: 
                   1442: static JSBool
                   1443: js_save_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1444: {
                   1445:        char*           body=NULL;
                   1446:        uintN           n;
                   1447:     jsuint      i;
                   1448:     jsuint      rcpt_list_length;
                   1449:        jsval       val;
                   1450:        JSObject*       hdr=NULL;
                   1451:        JSObject*       objarg;
                   1452:        JSObject*       rcpt_list=NULL;
                   1453:        JSClass*        cl;
                   1454:        smbmsg_t        rcpt_msg;
                   1455:        smbmsg_t        msg;
                   1456:        client_t*       client=NULL;
                   1457:        jsval           open_rval;
                   1458:        private_t*      p;
                   1459: 
                   1460:        *rval = JSVAL_FALSE;
                   1461: 
                   1462:        if(argc<2)
                   1463:                return(JS_TRUE);
                   1464:        
                   1465:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1466:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1467:                return(JS_FALSE);
                   1468:        }
                   1469: 
                   1470:        if(!SMB_IS_OPEN(&(p->smb))) {
                   1471:                if(!js_open(cx, obj, 0, NULL, &open_rval))
                   1472:                        return(JS_FALSE);
                   1473:                if(open_rval == JSVAL_FALSE)
                   1474:                        return(JS_TRUE);
                   1475:        }
                   1476: 
                   1477:        memset(&msg,0,sizeof(msg));
                   1478: 
                   1479:        for(n=0;n<argc;n++) {
1.1.1.2 ! root     1480:                if(JSVAL_IS_OBJECT(argv[n]) && !JSVAL_IS_NULL(argv[n])) {
1.1       root     1481:                        objarg = JSVAL_TO_OBJECT(argv[n]);
                   1482:                        if((cl=JS_GetClass(cx,objarg))!=NULL && strcmp(cl->name,"Client")==0) {
                   1483:                                client=JS_GetPrivate(cx,objarg);
                   1484:                                continue;
                   1485:                        }
                   1486:                        if(JS_IsArrayObject(cx, objarg)) {              /* recipient_list is an array of objects */
                   1487:                                if(body!=NULL && rcpt_list==NULL) {     /* body text already specified */
                   1488:                                        rcpt_list = objarg;
                   1489:                                        continue;
                   1490:                                }
                   1491:                        }
                   1492:                        else if(hdr==NULL) {
                   1493:                                hdr = objarg;
                   1494:                                continue;
                   1495:                        }
                   1496:                }
                   1497:                if(body==NULL 
                   1498:                        && (body=JS_GetStringBytes(JS_ValueToString(cx,argv[n])))==NULL) {
                   1499:                        JS_ReportError(cx,"JS_GetStringBytes failed");
                   1500:                        return(JS_FALSE);
                   1501:                }
                   1502:        }
                   1503: 
                   1504:        if(hdr==NULL)
                   1505:                return(JS_TRUE);
                   1506:        if(body==NULL)
                   1507:                body="";
                   1508: 
                   1509:        if(rcpt_list!=NULL) {
                   1510:                if(!JS_GetArrayLength(cx, rcpt_list, &rcpt_list_length))
                   1511:                        return(JS_TRUE);
                   1512:                if(!rcpt_list_length)
                   1513:                        return(JS_TRUE);
                   1514:        }
                   1515: 
                   1516:        if(parse_header_object(cx, p, hdr, &msg, rcpt_list==NULL)) {
                   1517: 
                   1518:                if(body[0])
                   1519:                        truncsp(body);
1.1.1.2 ! root     1520:                if((p->status=savemsg(scfg, &(p->smb), &msg, client, /* ToDo server hostname: */NULL, body))==SMB_SUCCESS) {
1.1       root     1521:                        *rval = JSVAL_TRUE;
                   1522: 
1.1.1.2 ! root     1523:                        if(rcpt_list!=NULL) {   /* Sending to a list of recipients */
1.1       root     1524: 
1.1.1.2 ! root     1525:                                *rval = JSVAL_FALSE;    /* failure, by default */
        !          1526:                                SAFECOPY(p->smb.last_error,"Recipient list parsing failure");
1.1       root     1527: 
1.1.1.2 ! root     1528:                                memset(&rcpt_msg, 0, sizeof(rcpt_msg));
1.1       root     1529: 
1.1.1.2 ! root     1530:                                for(i=0;i<rcpt_list_length;i++) {
1.1       root     1531: 
1.1.1.2 ! root     1532:                                        if(!JS_GetElement(cx, rcpt_list, i, &val))
        !          1533:                                                break;
        !          1534:                                        
        !          1535:                                        if(!JSVAL_IS_OBJECT(val))
        !          1536:                                                break;
1.1       root     1537: 
1.1.1.2 ! root     1538:                                        if((p->status=smb_copymsgmem(&(p->smb), &rcpt_msg, &msg))!=SMB_SUCCESS)
        !          1539:                                                break;
1.1       root     1540: 
1.1.1.2 ! root     1541:                                        if(!parse_recipient_object(cx, p, JSVAL_TO_OBJECT(val), &rcpt_msg))
        !          1542:                                                break;
1.1       root     1543: 
1.1.1.2 ! root     1544:                                        if((p->status=smb_addmsghdr(&(p->smb), &rcpt_msg, SMB_SELFPACK))!=SMB_SUCCESS)
        !          1545:                                                break;
1.1       root     1546: 
1.1.1.2 ! root     1547:                                        smb_freemsgmem(&rcpt_msg);
        !          1548:                                }
        !          1549:                                smb_freemsgmem(&rcpt_msg);      /* just in case we broke the loop */
1.1       root     1550: 
1.1.1.2 ! root     1551:                                if(i==rcpt_list_length)
        !          1552:                                        *rval = JSVAL_TRUE;     /* success */
        !          1553:                        }
1.1       root     1554:                }
                   1555:        } else
1.1.1.2 ! root     1556:                SAFECOPY(p->smb.last_error,"Header parsing failure (required field missing?)");
1.1       root     1557: 
                   1558:        smb_freemsgmem(&msg);
                   1559: 
                   1560:        return(JS_TRUE);
                   1561: }
                   1562: 
                   1563: /* MsgBase Object Properites */
                   1564: enum {
                   1565:         SMB_PROP_LAST_ERROR
                   1566:        ,SMB_PROP_FILE          
                   1567:        ,SMB_PROP_DEBUG         
                   1568:        ,SMB_PROP_RETRY_TIME
                   1569:        ,SMB_PROP_RETRY_DELAY
                   1570:        ,SMB_PROP_FIRST_MSG             /* first message number */
                   1571:        ,SMB_PROP_LAST_MSG              /* last message number */
                   1572:        ,SMB_PROP_TOTAL_MSGS    /* total messages */
                   1573:        ,SMB_PROP_MAX_CRCS              /* Maximum number of CRCs to keep in history */
                   1574:     ,SMB_PROP_MAX_MSGS      /* Maximum number of message to keep in sub */
                   1575:     ,SMB_PROP_MAX_AGE       /* Maximum age of message to keep in sub (in days) */
                   1576:        ,SMB_PROP_ATTR                  /* Attributes for this message base (SMB_HYPER,etc) */
                   1577:        ,SMB_PROP_SUBNUM                /* sub-board number */
                   1578:        ,SMB_PROP_IS_OPEN
                   1579:        ,SMB_PROP_STATUS                /* Last SMBLIB returned status value (e.g. retval) */
                   1580: };
                   1581: 
                   1582: static JSBool js_msgbase_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                   1583: {
                   1584:     jsint       tiny;
                   1585:        private_t*      p;
                   1586: 
                   1587:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1588:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1589:                return(JS_FALSE);
                   1590:        }
                   1591: 
                   1592:     tiny = JSVAL_TO_INT(id);
                   1593: 
                   1594:        switch(tiny) {
                   1595:                case SMB_PROP_RETRY_TIME:
                   1596:                        JS_ValueToInt32(cx,*vp,(int32*)&(p->smb).retry_time);
                   1597:                        break;
                   1598:                case SMB_PROP_RETRY_DELAY:
                   1599:                        JS_ValueToInt32(cx,*vp,(int32*)&(p->smb).retry_delay);
                   1600:                        break;
                   1601:                case SMB_PROP_DEBUG:
                   1602:                        JS_ValueToBoolean(cx,*vp,&p->debug);
                   1603:                        break;
                   1604:        }
                   1605: 
                   1606:        return(JS_TRUE);
                   1607: }
                   1608: 
                   1609: static JSBool js_msgbase_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                   1610: {
                   1611:        char*           s=NULL;
                   1612:        JSString*       js_str;
                   1613:     jsint       tiny;
                   1614:        idxrec_t        idx;
                   1615:        private_t*      p;
1.1.1.2 ! root     1616:        jsrefcount      rc;
1.1       root     1617: 
                   1618:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1619:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1620:                return(JS_FALSE);
                   1621:        }
                   1622: 
                   1623:     tiny = JSVAL_TO_INT(id);
                   1624: 
                   1625:        switch(tiny) {
                   1626:                case SMB_PROP_FILE:
                   1627:                        s=p->smb.file;
                   1628:                        break;
                   1629:                case SMB_PROP_LAST_ERROR:
                   1630:                        s=p->smb.last_error;
                   1631:                        break;
                   1632:                case SMB_PROP_STATUS:
                   1633:                        *vp = INT_TO_JSVAL(p->status);
                   1634:                        break;
                   1635:                case SMB_PROP_RETRY_TIME:
                   1636:                        *vp = INT_TO_JSVAL(p->smb.retry_time);
                   1637:                        break;
                   1638:                case SMB_PROP_RETRY_DELAY:
                   1639:                        *vp = INT_TO_JSVAL(p->smb.retry_delay);
                   1640:                        break;
                   1641:                case SMB_PROP_DEBUG:
                   1642:                        *vp = INT_TO_JSVAL(p->debug);
                   1643:                        break;
                   1644:                case SMB_PROP_FIRST_MSG:
1.1.1.2 ! root     1645:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1646:                        memset(&idx,0,sizeof(idx));
                   1647:                        smb_getfirstidx(&(p->smb),&idx);
1.1.1.2 ! root     1648:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1649:                        JS_NewNumberValue(cx,idx.number,vp);
                   1650:                        break;
                   1651:                case SMB_PROP_LAST_MSG:
1.1.1.2 ! root     1652:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1653:                        smb_getstatus(&(p->smb));
1.1.1.2 ! root     1654:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1655:                        JS_NewNumberValue(cx,p->smb.status.last_msg,vp);
                   1656:                        break;
                   1657:                case SMB_PROP_TOTAL_MSGS:
1.1.1.2 ! root     1658:                        rc=JS_SUSPENDREQUEST(cx);
1.1       root     1659:                        smb_getstatus(&(p->smb));
1.1.1.2 ! root     1660:                        JS_RESUMEREQUEST(cx, rc);
1.1       root     1661:                        JS_NewNumberValue(cx,p->smb.status.total_msgs,vp);
                   1662:                        break;
                   1663:                case SMB_PROP_MAX_CRCS:
                   1664:                        JS_NewNumberValue(cx,p->smb.status.max_crcs,vp);
                   1665:                        break;
                   1666:                case SMB_PROP_MAX_MSGS:
                   1667:                        JS_NewNumberValue(cx,p->smb.status.max_msgs,vp);
                   1668:                        break;
                   1669:                case SMB_PROP_MAX_AGE:
                   1670:                        JS_NewNumberValue(cx,p->smb.status.max_age,vp);
                   1671:                        break;
                   1672:                case SMB_PROP_ATTR:
                   1673:                        JS_NewNumberValue(cx,p->smb.status.attr,vp);
                   1674:                        break;
                   1675:                case SMB_PROP_SUBNUM:
                   1676:                        *vp = INT_TO_JSVAL(p->smb.subnum);
                   1677:                        break;
                   1678:                case SMB_PROP_IS_OPEN:
                   1679:                        *vp = BOOLEAN_TO_JSVAL(SMB_IS_OPEN(&(p->smb)));
                   1680:                        break;
                   1681:        }
                   1682: 
                   1683:        if(s!=NULL) {
                   1684:                if((js_str=JS_NewStringCopyZ(cx, s))==NULL)
                   1685:                        return(JS_FALSE);
                   1686:                *vp = STRING_TO_JSVAL(js_str);
                   1687:        }
                   1688: 
                   1689:        return(JS_TRUE);
                   1690: }
                   1691: 
                   1692: #define SMB_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
                   1693: 
                   1694: static jsSyncPropertySpec js_msgbase_properties[] = {
                   1695: /*              name                           ,tinyid                                 ,flags,                         ver     */
                   1696: 
                   1697:        {       "error"                         ,SMB_PROP_LAST_ERROR    ,SMB_PROP_FLAGS,        310 },
                   1698:        {       "last_error"            ,SMB_PROP_LAST_ERROR    ,JSPROP_READONLY,       311 },  /* alias */
                   1699:        {       "status"                        ,SMB_PROP_STATUS                ,SMB_PROP_FLAGS,        312 },
                   1700:        {       "file"                          ,SMB_PROP_FILE                  ,SMB_PROP_FLAGS,        310 },
                   1701:        {       "debug"                         ,SMB_PROP_DEBUG                 ,0,                                     310 },
                   1702:        {       "retry_time"            ,SMB_PROP_RETRY_TIME    ,JSPROP_ENUMERATE,      310 },
                   1703:        {       "retry_delay"           ,SMB_PROP_RETRY_DELAY   ,JSPROP_ENUMERATE,      311 },
                   1704:        {       "first_msg"                     ,SMB_PROP_FIRST_MSG             ,SMB_PROP_FLAGS,        310 },
                   1705:        {       "last_msg"                      ,SMB_PROP_LAST_MSG              ,SMB_PROP_FLAGS,        310 },
                   1706:        {       "total_msgs"            ,SMB_PROP_TOTAL_MSGS    ,SMB_PROP_FLAGS,        310 },
                   1707:        {       "max_crcs"                      ,SMB_PROP_MAX_CRCS              ,SMB_PROP_FLAGS,        310 },
                   1708:        {       "max_msgs"                      ,SMB_PROP_MAX_MSGS      ,SMB_PROP_FLAGS,        310 },
                   1709:        {       "max_age"                       ,SMB_PROP_MAX_AGE       ,SMB_PROP_FLAGS,        310 },
                   1710:        {       "attributes"            ,SMB_PROP_ATTR                  ,SMB_PROP_FLAGS,        310 },
                   1711:        {       "subnum"                        ,SMB_PROP_SUBNUM                ,SMB_PROP_FLAGS,        310 },
                   1712:        {       "is_open"                       ,SMB_PROP_IS_OPEN               ,SMB_PROP_FLAGS,        310 },
                   1713:        {0}
                   1714: };
                   1715: 
                   1716: #ifdef BUILD_JSDOCS
                   1717: static char* msgbase_prop_desc[] = {
                   1718: 
                   1719:         "last occurred message base error - <small>READ ONLY</small>"
                   1720:        ,"return value of last <i>SMB Library</i> function call - <small>READ ONLY</small>"
                   1721:        ,"base path and filename of message base - <small>READ ONLY</small>"
                   1722:        ,"message base open/lock retry timeout (in seconds)"
                   1723:        ,"delay between message base open/lock retries (in milliseconds)"
                   1724:        ,"first message number - <small>READ ONLY</small>"
                   1725:        ,"last message number - <small>READ ONLY</small>"
                   1726:        ,"total number of messages - <small>READ ONLY</small>"
                   1727:        ,"maximum number of message CRCs to store (for dupe checking) - <small>READ ONLY</small>"
                   1728:        ,"maximum number of messages before expiration - <small>READ ONLY</small>"
                   1729:        ,"maximum age (in days) of messages to store - <small>READ ONLY</small>"
                   1730:        ,"message base attributes - <small>READ ONLY</small>"
1.1.1.2 ! root     1731:        ,"sub-board number (0-based, 65535 for e-mail) - <small>READ ONLY</small>"
1.1       root     1732:        ,"<i>true</i> if the message base has been opened successfully - <small>READ ONLY</small>"
                   1733:        ,NULL
                   1734: };
                   1735: #endif
                   1736: 
                   1737: static jsSyncMethodSpec js_msgbase_functions[] = {
                   1738:        {"open",                        js_open,                        0, JSTYPE_BOOLEAN,      JSDOCSTR("")
                   1739:        ,JSDOCSTR("open message base")
                   1740:        ,310
                   1741:        },
                   1742:        {"close",                       js_close,                       0, JSTYPE_BOOLEAN,      JSDOCSTR("")
                   1743:        ,JSDOCSTR("close message base (if open)")
                   1744:        ,310
                   1745:        },
                   1746:        {"get_msg_header",      js_get_msg_header,      2, JSTYPE_OBJECT,       JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_id [,expand_fields=<tt>true</tt>]")
                   1747:        ,JSDOCSTR("returns a specific message header, <i>null</i> on failure. "
                   1748:        "<br><i>New in v3.12:</i> Pass <i>false</i> for the <i>expand_fields</i> argument (default: <i>true</i>) "
                   1749:        "if you will be re-writing the header later with <i>put_msg_header()</i>")
                   1750:        ,312
                   1751:        },
                   1752:        {"put_msg_header",      js_put_msg_header,      2, JSTYPE_BOOLEAN,      JSDOCSTR("[by_offset=<tt>false</tt>,] number, object header")
                   1753:        ,JSDOCSTR("write a message header")
                   1754:        ,310
                   1755:        },
                   1756:        {"get_msg_body",        js_get_msg_body,        2, JSTYPE_STRING,       JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_id [,strip_ctrl_a=<tt>false</tt>] "
                   1757:                "[,rfc822_encoded=<tt>false</tt>] [,include_tails=<tt>true</tt>]")
1.1.1.2 ! root     1758:        ,JSDOCSTR("returns the entire body text of a specific message as a single String, <i>null</i> on failure. "
1.1       root     1759:                "The default behavior is to leave Ctrl-A codes intact, perform no RFC-822 encoding, and to include tails (if any) in the "
                   1760:                "returned body text."
                   1761:        )
                   1762:        ,310
                   1763:        },
                   1764:        {"get_msg_tail",        js_get_msg_tail,        2, JSTYPE_STRING,       JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_id [,strip_ctrl_a]=<tt>false</tt>")
                   1765:        ,JSDOCSTR("returns the tail text of a specific message, <i>null</i> on failure")
                   1766:        ,310
                   1767:        },
                   1768:        {"get_msg_index",       js_get_msg_index,       2, JSTYPE_OBJECT,       JSDOCSTR("[by_offset=<tt>false</tt>,] number")
                   1769:        ,JSDOCSTR("returns a specific message index, <i>null</i> on failure. "
                   1770:        "The index object will contain the following properties:<br>"
                   1771:        "<table>"
                   1772:        "<tr><td align=top><tt>subject</tt><td>CRC-16 of lowercase message subject"
                   1773:        "<tr><td align=top><tt>to</tt><td>CRC-16 of lowercase recipient's name (or user number if e-mail)"
                   1774:        "<tr><td align=top><tt>from</tt><td>CRC-16 of lowercase sender's name (or user number if e-mail)"
                   1775:        "<tr><td align=top><tt>attr</tt><td>Attribute bitfield"
                   1776:        "<tr><td align=top><tt>time</tt><td>Date/time imported (in time_t format)"
                   1777:        "<tr><td align=top><tt>number</tt><td>Message number"
                   1778:        "<tr><td align=top><tt>offset</tt><td>Record number in index file"
                   1779:        "</table>")
                   1780:        ,311
                   1781:        },
                   1782:        {"remove_msg",          js_remove_msg,          2, JSTYPE_BOOLEAN,      JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_id")
                   1783:        ,JSDOCSTR("mark message for deletion")
                   1784:        ,311
                   1785:        },
                   1786:        {"save_msg",            js_save_msg,            2, JSTYPE_BOOLEAN,      JSDOCSTR("object header [,client=<i>none</i>] [,body_text=<tt>\"\"</tt>] [,array rcpt_list=<i>none</i>]")
                   1787:        ,JSDOCSTR("create a new message in message base, the <i>header</i> object may contain the following properties:<br>"
                   1788:        "<table>"
                   1789:        "<tr><td align=top><tt>subject</tt><td>Message subject <i>(required)</i>"
                   1790:        "<tr><td align=top><tt>to</tt><td>Recipient's name <i>(required)</i>"
                   1791:        "<tr><td align=top><tt>to_ext</tt><td>Recipient's user number (for local e-mail)"
                   1792:        "<tr><td align=top><tt>to_org</tt><td>Recipient's organization"
                   1793:        "<tr><td align=top><tt>to_net_type</tt><td>Recipient's network type (default: 0 for local)"
                   1794:        "<tr><td align=top><tt>to_net_addr</tt><td>Recipient's network address"
                   1795:        "<tr><td align=top><tt>to_agent</tt><td>Recipient's agent type"
                   1796:        "<tr><td align=top><tt>from</tt><td>Sender's name <i>(required)</i>"
                   1797:        "<tr><td align=top><tt>from_ext</tt><td>Sender's user number"
                   1798:        "<tr><td align=top><tt>from_org</tt><td>Sender's organization"
                   1799:        "<tr><td align=top><tt>from_net_type</tt><td>Sender's network type (default: 0 for local)"
                   1800:        "<tr><td align=top><tt>from_net_addr</tt><td>Sender's network address"
                   1801:        "<tr><td align=top><tt>from_agent</tt><td>Sender's agent type"
                   1802:        "<tr><td align=top><tt>from_ip_addr</tt><td>Sender's IP address (if available, for security tracking)"
                   1803:        "<tr><td align=top><tt>from_host_name</tt><td>Sender's host name (if available, for security tracking)"
                   1804:        "<tr><td align=top><tt>from_protocol</tt><td>TCP/IP protocol used by sender (if available, for security tracking)"
                   1805:        "<tr><td align=top><tt>from_port</tt><td>TCP/UDP port number used by sender (if available, for security tracking)"
                   1806:        "<tr><td align=top><tt>replyto</tt><td>Replies should be sent to this name"
                   1807:        "<tr><td align=top><tt>replyto_ext</tt><td>Replies should be sent to this user number"
                   1808:        "<tr><td align=top><tt>replyto_org</tt><td>Replies should be sent to organization"
                   1809:        "<tr><td align=top><tt>replyto_net_type</tt><td>Replies should be sent to this network type"
                   1810:        "<tr><td align=top><tt>replyto_net_addr</tt><td>Replies should be sent to this network address"
                   1811:        "<tr><td align=top><tt>replyto_agent</tt><td>Replies should be sent to this agent type"
                   1812:        "<tr><td align=top><tt>id</tt><td>Message's RFC-822 compliant Message-ID"
                   1813:        "<tr><td align=top><tt>reply_id</tt><td>Message's RFC-822 compliant Reply-ID"
                   1814:        "<tr><td align=top><tt>reverse_path</tt><td>Message's SMTP sender address"
                   1815:        "<tr><td align=top><tt>forward_path</tt><td>Argument to SMTP 'RCPT TO' command"
                   1816:        "<tr><td align=top><tt>path</tt><td>Messages's NNTP path"
                   1817:        "<tr><td align=top><tt>newsgroups</tt><td>Message's NNTP newsgroups header"
                   1818:        "<tr><td align=top><tt>ftn_msgid</tt><td>FidoNet FTS-9 Message-ID"
                   1819:        "<tr><td align=top><tt>ftn_reply</tt><td>FidoNet FTS-9 Reply-ID"
                   1820:        "<tr><td align=top><tt>ftn_area</tt><td>FidoNet FTS-4 echomail AREA tag"
                   1821:        "<tr><td align=top><tt>ftn_flags</tt><td>FidoNet FSC-53 FLAGS"
                   1822:        "<tr><td align=top><tt>ftn_pid</tt><td>FidoNet FSC-46 Program Identifier"
                   1823:        "<tr><td align=top><tt>ftn_tid</tt><td>FidoNet FSC-46 Tosser Identifier"
                   1824:        "<tr><td align=top><tt>date</tt><td>RFC-822 formatted date/time"
                   1825:        "<tr><td align=top><tt>attr</tt><td>Attribute bitfield"
                   1826:        "<tr><td align=top><tt>auxattr</tt><td>Auxillary attribute bitfield"
                   1827:        "<tr><td align=top><tt>netattr</tt><td>Network attribute bitfield"
                   1828:        "<tr><td align=top><tt>when_written_time</tt><td>Date/time (in time_t format)"
1.1.1.2 ! root     1829:        "<tr><td align=top><tt>when_written_zone</tt><td>Time zone (in SMB format)"
        !          1830:        "<tr><td align=top><tt>when_written_zone_offset</tt><td>Time zone in minutes east of UTC"
1.1       root     1831:        "<tr><td align=top><tt>when_imported_time</tt><td>Date/time message was imported"
1.1.1.2 ! root     1832:        "<tr><td align=top><tt>when_imported_zone</tt><td>Time zone (in SMB format)"
        !          1833:        "<tr><td align=top><tt>when_imported_zone_offset</tt><td>Time zone in minutes east of UTC"
1.1       root     1834:        "<tr><td align=top><tt>thread_back</tt><td>Message number that this message is a reply to"
                   1835:        "<tr><td align=top><tt>thread_next</tt><td>Message number of the next reply to the original message in this thread"
                   1836:        "<tr><td align=top><tt>thread_first</tt><td>Message number of the first reply to this message"
                   1837:        "<tr><td align=top><tt>field_list[].type</tt><td>Other SMB header fields (type)"
                   1838:        "<tr><td align=top><tt>field_list[].data</tt><td>Other SMB header fields (data)"
                   1839:        "</table>"
                   1840:        "<br><i>New in v3.12:</i> "
                   1841:        "The optional <i>client</i> argument is an instance of the <i>Client</i> class to be used for the "
                   1842:        "security log header fields (e.g. sender IP address, hostname, protocol, and port). "
                   1843:        "<br><br><i>New in v3.12:</i> "
                   1844:        "The optional <i>rcpt_list</i> is an array of objects that specifies multiple recipients "
                   1845:        "for a single message (e.g. bulk e-mail). Each object in the array may include the following header properties "
                   1846:        "(described above): <br>"
                   1847:        "<i>to</i>, <i>to_ext</i>, <i>to_org</i>, <i>to_net_type</i>, <i>to_net_addr</i>, and <i>to_agent</i>"
                   1848:        )
                   1849:        ,312
                   1850:        },
                   1851:        {0}
                   1852: };
                   1853: 
1.1.1.2 ! root     1854: static JSBool js_msgbase_resolve(JSContext *cx, JSObject *obj, jsval id)
        !          1855: {
        !          1856:        char*                   name=NULL;
        !          1857: 
        !          1858:        if(id != JSVAL_NULL)
        !          1859:                name=JS_GetStringBytes(JSVAL_TO_STRING(id));
        !          1860: 
        !          1861:        return(js_SyncResolve(cx, obj, name, js_msgbase_properties, js_msgbase_functions, NULL, 0));
        !          1862: }
        !          1863: 
        !          1864: static JSBool js_msgbase_enumerate(JSContext *cx, JSObject *obj)
        !          1865: {
        !          1866:        return(js_msgbase_resolve(cx, obj, JSVAL_NULL));
        !          1867: }
        !          1868: 
        !          1869: static JSClass js_msgbase_class = {
        !          1870:      "MsgBase"                         /* name                 */
        !          1871:     ,JSCLASS_HAS_PRIVATE       /* flags                */
        !          1872:        ,JS_PropertyStub                /* addProperty  */
        !          1873:        ,JS_PropertyStub                /* delProperty  */
        !          1874:        ,js_msgbase_get                 /* getProperty  */
        !          1875:        ,js_msgbase_set                 /* setProperty  */
        !          1876:        ,js_msgbase_enumerate   /* enumerate    */
        !          1877:        ,js_msgbase_resolve             /* resolve              */
        !          1878:        ,JS_ConvertStub                 /* convert              */
        !          1879:        ,js_finalize_msgbase    /* finalize             */
        !          1880: };
        !          1881: 
1.1       root     1882: /* MsgBase Constructor (open message base) */
                   1883: 
                   1884: static JSBool
                   1885: js_msgbase_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1886: {
                   1887:        JSString*       js_str;
                   1888:        JSObject*       cfgobj;
                   1889:        char*           base;
                   1890:        private_t*      p;
                   1891: 
                   1892:        if((p=(private_t*)malloc(sizeof(private_t)))==NULL) {
                   1893:                JS_ReportError(cx,"malloc failed");
                   1894:                return(JS_FALSE);
                   1895:        }
                   1896: 
                   1897:        memset(p,0,sizeof(private_t));
                   1898:        p->smb.retry_time=scfg->smb_retry_time;
                   1899: 
                   1900:        js_str = JS_ValueToString(cx, argv[0]);
                   1901:        base=JS_GetStringBytes(js_str);
                   1902: 
                   1903:        p->debug=JS_FALSE;
                   1904: 
                   1905:        if(!JS_SetPrivate(cx, obj, p)) {
                   1906:                JS_ReportError(cx,"JS_SetPrivate failed");
                   1907:                free(p);
                   1908:                return(JS_FALSE);
                   1909:        }
                   1910: 
                   1911: #ifdef BUILD_JSDOCS
                   1912:        js_DescribeSyncObject(cx,obj,"Class used for accessing message bases",310);
                   1913:        js_DescribeSyncConstructor(cx,obj,"To create a new MsgBase object: "
                   1914:                "<tt>var msgbase = new MsgBase('<i>code</i>')</tt><br>"
                   1915:                "where <i>code</i> is a sub-board internal code, or <tt>mail</tt> for the e-mail message base");
                   1916:        js_CreateArrayOfStrings(cx, obj, "_property_desc_list", msgbase_prop_desc, JSPROP_READONLY);
                   1917: #endif
                   1918: 
                   1919:        if(stricmp(base,"mail")==0) {
                   1920:                p->smb.subnum=INVALID_SUB;
                   1921:                snprintf(p->smb.file,sizeof(p->smb.file),"%s%s",scfg->data_dir,"mail");
                   1922:        } else {
                   1923:                for(p->smb.subnum=0;p->smb.subnum<scfg->total_subs;p->smb.subnum++) {
                   1924:                        if(!stricmp(scfg->sub[p->smb.subnum]->code,base))       /* null ptr dereference here Apr-16-2003 */
                   1925:                                break;                                                                                  /* and again, Aug-18-2004 upon recycle */
1.1.1.2 ! root     1926: /* One more time, Mon Jan 26 22:44:23 PST 2009 */
        !          1927: /*
        !          1928: #0  0x282d61b6 in js_msgbase_constructor (cx=0x288bf180, obj=0x29e39460, argc=1, argv=0x28e7413c, rval=0xbf0e8b30)
        !          1929:     at js_msgbase.c:1905
        !          1930: #1  0x2813cb9f in js_Invoke (cx=0x288bf180, argc=1, flags=1) at jsinterp.c:1375
        !          1931: #2  0x2813e6c7 in js_InvokeConstructor (cx=0x288bf180, vp=0x28e74134, argc=1) at jsinterp.c:1947
        !          1932: #3  0x28146a3b in js_Interpret (cx=0x288bf180, pc=0x28e828dd "#", result=0xbf0e9450) at jsinterp.c:3396
        !          1933: #4  0x2813d669 in js_Execute (cx=0x288bf180, chain=0x288c79a0, script=0x28e82800, down=0x0, flags=0, 
        !          1934:     result=0xbf0e9a60) at jsinterp.c:1633
        !          1935: #5  0x2810208a in JS_ExecuteScript (cx=0x288bf180, obj=0x288c79a0, script=0x28e82800, rval=0xbf0e9a60)
        !          1936:     at jsapi.c:4188
        !          1937: #6  0x282c4f1f in js_load (cx=0x288bf180, obj=0x288c66c0, argc=1, argv=0x28e74024, rval=0xbf0e9a60)
        !          1938:     at js_global.c:364
        !          1939: #7  0x2813cb9f in js_Invoke (cx=0x288bf180, argc=1, flags=0) at jsinterp.c:1375
        !          1940: #8  0x2814bfe3 in js_Interpret (cx=0x288bf180, pc=0x28e17a97 ":", result=0xbf0ea300) at jsinterp.c:3944
        !          1941: #9  0x2813d669 in js_Execute (cx=0x288bf180, chain=0x288c79a0, script=0x28e17a60, down=0x0, flags=0, 
        !          1942:     result=0xbf0eabc0) at jsinterp.c:1633
        !          1943: #10 0x2810208a in JS_ExecuteScript (cx=0x288bf180, obj=0x288c79a0, script=0x28e17a60, rval=0xbf0eabc0)
        !          1944:     at jsapi.c:4188
        !          1945: #11 0x2828c066 in sbbs_t::js_execfile (this=0x28ac8000, cmd=0x28ad178e "chinkmaster.js") at exec.cpp:645
        !          1946: #12 0x283725c7 in sbbs_t::external (this=0x28ac8000, cmdline=0x28ad178d "?chinkmaster.js", mode=256, 
        !          1947:     startup_dir=0x28a2bcaa "") at xtrn.cpp:1318
        !          1948: #13 0x283068d9 in event_thread (arg=0x28ac8000) at main.cpp:2713
        !          1949: #14 0x28550a99 in pthread_getprio () from /lib/libthr.so.3
        !          1950: #15 0x00000000 in ?? ()
        !          1951: (gdb) print scfg
        !          1952: $1 = (scfg_t *) 0x2842f480
        !          1953: (gdb) print scfg->sub
        !          1954: $2 = (sub_t **) 0x0
        !          1955: (gdb) print scfg->sub
        !          1956: $3 = (sub_t **) 0x0
        !          1957: (gdb) print p
        !          1958: $4 = (private_t *) 0x29e3c000
        !          1959: (gdb) print *scfg
        !          1960: $5 = {size = 23200, prepped = 1, grp = 0x0, total_grps = 3, sub = 0x0, total_subs = 79, lib = 0x0, 
        !          1961:   total_libs = 6, dir = 0x0, total_dirs = 232, txtsec = 0x0, total_txtsecs = 0, xtrnsec = 0x0, 
        !          1962:   total_xtrnsecs = 3, xtrn = 0x0, total_xtrns = 44, mdm_result = 0x0, mdm_results = 3, prot = 0x0, 
        !          1963:   total_prots = 9, fextr = 0x0, total_fextrs = 3, fcomp = 0x0, total_fcomps = 3, fview = 0x0, total_fviews = 12, 
        !          1964:   ftest = 0x0, total_ftests = 5, xedit = 0x0, total_xedits = 4, qhub = 0x0, total_qhubs = 1, phub = 0x0, 
        !          1965:   total_phubs = 0, chan = 0x0, total_chans = 3, chatact = 0x0, total_chatacts = 132, actset = 0x0, 
        !          1966:   total_actsets = 1, page = 0x0, total_pages = 2, event = 0x0, total_events = 16, dlevent = 0x0, 
        !          1967:   total_dlevents = 0, faddr = 0x0, total_faddrs = 0, swap = 0x0, total_swaps = 19, natvpgm = 0x0, 
        !          1968:   total_natvpgms = 10, guru = 0x0, total_gurus = 1, shell = 0x0, total_shells = 11, hotkey = 0x0, 
        !          1969:   total_hotkeys = 0, com_base = 15, com_irq = 3, com_rate = 2400, com_port = 1 '\001', 
        !          1970:   mdm_init = "AT&FS0=0S2=128E0V0X4&C1&D2", '\0' <repeats 37 times>, mdm_spec = '\0' <repeats 63 times>, 
        !          1971:   mdm_term = "ATE1V1", '\0' <repeats 57 times>, mdm_dial = "ATDT", '\0' <repeats 59 times>, 
        !          1972:   mdm_offh = "ATM0H1", '\0' <repeats 57 times>, mdm_answ = "ATA", '\0' <repeats 60 times>, 
        !          1973:   mdm_hang = '\0' <repeats 63 times>, mdm_misc = 0, mdm_reinit = 0, mdm_ansdelay = 5, mdm_rings = 1 '\001', 
        !          1974:   sys_misc = -2045643832, sys_pass = "XXXXXXXX", '\0' <repeats 32 times>, 
        !          1975:   sys_name = "Synchronix", '\0' <repeats 30 times>, sys_id = "SYNCNIX\000", sys_psname = '\0' <repeats 12 times>, 
        !          1976:   sys_psnum = 0, sys_inetaddr = "nix.synchro.net", '\0' <repeats 112 times>, 
        !          1977:   sys_location = "Springside, SK", '\0' <repeats 26 times>, sys_timezone = 16864, 
        !          1978:   sys_daily = '\0' <repeats 63 times>, sys_logon = '\0' <repeats 63 times>, sys_logout = '\0' <repeats 63 times>, 
        !          1979:   sys_pwdays = 0, sys_deldays = 14, sys_autodel = 180, sys_nodes = 4, sys_op = "Deuce", '\0' <repeats 35 times>, 
        !          1980:   sys_guru = "The Guru", '\0' <repeats 32 times>, sys_exp_warn = 30 '\036', sys_def_stat = 1 '\001', 
        !          1981:   sys_phonefmt = '!' <repeats 12 times>, sys_lastnode = 250, sys_autonode = 1, 
        !          1982:   sys_chat_arstr = '\0' <repeats 40 times>, sys_chat_ar = 0x2837ca04 "", msg_misc = -65536, file_misc = 0, 
        !          1983:   xtrn_misc = 0, node_comspec = '\0' <repeats 63 times>, node_editor = '\0' <repeats 63 times>, 
        !          1984:   node_viewer = "%!list %f", '\0' <repeats 54 times>, node_daily = '\0' <repeats 63 times>, 
        !          1985:   node_scrnlen = 0 '\0', node_scrnblank = 0 '\0', node_misc = 33298, node_valuser = 1, node_ivt = 1, 
        !          1986:   node_swap = 2 '\002', node_swapdir = '\0' <repeats 63 times>, node_minbps = 300, node_num = 1, 
        !          1987:   node_phone = "XXX-XXX-XXXX", node_name = "Node 1", '\0' <repeats 34 times>, 
        !          1988:   node_arstr = '\0' <repeats 40 times>, node_ar = 0x2837ca04 "", node_cost = 0, node_dollars_per_call = 0 '\0', 
        !          1989:   node_sem_check = 5, node_stat_check = 5, new_install = 0 '\0', new_pass = '\0' <repeats 40 times>, 
        !          1990:   new_magic = '\0' <repeats 20 times>, new_sif = "\000\000\000\000\000\000\000\000", 
        !          1991:   new_sof = "\000\000\000\000\000\000\000\000", new_level = 50 '2', new_flags1 = 0, new_flags2 = 0, 
        !          1992:   new_flags3 = 0, new_flags4 = 0, new_exempt = 0, new_rest = 0, new_cdt = 10485760, new_min = 0, 
        !          1993:   new_xedit = "\000\000\000\000\000\000\000\000", new_shell = 0, new_misc = 26896, new_expire = 0, 
        !          1994:   new_prot = 90 'Z', val_level = "\n\n\024\036(2<FPZ", val_flags1 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, val_flags2 = {
        !          1995:     0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, val_flags3 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, val_flags4 = {0, 0, 0, 0, 0, 0, 
        !          1996:     0, 0, 0, 0}, val_exempt = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, val_rest = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
        !          1997:   val_cdt = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, val_expire = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 
        !          1998: ---Type <return> to continue, or q <return> to quit---
        !          1999:   level_expireto = '\0' <repeats 99 times>, level_timepercall = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
        !          2000:     14, 15, 16, 17, 18, 19, 10, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 
        !          2001:     41, 42, 43, 44, 45, 46, 47, 48, 49, 240, 51, 52, 53, 54, 55, 56, 57, 58, 59, 90, 120, 90, 63, 64, 65, 66, 67, 
        !          2002:     68, 69, 120, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 120, 120, 120, 120, 120, 
        !          2003:     120, 120, 120, 120, 480, 500}, level_timeperday = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 11, 12, 13, 14, 15, 16, 
        !          2004:     17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 
        !          2005:     44, 45, 46, 47, 48, 49, 480, 51, 52, 53, 54, 55, 56, 57, 58, 59, 120, 120, 120, 63, 64, 65, 66, 67, 68, 69, 
        !          2006:     120, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 480, 240, 240, 240, 240, 240, 
        !          2007:     240, 240, 240, 500, 500}, level_callsperday = {0, 1, 2, 3, 4, 4, 4, 4, 4, 4, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 
        !          2008:     4 <repeats 29 times>, 50, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 8, 10, 8, 8, 8, 8, 8, 8, 8, 10 <repeats 11 times>, 4, 
        !          2009:     4, 4, 4, 4, 4, 4, 4, 200, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500}, level_linespermsg = {
        !          2010:     20 <repeats 11 times>, 40 <repeats 39 times>, 200, 50, 50, 50, 50, 50, 50, 50, 50, 50, 60 <repeats 11 times>, 
        !          2011:     70, 70, 70, 70, 70, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 90, 90, 90, 90, 90, 90, 90, 90, 
        !          2012:     90, 9999}, level_postsperday = {50 <repeats 50 times>, 20, 50 <repeats 48 times>, 500}, level_emailperday = {
        !          2013:     50 <repeats 50 times>, 20, 50 <repeats 48 times>, 500}, level_freecdtperday = {0 <repeats 50 times>, 4194304, 
        !          2014:     0 <repeats 49 times>}, level_misc = {0 <repeats 100 times>}, expired_level = 0 '\0', expired_flags1 = 0, 
        !          2015:   expired_flags2 = 0, expired_flags3 = 0, expired_flags4 = 0, expired_exempt = 0, expired_rest = 0, 
        !          2016:   min_dspace = 4096, max_batup = 25, max_batdn = 100, max_userxfer = 5, max_minutes = 0, max_qwkmsgs = 10000, 
        !          2017:   preqwk_arstr = '\0' <repeats 40 times>, preqwk_ar = 0x2837ca04 "", cdt_min_value = 6, cdt_per_dollar = 2097152, 
        !          2018:   cdt_up_pct = 100, cdt_dn_pct = 90, node_dir = "/synchronet/sbbs/node1/", '\0' <repeats 40 times>, 
        !          2019:   ctrl_dir = "/synchronet/sbbs/ctrl/", '\0' <repeats 41 times>, 
        !          2020:   data_dir = "/synchronet/sbbs/data/", '\0' <repeats 41 times>, 
        !          2021:   text_dir = "/synchronet/sbbs/text/", '\0' <repeats 41 times>, 
        !          2022:   exec_dir = "/synchronet/sbbs/exec/", '\0' <repeats 41 times>, 
        !          2023:   temp_dir = "/tmp/SyncTemp/", '\0' <repeats 49 times>, 
        !          2024:   mods_dir = "/synchronet/sbbs/mods/", '\0' <repeats 41 times>, 
        !          2025:   logs_dir = "/synchronet/sbbs/data/", '\0' <repeats 41 times>, node_path = {
        !          2026:     "/synchronet/sbbs/node1/", '\0' <repeats 40 times>, "/synchronet/sbbs/node2/", '\0' <repeats 40 times>, 
        !          2027:     "/synchronet/sbbs/node3/", '\0' <repeats 40 times>, "/synchronet/sbbs/node4/", '\0' <repeats 40 times>, 
        !          2028:     '\0' <repeats 63 times> <repeats 246 times>}, sysop_dir = 11, user_dir = 12, upload_dir = 10, altpath = 0x0, 
        !          2029:   altpaths = 0, leech_pct = 0, leech_sec = 60, netmail_cost = 0, 
        !          2030:   netmail_dir = "/synchronet/sbbs/fido/outbound/", '\0' <repeats 32 times>, netmail_misc = 41, 
        !          2031:   inetmail_misc = 17, inetmail_cost = 0, smtpmail_sem = '\0' <repeats 63 times>, 
        !          2032:   inetmail_sem = '\0' <repeats 63 times>, echomail_dir = '\0' <repeats 63 times>, 
        !          2033:   fidofile_dir = "/synchronet/sbbs/fido/inbsecure/", '\0' <repeats 31 times>, 
        !          2034:   netmail_sem = "%jfidoout.now", '\0' <repeats 50 times>, 
        !          2035:   echomail_sem = "%jfidoout.now", '\0' <repeats 50 times>, origline = '\0' <repeats 50 times>, 
        !          2036:   qnet_tagline = "My Brand-New BBS (All the cool SysOps run STOCK!)", '\0' <repeats 78 times>, uq = 151027, 
        !          2037: ---Type <return> to continue, or q <return> to quit---
        !          2038:   mail_maxcrcs = 0, mail_maxage = 0, dflt_faddr = {zone = 0, net = 0, node = 0, point = 0}, 
        !          2039:   logon_mod = "logon\000\000\000", logoff_mod = "\000\000\000\000\000\000\000\000", newuser_mod = "newuser\000", 
        !          2040:   login_mod = "login\000\000\000", logout_mod = "\000\000\000\000\000\000\000\000", 
        !          2041:   sync_mod = "\000\000\000\000\000\000\000\000", expire_mod = "\000\000\000\000\000\000\000\000", 
        !          2042:   scfg_cmd = "%!scfg %k /t%w", '\0' <repeats 49 times>, smb_retry_time = 30 '\036', sec_warn = 180, 
        !          2043:   sec_hangup = 300, color = 0x0, total_colors = 0, ctrlkey_passthru = 0, wfc_cmd = {'\0' <repeats 63 times>, 
        !          2044:     "%!list ..\\data\\error.log", '\0' <repeats 39 times>, "%!list ..\\data\\guru.log", '\0' <repeats 40 times>, 
        !          2045:     "%!list ..\\data\\logons.lst", '\0' <repeats 38 times>, '\0' <repeats 63 times>, '\0' <repeats 63 times>, 
        !          2046:     '\0' <repeats 63 times>, '\0' <repeats 63 times>, '\0' <repeats 63 times>, '\0' <repeats 63 times>}, 
        !          2047:   wfc_scmd = {"%!qnet", '\0' <repeats 57 times>, "%!pnet", '\0' <repeats 57 times>, '\0' <repeats 63 times>, 
        !          2048:     '\0' <repeats 63 times>, '\0' <repeats 63 times>, '\0' <repeats 63 times>, '\0' <repeats 63 times>, 
        !          2049:     '\0' <repeats 63 times>, '\0' <repeats 63 times>, '\0' <repeats 63 times>, '\0' <repeats 63 times>, 
        !          2050:     '\0' <repeats 63 times>}, user_backup_level = 5, mail_backup_level = 5}
        !          2051: */
1.1       root     2052:                }
                   2053:                if(p->smb.subnum<scfg->total_subs) {
                   2054:                        cfgobj=JS_NewObject(cx,NULL,NULL,obj);
                   2055: 
                   2056: #ifdef BUILD_JSDOCS    
                   2057:                        /* needed for property description alignment */
                   2058:                        JS_DefineProperty(cx,cfgobj,"index",JSVAL_VOID
                   2059:                                ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
                   2060:                        JS_DefineProperty(cx,cfgobj,"grp_index",JSVAL_VOID
                   2061:                                ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
                   2062: #endif
                   2063: 
                   2064:                        js_CreateMsgAreaProperties(cx, scfg, cfgobj, p->smb.subnum);
                   2065: #ifdef BUILD_JSDOCS
                   2066:                        js_DescribeSyncObject(cx,cfgobj
                   2067:                                ,"Configuration parameters for this message area (<i>sub-boards only</i>) "
                   2068:                                "- <small>READ ONLY</small>"
                   2069:                                ,310);
                   2070: #endif
                   2071:                        JS_DefineProperty(cx,obj,"cfg",OBJECT_TO_JSVAL(cfgobj)
                   2072:                                ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
                   2073:                        snprintf(p->smb.file,sizeof(p->smb.file),"%s%s"
                   2074:                                ,scfg->sub[p->smb.subnum]->data_dir,scfg->sub[p->smb.subnum]->code);
                   2075:                } else { /* unknown code */
                   2076:                        SAFECOPY(p->smb.file,base);
                   2077:                        p->smb.subnum=INVALID_SUB;
                   2078:                }
                   2079:        }
                   2080: 
                   2081:        return(JS_TRUE);
                   2082: }
                   2083: 
1.1.1.2 ! root     2084: static struct JSPropertySpec js_msgbase_static_properties[] = {
        !          2085: /*              name                           ,tinyid                                 ,flags,                         getter, setter  */
        !          2086: 
        !          2087:        {       "IndexPrototype"                ,0      ,JSPROP_ENUMERATE|JSPROP_PERMANENT,     NULL,NULL},
        !          2088:        {       "HeaderPrototype"               ,0      ,JSPROP_ENUMERATE|JSPROP_PERMANENT,     NULL,NULL},
        !          2089:        {0}
        !          2090: };
        !          2091: 
1.1       root     2092: JSObject* DLLCALL js_CreateMsgBaseClass(JSContext* cx, JSObject* parent, scfg_t* cfg)
                   2093: {
                   2094:        JSObject*       obj;
1.1.1.2 ! root     2095:        JSObject*       constructor;
        !          2096:        jsval           val;
1.1       root     2097: 
                   2098:        scfg = cfg;
                   2099:        obj = JS_InitClass(cx, parent, NULL
                   2100:                ,&js_msgbase_class
                   2101:                ,js_msgbase_constructor
                   2102:                ,1      /* number of constructor args */
                   2103:                ,NULL /* js_msgbase_properties */
                   2104:                ,NULL /* js_msgbase_functions */
1.1.1.2 ! root     2105:                ,js_msgbase_static_properties,NULL);
        !          2106: 
        !          2107: 
        !          2108:        if(JS_GetProperty(cx, parent, js_msgbase_class.name, &val) && !JSVAL_NULL_OR_VOID(val)) {
        !          2109:                JS_ValueToObject(cx,val,&constructor);
        !          2110:                JS_DefineObject(cx,constructor,"IndexPrototype",NULL,NULL,JSPROP_PERMANENT|JSPROP_ENUMERATE);
        !          2111:                JS_DefineObject(cx,constructor,"HeaderPrototype",NULL,NULL,JSPROP_PERMANENT|JSPROP_ENUMERATE);
        !          2112:        }
1.1       root     2113: 
                   2114:        return(obj);
                   2115: }
                   2116: 
                   2117: 
                   2118: #endif /* JAVSCRIPT */

unix.superglobalmegacorp.com

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