Browse code
2006-03-24 Kevin Layer <layer@gemini>
layer authored on 24/03/2006 20:05:15
Showing 2 changed files
Showing 2 changed files
... | ... |
@@ -1,12 +1,14 @@ |
1 | 1 |
#+(version= 8 0) |
2 |
-(sys:defpatch "smtp" 1 |
|
3 |
- "v1: send-letter w/attachments; send-smtp* can take streams" |
|
2 |
+(sys:defpatch "smtp" 2 |
|
3 |
+ "v1: send-letter w/attachments; send-smtp* can take streams; |
|
4 |
+v2: add :port argument to send-letter, send-smtp, send-smtp-auth." |
|
4 | 5 |
:type :system |
5 | 6 |
:post-loadable t) |
6 | 7 |
|
7 | 8 |
#+(version= 7 0) |
8 |
-(sys:defpatch "smtp" 2 |
|
9 |
- "v2: send-letter w/attachments; send-smtp* can take streams" |
|
9 |
+(sys:defpatch "smtp" 3 |
|
10 |
+ "v2: send-letter w/attachments; send-smtp* can take streams; |
|
11 |
+v3: add :port argument to send-letter, send-smtp, send-smtp-auth." |
|
10 | 12 |
:type :system |
11 | 13 |
:post-loadable t) |
12 | 14 |
|
... | ... |
@@ -36,7 +38,7 @@ |
36 | 38 |
;; Suite 330, Boston, MA 02111-1307 USA |
37 | 39 |
;; |
38 | 40 |
;; |
39 |
-;; $Id: smtp.cl,v 1.15 2006/02/03 23:25:17 layer Exp $ |
|
41 |
+;; $Id: smtp.cl,v 1.16 2006/03/24 20:05:15 layer Exp $ |
|
40 | 42 |
|
41 | 43 |
;; Description: |
42 | 44 |
;; send mail to an smtp server. See rfc821 for the spec. |
... | ... |
@@ -332,46 +334,59 @@ Attachments must be filenames, streams, or mime-part-constructed, not ~s" |
332 | 334 |
;; make that initial connection to the mail server |
333 | 335 |
;; returning a socket connected to it and |
334 | 336 |
;; signaling an error if it can't be made. |
335 |
- (let ((ipaddr (determine-mail-server server)) |
|
336 |
- (sock) |
|
337 |
- (ok)) |
|
338 |
- |
|
339 |
- (if* (null ipaddr) |
|
340 |
- then (error "Can't determine ip address for mail server ~s" server)) |
|
337 |
+ |
|
338 |
+ (let ((port 25)) ;; standard SMTP port |
|
339 |
+ (if* (consp server) |
|
340 |
+ then (setf port (cdr server)) |
|
341 |
+ (setf server (car server)) |
|
342 |
+ elseif (stringp server) |
|
343 |
+ then (multiple-value-bind (match whole m1 m2) |
|
344 |
+ (match-re "^([^:]+):([0-9]+)$" server) |
|
345 |
+ (declare (ignore whole)) |
|
346 |
+ (if* match |
|
347 |
+ then (setf server m1) |
|
348 |
+ (setf port (parse-integer m2))))) |
|
341 | 349 |
|
342 |
- (setq sock (socket:make-socket :remote-host ipaddr |
|
343 |
- :remote-port 25 ; smtp |
|
344 |
- )) |
|
345 |
- (unwind-protect |
|
346 |
- (progn |
|
347 |
- (response-case (sock msg) |
|
348 |
- (2 ;; to the initial connect |
|
349 |
- nil) |
|
350 |
- (t (error "initial connect failed: ~s" msg))) |
|
350 |
+ (let ((ipaddr (determine-mail-server server)) |
|
351 |
+ (sock) |
|
352 |
+ (ok)) |
|
353 |
+ |
|
354 |
+ (if* (null ipaddr) |
|
355 |
+ then (error "Can't determine ip address for mail server ~s" server)) |
|
356 |
+ |
|
357 |
+ (setq sock (socket:make-socket :remote-host ipaddr |
|
358 |
+ :remote-port port |
|
359 |
+ )) |
|
360 |
+ (unwind-protect |
|
361 |
+ (progn |
|
362 |
+ (response-case (sock msg) |
|
363 |
+ (2 ;; to the initial connect |
|
364 |
+ nil) |
|
365 |
+ (t (error "initial connect failed: ~s" msg))) |
|
351 | 366 |
|
352 |
- ;; now that we're connected we can compute our hostname |
|
353 |
- (let ((hostname (socket:ipaddr-to-hostname |
|
354 |
- (socket:local-host sock)))) |
|
355 |
- (if* (null hostname) |
|
356 |
- then (setq hostname |
|
357 |
- (format nil "[~a]" (socket:ipaddr-to-dotted |
|
358 |
- (socket:local-host sock))))) |
|
359 |
- (let ((mechs (smtp-ehlo sock hostname))) |
|
360 |
- (if (and mechs login password) |
|
361 |
- (setf sock |
|
362 |
- (smtp-authenticate sock server mechs login password))))) |
|
367 |
+ ;; now that we're connected we can compute our hostname |
|
368 |
+ (let ((hostname (socket:ipaddr-to-hostname |
|
369 |
+ (socket:local-host sock)))) |
|
370 |
+ (if* (null hostname) |
|
371 |
+ then (setq hostname |
|
372 |
+ (format nil "[~a]" (socket:ipaddr-to-dotted |
|
373 |
+ (socket:local-host sock))))) |
|
374 |
+ (let ((mechs (smtp-ehlo sock hostname))) |
|
375 |
+ (if (and mechs login password) |
|
376 |
+ (setf sock |
|
377 |
+ (smtp-authenticate sock server mechs login password))))) |
|
363 | 378 |
|
364 |
- ; all is good |
|
365 |
- (setq ok t)) |
|
379 |
+ ;; all is good |
|
380 |
+ (setq ok t)) |
|
366 | 381 |
|
367 |
- ; cleanup: |
|
368 |
- (if* (null ok) |
|
369 |
- then (close sock :abort t) |
|
370 |
- (setq sock nil))) |
|
382 |
+ ;; cleanup: |
|
383 |
+ (if* (null ok) |
|
384 |
+ then (close sock :abort t) |
|
385 |
+ (setq sock nil))) |
|
371 | 386 |
|
372 |
- ; return: |
|
373 |
- sock |
|
374 |
- )) |
|
387 |
+ ;; return: |
|
388 |
+ sock |
|
389 |
+ ))) |
|
375 | 390 |
|
376 | 391 |
|
377 | 392 |
;; Returns string with mechanisms, or nil if none. |
... | ... |
@@ -601,17 +616,17 @@ Attachments must be filenames, streams, or mime-part-constructed, not ~s" |
601 | 616 |
;; return the ipaddress to be used to connect to the |
602 | 617 |
;; the mail server. |
603 | 618 |
;; name is any method for naming a machine: |
604 |
- ;; integer ip address |
|
619 |
+ ;; ip address (binary) |
|
605 | 620 |
;; string with dotted ip address |
606 |
- ;; string naming a machine |
|
621 |
+ ;; string naming a domain |
|
607 | 622 |
;; we can only do the mx lookup for the third case, the rest |
608 | 623 |
;; we just return the ipaddress for what we were given |
609 | 624 |
;; |
610 | 625 |
(let (ipaddr) |
611 |
- (if* (integerp name) |
|
626 |
+ (if* (socket:ipaddrp name) |
|
612 | 627 |
then name |
613 |
- elseif (integerp (setq ipaddr |
|
614 |
- (socket:dotted-to-ipaddr name :errorp nil))) |
|
628 |
+ elseif (socket:ipaddrp (setq ipaddr |
|
629 |
+ (socket:dotted-to-ipaddr name :errorp nil))) |
|
615 | 630 |
then ipaddr |
616 | 631 |
else ; do mx lookup if acldns is being used |
617 | 632 |
(if* (or (eq socket:*dns-mode* :acldns) |