Browse code
imap 1.8.. response-too-large error
jkf authored on 04/05/2001 16:01:45
Showing 3 changed files
Showing 3 changed files
... | ... |
@@ -19,7 +19,7 @@ |
19 | 19 |
;; Commercial Software developed at private expense as specified in |
20 | 20 |
;; DOD FAR Supplement 52.227-7013 (c) (1) (ii), as applicable. |
21 | 21 |
;; |
22 |
-;; $Id: imap.cl,v 1.16 2000/06/08 14:41:00 jkf Exp $ |
|
22 |
+;; $Id: imap.cl,v 1.17 2001/05/04 16:01:45 jkf Exp $ |
|
23 | 23 |
|
24 | 24 |
;; Description: |
25 | 25 |
;; |
... | ... |
@@ -95,7 +95,7 @@ |
95 | 95 |
|
96 | 96 |
(provide :imap) |
97 | 97 |
|
98 |
-(defparameter *imap-version-number* '(:major 1 :minor 7)) ; major.minor |
|
98 |
+(defparameter *imap-version-number* '(:major 1 :minor 8)) ; major.minor |
|
99 | 99 |
|
100 | 100 |
;; todo |
101 | 101 |
;; have the list of tags selected done on a per connection basis to |
... | ... |
@@ -262,7 +262,9 @@ |
262 | 262 |
; |
263 | 263 |
; :timeout error |
264 | 264 |
; server failed to respond within the timeout period |
265 |
- |
|
265 |
+; |
|
266 |
+; :response-too-large error |
|
267 |
+; contents of a response is too large to store in a Lisp array. |
|
266 | 268 |
|
267 | 269 |
|
268 | 270 |
;; conditions |
... | ... |
@@ -560,6 +562,13 @@ |
560 | 562 |
(flet ((add-to-buffer (ch) |
561 | 563 |
(if* (>= pos (length buf)) |
562 | 564 |
then ; grow buffer |
565 |
+ (if* (>= (length buf) |
|
566 |
+ (1- array-total-size-limit)) |
|
567 |
+ then ; can't grow it any further |
|
568 |
+ (po-error |
|
569 |
+ :response-too-large |
|
570 |
+ :format-control |
|
571 |
+ "response from mail server is too large to hold in a lisp array")) |
|
563 | 572 |
(let ((new-buf (get-line-buffer |
564 | 573 |
(* (length buf) 2)))) |
565 | 574 |
(init-line-buffer new-buf buf) |
... | ... |
@@ -1885,6 +1894,7 @@ |
1885 | 1894 |
|
1886 | 1895 |
(defun get-line-buffer (size) |
1887 | 1896 |
;; get a buffer of at least size bytes |
1897 |
+ (setq size (min size (1- array-total-size-limit))) |
|
1888 | 1898 |
(mp::without-scheduling |
1889 | 1899 |
(dolist (buff *line-buffers* (make-string size)) |
1890 | 1900 |
(if* (>= (length buff) size) |
... | ... |
@@ -1,7 +1,38 @@ |
1 |
-;; mail sending package |
|
1 |
+;; -*- mode: common-lisp; package: net.aserve -*- |
|
2 | 2 |
;; |
3 |
-;; smtp - rfc821 |
|
3 |
+;; smtp.cl |
|
4 | 4 |
;; |
5 |
+;; copyright (c) 1986-2000 Franz Inc, Berkeley, CA |
|
6 |
+;; |
|
7 |
+;; This code is free software; you can redistribute it and/or |
|
8 |
+;; modify it under the terms of the version 2.1 of |
|
9 |
+;; the GNU Lesser General Public License as published by |
|
10 |
+;; the Free Software Foundation, as clarified by the AllegroServe |
|
11 |
+;; prequel found in license-allegroserve.txt. |
|
12 |
+;; |
|
13 |
+;; This code is distributed in the hope that it will be useful, |
|
14 |
+;; but without any warranty; without even the implied warranty of |
|
15 |
+;; merchantability or fitness for a particular purpose. See the GNU |
|
16 |
+;; Lesser General Public License for more details. |
|
17 |
+;; |
|
18 |
+;; Version 2.1 of the GNU Lesser General Public License is in the file |
|
19 |
+;; license-lgpl.txt that was distributed with this file. |
|
20 |
+;; If it is not present, you can access it from |
|
21 |
+;; http://www.gnu.org/copyleft/lesser.txt (until superseded by a newer |
|
22 |
+;; version) or write to the Free Software Foundation, Inc., 59 Temple Place, |
|
23 |
+;; Suite 330, Boston, MA 02111-1307 USA |
|
24 |
+;; |
|
25 |
+;; |
|
26 |
+;; $Id: smtp.cl,v 1.3 2001/05/04 16:01:45 jkf Exp $ |
|
27 |
+ |
|
28 |
+;; Description: |
|
29 |
+;; send mail to an smtp server. See rfc821 for the spec. |
|
30 |
+ |
|
31 |
+;;- This code in this file obeys the Lisp Coding Standard found in |
|
32 |
+;;- http://www.franz.com/~jkf/coding_standards.html |
|
33 |
+;;- |
|
34 |
+ |
|
35 |
+ |
|
5 | 36 |
(defpackage :net.post-office |
6 | 37 |
(:use #:lisp #:excl) |
7 | 38 |
(:export |
... | ... |
@@ -10,23 +41,34 @@ |
10 | 41 |
|
11 | 42 |
(in-package :net.post-office) |
12 | 43 |
|
44 |
+ |
|
13 | 45 |
;; the exported functions: |
14 | 46 |
|
15 |
-;; (send-letter "mail-server" "from" "to" "message" &key subject reply-to) |
|
47 |
+;; (send-letter "mail-server" "from" "to" "message" |
|
48 |
+;; &key cc bcc subject reply-to headers) |
|
49 |
+;; |
|
16 | 50 |
;; |
17 | 51 |
;; sends a message to the mail server (which may be a relay server |
18 | 52 |
;; or the final destination). "from" is the address to be given |
19 | 53 |
;; as the sender. "to" can be a string or a list of strings naming |
20 | 54 |
;; recipients. |
21 | 55 |
;; "message" is the message to be sent |
22 |
-;; This builds a header and inserts the optional subject and reply-to |
|
23 |
-;; lines. |
|
56 |
+;; cc and bcc can be either be a string or a list of strings |
|
57 |
+;; naming recipients. All cc's and bcc's are sent the message |
|
58 |
+;; but the bcc's aren't included in the header created. |
|
59 |
+;; reply-to's value is a string and in cases a Reply-To header |
|
60 |
+;; to be created. |
|
61 |
+;; headers is a string or list of stings. These are raw header lines |
|
62 |
+;; added to the header build to send out. |
|
63 |
+;; |
|
64 |
+;; This builds a header and inserts the optional cc, bcc, |
|
65 |
+;; subject and reply-to lines. |
|
24 | 66 |
;; |
25 | 67 |
;; (send-smtp "mail-server" "from" "to" &rest messages) |
26 | 68 |
;; this is like send-letter except that it doesn't build a header. |
27 | 69 |
;; the messages should contain a header (and if not then sendmail |
28 | 70 |
;; notices this and builds one -- other MTAs may not be that smart). |
29 |
-;; The messages ia list of string to be concatenated together |
|
71 |
+;; The messages ia list of strings to be concatenated together |
|
30 | 72 |
;; and sent as one message |
31 | 73 |
;; |
32 | 74 |
;; |
... | ... |
@@ -35,18 +77,19 @@ |
35 | 77 |
|
36 | 78 |
|
37 | 79 |
|
38 |
- |
|
39 |
- |
|
40 |
- |
|
41 |
- |
|
42 |
- |
|
43 |
- |
|
44 |
-(defmacro response-case ((ftp-stream) &rest case-clauses) |
|
80 |
+(defmacro response-case ((smtp-stream &optional smtp-response) &rest case-clauses) |
|
81 |
+ ;; get a response from the smtp server and dispatch in a 'case' like |
|
82 |
+ ;; fashion to a clause based on the first digit of the return |
|
83 |
+ ;; code of the response. |
|
84 |
+ ;; smtp-response, if given, will be bound to string that is |
|
85 |
+ ;; the actual response |
|
86 |
+ ;; |
|
45 | 87 |
(let ((response-class (gensym))) |
46 |
- `(multiple-value-bind (,response-class ftp-response) |
|
47 |
- (progn (force-output ,ftp-stream) |
|
48 |
- (wait-for-response ,ftp-stream)) |
|
49 |
- (declare (ignorable ftp-response)) |
|
88 |
+ `(multiple-value-bind (,response-class ,@(if* smtp-response |
|
89 |
+ then (list smtp-response))) |
|
90 |
+ (progn (force-output ,smtp-stream) |
|
91 |
+ (wait-for-response ,smtp-stream)) |
|
92 |
+ ;;(declare (ignorable smtp-response)) |
|
50 | 93 |
(case ,response-class |
51 | 94 |
,@case-clauses)))) |
52 | 95 |
|
... | ... |
@@ -55,20 +98,38 @@ |
55 | 98 |
|
56 | 99 |
|
57 | 100 |
(defun send-letter (server from to message |
58 |
- &key subject |
|
59 |
- reply-to) |
|
60 |
- (let ((header (make-string-output-stream))) |
|
101 |
+ &key cc bcc subject reply-to headers) |
|
102 |
+ ;; |
|
103 |
+ ;; see documentation at the head of this file |
|
104 |
+ ;; |
|
105 |
+ (let ((header (make-string-output-stream)) |
|
106 |
+ (tos (if* (stringp to) |
|
107 |
+ then (list to) |
|
108 |
+ elseif (consp to) |
|
109 |
+ then to |
|
110 |
+ else (error "to should be a string or list, not ~s" to))) |
|
111 |
+ (ccs |
|
112 |
+ (if* (null cc) |
|
113 |
+ then nil |
|
114 |
+ elseif (stringp cc) |
|
115 |
+ then (list cc) |
|
116 |
+ elseif (consp cc) |
|
117 |
+ then cc |
|
118 |
+ else (error "cc should be a string or list, not ~s" cc))) |
|
119 |
+ (bccs (if* (null bcc) |
|
120 |
+ then nil |
|
121 |
+ elseif (stringp bcc) |
|
122 |
+ then (list bcc) |
|
123 |
+ elseif (consp bcc) |
|
124 |
+ then bcc |
|
125 |
+ else (error "bcc should be a string or list, not ~s" bcc)))) |
|
61 | 126 |
(format header "From: ~a~c~cTo: " |
62 | 127 |
from |
63 | 128 |
#\return |
64 | 129 |
#\linefeed) |
65 |
- (let ((tos (if* (stringp to) |
|
66 |
- then (list to) |
|
67 |
- elseif (consp to) |
|
68 |
- then to |
|
69 |
- else (error "to should be a string or list, not ~s" |
|
70 |
- to)))) |
|
71 |
- (format header "~{ ~a~^,~}~c~c" tos #\return #\linefeed)) |
|
130 |
+ (format header "~{ ~a~^,~}~c~c" tos #\return #\linefeed) |
|
131 |
+ (if* ccs |
|
132 |
+ then (format header "Cc: ~{ ~a~^,~}~c~c" ccs #\return #\linefeed)) |
|
72 | 133 |
|
73 | 134 |
(if* subject |
74 | 135 |
then (format header "Subject: ~a~c~c" subject #\return #\linefeed)) |
... | ... |
@@ -76,14 +137,20 @@ |
76 | 137 |
(if* reply-to |
77 | 138 |
then (format header "Reply-To: ~a~c~c" reply-to #\return #\linefeed)) |
78 | 139 |
|
140 |
+ (if* headers |
|
141 |
+ then (if* (stringp headers) |
|
142 |
+ then (setq headers (list headers)) |
|
143 |
+ elseif (consp headers) |
|
144 |
+ thenret |
|
145 |
+ else (error "Unknown headers format: ~s." headers)) |
|
146 |
+ (dolist (h headers) |
|
147 |
+ (format header "~a~c~c" h #\return #\linefeed))) |
|
79 | 148 |
|
80 | 149 |
(format header "~c~c" #\return #\linefeed) |
81 | 150 |
|
82 |
- (send-smtp server from to (get-output-stream-string header) message) |
|
83 |
- |
|
84 |
- |
|
85 |
- |
|
86 |
- )) |
|
151 |
+ (send-smtp server from (append tos ccs bccs) |
|
152 |
+ (get-output-stream-string header) |
|
153 |
+ message))) |
|
87 | 154 |
|
88 | 155 |
|
89 | 156 |
|
... | ... |
@@ -102,29 +169,30 @@ |
102 | 169 |
))) |
103 | 170 |
(unwind-protect |
104 | 171 |
(progn |
105 |
- (response-case (sock) |
|
106 |
- (2 ;; to the initial connect |
|
107 |
- nil) |
|
108 |
- (t (error "initial connect failed"))) |
|
172 |
+ (response-case (sock msg) |
|
173 |
+ (2 ;; to the initial connect |
|
174 |
+ nil) |
|
175 |
+ (t (error "initial connect failed: ~s" msg))) |
|
109 | 176 |
|
110 | 177 |
;; now that we're connected we can compute our hostname |
111 | 178 |
(let ((hostname (socket:ipaddr-to-hostname |
112 | 179 |
(socket:local-host sock)))) |
113 | 180 |
(if* (null hostname) |
114 |
- then (format nil "[~a]" (socket:ipaddr-to-dotted |
|
115 |
- (socket:local-host sock)))) |
|
181 |
+ then (setq hostname |
|
182 |
+ (format nil "[~a]" (socket:ipaddr-to-dotted |
|
183 |
+ (socket:local-host sock))))) |
|
116 | 184 |
(smtp-command sock "HELO ~a" hostname) |
117 |
- (response-case (sock) |
|
118 |
- (2 ;; ok |
|
119 |
- nil) |
|
120 |
- (t (error "hello greeting failed")))) |
|
185 |
+ (response-case (sock msg) |
|
186 |
+ (2 ;; ok |
|
187 |
+ nil) |
|
188 |
+ (t (error "hello greeting failed: ~s" msg)))) |
|
121 | 189 |
|
122 | 190 |
(smtp-command sock "MAIL from:<~a>" from) |
123 |
- (response-case (sock) |
|
124 |
- (2 ;; cool |
|
125 |
- nil |
|
126 |
- ) |
|
127 |
- (t (error "Mail from command failed"))) |
|
191 |
+ (response-case (sock msg) |
|
192 |
+ (2 ;; cool |
|
193 |
+ nil |
|
194 |
+ ) |
|
195 |
+ (t (error "Mail from command failed: ~s" msg))) |
|
128 | 196 |
|
129 | 197 |
(let ((tos (if* (stringp to) |
130 | 198 |
then (list to) |
... | ... |
@@ -134,18 +202,18 @@ |
134 | 202 |
to)))) |
135 | 203 |
(dolist (to tos) |
136 | 204 |
(smtp-command sock "RCPT to:<~a>" to) |
137 |
- (response-case (sock) |
|
138 |
- (2 ;; cool |
|
139 |
- nil |
|
140 |
- ) |
|
141 |
- (t (error "rcpt to command failed"))))) |
|
205 |
+ (response-case (sock msg) |
|
206 |
+ (2 ;; cool |
|
207 |
+ nil |
|
208 |
+ ) |
|
209 |
+ (t (error "rcpt to command failed: ~s" msg))))) |
|
142 | 210 |
|
143 | 211 |
(smtp-command sock "DATA") |
144 |
- (response-case (sock) |
|
145 |
- (3 ;; cool |
|
146 |
- nil) |
|
147 |
- (t (error "Data command failed"))) |
|
148 |
- ;(format t "sending message~%") (force-output t) |
|
212 |
+ (response-case (sock msg) |
|
213 |
+ (3 ;; cool |
|
214 |
+ nil) |
|
215 |
+ (t (error "Data command failed: ~s" msg))) |
|
216 |
+ |
|
149 | 217 |
|
150 | 218 |
|
151 | 219 |
(let ((at-bol t)) |
... | ... |
@@ -165,19 +233,19 @@ |
165 | 233 |
(write-char #\. sock) |
166 | 234 |
(write-char #\return sock) (write-char #\linefeed sock) |
167 | 235 |
|
168 |
- (response-case (sock) |
|
169 |
- (2 nil ; (format t "Message sent to ~a~%" to) |
|
170 |
- ) |
|
236 |
+ (response-case (sock msg) |
|
237 |
+ (2 nil ; (format t "Message sent to ~a~%" to) |
|
238 |
+ ) |
|
171 | 239 |
|
172 |
- (t (error "message not sent"))) |
|
240 |
+ (t (error "message not sent: ~s" msg))) |
|
173 | 241 |
|
174 | 242 |
(force-output t) |
175 | 243 |
|
176 | 244 |
(smtp-command sock "QUIT") |
177 |
- (response-case (sock) |
|
178 |
- (2 ;; cool |
|
179 |
- nil) |
|
180 |
- (t (error "quit failed")))) |
|
245 |
+ (response-case (sock msg) |
|
246 |
+ (2 ;; cool |
|
247 |
+ nil) |
|
248 |
+ (t (error "quit failed: ~s" msg)))) |
|
181 | 249 |
(close sock)))) |
182 | 250 |
|
183 | 251 |
|
... | ... |
@@ -189,7 +257,7 @@ |
189 | 257 |
|
190 | 258 |
|
191 | 259 |
(defun wait-for-response (stream) |
192 |
- ;; read the response of the ftp server. |
|
260 |
+ ;; read the response of the smtp server. |
|
193 | 261 |
;; collect it all in a string. |
194 | 262 |
;; Return two values: |
195 | 263 |
;; response class |
... | ... |
@@ -287,3 +355,5 @@ |
287 | 355 |
then (vector-push-extend ch res)) |
288 | 356 |
|
289 | 357 |
(setq last-ch ch)))) |
358 |
+ |
|
359 |
+(provide :smtp) |