aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1997-06-01 22:24:22 +0000
committerRichard M. Stallman1997-06-01 22:24:22 +0000
commitc50d5ce0d1c6ef8a064e16834da8b903fd73c98d (patch)
tree3a3cf3fee67bf5b195c7fa69f741dfd186e15d5e
parent95b597ce99aea8d8af098a776a9099afad775552 (diff)
downloademacs-c50d5ce0d1c6ef8a064e16834da8b903fd73c98d.tar.gz
emacs-c50d5ce0d1c6ef8a064e16834da8b903fd73c98d.zip
(smtpmail-via-smtp): Recognize XVRB as a synonym for
VERB and XONE as a synonym for ONEX. (smtpmail-read-response): Add "%s" to `message' calls to avoid problems with percent signs in strings. (smtpmail-read-response): Return all lines of the response text as a list of strings. Formerly only the first line was returned. This is insufficient when one wants to parse e.g. an EHLO response. Ignore responses starting with "0". This is necessary to support the VERB SMTP extension. (smtpmail-via-smtp): Try EHLO and find out which SMTP service extensions the receiving mailer supports. Issue the ONEX and XUSR commands if the corresponding extensions are supported. Issue VERB if supported and `smtpmail-debug-info' is non-nil. Add SIZE attribute to MAIL FROM: command if SIZE extension is supported. Add code that could set the BODY= attribute to MAIL FROM: if the receiving mailer supports 8BITMIME. This is currently disabled, since doing it right might involve adding MIME headers to, and in some cases reencoding, the message.
-rw-r--r--lisp/mail/smtpmail.el154
1 files changed, 120 insertions, 34 deletions
diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el
index 71cce7ced0d..6fa2418ce72 100644
--- a/lisp/mail/smtpmail.el
+++ b/lisp/mail/smtpmail.el
@@ -4,6 +4,7 @@
4 4
5;; Author: Tomoji Kagatani <kagatani@rbc.ncl.omron.co.jp> 5;; Author: Tomoji Kagatani <kagatani@rbc.ncl.omron.co.jp>
6;; Maintainer: Brian D. Carlstrom <bdc@ai.mit.edu> 6;; Maintainer: Brian D. Carlstrom <bdc@ai.mit.edu>
7;; ESMTP support: Simon Leinen <simon@switch.ch>
7;; Keywords: mail 8;; Keywords: mail
8 9
9;; This file is part of GNU Emacs. 10;; This file is part of GNU Emacs.
@@ -243,7 +244,8 @@ don't define this value."
243 (port smtpmail-smtp-service) 244 (port smtpmail-smtp-service)
244 response-code 245 response-code
245 greeting 246 greeting
246 process-buffer) 247 process-buffer
248 (supported-extensions '()))
247 (unwind-protect 249 (unwind-protect
248 (catch 'done 250 (catch 'done
249 ;; get or create the trace buffer 251 ;; get or create the trace buffer
@@ -274,24 +276,105 @@ don't define this value."
274 (throw 'done nil) 276 (throw 'done nil)
275 ) 277 )
276 278
277 ;; HELO 279 ;; EHLO
278 (smtpmail-send-command process (format "HELO %s" (smtpmail-fqdn))) 280 (smtpmail-send-command process (format "EHLO %s" (smtpmail-fqdn)))
279 281
280 (if (or (null (car (setq response-code (smtpmail-read-response process)))) 282 (if (or (null (car (setq response-code (smtpmail-read-response process))))
281 (not (integerp (car response-code))) 283 (not (integerp (car response-code)))
282 (>= (car response-code) 400)) 284 (>= (car response-code) 400))
283 (throw 'done nil) 285 (progn
284 ) 286 ;; HELO
287 (smtpmail-send-command process (format "HELO %s" (smtpmail-fqdn)))
288
289 (if (or (null (car (setq response-code (smtpmail-read-response process))))
290 (not (integerp (car response-code)))
291 (>= (car response-code) 400))
292 (throw 'done nil)))
293 (let ((extension-lines (cdr (cdr response-code))))
294 (while extension-lines
295 (let ((name (intern (downcase (substring (car extension-lines) 4)))))
296 (and name
297 (cond ((memq name '(verb xvrb 8bitmime onex xone
298 expn size dsn etrn
299 help xusr))
300 (setq supported-extensions
301 (cons name supported-extensions)))
302 (t (message "unknown extension %s"
303 name)))))
304 (setq extension-lines (cdr extension-lines)))))
305
306 (if (or (member 'onex supported-extensions)
307 (member 'xone supported-extensions))
308 (progn
309 (smtpmail-send-command process (format "ONEX"))
310 (if (or (null (car (setq response-code (smtpmail-read-response process))))
311 (not (integerp (car response-code)))
312 (>= (car response-code) 400))
313 (throw 'done nil))))
314
315 (if (and smtpmail-debug-info
316 (or (member 'verb supported-extensions)
317 (member 'xvrb supported-extensions)))
318 (progn
319 (smtpmail-send-command process (format "VERB"))
320 (if (or (null (car (setq response-code (smtpmail-read-response process))))
321 (not (integerp (car response-code)))
322 (>= (car response-code) 400))
323 (throw 'done nil))))
324
325 (if (member 'xusr supported-extensions)
326 (progn
327 (smtpmail-send-command process (format "XUSR"))
328 (if (or (null (car (setq response-code (smtpmail-read-response process))))
329 (not (integerp (car response-code)))
330 (>= (car response-code) 400))
331 (throw 'done nil))))
285 332
286 ;; MAIL FROM: <sender> 333 ;; MAIL FROM: <sender>
287; (smtpmail-send-command process (format "MAIL FROM:%s@%s" (user-login-name) (smtpmail-fqdn))) 334 (let ((size-part
288 (smtpmail-send-command process (format "MAIL FROM: <%s>" user-mail-address)) 335 (if (member 'size supported-extensions)
289 336 (format " SIZE=%d"
290 (if (or (null (car (setq response-code (smtpmail-read-response process)))) 337 (save-excursion
291 (not (integerp (car response-code))) 338 (set-buffer smtpmail-text-buffer)
292 (>= (car response-code) 400)) 339 ;; size estimate:
293 (throw 'done nil) 340 (+ (- (point-max) (point-min))
294 ) 341 ;; Add one byte for each change-of-line
342 ;; because or CR-LF representation:
343 (count-lines (point-min) (point-max))
344 ;; For some reason, an empty line is
345 ;; added to the message. Maybe this
346 ;; is a bug, but it can't hurt to add
347 ;; those two bytes anyway:
348 2)))
349 ""))
350 (body-part
351 (if (member '8bitmime supported-extensions)
352 ;; FIXME:
353 ;; Code should be added here that transforms
354 ;; the contents of the message buffer into
355 ;; something the receiving SMTP can handle.
356 ;; For a receiver that supports 8BITMIME, this
357 ;; may mean converting BINARY to BASE64, or
358 ;; adding Content-Transfer-Encoding and the
359 ;; other MIME headers. The code should also
360 ;; return an indication of what encoding the
361 ;; message buffer is now, i.e. ASCII or
362 ;; 8BITMIME.
363 (if nil
364 " BODY=8BITMIME"
365 "")
366 "")))
367; (smtpmail-send-command process (format "MAIL FROM:%s@%s" (user-login-name) (smtpmail-fqdn)))
368 (smtpmail-send-command process (format "MAIL FROM: <%s>%s%s"
369 user-mail-address
370 size-part
371 body-part))
372
373 (if (or (null (car (setq response-code (smtpmail-read-response process))))
374 (not (integerp (car response-code)))
375 (>= (car response-code) 400))
376 (throw 'done nil)
377 ))
295 378
296 ;; RCPT TO: <recipient> 379 ;; RCPT TO: <recipient>
297 (let ((n 0)) 380 (let ((n 0))
@@ -299,7 +382,8 @@ don't define this value."
299 (smtpmail-send-command process (format "RCPT TO: <%s>" (nth n recipient))) 382 (smtpmail-send-command process (format "RCPT TO: <%s>" (nth n recipient)))
300 (setq n (1+ n)) 383 (setq n (1+ n))
301 384
302 (if (or (null (car (setq response-code (smtpmail-read-response process)))) 385 (setq response-code (smtpmail-read-response process))
386 (if (or (null (car response-code))
303 (not (integerp (car response-code))) 387 (not (integerp (car response-code)))
304 (>= (car response-code) 400)) 388 (>= (car response-code) 400))
305 (throw 'done nil) 389 (throw 'done nil)
@@ -354,15 +438,11 @@ don't define this value."
354 438
355(defun smtpmail-read-response (process) 439(defun smtpmail-read-response (process)
356 (let ((case-fold-search nil) 440 (let ((case-fold-search nil)
357 (response-string nil) 441 (response-strings nil)
358 (response-continue t) 442 (response-continue t)
359 (return-value '(nil "")) 443 (return-value '(nil ()))
360 match-end) 444 match-end)
361 445
362; (setq response-string nil)
363; (setq response-continue t)
364; (setq return-value '(nil ""))
365
366 (while response-continue 446 (while response-continue
367 (goto-char smtpmail-read-point) 447 (goto-char smtpmail-read-point)
368 (while (not (search-forward "\r\n" nil t)) 448 (while (not (search-forward "\r\n" nil t))
@@ -370,32 +450,38 @@ don't define this value."
370 (goto-char smtpmail-read-point)) 450 (goto-char smtpmail-read-point))
371 451
372 (setq match-end (point)) 452 (setq match-end (point))
373 (if (null response-string) 453 (setq response-strings
374 (setq response-string 454 (cons (buffer-substring smtpmail-read-point (- match-end 2))
375 (buffer-substring smtpmail-read-point (- match-end 2)))) 455 response-strings))
376 456
377 (goto-char smtpmail-read-point) 457 (goto-char smtpmail-read-point)
378 (if (looking-at "[0-9]+ ") 458 (if (looking-at "[0-9]+ ")
379 (progn (setq response-continue nil) 459 (let ((begin (match-beginning 0))
380; (setq return-value response-string) 460 (end (match-end 0)))
461 (if smtpmail-debug-info
462 (message "%s" (car response-strings)))
381 463
382 (if smtpmail-debug-info 464 (setq smtpmail-read-point match-end)
383 (message "%s" response-string))
384 465
385 (setq smtpmail-read-point match-end) 466 ;; ignore lines that start with "0"
386 (setq return-value 467 (if (looking-at "0[0-9]+ ")
387 (cons (string-to-int 468 nil
388 (buffer-substring (match-beginning 0) (match-end 0))) 469 (setq response-continue nil)
389 response-string))) 470 (setq return-value
471 (cons (string-to-int
472 (buffer-substring begin end))
473 (nreverse response-strings)))))
390 474
391 (if (looking-at "[0-9]+-") 475 (if (looking-at "[0-9]+-")
392 (progn (setq smtpmail-read-point match-end) 476 (progn (if smtpmail-debug-info
477 (message "%s" (car response-strings)))
478 (setq smtpmail-read-point match-end)
393 (setq response-continue t)) 479 (setq response-continue t))
394 (progn 480 (progn
395 (setq smtpmail-read-point match-end) 481 (setq smtpmail-read-point match-end)
396 (setq response-continue nil) 482 (setq response-continue nil)
397 (setq return-value 483 (setq return-value
398 (cons nil response-string)) 484 (cons nil (nreverse response-strings)))
399 ) 485 )
400 ))) 486 )))
401 (setq smtpmail-read-point match-end) 487 (setq smtpmail-read-point match-end)