Lisp HUG Maillist Archive

Lispworks POP interface

     I'm writing a Lispworks email indexing application
which needs to download email from a POP server.
Has anybody already written a Lispworks interface to POP?
I've looked at the open source Allegro imap.cl file which
interfaces Allegro 6.2 to POP.

Has anybody already tried to convert imap.cl to a Lispworks version?
imap.cl calls:

(socket:make-socket :remote-host host :remote-port port)

and imap.cl calls:

(send-command-get-results
     socket
     command-string
     untagged-response-function
     check-for-success-function)

The above might have to be replace by Lispworks calls like:

(with-open-stream (x
(comm:open-tcp-stream
host port
:element-type '(unsigned-byte 8)))
(write-sequence command-string x)
(force-output x)
(let ((response (make-array 20 :element-type 'base-char)))
(values (read-sequence response x) res)))



Re: Lispworks POP interface

On Sep 8, 2004, at 12:43 PM, Lawrence Au wrote:

>     I'm writing a Lispworks email indexing application
> which needs to download email from a POP server.
> Has anybody already written a Lispworks interface to POP?
> I've looked at the open source Allegro imap.cl file which
> interfaces Allegro 6.2 to POP.

If you used imap.cl you might want to consider using the acl-compat 
library that is part of Portable AllegroServe. With this approach you 
probably won't have to change any of the networking code.


Best,

John DeSoi, Ph.D.


Re: Lispworks POP interface

On Wed, 8 Sep 2004 12:43:47 -0400, Lawrence Au <laau@erols.com> wrote:

>     I'm writing a Lispworks email indexing application which needs
> to download email from a POP server.  Has anybody already written a
> Lispworks interface to POP?  I've looked at the open source Allegro
> imap.cl file which interfaces Allegro 6.2 to POP.
>
> Has anybody already tried to convert imap.cl to a Lispworks version?
> imap.cl calls:

I've used Franz' code to implement an application in LispWorks to test
an IMAP server. IIRC this was rather easy using ACL-COMPAT. You should
check that first. Let me know if you don't succeed and I'll dig out
the code I was talking about.

Cheers,
Edi.


Re: Lispworks POP interface

Lawrence Au wrote:

>   I'm writing a Lispworks email indexing application
> which needs to download email from a POP server.
> Has anybody already written a Lispworks interface to POP?

Yes I have.  It has not been roughly tested and right now
it is copyright.
If you give it a try you can use it.  If others could
give it a quick try I would appreciate it.

If I do release it it will be under a BSD license.

You can get it from

http://www3.telus.net/public/whumeniu/cl-email.zip

Wade


Re: Lispworks POP interface

Lawrence Au <laau@erols.com> writes:

> Has anybody already written a Lispworks interface to POP?

yes, it's rather toyish (it's really a part of my personal
spam-fighting software), but maybe I should clean it a little up and
release it?
-- 
  (espen)


Re: Lispworks POP interface

Espen Vestre <ev@netfonds.no> writes:

> yes, it's rather toyish (it's really a part of my personal
> spam-fighting software), but maybe I should clean it a little up and
> release it?

oh well, no time for that, I'll just paste the relevant part of
the code here. I hope it can serve as a useful starting point!

(defun crlf-read-line (stream)
  (let ((foo (read-line stream nil nil)))
    (when foo
      (string-trim '(#\Return) foo))))

(defun pop-prompt (stream)
  (force-output stream)
  (let ((line (read-line stream nil nil)))
    (unless line
      (error "Timeout for ~a" stream))
    (case (elt line 0)
      (#\- (error "Error from pop server: ~a" line))
      (#\+ line)
      (otherwise (error "Unexpected response rom pop server: ~a" line)))))

(defun connect-to-server (pop-server username password)
  (let ((pop (comm:open-tcp-stream pop-server 110
                              :direction :io
                              :element-type 'base-char
                              :read-timeout 10)))
    (pop-prompt pop)
    (format pop "user ~a~%" username)
    (pop-prompt pop)
    (format pop "pass ~a~%" password)
    (pop-prompt pop)
    pop))

(defun new-mail-listing (pop-server username password)
  (with-open-stream (pop (connect-to-server pop-server username password))
    (format pop "list~%")
    (pop-prompt pop)
    (prog1 (loop for line = (crlf-read-line pop)
                 while (and line (not (equal line ".")))
                 collect line)
      (format pop "quit~%"))))

(defun new-mails (pop)
  (format pop "list~%")
  (pop-prompt pop)
  (loop for line = (crlf-read-line pop)
        while (and line (not (equal line ".")))
        collect (parse-integer line :junk-allowed t)))

(defmacro with-pop-connection ((stream pop-server username password)
                               &body body)
  `(with-open-stream (,stream (connect-to-server ,pop-server ,username 
                                             ,password))
     (prog1
         (progn
           ,@body)
       (format ,stream "quit~%"))))

(defun get-headers (message)
  (loop with plist = nil
        with prev = nil
        for string in message
        for rest-message on message
        while (not (equal string ""))
        for kolon = (and (alphanumericp (elt string 0))
                         (position #\: string))
        do
        (if kolon
            (let ((header (intern (string-upcase (subseq string 0 kolon))
                                  :keyword))
                  (value (ignore-errors
                           (subseq string (+ kolon 2)))))
              (setf (getf plist header)
                    (concatenate 'string (getf plist header) value))
              (setf prev header))
          (setf (getf plist prev)
                (concatenate 'string (getf plist prev) string)))
        finally return (values plist rest-message)))


(defun delete-mail (pop number)
  (format pop "dele ~a~%" number)
  (pop-prompt pop))


-- 
  (espen)


Re: Lispworks POP interface

Lawrence Au schrieb:

> I'm writing a Lispworks email indexing application
> which needs to download email from a POP server.
> Has anybody already written a Lispworks interface to POP?
> I've looked at the open source Allegro imap.cl file which
> interfaces Allegro 6.2 to POP.
>
> Has anybody already tried to convert imap.cl to a Lispworks version?


Yes I tried it and it seems that it works using ACL-COMPAT.

It might be interesting for you (and maybe others?)
that I plan to open source my email system called "Mel" which consists
of ~ 10000 LOC under a BSD style license soon.

It contains implementations of POP3, IMAP, Maildir, SMTP, MIME 
(including multipart stuff).

I'm over writing an article series for a German magazine about it.

ciao,
Jochen Schmidt


Re: Lispworks POP interface

>    I'm writing a Lispworks email indexing application
>which needs to download email from a POP server.
>Has anybody already written a Lispworks interface to POP?

CL-HTTP has a POP3 interface in its distribution. It
also works with LispWorks.


>I've looked at the open source Allegro imap.cl file which
>interfaces Allegro 6.2 to POP. 
>
>Has anybody already tried to convert imap.cl to a Lispworks version?
>imap.cl calls:
>
>(socket:make-socket :remote-host host :remote-port port)
>
>and imap.cl calls:
>
>(send-command-get-results
>    socket
>    command-string
>    untagged-response-function
>    check-for-success-function)
>
>The above might have to be replace by Lispworks calls like:
>
>(with-open-stream (x
>(comm:open-tcp-stream
>host port
>:element-type '(unsigned-byte 8)))
>(write-sequence command-string x)
>(force-output x)
>(let ((response (make-array 20 :element-type 'base-char)))
>(values (read-sequence response x) res)))


Updated at: 2020-12-10 08:55 UTC