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