aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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)