From rastandy at inventati.org Mon Jan 4 16:02:16 2010 From: rastandy at inventati.org (Andrea Russo) Date: Mon, 04 Jan 2010 17:02:16 +0100 Subject: [mel-base-devel] Compilation error when compiling package mel-base Message-ID: <86fx6lg8on.fsf@inventati.org> Hi, Sorry if this has been discussed already but I haven't find any thread about this. When trying to load the mel-base package using slime with sbcl, I get the error attached below. I included the entire backtrace just in case it would be useful. I'm using sbcl 1.0.34 and the latest version of mel-base from the darcs repo at http://www.crispylogics.com/opensource/repos/mel-base Any help would be much appreciated. Thank you, Andrea. -- Reclama i tuoi diritti digitali, elimina il DRM. Approfondisci su http://www.no1984.org Reclaim your digital rights, eliminate DRM. Learn more at http://www.defectivebydesign.org/what_is_drm -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: mel-base-error.txt URL: From js at crispylogics.com Tue Jan 5 16:05:40 2010 From: js at crispylogics.com (Jochen Schmidt) Date: Tue, 5 Jan 2010 17:05:40 +0100 Subject: [mel-base-devel] Compilation error when compiling package mel-base In-Reply-To: <86fx6lg8on.fsf@inventati.org> References: <86fx6lg8on.fsf@inventati.org> Message-ID: Am 04.01.2010 um 17:02 schrieb Andrea Russo: > Hi, > > Sorry if this has been discussed already but I haven't find any thread > about this. > > When trying to load the mel-base package using slime with sbcl, I get > the error attached below. I included the entire backtrace just in case > it would be useful. > > I'm using sbcl 1.0.34 and the latest version of mel-base from the darcs > repo at http://www.crispylogics.com/opensource/repos/mel-base I've tried sbcl 1.0.34 on one of my linux boxes and it compiled the current mel-base without problems. I didn't compile it within slime though. Did you use the sbcl release binary or compile your own? You may try compiling it without slime for a start. ciao, Jochen -- Jochen Schmidt CRISPYLOGICS Uhlandstr. 9, 90408 Nuremberg Fon +49 (0)911 517 999 82 Fax +49 (0)911 517 999 83 mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com From rastandy at inventati.org Tue Jan 5 17:26:01 2010 From: rastandy at inventati.org (Andrea Russo) Date: Tue, 05 Jan 2010 18:26:01 +0100 Subject: [mel-base-devel] Compilation error when compiling package mel-base References: <86fx6lg8on.fsf@inventati.org> Message-ID: <86bph85uqe.fsf@inventati.org> Jochen Schmidt writes: > Am 04.01.2010 um 17:02 schrieb Andrea Russo: > >> Hi, Hi Jochen, > I've tried sbcl 1.0.34 on one of my linux boxes and it compiled the > current mel-base without problems. I didn't compile it within slime > though. Did you use the sbcl release binary or compile your own? I compiled it on my own using the `clbuild compile-implementation sbcl' command. > You may try compiling it without slime for a start. Yeah, that worked great! Btw, I wonder what triggers the problem when slime is loaded. Thank you very much for your help! Best wishes (and Happy New Year), Andrea. -- Reclama i tuoi diritti digitali, elimina il DRM. Approfondisci su http://www.no1984.org Reclaim your digital rights, eliminate DRM. Learn more at http://www.defectivebydesign.org/what_is_drm From gardnermj at gmail.com Wed Jan 13 23:18:50 2010 From: gardnermj at gmail.com (Michael Gardner) Date: Wed, 13 Jan 2010 17:18:50 -0600 Subject: [mel-base-devel] Parsing message from string Message-ID: <8E105E6B-B20D-4FCF-B79A-439A2A6E2D3E@gmail.com> I'm writing a simple NNTP->IMAP cron tool. It pulls each NNTP article as a single string, and then must turn that string into a mel-base message somehow for upload to an IMAP server. But I can't figure out how to get mel-base to parse a string into an email directly. I can output to a temporary file (or named pipe) and then use make-message-from-file, but it seems like there should be an easier way to do this. Am I missing something? -Michael From gardnermj at gmail.com Mon Jan 18 22:55:31 2010 From: gardnermj at gmail.com (Michael Gardner) Date: Mon, 18 Jan 2010 16:55:31 -0600 Subject: [mel-base-devel] UTF-8 messages Message-ID: <473A4DE7-A22B-4B4E-9CB8-DDD426B36A0B@gmail.com> I'm having trouble uploading utf8-encoded messages to an IMAP folder using mel-base. There's a post regarding a similar problem at http://common-lisp.net/pipermail/mel-base-devel/2006-November/000030.html, but it's a few years old. Does mel-base currently support what I'm trying to do? If not, how much work would be necessary to get it to do so? -Michael From fred at streamfocus.com Thu Jan 21 04:49:05 2010 From: fred at streamfocus.com (Fred Gibson) Date: Wed, 20 Jan 2010 20:49:05 -0800 Subject: [mel-base-devel] EOF error on mel.mime:scan-forward-boundary-tag Message-ID: <19290c161001202049l124013f3pa35b3e61aa8b66c1@mail.gmail.com> When running (mel:parts (mel.mime::make-message-from-file filename) I was getting an end of file error. I narrowed the problem down to peek in mel.mime:scan-forward-boundary-tag, and got the function working by changing: (flet ((peek () (peek-char nil in-stream)) to (flet ((peek () (peek-char nil in-stream nil :eof)) My best, Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From fred at streamfocus.com Fri Jan 22 06:36:10 2010 From: fred at streamfocus.com (Fred Gibson) Date: Thu, 21 Jan 2010 22:36:10 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) Message-ID: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> I've been working with reading in an rfc 2822 file, and the parts method returns only 1 large part for the whole message rather than breaking it into smaller parts. It looks like the mel.mime:read-multipart-body-1 function starts off from mel.mime:compute-bodystructure-using-folder with the whole message and then is sent to scan-forward-boundary-tag with the boundary tag for the overall message, which then only matches at the end of the file and so only 1 big part is returned. I'm troubleshooting this problem now. Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From fred at streamfocus.com Sat Jan 23 09:44:01 2010 From: fred at streamfocus.com (Fred Gibson) Date: Sat, 23 Jan 2010 01:44:01 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> Message-ID: <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> I had to rewrite a good portion of read-multipart-body-1 to get the parts to parse correctly. I've tested this with text/plain, multipart/alternative and multipart/mixed, and all parsed correctly. Here is the diff from my git commit: commit 87842c16b7021a28f776fb952535c43426ba55d6 Author: Fred Gibson Date: Sat Jan 23 01:28:13 2010 -0800 revised mel-base read-multipart-body-1 to work with alternative and mixed multipart mime types diff --git a/lib/mel-base_0.9-2/multiparts.lisp b/lib/mel-base_0.9-2/multiparts.lisp index 7c1e7f1..ee30f88 100644 --- a/lib/mel-base_0.9-2/multiparts.lisp +++ b/lib/mel-base_0.9-2/multiparts.lisp @@ -286,41 +286,58 @@ (defun compute-bodystructure (message) (compute-bodystructure-using-folder (folder message) message)) -(defun read-multipart-body-1 (part stream) - (let ((boundary (boundary-tag part))) - (let (parts - last-part) - (loop - (multiple-value-bind (octets lines endp) - (scan-forward-boundary-tag stream boundary) - (when last-part - #+nil (incf (seventh last-part) octets) - (setf (seventh last-part) octets) - (setf (eighth last-part) lines) - (setf last-part nil)) - (cond (endp - ; (format t "End tag of boundary=~A~%" boundary) - (multiple-value-bind (super sub params) - (content-type part) - (declare (ignore super)) - (let ((result `(,@(nreverse parts) ,sub ,params nil nil))) - ; (format t "Multipart-Structure: ~A~%" result) - (return result)))) - (t - (multiple-value-bind (headers hoctets) (read-rfc2822-header stream) - ; (format t "Headers read ~A" hoctets) - (let ((content-type (or (cdr (assoc :content-type headers)) - "text/plain"))) - (multiple-value-bind (super sub params) (parse-content-type content-type) - (declare (ignore params)) - (let ((next-part (make-instance (if (eq super :multipart) - (multipart-type-class sub) - 'simple-part) - :header-fields (or headers - '((:content-type . "text/plain")))))) - (if (eq super :multipart) - (push (read-multipart-body-1 next-part stream) parts) - (push (setf last-part (read-simple-body next-part)) parts))))))))))))) +(defun read-multipart-body-1 (part stream &key recurse?) + (multiple-value-bind (p-super p-sub p-params)(content-type part) + (declare (ignore p-super)) + (flet ((build-return (parts) + `(,@(nreverse parts) ,p-sub ,p-params nil nil))) + (let (parts + last-part + boundary) + (loop + (multiple-value-bind (headers hoctets) (read-rfc2822-header stream) + (declare (ignore hoctets)) + (let ((content-type (or (cdr (assoc :content-type headers)) + "text/plain")) + (boundary-read + (let ((assoc-hdr + (assoc "--" headers + :test #'string= + :key (lambda (x) (let ((nm (symbol-name x))) + (when (> (length nm) 2) + (let ((a (char nm 0)) + (b (char nm 1))) + (concatenate 'string (list a b))))))))) + (when assoc-hdr + (string-downcase (string-left-trim "-" (car assoc-hdr))))))) + (setf boundary (or boundary-read boundary)) + (multiple-value-bind (super sub params) (parse-content-type content-type) + (declare (ignore params)) + (when (and (eq p-sub :mixed) (not recurse?)) + (return (append (read-multipart-body-1 part stream :recurse? t) + (build-return (read-multipart-body-1 part stream :recurse? t))))) + (let ((next-part (make-instance + (if (eq super :multipart) + (multipart-type-class sub) + 'simple-part) + :header-fields (or headers '((:content-type . "text/plain")))))) + (if (eq super :multipart) + (progn + (setf last-part (read-simple-body next-part)) + (push (read-multipart-body-1 next-part stream) parts)) + (push (setf last-part (read-simple-body next-part)) parts)) + (multiple-value-bind (octets lines endp) + (scan-forward-boundary-tag stream boundary) + (when last-part + #+nil (incf (seventh last-part) octets) + (setf (seventh last-part) octets) + (setf (eighth last-part) lines) + (setf last-part nil)) + (when endp ; (format t "End tag of boundary=~A~%" boundary) + (if recurse? + (return (nreverse parts)) + (return (build-return parts)))) + )))))))))) (defun read-simple-body (part) (multiple-value-bind (super sub params) On Thu, Jan 21, 2010 at 10:36 PM, Fred Gibson wrote: > I've been working with reading in an rfc 2822 file, and the parts > method returns only 1 large part for the whole message rather than > breaking it into smaller parts. ?It looks like the > mel.mime:read-multipart-body-1 function starts off from > mel.mime:compute-bodystructure-using-folder with the whole message and > then is sent to scan-forward-boundary-tag with the boundary tag for > the overall message, which then only matches at the end of the file > and so only 1 big part is returned. ?I'm troubleshooting this problem > now. > > Fred Gibson > > Founder / Software Developer > http://www.streamfocus.com > > (c)2010 Organon Technologies LLC > -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From js at crispylogics.com Sat Jan 23 10:52:00 2010 From: js at crispylogics.com (Jochen Schmidt) Date: Sat, 23 Jan 2010 11:52:00 +0100 Subject: [mel-base-devel] Parsing message from string In-Reply-To: <8E105E6B-B20D-4FCF-B79A-439A2A6E2D3E@gmail.com> References: <8E105E6B-B20D-4FCF-B79A-439A2A6E2D3E@gmail.com> Message-ID: Am 14.01.2010 um 00:18 schrieb Michael Gardner: > I'm writing a simple NNTP->IMAP cron tool. It pulls each NNTP article as a single string, and then must turn that string into a mel-base message somehow for upload to an IMAP server. > > But I can't figure out how to get mel-base to parse a string into an email directly. I can output to a temporary file (or named pipe) and then use make-message-from-file, but it seems like there should be an easier way to do this. Am I missing something? There currently is indeed no function to directly do that, but its actually quite easy given the tools available. You have to implement a minimal folder protocol for strings then: (defclass basic-receiver-from-string (mel:basic-receiver) ((string :initarg :string))) (defmethod mel:open-message-input-stream-using-folder ((folder basic-receiver-from-string) (message mel:message) start) (make-string-input-stream (slot-value folder 'string) start)) (defun make-message-from-string (string) (make-instance 'mel:mime-message :folder (make-instance 'basic-receiver-from-string :string string))) Simple enough? ;-) Yes I will add something like that so that it works out of the box. ciao, Jochen -- Jochen Schmidt CRISPYLOGICS Uhlandstr. 9, 90408 Nuremberg Fon +49 (0)911 517 999 82 Fax +49 (0)911 517 999 83 mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com From js at crispylogics.com Sat Jan 23 13:04:15 2010 From: js at crispylogics.com (Jochen Schmidt) Date: Sat, 23 Jan 2010 14:04:15 +0100 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> Message-ID: Am 23.01.2010 um 10:44 schrieb Fred Gibson: > I had to rewrite a good portion of read-multipart-body-1 to get the > parts to parse correctly. I've tested this with text/plain, > multipart/alternative and multipart/mixed, and all parsed correctly. > Here is the diff from my git commit: Sorry for the inconvenience, but the bug was actually not in READ-MULTIPART-BODY-1 but in SCAN-FORWARD-BOUNDARY. It didn't expect a boundary directly as the first line of the message body - so the top boundary was actually skipped. If you add this clause to the start of the tagbody in SCAN-FORWARD-BOUNDARY, it works again. init (let ((c (peek))) (if (char= c #\-) (go possible-boundary) (go start))) Fix is in repository soon (with some other stuff). ciao, Jochen -- Jochen Schmidt CRISPYLOGICS Uhlandstr. 9, 90408 Nuremberg Fon +49 (0)911 517 999 82 Fax +49 (0)911 517 999 83 mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com From fred at streamfocus.com Sun Jan 24 00:00:01 2010 From: fred at streamfocus.com (Fred Gibson) Date: Sat, 23 Jan 2010 16:00:01 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> Message-ID: <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> Hi Jochen, Your fix works great for text/plain and multipart/alternative where the same body tag is used throughout the message. The problem happens when you have a multipart/mixed structure where there is more than one boundary in the message. So what I did in the rewrite of read-multipart-body-1 (RMB1) is in the case of a mixed type, read just beyond the first boundary which can be ignored, then recurse on RMB1 again to deal with only the boundaries that matter by reading each one in at the top of a message section and then sending it to scan rather than trying to use the boundary identified in the message header, thus allowing for many boundaries. I realize it is pretty brute force, but it works flawlessly so far. It made more sense to me to deal with the multiple tag issue in RMB1. Is there a more elegant solution to this? (I've included a sample shortened version of the mixed structure below so you can see the varying boundary issue. This is the case for any mail with an attachment I think.) My best, Fred Partial sample mutlipart/mixed type: MIME-Version: 1.0 Received: by 10.140.136.4 with HTTP; Mon, 21 Dec 2009 12:06:02 -0800 (PST) Date: Mon, 21 Dec 2009 12:06:02 -0800 Delivered-To: frederick at gibson-design.com Message-ID: <306ae50912211206u58f1b598sf2fa7f561ec9cbb1 at mail.gmail.com> Subject: Architectural Invoice + Brian From: "Frederick Gibson, Architect" To: ... Content-Type: multipart/mixed; boundary=000e0cd1465866ab58047b429eca --000e0cd1465866ab58047b429eca Content-Type: multipart/alternative; boundary=000e0cd1465866ab51047b429ec8 --000e0cd1465866ab51047b429ec8 Content-Type: text/plain; charset=ISO-8859-1 Hi Dave & Carol, I just had an upbeat talk with Brian about the issue of which contractor ... 415.227.1684 |tel| 888 671-4958 |fax| (c)2009 http://www.gibson-design.com --000e0cd1465866ab51047b429ec8 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Hi Dave & Carol,

I just had an upbeat talk with Brian about the = ... p://www.gibson-design.com">http://www.gibson-design.com


--000e0cd1465866ab51047b429ec8-- --000e0cd1465866ab58047b429eca Content-Type: application/pdf; name="Invoice-2290.pdf" Content-Disposition: attachment; filename="Invoice-2290.pdf" Content-Transfer-Encoding: base64 X-Attachment-Id: f_g3hoa5eb0 JVBERi0xLjQNJeLjz9MNCjYgMCBvYmogPDwvTGluZWFyaXplZCAxL0wgMjc1MDUvTyA4L0UgMjM0 ... emUgNj4+DQpzdGFydHhyZWYNCjExNg0KJSVFT0YNCg== --000e0cd1465866ab58047b429eca-- On Sat, Jan 23, 2010 at 5:04 AM, Jochen Schmidt wrote: > > Am 23.01.2010 um 10:44 schrieb Fred Gibson: > >> I had to rewrite a good portion of read-multipart-body-1 to get the >> parts to parse correctly. ?I've tested this with text/plain, >> multipart/alternative and multipart/mixed, and all parsed correctly. >> Here is the diff from my git commit: > > Sorry for the inconvenience, but the bug was actually not in READ-MULTIPART-BODY-1 but in SCAN-FORWARD-BOUNDARY. > It didn't expect a boundary directly as the first line of the message body - so the top boundary was actually skipped. > If you add this clause to the start of the tagbody in SCAN-FORWARD-BOUNDARY, it works again. > > init (let ((c (peek))) > ? ? ? ? ? ? ? ? ? ? (if (char= c #\-) > ? ? ? ? ? ? ? ? ? ? ? (go possible-boundary) > ? ? ? ? ? ? ? ? ? ? ? (go start))) > > Fix is in repository soon (with some other stuff). > > ciao, > Jochen > > -- > Jochen Schmidt > CRISPYLOGICS > Uhlandstr. 9, 90408 Nuremberg > > Fon +49 (0)911 517 999 82 > Fax +49 (0)911 517 999 83 > > mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com > > -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From js at crispylogics.com Sun Jan 24 02:04:13 2010 From: js at crispylogics.com (Jochen Schmidt) Date: Sun, 24 Jan 2010 03:04:13 +0100 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> Message-ID: Am 24.01.2010 um 01:00 schrieb Fred Gibson: > Hi Jochen, > > Your fix works great for text/plain and multipart/alternative where > the same body tag is used throughout the message. The problem happens > when you have a multipart/mixed structure where there is more than one > boundary in the message. So what I did in the rewrite of > read-multipart-body-1 (RMB1) is in the case of a mixed type, read just > beyond the first boundary which can be ignored, then recurse on RMB1 > again to deal with only the boundaries that matter by reading each one > in at the top of a message section and then sending it to scan rather > than trying to use the boundary identified in the message header, thus > allowing for many boundaries. I realize it is pretty brute force, > but it works flawlessly so far. It made more sense to me to deal with > the multiple tag issue in RMB1. Is there a more elegant solution to > this? (I've included a sample shortened version of the mixed > structure below so you can see the varying boundary issue. This is the > case for any mail with an attachment I think.) I've checked the example - it is not an issue with RMB1 but with SFBT; believe me :-). Your example exposed another bug in that the content-type header wasn't recognized because SFBT left a newline in the stream. after a boundary is matched one still has to scan to the end of the line: (loop while (case (peek) ((#\return #\linefeed) t) (otherwise nil)) do (skip)) After this change and still the original RMB1 I get this bodystructure: (((:TEXT :PLAIN (:CHARSET "ISO-8859-1") NIL NIL NIL 173 8 NIL NIL NIL) (:TEXT :HTML (:CHARSET "ISO-8859-1") NIL NIL :QUOTED-PRINTABLE 155 5 NIL NIL NIL) :ALTERNATIVE (:BOUNDARY "000e0cd1465866ab51047b429ec8") NIL NIL) (:APPLICATION :PDF (:CHARSET "us-ascii" :NAME "Invoice-2290.pdf") NIL NIL :BASE64 125 2 NIL NIL NIL) :MIXED (:BOUNDARY "000e0cd1465866ab58047b429eca") NIL NIL) Here is the final SFBT: (defun scan-forward-boundary-tag (in-stream boundary) (let ((tag (concatenate 'string "--" boundary)) (match 0) (octets 0) (lines 0) (line-ending-octets 0)) (flet ((peek () (peek-char nil in-stream)) (skip () (read-char in-stream)) (consume () (prog1 (read-char in-stream) (incf octets)))) (tagbody init (let ((c (peek))) (if (char= c #\-) (go possible-boundary) (go start))) start (let ((c (peek))) (case c (#\return (skip) (go cr)) (#\linefeed (skip) (go lf)) (otherwise (consume) (go start)))) lf (setf line-ending-octets 1) (go newline) cr (let ((c (peek))) (case c (#\linefeed (setf line-ending-octets 2) (skip) (go newline)) (otherwise (setf line-ending-octets 1) (go newline)))) newline (let ((c (peek))) (case c (#\- (go possible-boundary)) (otherwise (incf octets line-ending-octets) (incf lines) (setf line-ending-octets 0) (go start)))) possible-boundary (if (= match (length tag)) (go boundary-matched) (let ((c (peek))) (cond ((char= c (char tag match)) (skip) (incf match)(go possible-boundary)) (t (incf octets (+ line-ending-octets match)) (setf match 0 line-ending-octets 0) (incf lines) (go start))))) boundary-matched (let ((c (peek))) (case c (#\- (skip) (case c (#\- (go end-boundary)) (otherwise (go boundary)))) (otherwise (go boundary)))) boundary (loop until (case (peek) ((#\return #\linefeed :eof) t) (otherwise nil)) do (skip)) (loop while (case (peek) ((#\return #\linefeed) t) (otherwise nil)) do (skip)) (return-from scan-forward-boundary-tag (values octets lines nil)) end-boundary (loop until (case (peek) ((#\return #\linefeed #\newline :eof) t) (otherwise nil)) do (skip)) (return-from scan-forward-boundary-tag (values octets lines t)) )))) Does that work for you? (The EOF handling is still borked, but it should work - I'll fix that tomorrow) ciao, Jochen -- Jochen Schmidt CRISPYLOGICS Uhlandstr. 9, 90408 Nuremberg Fon +49 (0)911 517 999 82 Fax +49 (0)911 517 999 83 mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com From fred at streamfocus.com Sun Jan 24 13:03:51 2010 From: fred at streamfocus.com (Fred Gibson) Date: Sun, 24 Jan 2010 05:03:51 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> Message-ID: <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> Hi Jochen, Yes, that is a beautiful thing - works great now. (I had to change the peek flet to: ((peek () (peek-char nil in-stream nil :eof)) to cure the eof problem. All is well now. I made the mistake in my version of thinking the result should give just the low level parts (so 3 parts in the example case instead of a new smaller message + 1 part), so that was part of my misunderstanding about it. Thanks :) Fred On Sat, Jan 23, 2010 at 6:04 PM, Jochen Schmidt wrote: > > Am 24.01.2010 um 01:00 schrieb Fred Gibson: > >> Hi Jochen, >> >> Your fix works great for text/plain and multipart/alternative where >> the same body tag is used throughout the message. ?The problem happens >> when you have a multipart/mixed structure where there is more than one >> boundary in the message. ?So what I did in the rewrite of >> read-multipart-body-1 (RMB1) is in the case of a mixed type, read just >> beyond the first boundary which can be ignored, then recurse on RMB1 >> again to deal with only the boundaries that matter by reading each one >> in at the top of a message section and then sending it to scan rather >> than trying to use the boundary identified in the message header, thus >> allowing for many boundaries. ? I realize it is pretty brute force, >> but it works flawlessly so far. ?It made more sense to me to deal with >> the multiple tag issue in RMB1. ?Is there a more elegant solution to >> this? ?(I've included a sample shortened version of the mixed >> structure below so you can see the varying boundary issue. This is the >> case for any mail with an attachment I think.) > > > I've checked the example - it is not an issue with RMB1 but with SFBT; believe me :-). Your example exposed another bug in that the content-type header wasn't recognized because SFBT left a newline in the stream. > > after a boundary is matched one still has to scan to the end of the line: > > (loop while (case (peek) ((#\return #\linefeed) t) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(otherwise nil)) > ? ? ? ? ? ? ? ? ? ? ? ?do (skip)) > > After this change and still the original RMB1 I get this bodystructure: > > (((:TEXT :PLAIN (:CHARSET "ISO-8859-1") NIL NIL NIL 173 8 NIL NIL NIL) > ?(:TEXT :HTML (:CHARSET "ISO-8859-1") NIL NIL :QUOTED-PRINTABLE 155 5 NIL NIL NIL) > ?:ALTERNATIVE > ?(:BOUNDARY "000e0cd1465866ab51047b429ec8") > ?NIL > ?NIL) > ?(:APPLICATION :PDF (:CHARSET "us-ascii" :NAME "Invoice-2290.pdf") NIL NIL :BASE64 125 2 NIL NIL NIL) > ?:MIXED > ?(:BOUNDARY "000e0cd1465866ab58047b429eca") > ?NIL > ?NIL) > > Here is the final SFBT: > > (defun scan-forward-boundary-tag (in-stream boundary) > ?(let ((tag (concatenate 'string "--" boundary)) > ? ? ? ?(match 0) > ? ? ? ?(octets 0) > ? ? ? ?(lines 0) > ? ? ? ?(line-ending-octets 0)) > ? ?(flet ((peek () > ? ? ? ? ? ? (peek-char nil in-stream)) > ? ? ? ? ? (skip () (read-char in-stream)) > ? ? ? ? ? (consume () > ? ? ? ? ? ? (prog1 > ? ? ? ? ? ? ? ? (read-char in-stream) > ? ? ? ? ? ? ? (incf octets)))) > ? ? ? ? ? ? (tagbody > ? ? ? ? ? ? ?init (let ((c (peek))) > ? ? ? ? ? ? ? ? ? ? (if (char= c #\-) > ? ? ? ? ? ? ? ? ? ? ? (go possible-boundary) > ? ? ? ? ? ? ? ? ? ? ? (go start))) > ? ? ? ? ? ? ?start (let ((c (peek))) > ? ? ? ? ? ? ? ? ? ? ?(case c > ? ? ? ? ? ? ? ? ? ? ? ?(#\return (skip) (go cr)) > ? ? ? ? ? ? ? ? ? ? ? ?(#\linefeed (skip) (go lf)) > ? ? ? ? ? ? ? ? ? ? ? ?(otherwise (consume) (go start)))) > > ? ? ? ? ? ? ?lf (setf line-ending-octets 1) (go newline) > > ? ? ? ? ? ? ?cr > ? ? ? ? ? ? ? ?(let ((c (peek))) > ? ? ? ? ? ? ? ? ?(case c > ? ? ? ? ? ? ? ? ? ?(#\linefeed (setf line-ending-octets 2) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(skip) (go newline)) > ? ? ? ? ? ? ? ? ? ?(otherwise > ? ? ? ? ? ? ? ? ? ? (setf line-ending-octets 1) > ? ? ? ? ? ? ? ? ? ? (go newline)))) > > ? ? ? ? ? ? ?newline > ? ? ? ? ? ? ? ?(let ((c (peek))) > ? ? ? ? ? ? ? ? ?(case c > ? ? ? ? ? ? ? ? ? ?(#\- (go possible-boundary)) > ? ? ? ? ? ? ? ? ? ?(otherwise (incf octets line-ending-octets) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (incf lines) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (setf line-ending-octets 0) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (go start)))) > > ? ? ? ? ? ? ?possible-boundary > ? ? ? ? ? ? ? ? ?(if (= match (length tag)) > ? ? ? ? ? ? ? ? ? ?(go boundary-matched) > ? ? ? ? ? ? ? ? ? ?(let ((c (peek))) > ? ? ? ? ? ? ? ? ? ? ?(cond ((char= c (char tag match)) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? (skip) (incf match)(go possible-boundary)) > ? ? ? ? ? ? ? ? ? ? ? ? ? ?(t (incf octets (+ line-ending-octets match)) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (setf match 0 line-ending-octets 0) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (incf lines) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (go start))))) > ? ? ? ? ? ? ?boundary-matched > ? ? ? ? ? ? ? ? ?(let ((c (peek))) > ? ? ? ? ? ? ? ? ? ?(case c > ? ? ? ? ? ? ? ? ? ? ?(#\- (skip) > ? ? ? ? ? ? ? ? ? ? ? ? ? (case c > ? ? ? ? ? ? ? ? ? ? ? ? ? ? (#\- (go end-boundary)) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? (otherwise (go boundary)))) > ? ? ? ? ? ? ? ? ? ? ?(otherwise (go boundary)))) > > ? ? ? ? ? ? ?boundary > ? ? ? ? ? ? ? ? ?(loop until (case (peek) ((#\return #\linefeed :eof) t) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(otherwise nil)) > ? ? ? ? ? ? ? ? ? ? ? ?do (skip)) > ? ? ? ? ? ? ? ? ?(loop while (case (peek) ((#\return #\linefeed) t) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(otherwise nil)) > ? ? ? ? ? ? ? ? ? ? ? ?do (skip)) > ? ? ? ? ? ? ? ? ?(return-from scan-forward-boundary-tag > ? ? ? ? ? ? ? ? ? ?(values octets lines nil)) > > ? ? ? ? ? ? ?end-boundary > ? ? ? ? ? ? ? ? ? (loop until (case (peek) ((#\return #\linefeed #\newline :eof) t) > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (otherwise nil)) > ? ? ? ? ? ? ? ? ? ? ? ? do (skip)) > ? ? ? ? ? ? ? ? ?(return-from scan-forward-boundary-tag > ? ? ? ? ? ? ? ? ? ?(values octets lines t)) > ? ? ? ? ? ? ? ? ? )))) > > Does that work for you? > > (The EOF handling is still borked, but it should work - I'll fix that tomorrow) > > > ciao, > Jochen > > -- > Jochen Schmidt > CRISPYLOGICS > Uhlandstr. 9, 90408 Nuremberg > > Fon +49 (0)911 517 999 82 > Fax +49 (0)911 517 999 83 > > mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com > > -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From js at crispylogics.com Sun Jan 24 13:36:51 2010 From: js at crispylogics.com (Jochen Schmidt) Date: Sun, 24 Jan 2010 14:36:51 +0100 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> Message-ID: <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> Am 24.01.2010 um 14:03 schrieb Fred Gibson : > Hi Jochen, > > Yes, that is a beautiful thing - works great now. (I had to change > the peek flet to: ((peek () (peek-char nil in-stream nil :eof)) to > cure the eof problem. All is well now. Yes that should be the right thing to do. > > I made the mistake in my version of thinking the result should give > just the low level parts (so 3 parts in the example case instead of a > new smaller message + 1 part), so that was part of my misunderstanding > about it. The nice thing of mel-base's body structures is that they actually don't reinvent the wheel. I generate just plain standard IMAP body structures. This allowed me to just use the IMAP server provided body structure for IMAP folders and the generated one for all others. The multipart code just demands correct body structures. This is also why these bugs never occured with IMAP folders. ciao, Jochen From fred at streamfocus.com Sun Jan 24 14:05:27 2010 From: fred at streamfocus.com (Fred Gibson) Date: Sun, 24 Jan 2010 06:05:27 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> Message-ID: <19290c161001240605o637375b1x647ff7c49d37f7ae@mail.gmail.com> Hi Jochen, Continuing with the acid email test, I found another issue while trying to parse a multipart/related email. I've attached the email. The structure I get is 3 objects, an alternative and 2 simple parts (files). But when I go into the alternative, it parses into 2 parts, a text/plain which still includes part of the header and the 2nd file part rather than the html section of the alternative structure. Another scan issue? My best, Fred On Sun, Jan 24, 2010 at 5:36 AM, Jochen Schmidt wrote: > Am 24.01.2010 um 14:03 schrieb Fred Gibson : > >> Hi Jochen, >> >> Yes, that is a beautiful thing - works great now. ?(I had to change >> the peek flet to: ((peek () ? (peek-char nil in-stream nil :eof)) ?to >> cure the eof problem. ?All is well now. > > Yes that should be the right thing to do. > >> >> I made the mistake in my version of thinking the result should give >> just the low level parts (so 3 parts in the example case instead of a >> new smaller message + 1 part), so that was part of my misunderstanding >> about it. > > The nice thing of mel-base's body structures is that they actually don't > reinvent the wheel. I generate just plain standard IMAP body structures. > This allowed me to just use the IMAP server provided body structure for IMAP > folders and the generated one for all others. The multipart code just > demands correct body structures. This is also why these bugs never occured > with IMAP folders. > > ciao, > Jochen > -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC -------------- next part -------------- Delivered-To: frederick at gibson-design.com Received: by 10.140.136.4 with SMTP id j4cs814554rvd; Wed, 20 Jan 2010 19:50:38 -0800 (PST) Received: by 10.101.187.18 with SMTP id o18mr1239719anp.8.1264045837389; Wed, 20 Jan 2010 19:50:37 -0800 (PST) Return-Path: Received: from mail-gx0-f236.google.com (mail-gx0-f236.google.com [209.85.217.236]) by mx.google.com with ESMTP id 9si835712ywh.118.2010.01.20.19.50.37; Wed, 20 Jan 2010 19:50:37 -0800 (PST) Received-SPF: pass (google.com: domain of eqo at photos-server.bounces.google.com designates 209.85.217.236 as permitted sender) client-ip=209.85.217.236; Authentication-Results: mx.google.com; spf=pass (google.com: domain of eqo at photos-server.bounces.google.com designates 209.85.217.236 as permitted sender) smtp.mail=3DM9XSwwJCX4ugcp.dgpyctfiockn.eqohtgfgtkemikduqp-fgukip.eqo at photos-server.bounces.google.com Received: by gxk16 with SMTP id 16so1547518gxk.3 for ; Wed, 20 Jan 2010 19:50:37 -0800 (PST) MIME-Version: 1.0 Reply-To: Cychotic Received: by 10.91.162.27 with SMTP id p27mt1671939ago.3.1264045836732; Wed, 20 Jan 2010 19:50:36 -0800 (PST) Message-ID: <001485f91b3e143277047da49b42 at google.com> Date: Thu, 21 Jan 2010 03:50:36 +0000 Subject: Invitation to view Cychotic's Picasa Web Album - Walk A Thon Award Ceremonies at Clarendon Kindergarten From: Cychotic To: frederick at gibson-design.com Content-Type: multipart/related; boundary=001485f91b3e159e1d047da49b53 --001485f91b3e159e1d047da49b53 Content-Type: multipart/alternative; boundary=001485f91b3e159e1b047da49b52 --001485f91b3e159e1b047da49b52 Content-Type: text/plain; charset=ISO-8859-1; format=flowed; delsp=yes Hi folks, between red eye, reflective clothing and someone who really shouldn't holding a camera, here are the shots. There is a couple of videos as well. Sean http://picasaweb.google.com/lh/sredir?uname=Streets&target=ALBUM&id=542892618&authkey=Gv1sRgCJfc5_vTgNbBXA&feat=email --001485f91b3e159e1b047da49b52 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
You are invited to view Cychotic's photo album: Walk A Thon Award Ceremonies at Clarendon Kindergarten
Walk A Thon Award Ceremonies at Clarendon Kindergarten
Jan 20, 2010
by Cychotic
Message = from Cy:
Hi folks, between red eye, reflective clothing and someone who rea= lly shouldn't holding a camera, here are the shots. There is a couple o= f videos as well.
Sean
To share your photos or receive notification when your friends sha= re photos, get your own free Picasa= Web Albums account.
--001485f91b3e159e1b047da49b52-- --001485f91b3e159e1d047da49b53 Content-Type: image/gif; name="picasaweblogo-en_US.gif" Content-Disposition: attachment; filename="picasaweblogo-en_US.gif" Content-Transfer-Encoding: base64 Content-ID: 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 Ry6fdwSwZ4NKuIRMWAZBAAA7 --001485f91b3e159e1d047da49b53 Content-Type: image/jpeg; name="email.jpg" Content-Disposition: attachment; filename="email.jpg" Content-Transfer-Encoding: base64 Content-ID: <5428926183426922897> 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 --001485f91b3e159e1d047da49b53-- From fred at streamfocus.com Thu Jan 28 15:56:13 2010 From: fred at streamfocus.com (Fred Gibson) Date: Thu, 28 Jan 2010 07:56:13 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> Message-ID: <19290c161001280756l67952bfap5c39ca6209268631@mail.gmail.com> Hi Jochen, On further looking at the problem, the scan and multipart-read seem to work exactly as designed no matter the message complexity - very nice. The reason I'm getting strange results is when using part-body-string, there seems to be a problem with not skipping enough headers with increased message complexity, thereby giving a bad read on a correctly parsed part. I'm working on troubleshooting this now. My best, Fred Gibson On Sun, Jan 24, 2010 at 5:36 AM, Jochen Schmidt wrote: > Am 24.01.2010 um 14:03 schrieb Fred Gibson : > >> Hi Jochen, >> >> Yes, that is a beautiful thing - works great now. ?(I had to change >> the peek flet to: ((peek () ? (peek-char nil in-stream nil :eof)) ?to >> cure the eof problem. ?All is well now. > > Yes that should be the right thing to do. > >> >> I made the mistake in my version of thinking the result should give >> just the low level parts (so 3 parts in the example case instead of a >> new smaller message + 1 part), so that was part of my misunderstanding >> about it. > > The nice thing of mel-base's body structures is that they actually don't > reinvent the wheel. I generate just plain standard IMAP body structures. > This allowed me to just use the IMAP server provided body structure for IMAP > folders and the generated one for all others. The multipart code just > demands correct body structures. This is also why these bugs never occured > with IMAP folders. > > ciao, > Jochen > -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From js at crispylogics.com Thu Jan 28 16:05:27 2010 From: js at crispylogics.com (Jochen Schmidt) Date: Thu, 28 Jan 2010 17:05:27 +0100 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <19290c161001280756l67952bfap5c39ca6209268631@mail.gmail.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> <19290c161001280756l67952bfap5c39ca6209268631@mail.gmail.com> Message-ID: Am 28.01.2010 um 16:56 schrieb Fred Gibson: > Hi Jochen, > > On further looking at the problem, the scan and multipart-read seem to > work exactly as designed no matter the message complexity - very nice. > The reason I'm getting strange results is when using > part-body-string, there seems to be a problem with not skipping enough > headers with increased message complexity, thereby giving a bad read > on a correctly parsed part. I'm working on troubleshooting this now. I've also looked into this. Scanning and creating body structures is not the problem. Actually part-body-string does only work for quite simple multipart messages. I had an idea though how to simplify part lookup and at the same time support komplex multipart messages: AFAIR the body structure stores the boundary of the part. So it should be possible to scan the message for the beginning boundary tag of the given part - completely ignoring any hierarchy. I'll try that as soon as my time permits. ciao, Jochen -- Jochen Schmidt CRISPYLOGICS Uhlandstr. 9, 90408 Nuremberg Fon +49 (0)911 517 999 82 Fax +49 (0)911 517 999 83 mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com From fred at streamfocus.com Thu Jan 28 16:32:17 2010 From: fred at streamfocus.com (Fred Gibson) Date: Thu, 28 Jan 2010 08:32:17 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> <19290c161001280756l67952bfap5c39ca6209268631@mail.gmail.com> Message-ID: <19290c161001280832s372ad5c5pdb18223b0172a11b@mail.gmail.com> How about a function such as "(defun skip-rfc2822-header-part (stream part) ..." which would read the stream just past the desired header? I can take a pass at this if it would help. My best, Fred On Thu, Jan 28, 2010 at 8:05 AM, Jochen Schmidt wrote: > > Am 28.01.2010 um 16:56 schrieb Fred Gibson: > >> Hi Jochen, >> >> On further looking at the problem, the scan and multipart-read seem to >> work exactly as designed no matter the message complexity - very nice. >> The reason I'm getting strange results is when using >> part-body-string, there seems to be a problem with not skipping enough >> headers with increased message complexity, thereby giving a bad read >> on a correctly parsed part. ?I'm working on troubleshooting this now. > > I've also looked into this. Scanning and creating body structures is not the problem. > Actually part-body-string does only work for quite simple multipart messages. I had an idea though how to simplify part lookup and at the same time support komplex multipart messages: > > AFAIR the body structure stores the boundary of the part. So it should be possible to scan the message for the beginning boundary tag of the given part - completely ignoring any hierarchy. I'll try that as soon as my time permits. > > ciao, > Jochen > > -- > Jochen Schmidt > CRISPYLOGICS > Uhlandstr. 9, 90408 Nuremberg > > Fon +49 (0)911 517 999 82 > Fax +49 (0)911 517 999 83 > > mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com > > -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From js at crispylogics.com Thu Jan 28 16:39:30 2010 From: js at crispylogics.com (Jochen Schmidt) Date: Thu, 28 Jan 2010 17:39:30 +0100 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <19290c161001280832s372ad5c5pdb18223b0172a11b@mail.gmail.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001230144w51c125b2j8587f3588639e17c@mail.gmail.com> <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> <19290c161001280756l67952bfap5c39ca6209268631@mail.gmail.com> <19290c161001280832s372ad5c5pdb18223b0172a11b@mail.gmail.com> Message-ID: <2940150B-85E8-45CD-B93A-65053B3BAF7B@crispylogics.com> Am 28.01.2010 um 17:32 schrieb Fred Gibson: > How about a function such as "(defun skip-rfc2822-header-part (stream > part) ..." which would read the stream just past the desired header? > > I can take a pass at this if it would help. I don't think so. It would be fixing symptoms. I think the right thing to do would be scanning for the boundary in question and then calling just skrip-rfc2822-headers on the stream. Given some part P with boundary B 1) Locate the message object by following the parent chain 2) Get a message-body-stream 3) scan the stream for the boundary B 4) If boundary is found => return stream as part-stream If you want a part-body-stream just get a part-stream and do skip-rfc2822-headers. ciao, Jochen > > My best, > > Fred > > On Thu, Jan 28, 2010 at 8:05 AM, Jochen Schmidt wrote: >> >> Am 28.01.2010 um 16:56 schrieb Fred Gibson: >> >>> Hi Jochen, >>> >>> On further looking at the problem, the scan and multipart-read seem to >>> work exactly as designed no matter the message complexity - very nice. >>> The reason I'm getting strange results is when using >>> part-body-string, there seems to be a problem with not skipping enough >>> headers with increased message complexity, thereby giving a bad read >>> on a correctly parsed part. I'm working on troubleshooting this now. >> >> I've also looked into this. Scanning and creating body structures is not the problem. >> Actually part-body-string does only work for quite simple multipart messages. I had an idea though how to simplify part lookup and at the same time support komplex multipart messages: >> >> AFAIR the body structure stores the boundary of the part. So it should be possible to scan the message for the beginning boundary tag of the given part - completely ignoring any hierarchy. I'll try that as soon as my time permits. >> >> ciao, >> Jochen >> >> -- >> Jochen Schmidt >> CRISPYLOGICS >> Uhlandstr. 9, 90408 Nuremberg >> >> Fon +49 (0)911 517 999 82 >> Fax +49 (0)911 517 999 83 >> >> mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com >> >> > > > > -- > Fred Gibson > > Founder / Software Developer > http://www.streamfocus.com > > (c)2010 Organon Technologies LLC From js at crispylogics.com Thu Jan 28 16:56:58 2010 From: js at crispylogics.com (Jochen Schmidt) Date: Thu, 28 Jan 2010 17:56:58 +0100 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <19290c161001280849j4e029f8fn91f3f78b565bcebf@mail.gmail.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> <19290c161001280756l67952bfap5c39ca6209268631@mail.gmail.com> <19290c161001280832s372ad5c5pdb18223b0172a11b@mail.gmail.com> <2940150B-85E8-45CD-B93A-65053B3BAF7B@crispylogics.com> <19290c161001280849j4e029f8fn91f3f78b565bcebf@mail.gmail.com> Message-ID: Am 28.01.2010 um 17:49 schrieb Fred Gibson: > Would that approach work with an alternative structure where both a > text/plain and a text/html have the same boundary? I was thinking > that the content-type would need to be used to get an exact part > match. No you use the part-number. This is a strict numbering on the same level. So if you scan for a part with part number 2 you have to skip the first found boundary. > > How about: > >> Given some part P with boundary B >> 1) Locate the message object by following the parent chain >> 2) Get a message-body-stream >> 3) scan the stream for the boundary B > 4) if boundary is found > 5) process the content-type > if content-type matches > then return stream as part-stream > else go to 3) That isn't needed - the bodystructure (and the mel-base part objects) already contain the part-number. ciao, Jochen From fred at streamfocus.com Thu Jan 28 16:49:42 2010 From: fred at streamfocus.com (Fred Gibson) Date: Thu, 28 Jan 2010 08:49:42 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <2940150B-85E8-45CD-B93A-65053B3BAF7B@crispylogics.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001231600j6f14d76ch940da937784d5d4b@mail.gmail.com> <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> <19290c161001280756l67952bfap5c39ca6209268631@mail.gmail.com> <19290c161001280832s372ad5c5pdb18223b0172a11b@mail.gmail.com> <2940150B-85E8-45CD-B93A-65053B3BAF7B@crispylogics.com> Message-ID: <19290c161001280849j4e029f8fn91f3f78b565bcebf@mail.gmail.com> Would that approach work with an alternative structure where both a text/plain and a text/html have the same boundary? I was thinking that the content-type would need to be used to get an exact part match. How about: > Given some part P with boundary B > 1) Locate the message object by following the parent chain > 2) Get a message-body-stream > 3) scan the stream for the boundary B 4) if boundary is found 5) process the content-type if content-type matches then return stream as part-stream else go to 3) 5) if On Thu, Jan 28, 2010 at 8:39 AM, Jochen Schmidt wrote: > > Am 28.01.2010 um 17:32 schrieb Fred Gibson: > >> How about a function such as "(defun skip-rfc2822-header-part (stream >> part) ..." which would read the stream just past the desired header? >> >> I can take a pass at this if it would help. > > I don't think so. It would be fixing symptoms. I think the right thing to do would be scanning for the boundary in question and then calling just skrip-rfc2822-headers on the stream. > > Given some part P with boundary B > 1) Locate the message object by following the parent chain > 2) Get a message-body-stream > 3) scan the stream for the boundary B > 4) If boundary is found => return stream as part-stream > > If you want a part-body-stream just get a part-stream and do skip-rfc2822-headers. > > ciao, > Jochen > >> >> My best, >> >> Fred >> >> On Thu, Jan 28, 2010 at 8:05 AM, Jochen Schmidt wrote: >>> >>> Am 28.01.2010 um 16:56 schrieb Fred Gibson: >>> >>>> Hi Jochen, >>>> >>>> On further looking at the problem, the scan and multipart-read seem to >>>> work exactly as designed no matter the message complexity - very nice. >>>> The reason I'm getting strange results is when using >>>> part-body-string, there seems to be a problem with not skipping enough >>>> headers with increased message complexity, thereby giving a bad read >>>> on a correctly parsed part. ?I'm working on troubleshooting this now. >>> >>> I've also looked into this. Scanning and creating body structures is not the problem. >>> Actually part-body-string does only work for quite simple multipart messages. I had an idea though how to simplify part lookup and at the same time support komplex multipart messages: >>> >>> AFAIR the body structure stores the boundary of the part. So it should be possible to scan the message for the beginning boundary tag of the given part - completely ignoring any hierarchy. I'll try that as soon as my time permits. >>> >>> ciao, >>> Jochen >>> >>> -- >>> Jochen Schmidt >>> CRISPYLOGICS >>> Uhlandstr. 9, 90408 Nuremberg >>> >>> Fon +49 (0)911 517 999 82 >>> Fax +49 (0)911 517 999 83 >>> >>> mailto:(format nil "~(~36r@~36r.~36r~)" 870180 1680085828711918828 16438) http://www.crispylogics.com >>> >>> >> >> >> >> -- >> Fred Gibson >> >> Founder / Software Developer >> http://www.streamfocus.com >> >> (c)2010 Organon Technologies LLC > > -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From fred at streamfocus.com Thu Jan 28 17:40:46 2010 From: fred at streamfocus.com (Fred Gibson) Date: Thu, 28 Jan 2010 09:40:46 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> <19290c161001280756l67952bfap5c39ca6209268631@mail.gmail.com> <19290c161001280832s372ad5c5pdb18223b0172a11b@mail.gmail.com> <2940150B-85E8-45CD-B93A-65053B3BAF7B@crispylogics.com> <19290c161001280849j4e029f8fn91f3f78b565bcebf@mail.gmail.com> Message-ID: <19290c161001280940v3e7534b7pbe221214e388d9b4@mail.gmail.com> Hi Jochen, This seems to do the trick nicely: (defmethod part-body-stream ((part part)) "Skip headers to beginning of part body and return stream" (let* ((stream (message-body-stream (part-to-message part))) (parent (loop for parent = (parent part) then (parent parent) until (typep parent 'message) finally (return parent))) (boundary (boundary-tag (parent part)))) (dotimes (number (part-number part)) (scan-forward-boundary-tag stream boundary)) (read-rfc2822-header stream) stream)) My best, Fred On Thu, Jan 28, 2010 at 8:56 AM, Jochen Schmidt wrote: > > Am 28.01.2010 um 17:49 schrieb Fred Gibson: > >> Would that approach work with an alternative structure where both a >> text/plain and a text/html have the same boundary? ?I was thinking >> that the content-type would need to be used to get an exact part >> match. > > No you use the part-number. This is a strict numbering on the same level. So if you scan for a part with part number 2 you have to skip the first found boundary. > >> >> How about: >> >>> Given some part P with boundary B >>> 1) Locate the message object by following the parent chain >>> 2) Get a message-body-stream >>> 3) scan the stream for the boundary B >> 4) if boundary is found >> 5) ?process the content-type >> ? ? ? ? ?if content-type matches >> ? ? ? ? ?then return stream as part-stream >> ? ? ? ? ?else go to 3) > > That isn't needed - the bodystructure (and the mel-base part objects) already contain the part-number. > > ciao, > Jochen > > -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From fred at streamfocus.com Thu Jan 28 18:15:40 2010 From: fred at streamfocus.com (Fred Gibson) Date: Thu, 28 Jan 2010 10:15:40 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <19290c161001280940v3e7534b7pbe221214e388d9b4@mail.gmail.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <19290c161001240503p28fcefaaq5b8d36266433643b@mail.gmail.com> <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> <19290c161001280756l67952bfap5c39ca6209268631@mail.gmail.com> <19290c161001280832s372ad5c5pdb18223b0172a11b@mail.gmail.com> <2940150B-85E8-45CD-B93A-65053B3BAF7B@crispylogics.com> <19290c161001280849j4e029f8fn91f3f78b565bcebf@mail.gmail.com> <19290c161001280940v3e7534b7pbe221214e388d9b4@mail.gmail.com> Message-ID: <19290c161001281015p375e0ba8ga1ec7040129eb76b@mail.gmail.com> Sorry about that, the method should read: (defmethod part-body-stream ((part part)) "Skip headers to beginning of part body and return stream" (let* ((message (loop for parent = (parent part) then (parent parent) until (typep parent 'message) finally (return parent))) (stream (message-body-stream message)) (boundary (boundary-tag (parent part)))) (dotimes (number (part-number part)) (scan-forward-boundary-tag stream boundary)) (read-rfc2822-header stream) stream)) My best, Fred On Thu, Jan 28, 2010 at 9:40 AM, Fred Gibson wrote: > Hi Jochen, > > This seems to do the trick nicely: > > (defmethod part-body-stream ((part part)) > ?"Skip headers to beginning of part body and return stream" > ?(let* ((stream (message-body-stream (part-to-message part))) > ? ? ? ? (parent (loop for parent = (parent part) then (parent parent) > ? ? ? ? ? ? ? ? ? ?until (typep parent 'message) > ? ? ? ? ? ? ? ? ? ?finally (return parent))) > ? ? ? ? (boundary (boundary-tag (parent part)))) > ? ? ?(dotimes (number (part-number part)) > ? ? ? ?(scan-forward-boundary-tag stream boundary)) > ? ? ?(read-rfc2822-header stream) > ? ? ?stream)) > > My best, > > Fred > > On Thu, Jan 28, 2010 at 8:56 AM, Jochen Schmidt wrote: >> >> Am 28.01.2010 um 17:49 schrieb Fred Gibson: >> >>> Would that approach work with an alternative structure where both a >>> text/plain and a text/html have the same boundary? ?I was thinking >>> that the content-type would need to be used to get an exact part >>> match. >> >> No you use the part-number. This is a strict numbering on the same level. So if you scan for a part with part number 2 you have to skip the first found boundary. >> >>> >>> How about: >>> >>>> Given some part P with boundary B >>>> 1) Locate the message object by following the parent chain >>>> 2) Get a message-body-stream >>>> 3) scan the stream for the boundary B >>> 4) if boundary is found >>> 5) ?process the content-type >>> ? ? ? ? ?if content-type matches >>> ? ? ? ? ?then return stream as part-stream >>> ? ? ? ? ?else go to 3) >> >> That isn't needed - the bodystructure (and the mel-base part objects) already contain the part-number. >> >> ciao, >> Jochen >> >> > > > > -- > Fred Gibson > > Founder / Software Developer > http://www.streamfocus.com > > (c)2010 Organon Technologies LLC > -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From fred at streamfocus.com Fri Jan 29 00:58:48 2010 From: fred at streamfocus.com (Fred Gibson) Date: Thu, 28 Jan 2010 16:58:48 -0800 Subject: [mel-base-devel] mel.mime:parts not working properly for rfc 2822 (reading from a file) In-Reply-To: <19290c161001281015p375e0ba8ga1ec7040129eb76b@mail.gmail.com> References: <19290c161001212236t6b47f0e1jd741e89f91827af0@mail.gmail.com> <654FE859-A4D6-402A-8638-DE82AEC01FCE@crispylogics.com> <19290c161001280756l67952bfap5c39ca6209268631@mail.gmail.com> <19290c161001280832s372ad5c5pdb18223b0172a11b@mail.gmail.com> <2940150B-85E8-45CD-B93A-65053B3BAF7B@crispylogics.com> <19290c161001280849j4e029f8fn91f3f78b565bcebf@mail.gmail.com> <19290c161001280940v3e7534b7pbe221214e388d9b4@mail.gmail.com> <19290c161001281015p375e0ba8ga1ec7040129eb76b@mail.gmail.com> Message-ID: <19290c161001281658j6b8bf941kc2d5f015f2eb9469@mail.gmail.com> Hi Jochen, I found a problem with the find-viewable-part function when parsing multipart/related, so I wrote a new version to handle any structure which seems to work in all cases: (defun eml-message->viewable-part (obj) "takes a part or eml message" (flet ((eml-content-subtype (o) (multiple-value-bind (a b c)(mel.mime:content-type o) (declare (ignore a c)) b)) (eml-content-type (o) (multiple-value-bind (a b c)(mel.mime:content-type o) (declare (ignore b c)) a))) (if (eq (eml-content-subtype obj) :plain) obj (let ((parts (mel.mime:parts obj))) (when parts (or (find :plain parts :key #'eml-content-subtype) (let ((mpart (find :multipart parts :key #'eml-content-type))) (when mpart (eml-message->viewable-part mpart))))))))) On Thu, Jan 28, 2010 at 10:15 AM, Fred Gibson wrote: > Sorry about that, the method should read: > > (defmethod part-body-stream ((part part)) > ?"Skip headers to beginning of part body and return stream" > ?(let* ((message (loop for parent = (parent part) then (parent parent) > ? ? ? ? ? ? ? ? ? ? until (typep parent 'message) > ? ? ? ? ? ? ? ? ? ? finally (return parent))) > ? ? ? ? (stream (message-body-stream message)) > ? ? ? ? (boundary (boundary-tag (parent part)))) > ? ? ?(dotimes (number (part-number part)) > ? ? ? ?(scan-forward-boundary-tag stream boundary)) > ? ? ?(read-rfc2822-header stream) > ? ? ?stream)) > > My best, > > Fred > > On Thu, Jan 28, 2010 at 9:40 AM, Fred Gibson wrote: >> Hi Jochen, >> >> This seems to do the trick nicely: >> >> (defmethod part-body-stream ((part part)) >> ?"Skip headers to beginning of part body and return stream" >> ?(let* ((stream (message-body-stream (part-to-message part))) >> ? ? ? ? (parent (loop for parent = (parent part) then (parent parent) >> ? ? ? ? ? ? ? ? ? ?until (typep parent 'message) >> ? ? ? ? ? ? ? ? ? ?finally (return parent))) >> ? ? ? ? (boundary (boundary-tag (parent part)))) >> ? ? ?(dotimes (number (part-number part)) >> ? ? ? ?(scan-forward-boundary-tag stream boundary)) >> ? ? ?(read-rfc2822-header stream) >> ? ? ?stream)) >> >> My best, >> >> Fred >> >> On Thu, Jan 28, 2010 at 8:56 AM, Jochen Schmidt wrote: >>> >>> Am 28.01.2010 um 17:49 schrieb Fred Gibson: >>> >>>> Would that approach work with an alternative structure where both a >>>> text/plain and a text/html have the same boundary? ?I was thinking >>>> that the content-type would need to be used to get an exact part >>>> match. >>> >>> No you use the part-number. This is a strict numbering on the same level. So if you scan for a part with part number 2 you have to skip the first found boundary. >>> >>>> >>>> How about: >>>> >>>>> Given some part P with boundary B >>>>> 1) Locate the message object by following the parent chain >>>>> 2) Get a message-body-stream >>>>> 3) scan the stream for the boundary B >>>> 4) if boundary is found >>>> 5) ?process the content-type >>>> ? ? ? ? ?if content-type matches >>>> ? ? ? ? ?then return stream as part-stream >>>> ? ? ? ? ?else go to 3) >>> >>> That isn't needed - the bodystructure (and the mel-base part objects) already contain the part-number. >>> >>> ciao, >>> Jochen >>> >>> >> >> >> >> -- >> Fred Gibson >> >> Founder / Software Developer >> http://www.streamfocus.com >> >> (c)2010 Organon Technologies LLC >> > > > > -- > Fred Gibson > > Founder / Software Developer > http://www.streamfocus.com > > (c)2010 Organon Technologies LLC > -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC From fred at streamfocus.com Fri Jan 29 01:14:48 2010 From: fred at streamfocus.com (Fred Gibson) Date: Thu, 28 Jan 2010 17:14:48 -0800 Subject: [mel-base-devel] Saving and finding attachments Message-ID: <19290c161001281714j356720cbgb309172c0b9219d@mail.gmail.com> I've written a function to save an attachment: (defun save-attachment-file (part filename) (let* ((attach (mel.mime:part-body-string part)) (length (length (string-trim '(#\newline #\return #\linefeed) (read-line (make-string-input-stream attach))))) (in (make-string-input-stream attach))) (with-open-file (out filename :direction :output :element-type '(unsigned-byte 8)) (loop with buffer = (make-array length :element-type 'character) for count = (read-sequence buffer in) while (> count 0) do (write-sequence (mel.mime::decode-base64 buffer) out) (flet ((peek ()(peek-char nil in nil :eof)) (consume () (read-char in nil :eof))) (tagbody start (let ((c (peek))) (when (member c '(#\return #\linefeed #\newline)) (progn (consume) (go start)))))))))) and for finding attachments in a message: (defun find-attachments (eml) (flet ((eml-mixed? (e) (multiple-value-bind (a b c) (mel.mime:content-type e) (declare (ignore a c)) (when (eq b :mixed) t))) (eml-part-base64? (part) (when (eq (mel.mime:content-transfer-encoding part) :base64) t))) (when (eml-mixed? eml) (let (attach) (dolist (part (mel:parts eml)) (when (eml-part-base64? part) (push part attach))) attach)))) -- Fred Gibson Founder / Software Developer http://www.streamfocus.com (c)2010 Organon Technologies LLC