|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.