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

1.1       root        1: /* js_msgbase.c */
                      2: 
                      3: /* Synchronet JavaScript "MsgBase" Object */
                      4: 
                      5: /* $Id: js_msgbase.c,v 1.126 2006/12/28 02:45:27 rswindell Exp $ */
                      6: 
                      7: /****************************************************************************
                      8:  * @format.tab-size 4          (Plain Text/Source Code File Header)                    *
                      9:  * @format.use-tabs true       (see http://www.synchro.net/ptsc_hdr.html)              *
                     10:  *                                                                                                                                                     *
                     11:  * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html         *
                     12:  *                                                                                                                                                     *
                     13:  * This program is free software; you can redistribute it and/or                       *
                     14:  * modify it under the terms of the GNU General Public License                         *
                     15:  * as published by the Free Software Foundation; either version 2                      *
                     16:  * of the License, or (at your option) any later version.                                      *
                     17:  * See the GNU General Public License for more details: gpl.txt or                     *
                     18:  * http://www.fsf.org/copyleft/gpl.html                                                                                *
                     19:  *                                                                                                                                                     *
                     20:  * Anonymous FTP access to the most recent released source is available at     *
                     21:  * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net     *
                     22:  *                                                                                                                                                     *
                     23:  * Anonymous CVS access to the development source and modification history     *
                     24:  * is available at cvs.synchro.net:/cvsroot/sbbs, example:                                     *
                     25:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs login                       *
                     26:  *     (just hit return, no password is necessary)                                                     *
                     27:  * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src                *
                     28:  *                                                                                                                                                     *
                     29:  * For Synchronet coding style and modification guidelines, see                                *
                     30:  * http://www.synchro.net/source.html                                                                          *
                     31:  *                                                                                                                                                     *
                     32:  * You are encouraged to submit any modifications (preferably in Unix diff     *
                     33:  * format) via e-mail to [email protected]                                                                      *
                     34:  *                                                                                                                                                     *
                     35:  * Note: If this box doesn't appear square, then you need to fix your tabs.    *
                     36:  ****************************************************************************/
                     37: 
                     38: #include "sbbs.h"
                     39: 
                     40: #ifdef JAVASCRIPT
                     41: 
                     42: static scfg_t* scfg=NULL;
                     43: 
                     44: typedef struct
                     45: {
                     46:        smb_t   smb;
                     47:        int             status;
                     48:        BOOL    debug;
                     49: 
                     50: } private_t;
                     51: 
                     52: static const char* getprivate_failure = "line %d %s JS_GetPrivate failed";
                     53: 
                     54: /* Destructor */
                     55: 
                     56: static void js_finalize_msgbase(JSContext *cx, JSObject *obj)
                     57: {
                     58:        private_t* p;
                     59:        
                     60:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL)
                     61:                return;
                     62: 
                     63:        if(SMB_IS_OPEN(&(p->smb)))
                     64:                smb_close(&(p->smb));
                     65: 
                     66:        free(p);
                     67: 
                     68:        JS_SetPrivate(cx, obj, NULL);
                     69: }
                     70: 
                     71: /* Methods */
                     72: 
                     73: static JSBool
                     74: js_open(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                     75: {
                     76:        private_t* p;
                     77:        
                     78:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                     79:                JS_ReportError(cx,getprivate_failure,WHERE);
                     80:                return(JS_FALSE);
                     81:        }
                     82: 
                     83:        *rval = JSVAL_FALSE;
                     84: 
                     85:        if(p->smb.subnum==INVALID_SUB 
                     86:                && strchr(p->smb.file,'/')==NULL
                     87:                && strchr(p->smb.file,'\\')==NULL) {
                     88:                JS_ReportError(cx,"Unrecognized msgbase code: %s",p->smb.file);
                     89:                return(JS_TRUE);
                     90:        }
                     91: 
                     92:        if((p->status=smb_open(&(p->smb)))!=SMB_SUCCESS)
                     93:                return(JS_TRUE);
                     94: 
                     95:        *rval = JSVAL_TRUE;
                     96:        return(JS_TRUE);
                     97: }
                     98: 
                     99: 
                    100: static JSBool
                    101: js_close(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    102: {
                    103:        private_t* p;
                    104:        
                    105:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    106:                JS_ReportError(cx,getprivate_failure,WHERE);
                    107:                return(JS_FALSE);
                    108:        }
                    109: 
                    110:        smb_close(&(p->smb));
                    111: 
                    112:        return(JS_TRUE);
                    113: }
                    114: 
                    115: static BOOL parse_recipient_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg)
                    116: {
                    117:        char*           cp;
                    118:        char            to[256];
                    119:        ushort          nettype=NET_UNKNOWN;
                    120:        ushort          agent;
                    121:        int32           i32;
                    122:        jsval           val;
                    123: 
                    124:        if(JS_GetProperty(cx, hdr, "to", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    125:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    126:                        return(FALSE);
                    127:        } else {
                    128:                if(p->smb.status.attr&SMB_EMAIL)        /* e-mail */
                    129:                        return(FALSE);                                  /* "to" property required */
                    130:                cp="All";
                    131:        }
                    132:        if((p->status=smb_hfield_str(msg, RECIPIENT, cp))!=SMB_SUCCESS)
                    133:                return(FALSE);
                    134:        if(!(p->smb.status.attr&SMB_EMAIL)) {
                    135:                SAFECOPY(to,cp);
                    136:                strlwr(to);
                    137:                msg->idx.to=crc16(to,0);
                    138:        }
                    139: 
                    140:        if(JS_GetProperty(cx, hdr, "to_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    141:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    142:                        return(FALSE);
                    143:                if((p->status=smb_hfield_str(msg, RECIPIENTEXT, cp))!=SMB_SUCCESS)
                    144:                        return(FALSE);
                    145:                if(p->smb.status.attr&SMB_EMAIL)
                    146:                        msg->idx.to=atoi(cp);
                    147:        }
                    148: 
                    149:        if(JS_GetProperty(cx, hdr, "to_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    150:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    151:                        return(FALSE);
                    152:                if((p->status=smb_hfield_str(msg, RECIPIENTORG, cp))!=SMB_SUCCESS)
                    153:                        return(FALSE);
                    154:        }
                    155: 
                    156:        if(JS_GetProperty(cx, hdr, "to_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    157:                JS_ValueToInt32(cx,val,&i32);
                    158:                nettype=(ushort)i32;
                    159:        }
                    160: 
                    161:        if(JS_GetProperty(cx, hdr, "to_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    162:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    163:                        return(FALSE);
                    164:                if((p->status=smb_hfield_netaddr(msg, RECIPIENTNETADDR, cp, &nettype))!=SMB_SUCCESS)
                    165:                        return(FALSE);
                    166:        }
                    167: 
                    168:        if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
                    169:                if(p->smb.status.attr&SMB_EMAIL)
                    170:                        msg->idx.to=0;
                    171:                if((p->status=smb_hfield_bin(msg, RECIPIENTNETTYPE, nettype))!=SMB_SUCCESS)
                    172:                        return(FALSE);
                    173:        }
                    174: 
                    175:        if(JS_GetProperty(cx, hdr, "to_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    176:                JS_ValueToInt32(cx,val,&i32);
                    177:                agent=(ushort)i32;
                    178:                if((p->status=smb_hfield_bin(msg, RECIPIENTAGENT, agent))!=SMB_SUCCESS)
                    179:                        return(FALSE);
                    180:        }
                    181: 
                    182:        return(TRUE);
                    183: }
                    184: 
                    185: static BOOL parse_header_object(JSContext* cx, private_t* p, JSObject* hdr, smbmsg_t* msg
                    186:                                                                ,BOOL recipient)
                    187: {
                    188:        char*           cp;
                    189:        char            from[256];
                    190:        ushort          nettype=NET_UNKNOWN;
                    191:        ushort          type;
                    192:        ushort          agent;
                    193:        ushort          port;
                    194:        int32           i32;
                    195:        jsval           val;
                    196:        JSObject*       array;
                    197:        JSObject*       field;
                    198:        jsuint          i,len;
                    199: 
                    200:        if(hdr==NULL)
                    201:                return(FALSE);
                    202: 
                    203:        if(recipient && !parse_recipient_object(cx,p,hdr,msg))
                    204:                return(FALSE);
                    205: 
                    206:        /* Required Header Fields */
                    207:        if(JS_GetProperty(cx, hdr, "subject", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    208:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    209:                        return(FALSE);
                    210:        } else
                    211:                cp="";
                    212:        if((p->status=smb_hfield_str(msg, SUBJECT, cp))!=SMB_SUCCESS)
                    213:                return(FALSE);
                    214:        msg->idx.subj=smb_subject_crc(cp);
                    215: 
                    216:        if(JS_GetProperty(cx, hdr, "from", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    217:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    218:                        return(FALSE);
                    219:        } else
                    220:                return(FALSE);  /* "from" property required */
                    221:        if((p->status=smb_hfield_str(msg, SENDER, cp))!=SMB_SUCCESS)
                    222:                return(FALSE);
                    223:        if(!(p->smb.status.attr&SMB_EMAIL)) {
                    224:                SAFECOPY(from,cp);
                    225:                strlwr(from);
                    226:                msg->idx.from=crc16(from,0);
                    227:        }
                    228: 
                    229:        /* Optional Header Fields */
                    230:        if(JS_GetProperty(cx, hdr, "from_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    231:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    232:                        return(FALSE);
                    233:                if((p->status=smb_hfield_str(msg, SENDEREXT, cp))!=SMB_SUCCESS)
                    234:                        return(FALSE);
                    235:                if(p->smb.status.attr&SMB_EMAIL)
                    236:                        msg->idx.from=atoi(cp);
                    237:        }
                    238: 
                    239:        if(JS_GetProperty(cx, hdr, "from_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    240:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    241:                        return(FALSE);
                    242:                if((p->status=smb_hfield_str(msg, SENDERORG, cp))!=SMB_SUCCESS)
                    243:                        return(FALSE);
                    244:        }
                    245: 
                    246:        if(JS_GetProperty(cx, hdr, "from_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    247:                JS_ValueToInt32(cx,val,&i32);
                    248:                nettype=(ushort)i32;
                    249:        }
                    250: 
                    251:        if(JS_GetProperty(cx, hdr, "from_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    252:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    253:                        return(FALSE);
                    254:                if((p->status=smb_hfield_netaddr(msg, SENDERNETADDR, cp, &nettype))!=SMB_SUCCESS)
                    255:                        return(FALSE);
                    256:        }
                    257:        
                    258:        if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
                    259:                if(p->smb.status.attr&SMB_EMAIL)
                    260:                        msg->idx.from=0;
                    261:                if((p->status=smb_hfield_bin(msg, SENDERNETTYPE, nettype))!=SMB_SUCCESS)
                    262:                        return(FALSE);
                    263:        }
                    264: 
                    265:        if(JS_GetProperty(cx, hdr, "from_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    266:                JS_ValueToInt32(cx,val,&i32);
                    267:                agent=(ushort)i32;
                    268:                if((p->status=smb_hfield_bin(msg, SENDERAGENT, agent))!=SMB_SUCCESS)
                    269:                        return(FALSE);
                    270:        }
                    271: 
                    272:        if(JS_GetProperty(cx, hdr, "from_ip_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    273:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    274:                        return(FALSE);
                    275:                if((p->status=smb_hfield_str(msg, SENDERIPADDR, cp))!=SMB_SUCCESS)
                    276:                        return(FALSE);
                    277:        }
                    278: 
                    279:        if(JS_GetProperty(cx, hdr, "from_host_name", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    280:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    281:                        return(FALSE);
                    282:                if((p->status=smb_hfield_str(msg, SENDERHOSTNAME, cp))!=SMB_SUCCESS)
                    283:                        return(FALSE);
                    284:        }
                    285: 
                    286:        if(JS_GetProperty(cx, hdr, "from_protocol", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    287:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    288:                        return(FALSE);
                    289:                if((p->status=smb_hfield_str(msg, SENDERPROTOCOL, cp))!=SMB_SUCCESS)
                    290:                        return(FALSE);
                    291:        }
                    292: 
                    293:        if(JS_GetProperty(cx, hdr, "from_port", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    294:                JS_ValueToInt32(cx,val,&i32);
                    295:                port=(ushort)i32;
                    296:                if((p->status=smb_hfield_bin(msg, SENDERPORT, port))!=SMB_SUCCESS)
                    297:                        return(FALSE);
                    298:        }
                    299: 
                    300:        if(JS_GetProperty(cx, hdr, "replyto", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    301:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    302:                        return(FALSE);
                    303:                if((p->status=smb_hfield_str(msg, REPLYTO, cp))!=SMB_SUCCESS)
                    304:                        return(FALSE);
                    305:        }
                    306: 
                    307:        if(JS_GetProperty(cx, hdr, "replyto_ext", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    308:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    309:                        return(FALSE);
                    310:                if((p->status=smb_hfield_str(msg, REPLYTOEXT, cp))!=SMB_SUCCESS)
                    311:                        return(FALSE);
                    312:        }
                    313: 
                    314:        if(JS_GetProperty(cx, hdr, "replyto_org", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    315:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    316:                        return(FALSE);
                    317:                if((p->status=smb_hfield_str(msg, REPLYTOORG, cp))!=SMB_SUCCESS)
                    318:                        return(FALSE);
                    319:        }
                    320: 
                    321:        nettype=NET_UNKNOWN;
                    322:        if(JS_GetProperty(cx, hdr, "replyto_net_type", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    323:                JS_ValueToInt32(cx,val,&i32);
                    324:                nettype=(ushort)i32;
                    325:        }
                    326:        if(JS_GetProperty(cx, hdr, "replyto_net_addr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    327:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    328:                        return(FALSE);
                    329:                if((p->status=smb_hfield_netaddr(msg, REPLYTONETADDR, cp, &nettype))!=SMB_SUCCESS)
                    330:                        return(FALSE);
                    331:        }
                    332:        if(nettype!=NET_UNKNOWN && nettype!=NET_NONE) {
                    333:                if((p->status=smb_hfield_bin(msg, REPLYTONETTYPE, nettype))!=SMB_SUCCESS)
                    334:                        return(FALSE);
                    335:        }
                    336: 
                    337:        if(JS_GetProperty(cx, hdr, "replyto_agent", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    338:                JS_ValueToInt32(cx,val,&i32);
                    339:                agent=(ushort)i32;
                    340:                if((p->status=smb_hfield_bin(msg, REPLYTOAGENT, agent))!=SMB_SUCCESS)
                    341:                        return(FALSE);
                    342:        }
                    343: 
                    344:        /* RFC822 headers */
                    345:        if(JS_GetProperty(cx, hdr, "id", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    346:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    347:                        return(FALSE);
                    348:                if((p->status=smb_hfield_str(msg, RFC822MSGID, cp))!=SMB_SUCCESS)
                    349:                        return(FALSE);
                    350:        }
                    351: 
                    352:        if(JS_GetProperty(cx, hdr, "reply_id", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    353:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    354:                        return(FALSE);
                    355:                if((p->status=smb_hfield_str(msg, RFC822REPLYID, cp))!=SMB_SUCCESS)
                    356:                        return(FALSE);
                    357:        }
                    358: 
                    359:        /* SMTP headers */
                    360:        if(JS_GetProperty(cx, hdr, "reverse_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    361:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    362:                        return(FALSE);
                    363:                if((p->status=smb_hfield_str(msg, SMTPREVERSEPATH, cp))!=SMB_SUCCESS)
                    364:                        return(FALSE);
                    365:        }
                    366: 
                    367:        if(JS_GetProperty(cx, hdr, "forward_path", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    368:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    369:                        return(FALSE);
                    370:                if((p->status=smb_hfield_str(msg, SMTPFORWARDPATH, cp))!=SMB_SUCCESS)
                    371:                        return(FALSE);
                    372:        }
                    373: 
                    374:        /* USENET headers */
                    375:        if(JS_GetProperty(cx, hdr, "path", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    376:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    377:                        return(FALSE);
                    378:                if((p->status=smb_hfield_str(msg, USENETPATH, cp))!=SMB_SUCCESS)
                    379:                        return(FALSE);
                    380:        }
                    381: 
                    382:        if(JS_GetProperty(cx, hdr, "newsgroups", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    383:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    384:                        return(FALSE);
                    385:                if((p->status=smb_hfield_str(msg, USENETNEWSGROUPS, cp))!=SMB_SUCCESS)
                    386:                        return(FALSE);
                    387:        }
                    388: 
                    389:        /* FTN headers */
                    390:        if(JS_GetProperty(cx, hdr, "ftn_msgid", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    391:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    392:                        return(FALSE);
                    393:                if((p->status=smb_hfield_str(msg, FIDOMSGID, cp))!=SMB_SUCCESS)
                    394:                        return(FALSE);
                    395:        }
                    396: 
                    397:        if(JS_GetProperty(cx, hdr, "ftn_reply", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    398:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    399:                        return(FALSE);
                    400:                if((p->status=smb_hfield_str(msg, FIDOREPLYID, cp))!=SMB_SUCCESS)
                    401:                        return(FALSE);
                    402:        }
                    403: 
                    404:        if(JS_GetProperty(cx, hdr, "ftn_area", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    405:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    406:                        return(FALSE);
                    407:                if((p->status=smb_hfield_str(msg, FIDOAREA, cp))!=SMB_SUCCESS)
                    408:                        return(FALSE);
                    409:        }
                    410: 
                    411:        if(JS_GetProperty(cx, hdr, "ftn_flags", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    412:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    413:                        return(FALSE);
                    414:                if((p->status=smb_hfield_str(msg, FIDOFLAGS, cp))!=SMB_SUCCESS)
                    415:                        return(FALSE);
                    416:        }
                    417: 
                    418:        if(JS_GetProperty(cx, hdr, "ftn_pid", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    419:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    420:                        return(FALSE);
                    421:                if((p->status=smb_hfield_str(msg, FIDOPID, cp))!=SMB_SUCCESS)
                    422:                        return(FALSE);
                    423:        }
                    424: 
                    425:        if(JS_GetProperty(cx, hdr, "ftn_tid", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    426:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    427:                        return(FALSE);
                    428:                if((p->status=smb_hfield_str(msg, FIDOTID, cp))!=SMB_SUCCESS)
                    429:                        return(FALSE);
                    430:        }
                    431: 
                    432:        if(JS_GetProperty(cx, hdr, "date", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    433:                if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    434:                        return(FALSE);
                    435:                msg->hdr.when_written=rfc822date(cp);
                    436:        }
                    437:        
                    438:        /* Numeric Header Fields */
                    439:        if(JS_GetProperty(cx, hdr, "attr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    440:                JS_ValueToInt32(cx,val,&i32);
                    441:                msg->hdr.attr=(ushort)i32;
                    442:                msg->idx.attr=msg->hdr.attr;
                    443:        }
                    444:        if(JS_GetProperty(cx, hdr, "auxattr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    445:                JS_ValueToInt32(cx,val,&i32);
                    446:                msg->hdr.auxattr=i32;
                    447:        }
                    448:        if(JS_GetProperty(cx, hdr, "netattr", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    449:                JS_ValueToInt32(cx,val,&i32);
                    450:                msg->hdr.netattr=i32;
                    451:        }
                    452:        if(JS_GetProperty(cx, hdr, "when_written_time", &val) && !JSVAL_NULL_OR_VOID(val))  {
                    453:                JS_ValueToInt32(cx,val,&i32);
                    454:                msg->hdr.when_written.time=i32;
                    455:        }
                    456:        if(JS_GetProperty(cx, hdr, "when_written_zone", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    457:                JS_ValueToInt32(cx,val,&i32);
                    458:                msg->hdr.when_written.zone=(short)i32;
                    459:        }
                    460:        if(JS_GetProperty(cx, hdr, "when_imported_time", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    461:                JS_ValueToInt32(cx,val,&i32);
                    462:                msg->hdr.when_imported.time=i32;
                    463:        }
                    464:        if(JS_GetProperty(cx, hdr, "when_imported_zone", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    465:                JS_ValueToInt32(cx,val,&i32);
                    466:                msg->hdr.when_imported.zone=(short)i32;
                    467:        }
                    468: 
                    469:        if((JS_GetProperty(cx, hdr, "thread_orig", &val) 
                    470:                || JS_GetProperty(cx, hdr, "thread_back", &val)) && !JSVAL_NULL_OR_VOID(val)) {
                    471:                JS_ValueToInt32(cx,val,&i32);
                    472:                msg->hdr.thread_back=i32;
                    473:        }
                    474:        if(JS_GetProperty(cx, hdr, "thread_next", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    475:                JS_ValueToInt32(cx,val,&i32);
                    476:                msg->hdr.thread_next=i32;
                    477:        }
                    478:        if(JS_GetProperty(cx, hdr, "thread_first", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    479:                JS_ValueToInt32(cx,val,&i32);
                    480:                msg->hdr.thread_first=i32;
                    481:        }
                    482: 
                    483:        if(JS_GetProperty(cx, hdr, "field_list", &val) && JSVAL_IS_OBJECT(val)) {
                    484:                array=JSVAL_TO_OBJECT(val);
                    485:                len=0;
                    486:                if(!JS_GetArrayLength(cx, array, &len))
                    487:                        return(FALSE);
                    488: 
                    489:                for(i=0;i<len;i++) {
                    490:                        if(!JS_GetElement(cx, array, i, &val))
                    491:                                continue;
                    492:                        if(!JSVAL_IS_OBJECT(val))
                    493:                                continue;
                    494:                        field=JSVAL_TO_OBJECT(val);
                    495:                        if(!JS_GetProperty(cx, field, "type", &val))
                    496:                                continue;
                    497:                        if(JSVAL_IS_STRING(val))
                    498:                                type=smb_hfieldtypelookup(JS_GetStringBytes(JS_ValueToString(cx,val)));
                    499:                        else {
                    500:                                JS_ValueToInt32(cx,val,&i32);
                    501:                                type=(ushort)i32;
                    502:                        }
                    503:                        if(!JS_GetProperty(cx, field, "data", &val))
                    504:                                continue;
                    505:                        if((cp=JS_GetStringBytes(JS_ValueToString(cx,val)))==NULL)
                    506:                                return(FALSE);
                    507:                        if((p->status=smb_hfield_str(msg, type, cp))!=SMB_SUCCESS)
                    508:                                return(FALSE);
                    509:                }
                    510:        }
                    511: 
                    512:        if(msg->hdr.number==0 && JS_GetProperty(cx, hdr, "number", &val) && !JSVAL_NULL_OR_VOID(val)) {
                    513:                JS_ValueToInt32(cx,val,&i32);
                    514:                msg->hdr.number=i32;
                    515:        }
                    516: 
                    517:        return(TRUE);
                    518: }
                    519: 
                    520: /* obj must've been previously returned from get_msg_header() */
                    521: BOOL DLLCALL js_ParseMsgHeaderObject(JSContext* cx, JSObject* obj, smbmsg_t* msg)
                    522: {
                    523:        private_t*      p;
                    524: 
                    525:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    526:                JS_ReportError(cx,getprivate_failure,WHERE);
                    527:                return(FALSE);
                    528:        }
                    529: 
                    530:        if(!parse_header_object(cx, p, obj, msg, /* recipient */ TRUE)) {
                    531:                smb_freemsgmem(msg);
                    532:                return(FALSE);
                    533:        }
                    534: 
                    535:        return(TRUE);
                    536: }
                    537: 
                    538: static BOOL msg_offset_by_id(private_t* p, char* id, long* offset)
                    539: {
                    540:        smbmsg_t msg;
                    541: 
                    542:        if((p->status=smb_getmsgidx_by_msgid(&(p->smb),&msg,id))!=SMB_SUCCESS)
                    543:                return(FALSE);
                    544: 
                    545:        *offset = msg.offset;
                    546:        return(TRUE);
                    547: }
                    548: 
                    549: static JSBool
                    550: js_get_msg_index(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    551: {
                    552:        uintN           n;
                    553:        jsval           val;
                    554:        smbmsg_t        msg;
                    555:        JSObject*       idxobj;
                    556:        JSBool          by_offset=JS_FALSE;
                    557:        private_t*      p;
                    558: 
                    559:        *rval = JSVAL_NULL;
                    560:        
                    561:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    562:                JS_ReportError(cx,getprivate_failure,WHERE);
                    563:                return(JS_FALSE);
                    564:        }
                    565: 
                    566:        if(!SMB_IS_OPEN(&(p->smb)))
                    567:                return(JS_TRUE);
                    568: 
                    569:        memset(&msg,0,sizeof(msg));
                    570: 
                    571:        for(n=0;n<argc;n++) {
                    572:                if(JSVAL_IS_BOOLEAN(argv[n]))
                    573:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                    574:                else if(JSVAL_IS_NUM(argv[n])) {
                    575:                        if(by_offset)                                                   /* Get by offset */
                    576:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                    577:                        else                                                                    /* Get by number */
                    578:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                    579: 
                    580:                        if((p->status=smb_getmsgidx(&(p->smb), &msg))!=SMB_SUCCESS)
                    581:                                return(JS_TRUE);
                    582: 
                    583:                        break;
                    584:                }
                    585:        }
                    586: 
                    587:        if((idxobj=JS_NewObject(cx,NULL,NULL,obj))==NULL)
                    588:                return(JS_TRUE);
                    589: 
                    590:        JS_NewNumberValue(cx, msg.idx.number    ,&val);
                    591:        JS_DefineProperty(cx, idxobj, "number"  ,val
                    592:                ,NULL,NULL,JSPROP_ENUMERATE);
                    593: 
                    594:        JS_NewNumberValue(cx, msg.idx.to                ,&val);
                    595:        JS_DefineProperty(cx, idxobj, "to"              ,val
                    596:                ,NULL,NULL,JSPROP_ENUMERATE);
                    597: 
                    598:        JS_NewNumberValue(cx, msg.idx.from              ,&val);
                    599:        JS_DefineProperty(cx, idxobj, "from"    ,val
                    600:                ,NULL,NULL,JSPROP_ENUMERATE);
                    601: 
                    602:        JS_NewNumberValue(cx, msg.idx.subj              ,&val);
                    603:        JS_DefineProperty(cx, idxobj, "subject" ,val
                    604:                ,NULL,NULL,JSPROP_ENUMERATE);
                    605: 
                    606:        JS_NewNumberValue(cx, msg.idx.attr              ,&val);
                    607:        JS_DefineProperty(cx, idxobj, "attr"    ,val
                    608:                ,NULL,NULL,JSPROP_ENUMERATE);
                    609: 
                    610:        JS_NewNumberValue(cx, msg.offset                ,&val);
                    611:        JS_DefineProperty(cx, idxobj, "offset"  ,val
                    612:                ,NULL,NULL,JSPROP_ENUMERATE);
                    613: 
                    614:        JS_NewNumberValue(cx, msg.idx.time              ,&val);
                    615:        JS_DefineProperty(cx, idxobj, "time"    ,val
                    616:                ,NULL,NULL,JSPROP_ENUMERATE);
                    617: 
                    618:        *rval = OBJECT_TO_JSVAL(idxobj);
                    619: 
                    620:        return(JS_TRUE);
                    621: }
                    622: 
                    623: static JSClass js_msghdr_class = {
                    624:      "MsgHeader"                       /* name                 */
                    625:     ,JSCLASS_HAS_PRIVATE       /* flags                */
                    626:        ,JS_PropertyStub                /* addProperty  */
                    627:        ,JS_PropertyStub                /* delProperty  */
                    628:        ,JS_PropertyStub                /* getProperty  */
                    629:        ,JS_PropertyStub                /* setProperty  */
                    630:        ,JS_EnumerateStub               /* enumerate    */
                    631:        ,JS_ResolveStub                 /* resolve              */
                    632:        ,JS_ConvertStub                 /* convert              */
                    633:        ,JS_FinalizeStub                /* finalize             */
                    634: };
                    635: 
                    636: 
                    637: static JSBool
                    638: js_get_msg_header(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                    639: {
                    640:        char            date[128];
                    641:        char            msg_id[256];
                    642:        char            reply_id[256];
                    643:        char*           val;
                    644:        ushort*         port;
                    645:        int                     i;
                    646:        uintN           n;
                    647:        smbmsg_t        msg;
                    648:        smbmsg_t        remsg;
                    649:        JSObject*       hdrobj;
                    650:        JSObject*       array;
                    651:        JSObject*       field;
                    652:        JSString*       js_str;
                    653:        jsint           items;
                    654:        jsval           v;
                    655:        JSBool          by_offset=JS_FALSE;
                    656:        JSBool          expand_fields=JS_TRUE;
                    657:        private_t*      p;
                    658: 
                    659:        *rval = JSVAL_NULL;
                    660:        
                    661:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                    662:                JS_ReportError(cx,getprivate_failure,WHERE);
                    663:                return(JS_FALSE);
                    664:        }
                    665: 
                    666:        if(!SMB_IS_OPEN(&(p->smb)))
                    667:                return(JS_TRUE);
                    668: 
                    669:        memset(&msg,0,sizeof(msg));
                    670: 
                    671:        /* Parse boolean arguments first */
                    672:        for(n=0;n<argc;n++) {
                    673:                if(!JSVAL_IS_BOOLEAN(argv[n]))
                    674:                        continue;
                    675:                if(n)
                    676:                        expand_fields=JSVAL_TO_BOOLEAN(argv[n]);
                    677:                else
                    678:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                    679:        }
                    680: 
                    681:        /* Now parse message offset/id and get message */
                    682:        for(n=0;n<argc;n++) {
                    683:                if(JSVAL_IS_NUM(argv[n])) {
                    684:                        if(by_offset)                                                   /* Get by offset */
                    685:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                    686:                        else                                                                    /* Get by number */
                    687:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                    688: 
                    689:                        if((p->status=smb_getmsgidx(&(p->smb), &msg))!=SMB_SUCCESS)
                    690:                                return(JS_TRUE);
                    691: 
                    692:                        if((p->status=smb_lockmsghdr(&(p->smb),&msg))!=SMB_SUCCESS)
                    693:                                return(JS_TRUE);
                    694: 
                    695:                        if((p->status=smb_getmsghdr(&(p->smb), &msg))!=SMB_SUCCESS) {
                    696:                                smb_unlockmsghdr(&(p->smb),&msg); 
                    697:                                return(JS_TRUE);
                    698:                        }
                    699: 
                    700:                        smb_unlockmsghdr(&(p->smb),&msg); 
                    701:                        break;
                    702:                } else if(JSVAL_IS_STRING(argv[n]))     {               /* Get by ID */
                    703:                        if((p->status=smb_getmsghdr_by_msgid(&(p->smb),&msg
                    704:                                ,JS_GetStringBytes(JSVAL_TO_STRING(argv[n]))))!=SMB_SUCCESS)
                    705:                                return(JS_TRUE);        /* ID not found */
                    706:                        break;
                    707:                }
                    708:        }
                    709: 
                    710:        if(msg.hdr.number==0) /* No valid message number/id/offset specified */
                    711:                return(JS_TRUE);
                    712: 
                    713:        if((hdrobj=JS_NewObject(cx,&js_msghdr_class,NULL,obj))==NULL) {
                    714:                smb_freemsgmem(&msg);
                    715:                return(JS_TRUE);
                    716:        }
                    717: 
                    718:        if(!JS_SetPrivate(cx, hdrobj, p)) {
                    719:                smb_freemsgmem(&msg);
                    720:                JS_ReportError(cx,"JS_SetPrivate failed");
                    721:                return(JS_FALSE);
                    722:        }
                    723: 
                    724:        JS_NewNumberValue(cx,msg.hdr.number,&v);
                    725:        JS_DefineProperty(cx, hdrobj, "number", v, NULL,NULL,JSPROP_ENUMERATE);
                    726: 
                    727:        JS_NewNumberValue(cx,msg.offset,&v);
                    728:        JS_DefineProperty(cx, hdrobj, "offset", v, NULL,NULL,JSPROP_ENUMERATE);
                    729: 
                    730:        if((js_str=JS_NewStringCopyZ(cx,truncsp(msg.to)))==NULL)
                    731:                return(JS_FALSE);
                    732:        JS_DefineProperty(cx, hdrobj, "to"
                    733:                ,STRING_TO_JSVAL(js_str)
                    734:                ,NULL,NULL,JSPROP_ENUMERATE);
                    735: 
                    736:        if((js_str=JS_NewStringCopyZ(cx,truncsp(msg.from)))==NULL)
                    737:                return(JS_FALSE);
                    738:        JS_DefineProperty(cx, hdrobj, "from"
                    739:                ,STRING_TO_JSVAL(js_str)
                    740:                ,NULL,NULL,JSPROP_ENUMERATE);
                    741: 
                    742:        if((js_str=JS_NewStringCopyZ(cx,truncsp(msg.subj)))==NULL)
                    743:                return(JS_FALSE);
                    744:        JS_DefineProperty(cx, hdrobj, "subject"
                    745:                ,STRING_TO_JSVAL(js_str)
                    746:                ,NULL,NULL,JSPROP_ENUMERATE);
                    747:        if(msg.summary!=NULL 
                    748:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.summary)))!=NULL)
                    749:                JS_DefineProperty(cx, hdrobj, "summary"
                    750:                        ,STRING_TO_JSVAL(js_str)
                    751:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    752:        if(msg.to_ext!=NULL 
                    753:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.to_ext)))!=NULL)
                    754:                JS_DefineProperty(cx, hdrobj, "to_ext"
                    755:                        ,STRING_TO_JSVAL(js_str)
                    756:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    757:        if(msg.from_ext!=NULL 
                    758:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.from_ext)))!=NULL)
                    759:                JS_DefineProperty(cx, hdrobj, "from_ext"
                    760:                        ,STRING_TO_JSVAL(js_str)
                    761:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    762:        if(msg.from_org!=NULL
                    763:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.from_org)))!=NULL)
                    764:                JS_DefineProperty(cx, hdrobj, "from_org"
                    765:                        ,STRING_TO_JSVAL(js_str)
                    766:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    767:        if(msg.replyto!=NULL
                    768:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.replyto)))!=NULL)
                    769:                JS_DefineProperty(cx, hdrobj, "replyto"
                    770:                        ,STRING_TO_JSVAL(js_str)
                    771:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    772:        if(msg.replyto_ext!=NULL
                    773:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.replyto_ext)))!=NULL)
                    774:                JS_DefineProperty(cx, hdrobj, "replyto_ext"
                    775:                        ,STRING_TO_JSVAL(js_str)
                    776:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    777:        if(msg.reverse_path!=NULL
                    778:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.reverse_path)))!=NULL)
                    779:                JS_DefineProperty(cx, hdrobj, "reverse_path"
                    780:                        ,STRING_TO_JSVAL(js_str)
                    781:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    782:        if(msg.forward_path!=NULL
                    783:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.forward_path)))!=NULL)
                    784:                JS_DefineProperty(cx, hdrobj, "forward_path"
                    785:                        ,STRING_TO_JSVAL(js_str)
                    786:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    787: 
                    788:        if(expand_fields || msg.to_agent)
                    789:                JS_DefineProperty(cx, hdrobj, "to_agent",INT_TO_JSVAL(msg.to_agent)
                    790:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    791:        if(expand_fields || msg.from_agent)
                    792:                JS_DefineProperty(cx, hdrobj, "from_agent",INT_TO_JSVAL(msg.from_agent)
                    793:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    794:        if(expand_fields || msg.replyto_agent)
                    795:                JS_DefineProperty(cx, hdrobj, "replyto_agent",INT_TO_JSVAL(msg.replyto_agent)
                    796:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    797: 
                    798:        if(expand_fields || msg.to_net.type)
                    799:                JS_DefineProperty(cx, hdrobj, "to_net_type",INT_TO_JSVAL(msg.to_net.type)
                    800:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    801:        if(msg.to_net.type
                    802:                && (js_str=JS_NewStringCopyZ(cx,smb_netaddr(&msg.to_net)))!=NULL)
                    803:                JS_DefineProperty(cx, hdrobj, "to_net_addr"
                    804:                        ,STRING_TO_JSVAL(js_str)
                    805:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    806: 
                    807:        if(expand_fields || msg.from_net.type)
                    808:                JS_DefineProperty(cx, hdrobj, "from_net_type",INT_TO_JSVAL(msg.from_net.type)
                    809:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    810:        if(msg.from_net.type
                    811:                && (js_str=JS_NewStringCopyZ(cx,smb_netaddr(&msg.from_net)))!=NULL)
                    812:                JS_DefineProperty(cx, hdrobj, "from_net_addr"
                    813:                        ,STRING_TO_JSVAL(js_str)
                    814:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    815: 
                    816: 
                    817:        if(expand_fields || msg.replyto_net.type)
                    818:                JS_DefineProperty(cx, hdrobj, "replyto_net_type",INT_TO_JSVAL(msg.replyto_net.type)
                    819:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    820:        if(msg.replyto_net.type
                    821:                && (js_str=JS_NewStringCopyZ(cx,smb_netaddr(&msg.replyto_net)))!=NULL)
                    822:                JS_DefineProperty(cx, hdrobj, "replyto_net_addr"
                    823:                        ,STRING_TO_JSVAL(js_str)
                    824:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    825: 
                    826:        if((val=smb_get_hfield(&msg,SENDERIPADDR,NULL))!=NULL
                    827:                && (js_str=JS_NewStringCopyZ(cx,val))!=NULL)
                    828:                JS_DefineProperty(cx, hdrobj, "from_ip_addr"
                    829:                        ,STRING_TO_JSVAL(js_str)
                    830:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    831: 
                    832:        if((val=smb_get_hfield(&msg,SENDERHOSTNAME,NULL))!=NULL
                    833:                && (js_str=JS_NewStringCopyZ(cx,val))!=NULL)
                    834:                JS_DefineProperty(cx, hdrobj, "from_host_name"
                    835:                        ,STRING_TO_JSVAL(js_str)
                    836:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    837: 
                    838:        if((val=smb_get_hfield(&msg,SENDERPROTOCOL,NULL))!=NULL
                    839:                && (js_str=JS_NewStringCopyZ(cx,val))!=NULL)
                    840:                JS_DefineProperty(cx, hdrobj, "from_protocol"
                    841:                        ,STRING_TO_JSVAL(js_str)
                    842:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    843: 
                    844:        if((port=smb_get_hfield(&msg,SENDERPORT,NULL))!=NULL)
                    845:                JS_DefineProperty(cx, hdrobj, "from_port"
                    846:                        ,INT_TO_JSVAL(*port)
                    847:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    848:        
                    849:        if(expand_fields || msg.forwarded)
                    850:                JS_DefineProperty(cx, hdrobj, "forwarded",INT_TO_JSVAL(msg.forwarded)
                    851:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    852:        if(expand_fields || msg.expiration) {
                    853:                JS_NewNumberValue(cx,msg.expiration,&v);
                    854:                JS_DefineProperty(cx, hdrobj, "expiration",v,NULL,NULL,JSPROP_ENUMERATE);
                    855:        }
                    856:        if(expand_fields || msg.priority) {
                    857:                JS_NewNumberValue(cx,msg.priority,&v);
                    858:                JS_DefineProperty(cx, hdrobj, "priority",v,NULL,NULL,JSPROP_ENUMERATE);
                    859:        }
                    860:        if(expand_fields || msg.cost) {
                    861:                JS_NewNumberValue(cx,msg.cost,&v);
                    862:                JS_DefineProperty(cx, hdrobj, "cost",v,NULL,NULL,JSPROP_ENUMERATE);
                    863:        }
                    864: 
                    865:        /* Fixed length portion of msg header */
                    866:        JS_DefineProperty(cx, hdrobj, "type", INT_TO_JSVAL(msg.hdr.type)
                    867:                ,NULL,NULL,JSPROP_ENUMERATE);
                    868:        JS_DefineProperty(cx, hdrobj, "version", INT_TO_JSVAL(msg.hdr.version)
                    869:                ,NULL,NULL,JSPROP_ENUMERATE);
                    870:        JS_DefineProperty(cx, hdrobj, "attr", INT_TO_JSVAL(msg.hdr.attr)
                    871:                ,NULL,NULL,JSPROP_ENUMERATE);
                    872:        JS_NewNumberValue(cx,msg.hdr.auxattr,&v);
                    873:        JS_DefineProperty(cx, hdrobj, "auxattr", v, NULL,NULL,JSPROP_ENUMERATE);
                    874:        JS_NewNumberValue(cx,msg.hdr.netattr,&v);
                    875:        JS_DefineProperty(cx, hdrobj, "netattr", v, NULL,NULL,JSPROP_ENUMERATE);
                    876: 
                    877:        JS_NewNumberValue(cx,msg.hdr.when_written.time,&v);
                    878:        JS_DefineProperty(cx, hdrobj, "when_written_time", v, NULL,NULL,JSPROP_ENUMERATE);
                    879:        JS_NewNumberValue(cx,msg.hdr.when_written.zone,&v);
                    880:        JS_DefineProperty(cx, hdrobj, "when_written_zone", v, NULL,NULL,JSPROP_ENUMERATE);
                    881:        JS_NewNumberValue(cx,msg.hdr.when_imported.time,&v);
                    882:        JS_DefineProperty(cx, hdrobj, "when_imported_time", v, NULL,NULL,JSPROP_ENUMERATE);
                    883:        JS_NewNumberValue(cx,msg.hdr.when_imported.zone,&v);
                    884:        JS_DefineProperty(cx, hdrobj, "when_imported_zone", v, NULL,NULL,JSPROP_ENUMERATE);
                    885: 
                    886:        JS_NewNumberValue(cx,msg.hdr.thread_back,&v);
                    887:        JS_DefineProperty(cx, hdrobj, "thread_back", v, NULL,NULL,JSPROP_ENUMERATE);
                    888:        JS_DefineProperty(cx, hdrobj, "thread_orig", v, NULL,NULL,0);
                    889:        JS_NewNumberValue(cx,msg.hdr.thread_next,&v);
                    890:        JS_DefineProperty(cx, hdrobj, "thread_next", v, NULL,NULL,JSPROP_ENUMERATE);
                    891:        JS_NewNumberValue(cx,msg.hdr.thread_first,&v);
                    892:        JS_DefineProperty(cx, hdrobj, "thread_first", v, NULL,NULL,JSPROP_ENUMERATE);
                    893: 
                    894:        JS_NewNumberValue(cx,msg.hdr.delivery_attempts,&v);
                    895:        JS_DefineProperty(cx, hdrobj, "delivery_attempts", v, NULL,NULL,JSPROP_ENUMERATE);
                    896:        JS_NewNumberValue(cx,msg.hdr.last_downloaded,&v);
                    897:        JS_DefineProperty(cx, hdrobj, "last_downloaded", v, NULL,NULL,JSPROP_ENUMERATE);
                    898:        JS_NewNumberValue(cx,msg.hdr.times_downloaded,&v);
                    899:        JS_DefineProperty(cx, hdrobj, "times_downloaded", v, NULL,NULL,JSPROP_ENUMERATE);
                    900: 
                    901:        JS_NewNumberValue(cx,smb_getmsgdatlen(&msg),&v);
                    902:        JS_DefineProperty(cx, hdrobj, "data_length", v, NULL,NULL,JSPROP_ENUMERATE);
                    903: 
                    904:        if((js_str=JS_NewStringCopyZ(cx,msgdate(msg.hdr.when_written,date)))==NULL)
                    905:                return(JS_FALSE);
                    906:        JS_DefineProperty(cx, hdrobj, "date"
                    907:                ,STRING_TO_JSVAL(js_str)
                    908:                ,NULL,NULL,JSPROP_ENUMERATE);
                    909: 
                    910:        /* Reply-ID (References) */
                    911:        if(msg.reply_id!=NULL)
                    912:                val=msg.reply_id;
                    913:        else {
                    914:                reply_id[0]=0;
                    915:                if(expand_fields && msg.hdr.thread_back) {
                    916:                        memset(&remsg,0,sizeof(remsg));
                    917:                        remsg.hdr.number=msg.hdr.thread_back;
                    918:                        if(smb_getmsgidx(&(p->smb), &remsg))
                    919:                                sprintf(reply_id,"<%s>",p->smb.last_error);
                    920:                        else
                    921:                                SAFECOPY(reply_id,get_msgid(scfg,p->smb.subnum,&remsg));
                    922:                }
                    923:                val=reply_id;
                    924:        }
                    925:        if(val[0] && (js_str=JS_NewStringCopyZ(cx,truncsp(val)))!=NULL)
                    926:                JS_DefineProperty(cx, hdrobj, "reply_id"
                    927:                        , STRING_TO_JSVAL(js_str)
                    928:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    929: 
                    930:        /* Message-ID */
                    931:        if(expand_fields || msg.id!=NULL) {
                    932:                SAFECOPY(msg_id,get_msgid(scfg,p->smb.subnum,&msg));
                    933:                val=msg_id;
                    934:                if((js_str=JS_NewStringCopyZ(cx,truncsp(val)))==NULL)
                    935:                        return(JS_FALSE);
                    936:                JS_DefineProperty(cx, hdrobj, "id"
                    937:                        ,STRING_TO_JSVAL(js_str)
                    938:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    939:        }
                    940: 
                    941:        /* USENET Fields */
                    942:        if(msg.path!=NULL
                    943:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.path)))!=NULL)
                    944:                JS_DefineProperty(cx, hdrobj, "path"
                    945:                        ,STRING_TO_JSVAL(js_str)
                    946:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    947:        if(msg.newsgroups!=NULL
                    948:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.newsgroups)))!=NULL)
                    949:                JS_DefineProperty(cx, hdrobj, "newsgroups"
                    950:                        ,STRING_TO_JSVAL(js_str)
                    951:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    952: 
                    953:        /* FidoNet Header Fields */
                    954:        if(msg.ftn_msgid!=NULL
                    955:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.ftn_msgid)))!=NULL)
                    956:                JS_DefineProperty(cx, hdrobj, "ftn_msgid"
                    957:                        ,STRING_TO_JSVAL(js_str)
                    958:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    959:        if(msg.ftn_reply!=NULL
                    960:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.ftn_reply)))!=NULL)
                    961:                JS_DefineProperty(cx, hdrobj, "ftn_reply"
                    962:                        ,STRING_TO_JSVAL(js_str)
                    963:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    964:        if(msg.ftn_pid!=NULL
                    965:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.ftn_pid)))!=NULL)
                    966:                JS_DefineProperty(cx, hdrobj, "ftn_pid"
                    967:                        ,STRING_TO_JSVAL(js_str)
                    968:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    969:        if(msg.ftn_tid!=NULL
                    970:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.ftn_tid)))!=NULL)
                    971:                JS_DefineProperty(cx, hdrobj, "ftn_tid"
                    972:                        ,STRING_TO_JSVAL(js_str)
                    973:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    974:        if(msg.ftn_area!=NULL
                    975:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.ftn_area)))!=NULL)
                    976:                JS_DefineProperty(cx, hdrobj, "ftn_area"
                    977:                        ,STRING_TO_JSVAL(js_str)
                    978:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    979:        if(msg.ftn_flags!=NULL
                    980:                && (js_str=JS_NewStringCopyZ(cx,truncsp(msg.ftn_flags)))!=NULL)
                    981:                JS_DefineProperty(cx, hdrobj, "ftn_flags"
                    982:                        ,STRING_TO_JSVAL(js_str)
                    983:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    984: 
                    985:        /* Create hdr.field_list[] with repeating header fields (including type and data) */
                    986:        if((array=JS_NewArrayObject(cx,0,NULL))!=NULL) {
                    987:                JS_DefineProperty(cx,hdrobj,"field_list",OBJECT_TO_JSVAL(array)
                    988:                        ,NULL,NULL,JSPROP_ENUMERATE);
                    989:                items=0;
                    990:                for(i=0;i<msg.total_hfields;i++) {
                    991:                        switch(msg.hfield[i].type) {
                    992:                                case SMB_COMMENT:
                    993:                                case SMB_CARBONCOPY:
                    994:                                case SMB_GROUP:
                    995:                                case FILEATTACH:
                    996:                                case DESTFILE:
                    997:                                case FILEATTACHLIST:
                    998:                                case DESTFILELIST:
                    999:                                case FILEREQUEST:
                   1000:                                case FILEPASSWORD:
                   1001:                                case FILEREQUESTLIST:
                   1002:                                case FILEPASSWORDLIST:
                   1003:                                case FIDOCTRL:
                   1004:                                case FIDOSEENBY:
                   1005:                                case FIDOPATH:
                   1006:                                case RFC822HEADER:
                   1007:                                case UNKNOWNASCII:
                   1008:                                        /* only support these header field types */
                   1009:                                        break;
                   1010:                                default:
                   1011:                                        /* dupe or possibly binary header field */
                   1012:                                        continue;
                   1013:                        }
                   1014:                        if((field=JS_NewObject(cx,NULL,NULL,array))==NULL)
                   1015:                                continue;
                   1016:                        JS_DefineProperty(cx,field,"type"
                   1017:                                ,INT_TO_JSVAL(msg.hfield[i].type)
                   1018:                                ,NULL,NULL,JSPROP_ENUMERATE);
                   1019:                        if((js_str=JS_NewStringCopyN(cx,msg.hfield_dat[i],msg.hfield[i].length))==NULL)
                   1020:                                break;
                   1021:                        JS_DefineProperty(cx,field,"data"
                   1022:                                ,STRING_TO_JSVAL(js_str)
                   1023:                                ,NULL,NULL,JSPROP_ENUMERATE);
                   1024:                        JS_DefineElement(cx,array,items,OBJECT_TO_JSVAL(field)
                   1025:                                ,NULL,NULL,JSPROP_ENUMERATE);
                   1026:                        items++;
                   1027:                }
                   1028:        }
                   1029: 
                   1030:        smb_freemsgmem(&msg);
                   1031: 
                   1032:        *rval = OBJECT_TO_JSVAL(hdrobj);
                   1033: 
                   1034:        return(JS_TRUE);
                   1035: }
                   1036: 
                   1037: static JSBool
                   1038: js_put_msg_header(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1039: {
                   1040:        uintN           n;
                   1041:        JSBool          by_offset=JS_FALSE;
                   1042:        JSBool          msg_specified=JS_FALSE;
                   1043:        smbmsg_t        msg;
                   1044:        JSObject*       hdr=NULL;
                   1045:        private_t*      p;
                   1046: 
                   1047:        *rval = JSVAL_FALSE;
                   1048: 
                   1049:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1050:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1051:                return(JS_FALSE);
                   1052:        }
                   1053: 
                   1054:        if(!SMB_IS_OPEN(&(p->smb)))
                   1055:                return(JS_TRUE);
                   1056: 
                   1057:        memset(&msg,0,sizeof(msg));
                   1058: 
                   1059:        for(n=0;n<argc;n++) {
                   1060:                if(JSVAL_IS_BOOLEAN(argv[n]))
                   1061:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                   1062:                else if(JSVAL_IS_NUM(argv[n])) {
                   1063:                        if(by_offset)                                                   /* Get by offset */
                   1064:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                   1065:                        else                                                                    /* Get by number */
                   1066:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                   1067:                        msg_specified=JS_TRUE;
                   1068:                        n++;
                   1069:                        break;
                   1070:                } else if(JSVAL_IS_STRING(argv[n]))     {               /* Get by ID */
                   1071:                        if(!msg_offset_by_id(p
                   1072:                                ,JS_GetStringBytes(JSVAL_TO_STRING(argv[n]))
                   1073:                                ,&msg.offset))
                   1074:                                return(JS_TRUE);        /* ID not found */
                   1075:                        msg_specified=JS_TRUE;
                   1076:                        n++;
                   1077:                        break;
                   1078:                }
                   1079:        }
                   1080: 
                   1081:        if(!msg_specified)
                   1082:                return(JS_TRUE);
                   1083: 
                   1084:        if(n==argc || !JSVAL_IS_OBJECT(argv[n])) /* no header supplied? */
                   1085:                return(JS_TRUE);
                   1086: 
                   1087:        hdr = JSVAL_TO_OBJECT(argv[n++]);
                   1088: 
                   1089:        if((p->status=smb_getmsgidx(&(p->smb), &msg))!=SMB_SUCCESS)
                   1090:                return(JS_TRUE);
                   1091: 
                   1092:        if((p->status=smb_lockmsghdr(&(p->smb),&msg))!=SMB_SUCCESS)
                   1093:                return(JS_TRUE);
                   1094: 
                   1095:        do {
                   1096:                if((p->status=smb_getmsghdr(&(p->smb), &msg))!=SMB_SUCCESS)
                   1097:                        break;
                   1098: 
                   1099:                smb_freemsghdrmem(&msg);        /* prevent duplicate header fields */
                   1100: 
                   1101:                if(!parse_header_object(cx, p, hdr, &msg, TRUE)) {
                   1102:                        sprintf(p->smb.last_error,"Header parsing failure (required field missing?)");
                   1103:                        break;
                   1104:                }
                   1105: 
                   1106:                if((p->status=smb_putmsg(&(p->smb), &msg))!=SMB_SUCCESS)
                   1107:                        break;
                   1108: 
                   1109:                *rval = JSVAL_TRUE;
                   1110:        } while(0);
                   1111: 
                   1112:        smb_unlockmsghdr(&(p->smb),&msg); 
                   1113:        smb_freemsgmem(&msg);
                   1114: 
                   1115:        return(JS_TRUE);
                   1116: }
                   1117: 
                   1118: static JSBool
                   1119: js_remove_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1120: {
                   1121:        uintN           n;
                   1122:        JSBool          by_offset=JS_FALSE;
                   1123:        JSBool          msg_specified=JS_FALSE;
                   1124:        smbmsg_t        msg;
                   1125:        private_t*      p;
                   1126: 
                   1127:        *rval = JSVAL_FALSE;
                   1128: 
                   1129:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1130:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1131:                return(JS_FALSE);
                   1132:        }
                   1133: 
                   1134:        if(!SMB_IS_OPEN(&(p->smb)))
                   1135:                return(JS_TRUE);
                   1136: 
                   1137:        memset(&msg,0,sizeof(msg));
                   1138: 
                   1139:        for(n=0;n<argc;n++) {
                   1140:                if(JSVAL_IS_BOOLEAN(argv[n]))
                   1141:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                   1142:                else if(JSVAL_IS_NUM(argv[n])) {
                   1143:                        if(by_offset)                                                   /* Get by offset */
                   1144:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                   1145:                        else                                                                    /* Get by number */
                   1146:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                   1147:                        msg_specified=JS_TRUE;
                   1148:                        n++;
                   1149:                        break;
                   1150:                } else if(JSVAL_IS_STRING(argv[n]))     {               /* Get by ID */
                   1151:                        if(!msg_offset_by_id(p
                   1152:                                ,JS_GetStringBytes(JSVAL_TO_STRING(argv[n]))
                   1153:                                ,&msg.offset))
                   1154:                                return(JS_TRUE);        /* ID not found */
                   1155:                        msg_specified=JS_TRUE;
                   1156:                        n++;
                   1157:                        break;
                   1158:                }
                   1159:        }
                   1160: 
                   1161:        if(!msg_specified)
                   1162:                return(JS_TRUE);
                   1163: 
                   1164:        if((p->status=smb_getmsgidx(&(p->smb), &msg))==SMB_SUCCESS
                   1165:                && (p->status=smb_getmsghdr(&(p->smb), &msg))==SMB_SUCCESS) {
                   1166: 
                   1167:                msg.hdr.attr|=MSG_DELETE;
                   1168: 
                   1169:                if((p->status=smb_updatemsg(&(p->smb), &msg))==SMB_SUCCESS)
                   1170:                        *rval = JSVAL_TRUE;
                   1171:        }
                   1172: 
                   1173:        smb_freemsgmem(&msg);
                   1174: 
                   1175:        return(JS_TRUE);
                   1176: }
                   1177: 
                   1178: static char* get_msg_text(private_t* p, smbmsg_t* msg, BOOL strip_ctrl_a, BOOL rfc822, ulong mode)
                   1179: {
                   1180:        char*           buf;
                   1181: 
                   1182:        if((p->status=smb_getmsgidx(&(p->smb), msg))!=SMB_SUCCESS)
                   1183:                return(NULL);
                   1184: 
                   1185:        if((p->status=smb_lockmsghdr(&(p->smb),msg))!=SMB_SUCCESS)
                   1186:                return(NULL);
                   1187: 
                   1188:        if((p->status=smb_getmsghdr(&(p->smb), msg))!=SMB_SUCCESS) {
                   1189:                smb_unlockmsghdr(&(p->smb), msg); 
                   1190:                return(NULL);
                   1191:        }
                   1192: 
                   1193:        if((buf=smb_getmsgtxt(&(p->smb), msg, mode))==NULL) {
                   1194:                smb_unlockmsghdr(&(p->smb),msg); 
                   1195:                smb_freemsgmem(msg);
                   1196:                return(NULL);
                   1197:        }
                   1198: 
                   1199:        smb_unlockmsghdr(&(p->smb), msg); 
                   1200:        smb_freemsgmem(msg);
                   1201: 
                   1202:        if(strip_ctrl_a) {
                   1203:                char* newbuf;
                   1204:                if((newbuf=malloc(strlen(buf)+1))!=NULL) {
                   1205:                        int i,j;
                   1206:                        for(i=j=0;buf[i];i++) {
                   1207:                                if(buf[i]==CTRL_A && buf[i+1]!=0)
                   1208:                                        i++;
                   1209:                                else newbuf[j++]=buf[i]; 
                   1210:                        }
                   1211:                        newbuf[j]=0;
                   1212:                        strcpy(buf,newbuf);
                   1213:                        free(newbuf);
                   1214:                }
                   1215:        }
                   1216: 
                   1217:        if(rfc822) {    /* must escape lines starting with dot ('.') */
                   1218:                char* newbuf;
                   1219:                if((newbuf=malloc((strlen(buf)*2)+1))!=NULL) {
                   1220:                        int i,j;
                   1221:                        for(i=j=0;buf[i];i++) {
                   1222:                                if((i==0 || buf[i-1]=='\n') && buf[i]=='.')
                   1223:                                        newbuf[j++]='.';
                   1224:                                newbuf[j++]=buf[i]; 
                   1225:                        }
                   1226:                        newbuf[j]=0;
                   1227:                        free(buf);
                   1228:                        buf = newbuf;
                   1229:                }
                   1230:        }
                   1231: 
                   1232:        return(buf);
                   1233: }
                   1234: 
                   1235: static JSBool
                   1236: js_get_msg_body(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1237: {
                   1238:        char*           buf;
                   1239:        uintN           n;
                   1240:        smbmsg_t        msg;
                   1241:        JSBool          by_offset=JS_FALSE;
                   1242:        JSBool          strip_ctrl_a=JS_FALSE;
                   1243:        JSBool          tails=JS_TRUE;
                   1244:        JSBool          rfc822=JS_FALSE;
                   1245:        JSBool          msg_specified=JS_FALSE;
                   1246:        JSString*       js_str;
                   1247:        private_t*      p;
                   1248: 
                   1249:        *rval = JSVAL_NULL;
                   1250:        
                   1251:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1252:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1253:                return(JS_FALSE);
                   1254:        }
                   1255: 
                   1256:        if(!SMB_IS_OPEN(&(p->smb)))
                   1257:                return(JS_TRUE);
                   1258: 
                   1259:        memset(&msg,0,sizeof(msg));
                   1260: 
                   1261:        for(n=0;n<argc;n++) {
                   1262:                if(JSVAL_IS_BOOLEAN(argv[n]))
                   1263:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                   1264:                else if(JSVAL_IS_NUM(argv[n])) {
                   1265:                        if(by_offset)                                                   /* Get by offset */
                   1266:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                   1267:                        else                                                                    /* Get by number */
                   1268:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                   1269:                        msg_specified=JS_TRUE;
                   1270:                        n++;
                   1271:                        break;
                   1272:                } else if(JSVAL_IS_STRING(argv[n]))     {               /* Get by ID */
                   1273:                        if(!msg_offset_by_id(p
                   1274:                                ,JS_GetStringBytes(JSVAL_TO_STRING(argv[n]))
                   1275:                                ,&msg.offset))
                   1276:                                return(JS_TRUE);        /* ID not found */
                   1277:                        msg_specified=JS_TRUE;
                   1278:                        n++;
                   1279:                        break;
                   1280:                }
                   1281:        }
                   1282: 
                   1283:        if(!msg_specified)      /* No message number or id specified */
                   1284:                return(JS_TRUE);
                   1285: 
                   1286:        if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
                   1287:                strip_ctrl_a=JSVAL_TO_BOOLEAN(argv[n++]);
                   1288: 
                   1289:        if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
                   1290:                rfc822=JSVAL_TO_BOOLEAN(argv[n++]);
                   1291: 
                   1292:        if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
                   1293:                tails=JSVAL_TO_BOOLEAN(argv[n++]);
                   1294: 
                   1295:        buf = get_msg_text(p, &msg, strip_ctrl_a, rfc822, tails ? GETMSGTXT_TAILS : 0);
                   1296:        if(buf==NULL)
                   1297:                return(JS_TRUE);
                   1298: 
                   1299:        if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL)
                   1300:                *rval = STRING_TO_JSVAL(js_str);
                   1301: 
                   1302:        smb_freemsgtxt(buf);
                   1303: 
                   1304:        return(JS_TRUE);
                   1305: }
                   1306: 
                   1307: static JSBool
                   1308: js_get_msg_tail(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1309: {
                   1310:        char*           buf;
                   1311:        uintN           n;
                   1312:        smbmsg_t        msg;
                   1313:        JSBool          by_offset=JS_FALSE;
                   1314:        JSBool          strip_ctrl_a=JS_FALSE;
                   1315:        JSBool          rfc822=JS_FALSE;
                   1316:        JSBool          msg_specified=JS_FALSE;
                   1317:        JSString*       js_str;
                   1318:        private_t*      p;
                   1319: 
                   1320:        *rval = JSVAL_NULL;
                   1321:        
                   1322:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1323:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1324:                return(JS_FALSE);
                   1325:        }
                   1326: 
                   1327:        if(!SMB_IS_OPEN(&(p->smb)))
                   1328:                return(JS_TRUE);
                   1329: 
                   1330:        memset(&msg,0,sizeof(msg));
                   1331: 
                   1332:        for(n=0;n<argc;n++) {
                   1333:                if(JSVAL_IS_BOOLEAN(argv[n]))
                   1334:                        by_offset=JSVAL_TO_BOOLEAN(argv[n]);
                   1335:                else if(JSVAL_IS_NUM(argv[n])) {
                   1336:                        if(by_offset)                                                   /* Get by offset */
                   1337:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.offset);
                   1338:                        else                                                                    /* Get by number */
                   1339:                                JS_ValueToInt32(cx,argv[n],(int32*)&msg.hdr.number);
                   1340:                        msg_specified=JS_TRUE;
                   1341:                        n++;
                   1342:                        break;
                   1343:                } else if(JSVAL_IS_STRING(argv[n]))     {               /* Get by ID */
                   1344:                        if(!msg_offset_by_id(p
                   1345:                                ,JS_GetStringBytes(JSVAL_TO_STRING(argv[n]))
                   1346:                                ,&msg.offset))
                   1347:                                return(JS_TRUE);        /* ID not found */
                   1348:                        msg_specified=JS_TRUE;
                   1349:                        n++;
                   1350:                        break;
                   1351:                }
                   1352:        }
                   1353: 
                   1354:        if(!msg_specified)      /* No message number or id specified */
                   1355:                return(JS_TRUE);
                   1356: 
                   1357:        if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
                   1358:                strip_ctrl_a=JSVAL_TO_BOOLEAN(argv[n++]);
                   1359: 
                   1360:        if(n<argc && JSVAL_IS_BOOLEAN(argv[n]))
                   1361:                rfc822=JSVAL_TO_BOOLEAN(argv[n++]);
                   1362: 
                   1363:        buf = get_msg_text(p, &msg, strip_ctrl_a, rfc822, GETMSGTXT_TAILS|GETMSGTXT_NO_BODY);
                   1364:        if(buf==NULL)
                   1365:                return(JS_TRUE);
                   1366: 
                   1367:        if((js_str=JS_NewStringCopyZ(cx,buf))!=NULL)
                   1368:                *rval = STRING_TO_JSVAL(js_str);
                   1369: 
                   1370:        smb_freemsgtxt(buf);
                   1371: 
                   1372:        return(JS_TRUE);
                   1373: }
                   1374: 
                   1375: static JSBool
                   1376: js_save_msg(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1377: {
                   1378:        char*           body=NULL;
                   1379:        uintN           n;
                   1380:     jsuint      i;
                   1381:     jsuint      rcpt_list_length;
                   1382:        jsval       val;
                   1383:        JSObject*       hdr=NULL;
                   1384:        JSObject*       objarg;
                   1385:        JSObject*       rcpt_list=NULL;
                   1386:        JSClass*        cl;
                   1387:        smbmsg_t        rcpt_msg;
                   1388:        smbmsg_t        msg;
                   1389:        client_t*       client=NULL;
                   1390:        jsval           open_rval;
                   1391:        private_t*      p;
                   1392: 
                   1393:        *rval = JSVAL_FALSE;
                   1394: 
                   1395:        if(argc<2)
                   1396:                return(JS_TRUE);
                   1397:        
                   1398:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1399:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1400:                return(JS_FALSE);
                   1401:        }
                   1402: 
                   1403:        if(!SMB_IS_OPEN(&(p->smb))) {
                   1404:                if(!js_open(cx, obj, 0, NULL, &open_rval))
                   1405:                        return(JS_FALSE);
                   1406:                if(open_rval == JSVAL_FALSE)
                   1407:                        return(JS_TRUE);
                   1408:        }
                   1409: 
                   1410:        memset(&msg,0,sizeof(msg));
                   1411: 
                   1412:        for(n=0;n<argc;n++) {
                   1413:                if(JSVAL_IS_OBJECT(argv[n])) {
                   1414:                        objarg = JSVAL_TO_OBJECT(argv[n]);
                   1415:                        if((cl=JS_GetClass(cx,objarg))!=NULL && strcmp(cl->name,"Client")==0) {
                   1416:                                client=JS_GetPrivate(cx,objarg);
                   1417:                                continue;
                   1418:                        }
                   1419:                        if(JS_IsArrayObject(cx, objarg)) {              /* recipient_list is an array of objects */
                   1420:                                if(body!=NULL && rcpt_list==NULL) {     /* body text already specified */
                   1421:                                        rcpt_list = objarg;
                   1422:                                        continue;
                   1423:                                }
                   1424:                        }
                   1425:                        else if(hdr==NULL) {
                   1426:                                hdr = objarg;
                   1427:                                continue;
                   1428:                        }
                   1429:                }
                   1430:                if(body==NULL 
                   1431:                        && (body=JS_GetStringBytes(JS_ValueToString(cx,argv[n])))==NULL) {
                   1432:                        JS_ReportError(cx,"JS_GetStringBytes failed");
                   1433:                        return(JS_FALSE);
                   1434:                }
                   1435:        }
                   1436: 
                   1437:        if(hdr==NULL)
                   1438:                return(JS_TRUE);
                   1439:        if(body==NULL)
                   1440:                body="";
                   1441: 
                   1442:        if(rcpt_list!=NULL) {
                   1443:                if(!JS_GetArrayLength(cx, rcpt_list, &rcpt_list_length))
                   1444:                        return(JS_TRUE);
                   1445:                if(!rcpt_list_length)
                   1446:                        return(JS_TRUE);
                   1447:        }
                   1448: 
                   1449:        if(parse_header_object(cx, p, hdr, &msg, rcpt_list==NULL)) {
                   1450: 
                   1451:                if(body[0])
                   1452:                        truncsp(body);
                   1453:                if(savemsg(scfg, &(p->smb), &msg, client, body)==0)
                   1454:                        *rval = JSVAL_TRUE;
                   1455: 
                   1456:                if(rcpt_list!=NULL) {   /* Sending to a list of recipients */
                   1457: 
                   1458:                        *rval = JSVAL_FALSE;    /* failure, by default */
                   1459: 
                   1460:                        memset(&rcpt_msg, 0, sizeof(rcpt_msg));
                   1461: 
                   1462:                        for(i=0;i<rcpt_list_length;i++) {
                   1463: 
                   1464:                                if(!JS_GetElement(cx, rcpt_list, i, &val))
                   1465:                                        break;
                   1466:                                
                   1467:                                if(!JSVAL_IS_OBJECT(val))
                   1468:                                        break;
                   1469: 
                   1470:                                if((p->status=smb_copymsgmem(&(p->smb), &rcpt_msg, &msg))!=SMB_SUCCESS)
                   1471:                                        break;
                   1472: 
                   1473:                                if(!parse_recipient_object(cx, p, JSVAL_TO_OBJECT(val), &rcpt_msg))
                   1474:                                        break;
                   1475: 
                   1476:                                if((p->status=smb_addmsghdr(&(p->smb), &rcpt_msg, SMB_SELFPACK))!=SMB_SUCCESS)
                   1477:                                        break;
                   1478: 
                   1479:                                smb_freemsgmem(&rcpt_msg);
                   1480:                        }
                   1481:                        smb_freemsgmem(&rcpt_msg);      /* just in case we broke the loop */
                   1482: 
                   1483:                        if(i==rcpt_list_length)
                   1484:                                *rval = JSVAL_TRUE;     /* success */
                   1485:                }
                   1486:        } else
                   1487:                sprintf(p->smb.last_error,"Header parsing failure (required field missing?)");
                   1488: 
                   1489:        smb_freemsgmem(&msg);
                   1490: 
                   1491:        return(JS_TRUE);
                   1492: }
                   1493: 
                   1494: /* MsgBase Object Properites */
                   1495: enum {
                   1496:         SMB_PROP_LAST_ERROR
                   1497:        ,SMB_PROP_FILE          
                   1498:        ,SMB_PROP_DEBUG         
                   1499:        ,SMB_PROP_RETRY_TIME
                   1500:        ,SMB_PROP_RETRY_DELAY
                   1501:        ,SMB_PROP_FIRST_MSG             /* first message number */
                   1502:        ,SMB_PROP_LAST_MSG              /* last message number */
                   1503:        ,SMB_PROP_TOTAL_MSGS    /* total messages */
                   1504:        ,SMB_PROP_MAX_CRCS              /* Maximum number of CRCs to keep in history */
                   1505:     ,SMB_PROP_MAX_MSGS      /* Maximum number of message to keep in sub */
                   1506:     ,SMB_PROP_MAX_AGE       /* Maximum age of message to keep in sub (in days) */
                   1507:        ,SMB_PROP_ATTR                  /* Attributes for this message base (SMB_HYPER,etc) */
                   1508:        ,SMB_PROP_SUBNUM                /* sub-board number */
                   1509:        ,SMB_PROP_IS_OPEN
                   1510:        ,SMB_PROP_STATUS                /* Last SMBLIB returned status value (e.g. retval) */
                   1511: };
                   1512: 
                   1513: static JSBool js_msgbase_set(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                   1514: {
                   1515:     jsint       tiny;
                   1516:        private_t*      p;
                   1517: 
                   1518:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1519:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1520:                return(JS_FALSE);
                   1521:        }
                   1522: 
                   1523:     tiny = JSVAL_TO_INT(id);
                   1524: 
                   1525:        switch(tiny) {
                   1526:                case SMB_PROP_RETRY_TIME:
                   1527:                        JS_ValueToInt32(cx,*vp,(int32*)&(p->smb).retry_time);
                   1528:                        break;
                   1529:                case SMB_PROP_RETRY_DELAY:
                   1530:                        JS_ValueToInt32(cx,*vp,(int32*)&(p->smb).retry_delay);
                   1531:                        break;
                   1532:                case SMB_PROP_DEBUG:
                   1533:                        JS_ValueToBoolean(cx,*vp,&p->debug);
                   1534:                        break;
                   1535:        }
                   1536: 
                   1537:        return(JS_TRUE);
                   1538: }
                   1539: 
                   1540: static JSBool js_msgbase_get(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
                   1541: {
                   1542:        char*           s=NULL;
                   1543:        JSString*       js_str;
                   1544:     jsint       tiny;
                   1545:        idxrec_t        idx;
                   1546:        private_t*      p;
                   1547: 
                   1548:        if((p=(private_t*)JS_GetPrivate(cx,obj))==NULL) {
                   1549:                JS_ReportError(cx,getprivate_failure,WHERE);
                   1550:                return(JS_FALSE);
                   1551:        }
                   1552: 
                   1553:     tiny = JSVAL_TO_INT(id);
                   1554: 
                   1555:        switch(tiny) {
                   1556:                case SMB_PROP_FILE:
                   1557:                        s=p->smb.file;
                   1558:                        break;
                   1559:                case SMB_PROP_LAST_ERROR:
                   1560:                        s=p->smb.last_error;
                   1561:                        break;
                   1562:                case SMB_PROP_STATUS:
                   1563:                        *vp = INT_TO_JSVAL(p->status);
                   1564:                        break;
                   1565:                case SMB_PROP_RETRY_TIME:
                   1566:                        *vp = INT_TO_JSVAL(p->smb.retry_time);
                   1567:                        break;
                   1568:                case SMB_PROP_RETRY_DELAY:
                   1569:                        *vp = INT_TO_JSVAL(p->smb.retry_delay);
                   1570:                        break;
                   1571:                case SMB_PROP_DEBUG:
                   1572:                        *vp = INT_TO_JSVAL(p->debug);
                   1573:                        break;
                   1574:                case SMB_PROP_FIRST_MSG:
                   1575:                        memset(&idx,0,sizeof(idx));
                   1576:                        smb_getfirstidx(&(p->smb),&idx);
                   1577:                        JS_NewNumberValue(cx,idx.number,vp);
                   1578:                        break;
                   1579:                case SMB_PROP_LAST_MSG:
                   1580:                        smb_getstatus(&(p->smb));
                   1581:                        JS_NewNumberValue(cx,p->smb.status.last_msg,vp);
                   1582:                        break;
                   1583:                case SMB_PROP_TOTAL_MSGS:
                   1584:                        smb_getstatus(&(p->smb));
                   1585:                        JS_NewNumberValue(cx,p->smb.status.total_msgs,vp);
                   1586:                        break;
                   1587:                case SMB_PROP_MAX_CRCS:
                   1588:                        JS_NewNumberValue(cx,p->smb.status.max_crcs,vp);
                   1589:                        break;
                   1590:                case SMB_PROP_MAX_MSGS:
                   1591:                        JS_NewNumberValue(cx,p->smb.status.max_msgs,vp);
                   1592:                        break;
                   1593:                case SMB_PROP_MAX_AGE:
                   1594:                        JS_NewNumberValue(cx,p->smb.status.max_age,vp);
                   1595:                        break;
                   1596:                case SMB_PROP_ATTR:
                   1597:                        JS_NewNumberValue(cx,p->smb.status.attr,vp);
                   1598:                        break;
                   1599:                case SMB_PROP_SUBNUM:
                   1600:                        *vp = INT_TO_JSVAL(p->smb.subnum);
                   1601:                        break;
                   1602:                case SMB_PROP_IS_OPEN:
                   1603:                        *vp = BOOLEAN_TO_JSVAL(SMB_IS_OPEN(&(p->smb)));
                   1604:                        break;
                   1605:        }
                   1606: 
                   1607:        if(s!=NULL) {
                   1608:                if((js_str=JS_NewStringCopyZ(cx, s))==NULL)
                   1609:                        return(JS_FALSE);
                   1610:                *vp = STRING_TO_JSVAL(js_str);
                   1611:        }
                   1612: 
                   1613:        return(JS_TRUE);
                   1614: }
                   1615: 
                   1616: #define SMB_PROP_FLAGS JSPROP_ENUMERATE|JSPROP_READONLY
                   1617: 
                   1618: static jsSyncPropertySpec js_msgbase_properties[] = {
                   1619: /*              name                           ,tinyid                                 ,flags,                         ver     */
                   1620: 
                   1621:        {       "error"                         ,SMB_PROP_LAST_ERROR    ,SMB_PROP_FLAGS,        310 },
                   1622:        {       "last_error"            ,SMB_PROP_LAST_ERROR    ,JSPROP_READONLY,       311 },  /* alias */
                   1623:        {       "status"                        ,SMB_PROP_STATUS                ,SMB_PROP_FLAGS,        312 },
                   1624:        {       "file"                          ,SMB_PROP_FILE                  ,SMB_PROP_FLAGS,        310 },
                   1625:        {       "debug"                         ,SMB_PROP_DEBUG                 ,0,                                     310 },
                   1626:        {       "retry_time"            ,SMB_PROP_RETRY_TIME    ,JSPROP_ENUMERATE,      310 },
                   1627:        {       "retry_delay"           ,SMB_PROP_RETRY_DELAY   ,JSPROP_ENUMERATE,      311 },
                   1628:        {       "first_msg"                     ,SMB_PROP_FIRST_MSG             ,SMB_PROP_FLAGS,        310 },
                   1629:        {       "last_msg"                      ,SMB_PROP_LAST_MSG              ,SMB_PROP_FLAGS,        310 },
                   1630:        {       "total_msgs"            ,SMB_PROP_TOTAL_MSGS    ,SMB_PROP_FLAGS,        310 },
                   1631:        {       "max_crcs"                      ,SMB_PROP_MAX_CRCS              ,SMB_PROP_FLAGS,        310 },
                   1632:        {       "max_msgs"                      ,SMB_PROP_MAX_MSGS      ,SMB_PROP_FLAGS,        310 },
                   1633:        {       "max_age"                       ,SMB_PROP_MAX_AGE       ,SMB_PROP_FLAGS,        310 },
                   1634:        {       "attributes"            ,SMB_PROP_ATTR                  ,SMB_PROP_FLAGS,        310 },
                   1635:        {       "subnum"                        ,SMB_PROP_SUBNUM                ,SMB_PROP_FLAGS,        310 },
                   1636:        {       "is_open"                       ,SMB_PROP_IS_OPEN               ,SMB_PROP_FLAGS,        310 },
                   1637:        {0}
                   1638: };
                   1639: 
                   1640: #ifdef BUILD_JSDOCS
                   1641: static char* msgbase_prop_desc[] = {
                   1642: 
                   1643:         "last occurred message base error - <small>READ ONLY</small>"
                   1644:        ,"return value of last <i>SMB Library</i> function call - <small>READ ONLY</small>"
                   1645:        ,"base path and filename of message base - <small>READ ONLY</small>"
                   1646:        ,"message base open/lock retry timeout (in seconds)"
                   1647:        ,"delay between message base open/lock retries (in milliseconds)"
                   1648:        ,"first message number - <small>READ ONLY</small>"
                   1649:        ,"last message number - <small>READ ONLY</small>"
                   1650:        ,"total number of messages - <small>READ ONLY</small>"
                   1651:        ,"maximum number of message CRCs to store (for dupe checking) - <small>READ ONLY</small>"
                   1652:        ,"maximum number of messages before expiration - <small>READ ONLY</small>"
                   1653:        ,"maximum age (in days) of messages to store - <small>READ ONLY</small>"
                   1654:        ,"message base attributes - <small>READ ONLY</small>"
                   1655:        ,"sub-board number (0-based, -1 for e-mail) - <small>READ ONLY</small>"
                   1656:        ,"<i>true</i> if the message base has been opened successfully - <small>READ ONLY</small>"
                   1657:        ,NULL
                   1658: };
                   1659: #endif
                   1660: 
                   1661: 
                   1662: static JSClass js_msgbase_class = {
                   1663:      "MsgBase"                         /* name                 */
                   1664:     ,JSCLASS_HAS_PRIVATE       /* flags                */
                   1665:        ,JS_PropertyStub                /* addProperty  */
                   1666:        ,JS_PropertyStub                /* delProperty  */
                   1667:        ,js_msgbase_get                 /* getProperty  */
                   1668:        ,js_msgbase_set                 /* setProperty  */
                   1669:        ,JS_EnumerateStub               /* enumerate    */
                   1670:        ,JS_ResolveStub                 /* resolve              */
                   1671:        ,JS_ConvertStub                 /* convert              */
                   1672:        ,js_finalize_msgbase    /* finalize             */
                   1673: };
                   1674: 
                   1675: static jsSyncMethodSpec js_msgbase_functions[] = {
                   1676:        {"open",                        js_open,                        0, JSTYPE_BOOLEAN,      JSDOCSTR("")
                   1677:        ,JSDOCSTR("open message base")
                   1678:        ,310
                   1679:        },
                   1680:        {"close",                       js_close,                       0, JSTYPE_BOOLEAN,      JSDOCSTR("")
                   1681:        ,JSDOCSTR("close message base (if open)")
                   1682:        ,310
                   1683:        },
                   1684:        {"get_msg_header",      js_get_msg_header,      2, JSTYPE_OBJECT,       JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_id [,expand_fields=<tt>true</tt>]")
                   1685:        ,JSDOCSTR("returns a specific message header, <i>null</i> on failure. "
                   1686:        "<br><i>New in v3.12:</i> Pass <i>false</i> for the <i>expand_fields</i> argument (default: <i>true</i>) "
                   1687:        "if you will be re-writing the header later with <i>put_msg_header()</i>")
                   1688:        ,312
                   1689:        },
                   1690:        {"put_msg_header",      js_put_msg_header,      2, JSTYPE_BOOLEAN,      JSDOCSTR("[by_offset=<tt>false</tt>,] number, object header")
                   1691:        ,JSDOCSTR("write a message header")
                   1692:        ,310
                   1693:        },
                   1694:        {"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>] "
                   1695:                "[,rfc822_encoded=<tt>false</tt>] [,include_tails=<tt>true</tt>]")
                   1696:        ,JSDOCSTR("returns the body text of a specific message, <i>null</i> on failure. "
                   1697:                "The default behavior is to leave Ctrl-A codes intact, perform no RFC-822 encoding, and to include tails (if any) in the "
                   1698:                "returned body text."
                   1699:        )
                   1700:        ,310
                   1701:        },
                   1702:        {"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>")
                   1703:        ,JSDOCSTR("returns the tail text of a specific message, <i>null</i> on failure")
                   1704:        ,310
                   1705:        },
                   1706:        {"get_msg_index",       js_get_msg_index,       2, JSTYPE_OBJECT,       JSDOCSTR("[by_offset=<tt>false</tt>,] number")
                   1707:        ,JSDOCSTR("returns a specific message index, <i>null</i> on failure. "
                   1708:        "The index object will contain the following properties:<br>"
                   1709:        "<table>"
                   1710:        "<tr><td align=top><tt>subject</tt><td>CRC-16 of lowercase message subject"
                   1711:        "<tr><td align=top><tt>to</tt><td>CRC-16 of lowercase recipient's name (or user number if e-mail)"
                   1712:        "<tr><td align=top><tt>from</tt><td>CRC-16 of lowercase sender's name (or user number if e-mail)"
                   1713:        "<tr><td align=top><tt>attr</tt><td>Attribute bitfield"
                   1714:        "<tr><td align=top><tt>time</tt><td>Date/time imported (in time_t format)"
                   1715:        "<tr><td align=top><tt>number</tt><td>Message number"
                   1716:        "<tr><td align=top><tt>offset</tt><td>Record number in index file"
                   1717:        "</table>")
                   1718:        ,311
                   1719:        },
                   1720:        {"remove_msg",          js_remove_msg,          2, JSTYPE_BOOLEAN,      JSDOCSTR("[by_offset=<tt>false</tt>,] number_or_id")
                   1721:        ,JSDOCSTR("mark message for deletion")
                   1722:        ,311
                   1723:        },
                   1724:        {"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>]")
                   1725:        ,JSDOCSTR("create a new message in message base, the <i>header</i> object may contain the following properties:<br>"
                   1726:        "<table>"
                   1727:        "<tr><td align=top><tt>subject</tt><td>Message subject <i>(required)</i>"
                   1728:        "<tr><td align=top><tt>to</tt><td>Recipient's name <i>(required)</i>"
                   1729:        "<tr><td align=top><tt>to_ext</tt><td>Recipient's user number (for local e-mail)"
                   1730:        "<tr><td align=top><tt>to_org</tt><td>Recipient's organization"
                   1731:        "<tr><td align=top><tt>to_net_type</tt><td>Recipient's network type (default: 0 for local)"
                   1732:        "<tr><td align=top><tt>to_net_addr</tt><td>Recipient's network address"
                   1733:        "<tr><td align=top><tt>to_agent</tt><td>Recipient's agent type"
                   1734:        "<tr><td align=top><tt>from</tt><td>Sender's name <i>(required)</i>"
                   1735:        "<tr><td align=top><tt>from_ext</tt><td>Sender's user number"
                   1736:        "<tr><td align=top><tt>from_org</tt><td>Sender's organization"
                   1737:        "<tr><td align=top><tt>from_net_type</tt><td>Sender's network type (default: 0 for local)"
                   1738:        "<tr><td align=top><tt>from_net_addr</tt><td>Sender's network address"
                   1739:        "<tr><td align=top><tt>from_agent</tt><td>Sender's agent type"
                   1740:        "<tr><td align=top><tt>from_ip_addr</tt><td>Sender's IP address (if available, for security tracking)"
                   1741:        "<tr><td align=top><tt>from_host_name</tt><td>Sender's host name (if available, for security tracking)"
                   1742:        "<tr><td align=top><tt>from_protocol</tt><td>TCP/IP protocol used by sender (if available, for security tracking)"
                   1743:        "<tr><td align=top><tt>from_port</tt><td>TCP/UDP port number used by sender (if available, for security tracking)"
                   1744:        "<tr><td align=top><tt>replyto</tt><td>Replies should be sent to this name"
                   1745:        "<tr><td align=top><tt>replyto_ext</tt><td>Replies should be sent to this user number"
                   1746:        "<tr><td align=top><tt>replyto_org</tt><td>Replies should be sent to organization"
                   1747:        "<tr><td align=top><tt>replyto_net_type</tt><td>Replies should be sent to this network type"
                   1748:        "<tr><td align=top><tt>replyto_net_addr</tt><td>Replies should be sent to this network address"
                   1749:        "<tr><td align=top><tt>replyto_agent</tt><td>Replies should be sent to this agent type"
                   1750:        "<tr><td align=top><tt>id</tt><td>Message's RFC-822 compliant Message-ID"
                   1751:        "<tr><td align=top><tt>reply_id</tt><td>Message's RFC-822 compliant Reply-ID"
                   1752:        "<tr><td align=top><tt>reverse_path</tt><td>Message's SMTP sender address"
                   1753:        "<tr><td align=top><tt>forward_path</tt><td>Argument to SMTP 'RCPT TO' command"
                   1754:        "<tr><td align=top><tt>path</tt><td>Messages's NNTP path"
                   1755:        "<tr><td align=top><tt>newsgroups</tt><td>Message's NNTP newsgroups header"
                   1756:        "<tr><td align=top><tt>ftn_msgid</tt><td>FidoNet FTS-9 Message-ID"
                   1757:        "<tr><td align=top><tt>ftn_reply</tt><td>FidoNet FTS-9 Reply-ID"
                   1758:        "<tr><td align=top><tt>ftn_area</tt><td>FidoNet FTS-4 echomail AREA tag"
                   1759:        "<tr><td align=top><tt>ftn_flags</tt><td>FidoNet FSC-53 FLAGS"
                   1760:        "<tr><td align=top><tt>ftn_pid</tt><td>FidoNet FSC-46 Program Identifier"
                   1761:        "<tr><td align=top><tt>ftn_tid</tt><td>FidoNet FSC-46 Tosser Identifier"
                   1762:        "<tr><td align=top><tt>date</tt><td>RFC-822 formatted date/time"
                   1763:        "<tr><td align=top><tt>attr</tt><td>Attribute bitfield"
                   1764:        "<tr><td align=top><tt>auxattr</tt><td>Auxillary attribute bitfield"
                   1765:        "<tr><td align=top><tt>netattr</tt><td>Network attribute bitfield"
                   1766:        "<tr><td align=top><tt>when_written_time</tt><td>Date/time (in time_t format)"
                   1767:        "<tr><td align=top><tt>when_written_zone</tt><td>Time zone"
                   1768:        "<tr><td align=top><tt>when_imported_time</tt><td>Date/time message was imported"
                   1769:        "<tr><td align=top><tt>when_imported_zone</tt><td>Time zone"
                   1770:        "<tr><td align=top><tt>thread_back</tt><td>Message number that this message is a reply to"
                   1771:        "<tr><td align=top><tt>thread_next</tt><td>Message number of the next reply to the original message in this thread"
                   1772:        "<tr><td align=top><tt>thread_first</tt><td>Message number of the first reply to this message"
                   1773:        "<tr><td align=top><tt>field_list[].type</tt><td>Other SMB header fields (type)"
                   1774:        "<tr><td align=top><tt>field_list[].data</tt><td>Other SMB header fields (data)"
                   1775:        "</table>"
                   1776:        "<br><i>New in v3.12:</i> "
                   1777:        "The optional <i>client</i> argument is an instance of the <i>Client</i> class to be used for the "
                   1778:        "security log header fields (e.g. sender IP address, hostname, protocol, and port). "
                   1779:        "<br><br><i>New in v3.12:</i> "
                   1780:        "The optional <i>rcpt_list</i> is an array of objects that specifies multiple recipients "
                   1781:        "for a single message (e.g. bulk e-mail). Each object in the array may include the following header properties "
                   1782:        "(described above): <br>"
                   1783:        "<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>"
                   1784:        )
                   1785:        ,312
                   1786:        },
                   1787:        {0}
                   1788: };
                   1789: 
                   1790: /* MsgBase Constructor (open message base) */
                   1791: 
                   1792: static JSBool
                   1793: js_msgbase_constructor(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
                   1794: {
                   1795:        JSString*       js_str;
                   1796:        JSObject*       cfgobj;
                   1797:        char*           base;
                   1798:        private_t*      p;
                   1799: 
                   1800:        if((p=(private_t*)malloc(sizeof(private_t)))==NULL) {
                   1801:                JS_ReportError(cx,"malloc failed");
                   1802:                return(JS_FALSE);
                   1803:        }
                   1804: 
                   1805:        memset(p,0,sizeof(private_t));
                   1806:        p->smb.retry_time=scfg->smb_retry_time;
                   1807: 
                   1808:        js_str = JS_ValueToString(cx, argv[0]);
                   1809:        base=JS_GetStringBytes(js_str);
                   1810: 
                   1811:        p->debug=JS_FALSE;
                   1812: 
                   1813:        if(!JS_SetPrivate(cx, obj, p)) {
                   1814:                JS_ReportError(cx,"JS_SetPrivate failed");
                   1815:                free(p);
                   1816:                return(JS_FALSE);
                   1817:        }
                   1818: 
                   1819:        if(!js_DefineSyncProperties(cx,obj,js_msgbase_properties)) {
                   1820:                free(p);
                   1821:                return(JS_FALSE);
                   1822:        }
                   1823: 
                   1824: #ifdef BUILD_JSDOCS
                   1825:        js_DescribeSyncObject(cx,obj,"Class used for accessing message bases",310);
                   1826:        js_DescribeSyncConstructor(cx,obj,"To create a new MsgBase object: "
                   1827:                "<tt>var msgbase = new MsgBase('<i>code</i>')</tt><br>"
                   1828:                "where <i>code</i> is a sub-board internal code, or <tt>mail</tt> for the e-mail message base");
                   1829:        js_CreateArrayOfStrings(cx, obj, "_property_desc_list", msgbase_prop_desc, JSPROP_READONLY);
                   1830: #endif
                   1831: 
                   1832:        if(stricmp(base,"mail")==0) {
                   1833:                p->smb.subnum=INVALID_SUB;
                   1834:                snprintf(p->smb.file,sizeof(p->smb.file),"%s%s",scfg->data_dir,"mail");
                   1835:        } else {
                   1836:                for(p->smb.subnum=0;p->smb.subnum<scfg->total_subs;p->smb.subnum++) {
                   1837:                        if(!stricmp(scfg->sub[p->smb.subnum]->code,base))       /* null ptr dereference here Apr-16-2003 */
                   1838:                                break;                                                                                  /* and again, Aug-18-2004 upon recycle */
                   1839:                }
                   1840:                if(p->smb.subnum<scfg->total_subs) {
                   1841:                        cfgobj=JS_NewObject(cx,NULL,NULL,obj);
                   1842: 
                   1843: #ifdef BUILD_JSDOCS    
                   1844:                        /* needed for property description alignment */
                   1845:                        JS_DefineProperty(cx,cfgobj,"index",JSVAL_VOID
                   1846:                                ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
                   1847:                        JS_DefineProperty(cx,cfgobj,"grp_index",JSVAL_VOID
                   1848:                                ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
                   1849: #endif
                   1850: 
                   1851:                        js_CreateMsgAreaProperties(cx, scfg, cfgobj, p->smb.subnum);
                   1852: #ifdef BUILD_JSDOCS
                   1853:                        js_DescribeSyncObject(cx,cfgobj
                   1854:                                ,"Configuration parameters for this message area (<i>sub-boards only</i>) "
                   1855:                                "- <small>READ ONLY</small>"
                   1856:                                ,310);
                   1857: #endif
                   1858:                        JS_DefineProperty(cx,obj,"cfg",OBJECT_TO_JSVAL(cfgobj)
                   1859:                                ,NULL,NULL,JSPROP_ENUMERATE|JSPROP_READONLY);
                   1860:                        snprintf(p->smb.file,sizeof(p->smb.file),"%s%s"
                   1861:                                ,scfg->sub[p->smb.subnum]->data_dir,scfg->sub[p->smb.subnum]->code);
                   1862:                } else { /* unknown code */
                   1863:                        SAFECOPY(p->smb.file,base);
                   1864:                        p->smb.subnum=INVALID_SUB;
                   1865:                }
                   1866:        }
                   1867: 
                   1868:        if(!js_DefineSyncMethods(cx, obj, js_msgbase_functions, FALSE)) {
                   1869:                JS_ReportError(cx,"js_DefineSyncMethods failed");
                   1870:                return(JS_FALSE);
                   1871:        }
                   1872: 
                   1873:        return(JS_TRUE);
                   1874: }
                   1875: 
                   1876: JSObject* DLLCALL js_CreateMsgBaseClass(JSContext* cx, JSObject* parent, scfg_t* cfg)
                   1877: {
                   1878:        JSObject*       obj;
                   1879: 
                   1880:        scfg = cfg;
                   1881:        obj = JS_InitClass(cx, parent, NULL
                   1882:                ,&js_msgbase_class
                   1883:                ,js_msgbase_constructor
                   1884:                ,1      /* number of constructor args */
                   1885:                ,NULL /* js_msgbase_properties */
                   1886:                ,NULL /* js_msgbase_functions */
                   1887:                ,NULL,NULL);
                   1888: 
                   1889:        return(obj);
                   1890: }
                   1891: 
                   1892: 
                   1893: #endif /* JAVSCRIPT */

unix.superglobalmegacorp.com

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