diff options
| -rw-r--r-- | lisp/mail/smtpmail.el | 154 |
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) |