Mercurial > hg > xemacs-beta
comparison lisp/vm/vm-pop.el @ 70:131b0175ea99 r20-0b30
Import from CVS: tag r20-0b30
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:02:59 +0200 |
parents | 05472e90ae02 |
children | 0d2f883870bc |
comparison
equal
deleted
inserted
replaced
69:804d1389bcd6 | 70:131b0175ea99 |
---|---|
1 ;;; Simple POP (RFC 1939) client for VM | 1 ;;; Simple POP (RFC 1460) client for VM |
2 ;;; Copyright (C) 1993, 1994, 1997 Kyle E. Jones | 2 ;;; Copyright (C) 1993, 1994 Kyle E. Jones |
3 ;;; | 3 ;;; |
4 ;;; This program is free software; you can redistribute it and/or modify | 4 ;;; This program is free software; you can redistribute it and/or modify |
5 ;;; it under the terms of the GNU General Public License as published by | 5 ;;; it under the terms of the GNU General Public License as published by |
6 ;;; the Free Software Foundation; either version 1, or (at your option) | 6 ;;; the Free Software Foundation; either version 1, or (at your option) |
7 ;;; any later version. | 7 ;;; any later version. |
22 ;; just as if we were using movemail on a spool file. | 22 ;; just as if we were using movemail on a spool file. |
23 (defun vm-pop-move-mail (source destination) | 23 (defun vm-pop-move-mail (source destination) |
24 (let ((process nil) | 24 (let ((process nil) |
25 (folder-type vm-folder-type) | 25 (folder-type vm-folder-type) |
26 (saved-password t) | 26 (saved-password t) |
27 (m-per-session vm-pop-messages-per-session) | |
28 (b-per-session vm-pop-bytes-per-session) | |
29 (handler (and (fboundp 'find-file-name-handler) | 27 (handler (and (fboundp 'find-file-name-handler) |
30 (condition-case () | 28 (condition-case () |
31 (find-file-name-handler source 'vm-pop-move-mail) | 29 (find-file-name-handler source 'vm-pop-move-mail) |
32 (wrong-number-of-arguments | 30 (wrong-number-of-arguments |
33 (find-file-name-handler source))))) | 31 (find-file-name-handler source))))) |
34 (popdrop (vm-safe-popdrop-string source)) | 32 (popdrop (vm-safe-popdrop-string source)) |
35 (statblob nil) | 33 greeting timestamp n message-count |
36 mailbox-count mailbox-size message-size response | 34 host port auth user pass source-list process-buffer) |
37 n retrieved retrieved-bytes process-buffer) | |
38 (unwind-protect | 35 (unwind-protect |
39 (catch 'done | 36 (catch 'done |
40 (if handler | 37 (if handler |
41 (throw 'done | 38 (throw 'done |
42 (funcall handler 'vm-pop-move-mail source destination))) | 39 (funcall handler 'vm-pop-move-mail source destination))) |
43 (setq process (vm-pop-make-session source)) | |
44 (or process (throw 'done nil)) | |
45 (setq process-buffer (process-buffer process)) | |
46 (save-excursion | |
47 (set-buffer process-buffer) | |
48 (setq vm-folder-type (or folder-type vm-default-folder-type)) | |
49 ;; find out how many messages are in the box. | |
50 (vm-pop-send-command process "STAT") | |
51 (setq response (vm-pop-read-stat-response process) | |
52 mailbox-count (nth 0 response) | |
53 mailbox-size (nth 1 response)) | |
54 ;; forget it if the command fails | |
55 ;; or if there are no messages present. | |
56 (if (or (null mailbox-count) | |
57 (< mailbox-count 1)) | |
58 (throw 'done nil)) | |
59 ;; loop through the maildrop retrieving and deleting | |
60 ;; messages as we go. | |
61 (setq n 1 retrieved 0 retrieved-bytes 0) | |
62 (setq statblob (vm-pop-start-status-timer)) | |
63 (vm-set-pop-stat-x-box statblob popdrop) | |
64 (vm-set-pop-stat-x-maxmsg statblob mailbox-count) | |
65 (while (and (<= n mailbox-count) | |
66 (or (not (natnump m-per-session)) | |
67 (< retrieved m-per-session)) | |
68 (or (not (natnump b-per-session)) | |
69 (< retrieved-bytes b-per-session))) | |
70 (vm-set-pop-stat-x-currmsg statblob n) | |
71 (vm-pop-send-command process (format "LIST %d" n)) | |
72 (setq message-size (vm-pop-read-list-response process)) | |
73 (vm-set-pop-stat-x-need statblob message-size) | |
74 (if (and (integerp vm-pop-max-message-size) | |
75 (> message-size vm-pop-max-message-size) | |
76 (progn | |
77 (setq response | |
78 (if vm-pop-ok-to-ask | |
79 (vm-pop-ask-about-large-message process | |
80 message-size | |
81 n) | |
82 'skip)) | |
83 (not (eq response 'retrieve)))) | |
84 (if (eq response 'delete) | |
85 (progn | |
86 (message "Deleting message %d..." n) | |
87 (vm-pop-send-command process (format "DELE %d" n)) | |
88 (and (null (vm-pop-read-response process)) | |
89 (throw 'done (not (equal retrieved 0))))) | |
90 (if vm-pop-ok-to-ask | |
91 (message "Skipping message %d..." n) | |
92 (message "Skipping message %d in %s, too large (%d > %d)..." | |
93 n popdrop message-size vm-pop-max-message-size))) | |
94 (message "Retrieving message %d (of %d) from %s..." | |
95 n mailbox-count popdrop) | |
96 (vm-pop-send-command process (format "RETR %d" n)) | |
97 (and (null (vm-pop-read-response process)) | |
98 (throw 'done (not (equal retrieved 0)))) | |
99 (and (null (vm-pop-retrieve-to-crashbox process destination | |
100 statblob)) | |
101 (throw 'done (not (equal retrieved 0)))) | |
102 (vm-increment retrieved) | |
103 (and b-per-session | |
104 (setq retrieved-bytes (+ retrieved-bytes message-size))) | |
105 (vm-pop-send-command process (format "DELE %d" n)) | |
106 ;; DELE can't fail but Emacs or this code might | |
107 ;; blow a gasket and spew filth down the | |
108 ;; connection, so... | |
109 (and (null (vm-pop-read-response process)) | |
110 (throw 'done (not (equal retrieved 0))))) | |
111 (vm-increment n)) | |
112 (not (equal retrieved 0)) )) | |
113 (and statblob (vm-pop-stop-status-timer statblob)) | |
114 (if process | |
115 (vm-pop-end-session process))))) | |
116 | |
117 (defun vm-pop-check-mail (source) | |
118 (let ((process nil) | |
119 (handler (and (fboundp 'find-file-name-handler) | |
120 (condition-case () | |
121 (find-file-name-handler source 'vm-pop-check-mail) | |
122 (wrong-number-of-arguments | |
123 (find-file-name-handler source))))) | |
124 response) | |
125 (unwind-protect | |
126 (save-excursion | |
127 (catch 'done | |
128 (if handler | |
129 (throw 'done | |
130 (funcall handler 'vm-pop-check-mail source))) | |
131 (setq process (vm-pop-make-session source)) | |
132 (or process (throw 'done nil)) | |
133 (set-buffer (process-buffer process)) | |
134 (vm-pop-send-command process "STAT") | |
135 (setq response (vm-pop-read-stat-response process)) | |
136 (if (null response) | |
137 nil | |
138 (not (equal 0 (car response)))))) | |
139 (and process (vm-pop-end-session process))))) | |
140 | |
141 (defun vm-pop-make-session (source) | |
142 (let ((process-to-shutdown nil) | |
143 process | |
144 (saved-password t) | |
145 (popdrop (vm-safe-popdrop-string source)) | |
146 greeting timestamp | |
147 host port auth user pass source-list process-buffer) | |
148 (unwind-protect | |
149 (catch 'done | |
150 ;; parse the maildrop | 40 ;; parse the maildrop |
151 (setq source-list (vm-parse source "\\([^:]+\\):?") | 41 (setq source-list (vm-parse source "\\([^:]+\\):?") |
152 host (nth 0 source-list) | 42 host (nth 0 source-list) |
153 port (nth 1 source-list) | 43 port (nth 1 source-list) |
154 auth (nth 2 source-list) | 44 auth (nth 2 source-list) |
175 source)) | 65 source)) |
176 (if (equal pass "*") | 66 (if (equal pass "*") |
177 (progn | 67 (progn |
178 (setq pass (car (cdr (assoc source vm-pop-passwords)))) | 68 (setq pass (car (cdr (assoc source vm-pop-passwords)))) |
179 (if (null pass) | 69 (if (null pass) |
180 (if (null vm-pop-ok-to-ask) | 70 (setq pass |
181 (progn (message "Need password for %s" popdrop) | 71 (vm-read-password |
182 (throw 'done nil)) | 72 (format "POP password for %s: " |
183 (setq pass | 73 popdrop)) |
184 (vm-read-password | 74 vm-pop-passwords (cons (list source pass) |
185 (format "POP password for %s: " | 75 vm-pop-passwords) |
186 popdrop)) | 76 saved-password t)))) |
187 vm-pop-passwords (cons (list source pass) | |
188 vm-pop-passwords) | |
189 saved-password t))))) | |
190 ;; get the trace buffer | 77 ;; get the trace buffer |
191 (setq process-buffer | 78 (setq process-buffer |
192 (get-buffer-create (format "trace of POP session to %s" host))) | 79 (get-buffer-create (format "trace of POP session to %s" host))) |
193 ;; Tell XEmacs/MULE not to mess with the text. | |
194 (and vm-xemacs-mule-p | |
195 (set-buffer-file-coding-system 'binary t)) | |
196 ;; clear the trace buffer of old output | 80 ;; clear the trace buffer of old output |
197 (save-excursion | 81 (save-excursion |
198 (set-buffer process-buffer) | 82 (set-buffer process-buffer) |
199 (buffer-disable-undo) | |
200 (erase-buffer)) | 83 (erase-buffer)) |
201 ;; open the connection to the server | 84 ;; open the connection to the server |
202 (setq process (open-network-stream "POP" process-buffer host port)) | 85 (setq process (open-network-stream "POP" process-buffer host port)) |
203 (and (null process) (throw 'done nil)) | 86 (and (null process) (throw 'done nil)) |
204 (process-kill-without-query process) | 87 (set-process-filter process 'vm-pop-process-filter) |
205 (save-excursion | 88 (save-excursion |
206 (set-buffer process-buffer) | 89 (set-buffer process-buffer) |
207 (make-local-variable 'vm-pop-read-point) | 90 (make-local-variable 'vm-pop-read-point) |
208 (setq vm-pop-read-point (point-min)) | 91 (setq vm-pop-read-point (point-min) |
209 (if (null (setq greeting (vm-pop-read-response process t))) | 92 vm-folder-type (or folder-type vm-default-folder-type)) |
210 (progn (delete-process process) | 93 (and (null (setq greeting (vm-pop-read-response process t))) |
211 (throw 'done nil))) | 94 (throw 'done nil)) |
212 (setq process-to-shutdown process) | |
213 ;; authentication | 95 ;; authentication |
214 (cond ((equal auth "pass") | 96 (cond ((equal auth "pass") |
215 (vm-pop-send-command process (format "USER %s" user)) | 97 (vm-pop-send-command process (format "USER %s" user)) |
216 (and (null (vm-pop-read-response process)) | 98 (and (null (vm-pop-read-response process)) |
217 (throw 'done nil)) | 99 (throw 'done nil)) |
234 (setq timestamp (vm-parse greeting "[^<]+\\(<[^>]+>\\)") | 116 (setq timestamp (vm-parse greeting "[^<]+\\(<[^>]+>\\)") |
235 timestamp (car timestamp)) | 117 timestamp (car timestamp)) |
236 (if (null timestamp) | 118 (if (null timestamp) |
237 (progn | 119 (progn |
238 (goto-char (point-max)) | 120 (goto-char (point-max)) |
239 (insert-before-markers "<<< ooops, no timestamp found in greeting! >>>\n") | 121 (insert "<<< ooops, no timestamp found in greeting! >>>\n") |
240 (throw 'done nil))) | 122 (throw 'done nil))) |
241 (vm-pop-send-command | 123 (vm-pop-send-command |
242 process | 124 process |
243 (format "APOP %s %s" | 125 (format "APOP %s %s" |
244 user | 126 user |
245 (vm-pop-md5 (concat timestamp pass)))) | 127 (vm-pop-md5 (concat timestamp pass)))) |
246 (and (null (vm-pop-read-response process)) | 128 (and (null (vm-pop-read-response process)) |
247 (throw 'done nil))) | 129 (throw 'done nil))) |
248 (t (error "Don't know how to authenticate using %s" auth))) | 130 (t (error "Don't know how to authenticate with %s" auth))) |
249 (setq process-to-shutdown nil) | 131 ;; find out how many messages are in the box. |
250 process )) | 132 (vm-pop-send-command process "STAT") |
251 (if process-to-shutdown | 133 (setq message-count (vm-pop-read-stat-response process)) |
252 (vm-pop-end-session process-to-shutdown))))) | 134 ;; forget it if the command fails |
253 | 135 ;; or if there are no messages present. |
254 (defun vm-pop-end-session (process) | 136 (if (or (null message-count) |
137 (< message-count 1)) | |
138 (throw 'done nil)) | |
139 ;; loop through the maildrop retrieving and deleting | |
140 ;; messages as we go. | |
141 (setq n 1) | |
142 (while (<= n message-count) | |
143 (vm-unsaved-message "Retrieving message %d (of %d) from %s..." | |
144 n message-count popdrop) | |
145 (vm-pop-send-command process (format "RETR %d" n)) | |
146 (and (null (vm-pop-read-response process)) | |
147 (throw 'done (not (equal n 1)))) | |
148 (and (null (vm-pop-retrieve-to-crashbox process destination)) | |
149 (throw 'done (not (equal n 1)))) | |
150 (vm-pop-send-command process (format "DELE %d" n)) | |
151 ;; DELE can't fail but Emacs or this code might | |
152 ;; blow a gasket and spew filth down the | |
153 ;; connection, so... | |
154 (and (null (vm-pop-read-response process)) | |
155 (throw 'done (not (equal n 1)))) | |
156 (vm-increment n)) | |
157 t )) | |
158 (if process | |
159 (save-excursion | |
160 (set-buffer (process-buffer process)) | |
161 (vm-pop-send-command process "QUIT") | |
162 (vm-pop-read-response process) | |
163 (delete-process process)))))) | |
164 | |
165 (defun vm-pop-process-filter (process output) | |
255 (save-excursion | 166 (save-excursion |
256 (set-buffer (process-buffer process)) | 167 (set-buffer (process-buffer process)) |
257 (vm-pop-send-command process "QUIT") | 168 (goto-char (point-max)) |
258 (vm-pop-read-response process) | 169 (insert output))) |
259 (if (fboundp 'add-async-timeout) | |
260 (add-async-timeout 2 'delete-process process) | |
261 (run-at-time 2 nil 'delete-process process)))) | |
262 | |
263 (defun vm-pop-stat-timer (o) (aref o 0)) | |
264 (defun vm-pop-stat-x-box (o) (aref o 1)) | |
265 (defun vm-pop-stat-x-currmsg (o) (aref o 2)) | |
266 (defun vm-pop-stat-x-maxmsg (o) (aref o 3)) | |
267 (defun vm-pop-stat-x-got (o) (aref o 4)) | |
268 (defun vm-pop-stat-x-need (o) (aref o 5)) | |
269 (defun vm-pop-stat-y-box (o) (aref o 6)) | |
270 (defun vm-pop-stat-y-currmsg (o) (aref o 7)) | |
271 (defun vm-pop-stat-y-maxmsg (o) (aref o 8)) | |
272 (defun vm-pop-stat-y-got (o) (aref o 9)) | |
273 (defun vm-pop-stat-y-need (o) (aref o 10)) | |
274 | |
275 (defun vm-set-pop-stat-timer (o val) (aset o 0 val)) | |
276 (defun vm-set-pop-stat-x-box (o val) (aset o 1 val)) | |
277 (defun vm-set-pop-stat-x-currmsg (o val) (aset o 2 val)) | |
278 (defun vm-set-pop-stat-x-maxmsg (o val) (aset o 3 val)) | |
279 (defun vm-set-pop-stat-x-got (o val) (aset o 4 val)) | |
280 (defun vm-set-pop-stat-x-need (o val) (aset o 5 val)) | |
281 (defun vm-set-pop-stat-y-box (o val) (aset o 6 val)) | |
282 (defun vm-set-pop-stat-y-currmsg (o val) (aset o 7 val)) | |
283 (defun vm-set-pop-stat-y-maxmsg (o val) (aset o 8 val)) | |
284 (defun vm-set-pop-stat-y-got (o val) (aset o 9 val)) | |
285 (defun vm-set-pop-stat-y-need (o val) (aset o 10 val)) | |
286 | |
287 (defun vm-pop-start-status-timer () | |
288 (let ((blob (make-vector 11 nil)) | |
289 timer) | |
290 (setq timer (add-timeout 5 'vm-pop-report-retrieval-status blob 5)) | |
291 (vm-set-pop-stat-timer blob timer) | |
292 blob )) | |
293 | |
294 (defun vm-pop-stop-status-timer (status-blob) | |
295 (if (fboundp 'disable-timeout) | |
296 (disable-timeout (vm-pop-stat-timer status-blob)) | |
297 (cancel-timer (vm-pop-stat-timer status-blob)))) | |
298 | |
299 (defun vm-pop-report-retrieval-status (o) | |
300 (cond ((null (vm-pop-stat-x-got o)) t) | |
301 ;; should not be possible, but better safe... | |
302 ((not (eq (vm-pop-stat-x-box o) (vm-pop-stat-y-box o))) t) | |
303 ((not (eq (vm-pop-stat-x-currmsg o) (vm-pop-stat-y-currmsg o))) t) | |
304 (t (message "Retrieving message %d (of %d) from %s, %s..." | |
305 (vm-pop-stat-x-currmsg o) | |
306 (vm-pop-stat-x-maxmsg o) | |
307 (vm-pop-stat-x-box o) | |
308 (format "%d%s of %d%s" | |
309 (vm-pop-stat-x-got o) | |
310 (if (> (vm-pop-stat-x-got o) | |
311 (vm-pop-stat-x-need o)) | |
312 "!" | |
313 "") | |
314 (vm-pop-stat-x-need o) | |
315 (if (eq (vm-pop-stat-x-got o) | |
316 (vm-pop-stat-y-got o)) | |
317 " (stalled)" | |
318 ""))))) | |
319 (vm-set-pop-stat-y-box o (vm-pop-stat-x-box o)) | |
320 (vm-set-pop-stat-y-currmsg o (vm-pop-stat-x-currmsg o)) | |
321 (vm-set-pop-stat-y-maxmsg o (vm-pop-stat-x-maxmsg o)) | |
322 (vm-set-pop-stat-y-got o (vm-pop-stat-x-got o)) | |
323 (vm-set-pop-stat-y-need o (vm-pop-stat-x-need o))) | |
324 | 170 |
325 (defun vm-pop-send-command (process command) | 171 (defun vm-pop-send-command (process command) |
326 (goto-char (point-max)) | 172 (goto-char (point-max)) |
327 (if (= (aref command 0) ?P) | 173 (if (= (aref command 0) ?P) |
328 (insert-before-markers "PASS <omitted>\r\n") | 174 (insert "PASS <omitted>\r\n") |
329 (insert-before-markers command "\r\n")) | 175 (insert command "\r\n")) |
330 (setq vm-pop-read-point (point)) | 176 (setq vm-pop-read-point (point)) |
331 (process-send-string process command) | 177 (process-send-string process command) |
332 (process-send-string process "\r\n")) | 178 (process-send-string process "\r\n")) |
333 | 179 |
334 (defun vm-pop-read-response (process &optional return-response-string) | 180 (defun vm-pop-read-response (process &optional return-response-string) |
345 (setq vm-pop-read-point match-end) | 191 (setq vm-pop-read-point match-end) |
346 (if return-response-string | 192 (if return-response-string |
347 (buffer-substring (point) match-end) | 193 (buffer-substring (point) match-end) |
348 t )))) | 194 t )))) |
349 | 195 |
350 (defun vm-pop-read-past-dot-sentinel-line (process) | |
351 (let ((case-fold-search nil)) | |
352 (goto-char vm-pop-read-point) | |
353 (while (not (re-search-forward "^\\.\r\n" nil 0)) | |
354 (beginning-of-line) | |
355 ;; save-excursion doesn't work right | |
356 (let ((opoint (point))) | |
357 (accept-process-output process) | |
358 (goto-char opoint))) | |
359 (setq vm-pop-read-point (point)))) | |
360 | |
361 (defun vm-pop-read-stat-response (process) | 196 (defun vm-pop-read-stat-response (process) |
362 (let ((response (vm-pop-read-response process t)) | |
363 list) | |
364 (setq list (vm-parse response "\\([^ ]+\\) *")) | |
365 (list (string-to-int (nth 1 list)) (string-to-int (nth 2 list))))) | |
366 | |
367 (defun vm-pop-read-list-response (process) | |
368 (let ((response (vm-pop-read-response process t))) | 197 (let ((response (vm-pop-read-response process t))) |
369 (string-to-int (nth 2 (vm-parse response "\\([^ ]+\\) *"))))) | 198 (string-to-int (nth 1 (vm-parse response "\\([^ ]+\\) *"))))) |
370 | 199 |
371 (defun vm-pop-ask-about-large-message (process size n) | 200 (defun vm-pop-retrieve-to-crashbox (process crash) |
372 (let ((work-buffer nil) | |
373 (pop-buffer (current-buffer)) | |
374 start end) | |
375 (unwind-protect | |
376 (save-excursion | |
377 (save-window-excursion | |
378 (vm-pop-send-command process (format "TOP %d %d" n 0)) | |
379 (if (vm-pop-read-response process) | |
380 (progn | |
381 (setq start vm-pop-read-point) | |
382 (vm-pop-read-past-dot-sentinel-line process) | |
383 (setq end vm-pop-read-point) | |
384 (setq work-buffer (generate-new-buffer "*pop-glop*")) | |
385 (set-buffer work-buffer) | |
386 (insert-buffer-substring pop-buffer start end) | |
387 (forward-line -1) | |
388 (delete-region (point) (point-max)) | |
389 (vm-pop-cleanup-region (point-min) (point-max)) | |
390 (vm-display-buffer work-buffer) | |
391 (setq minibuffer-scroll-window (selected-window)) | |
392 (goto-char (point-min)) | |
393 (if (re-search-forward "^Received:" nil t) | |
394 (progn | |
395 (goto-char (match-beginning 0)) | |
396 (vm-reorder-message-headers | |
397 nil vm-visible-headers | |
398 vm-invisible-header-regexp))) | |
399 (set-window-point (selected-window) (point)))) | |
400 (if (y-or-n-p (format "Message %d, size = %d, retrieve? " n size)) | |
401 'retrieve | |
402 (if (y-or-n-p (format "Delete message %d from popdrop? " n size)) | |
403 'delete | |
404 'skip)))) | |
405 (and work-buffer (kill-buffer work-buffer))))) | |
406 | |
407 (defun vm-pop-retrieve-to-crashbox (process crash statblob) | |
408 (let ((start vm-pop-read-point) end) | 201 (let ((start vm-pop-read-point) end) |
409 (goto-char start) | 202 (goto-char start) |
410 (vm-set-pop-stat-x-got statblob 0) | 203 (while (not (re-search-forward "^\\.\r\n" nil t)) |
411 (while (not (re-search-forward "^\\.\r\n" nil 0)) | 204 (accept-process-output process) |
412 (beginning-of-line) | 205 (goto-char start)) |
413 ;; save-excursion doesn't work right | |
414 (let* ((opoint (point)) | |
415 (func | |
416 (function | |
417 (lambda (beg end len) | |
418 (if vm-pop-read-point | |
419 (progn | |
420 (vm-set-pop-stat-x-got statblob (- end start)) | |
421 (if (zerop (% (random) 10)) | |
422 (vm-pop-report-retrieval-status statblob))))))) | |
423 (after-change-functions (cons func after-change-functions))) | |
424 (accept-process-output process) | |
425 (goto-char opoint))) | |
426 (vm-set-pop-stat-x-got statblob nil) | |
427 (setq vm-pop-read-point (point-marker)) | 206 (setq vm-pop-read-point (point-marker)) |
428 (goto-char (match-beginning 0)) | 207 (goto-char (match-beginning 0)) |
429 (setq end (point-marker)) | 208 (setq end (point-marker)) |
430 (vm-pop-cleanup-region start end) | 209 (vm-pop-cleanup-region start end) |
431 ;; Some POP servers strip leading and trailing message | 210 ;; Some POP servers strip leading and trailing message |
454 ;; for the Content-Length stuff counting from eob is | 233 ;; for the Content-Length stuff counting from eob is |
455 ;; the same thing in this case. | 234 ;; the same thing in this case. |
456 (vm-convert-folder-type-headers nil vm-folder-type) | 235 (vm-convert-folder-type-headers nil vm-folder-type) |
457 (goto-char end) | 236 (goto-char end) |
458 (insert-before-markers (vm-trailing-message-separator)))) | 237 (insert-before-markers (vm-trailing-message-separator)))) |
459 ;; Set file type to binary for DOS/Windows. I don't know if | 238 (write-region start end crash t 0) |
460 ;; this is correct to do or not; it depends on whether the | |
461 ;; the CRLF or the LF newline convention is used on the inbox | |
462 ;; associated with this crashbox. This setting assumes the LF | |
463 ;; newline convention is used. | |
464 (let ((buffer-file-type t)) | |
465 (write-region start end crash t 0)) | |
466 (delete-region start end) | 239 (delete-region start end) |
467 t )) | 240 t )) |
468 | 241 |
469 (defun vm-pop-cleanup-region (start end) | 242 (defun vm-pop-cleanup-region (start end) |
470 (if (> (- end start) 30000) | |
471 (message "CRLF conversion and char unstuffing...")) | |
472 (setq end (vm-marker end)) | 243 (setq end (vm-marker end)) |
473 (save-excursion | 244 (save-excursion |
474 (goto-char start) | 245 (goto-char start) |
475 ;; CRLF -> LF | 246 ;; CRLF -> LF |
476 (while (and (< (point) end) (search-forward "\r\n" end t)) | 247 (while (and (< (point) end) (search-forward "\r\n" end t)) |
478 (goto-char start) | 249 (goto-char start) |
479 ;; chop leading dots | 250 ;; chop leading dots |
480 (while (and (< (point) end) (re-search-forward "^\\." end t)) | 251 (while (and (< (point) end) (re-search-forward "^\\." end t)) |
481 (replace-match "" t t) | 252 (replace-match "" t t) |
482 (forward-char))) | 253 (forward-char))) |
483 (if (> (- end start) 30000) | |
484 (message "CRLF conversion and dot unstuffing... done")) | |
485 (set-marker end nil)) | 254 (set-marker end nil)) |
486 | 255 |
487 (defun vm-pop-md5 (string) | 256 (defun vm-pop-md5 (string) |
488 (let ((buffer nil)) | 257 (let ((buffer nil)) |
489 (unwind-protect | 258 (unwind-protect |
491 (setq buffer (generate-new-buffer "*vm-work*")) | 260 (setq buffer (generate-new-buffer "*vm-work*")) |
492 (set-buffer buffer) | 261 (set-buffer buffer) |
493 (insert string) | 262 (insert string) |
494 (call-process-region (point-min) (point-max) | 263 (call-process-region (point-min) (point-max) |
495 "/bin/sh" t buffer nil | 264 "/bin/sh" t buffer nil |
496 shell-command-switch vm-pop-md5-program) | 265 "-c" vm-pop-md5-program) |
497 ;; MD5 digest is 32 chars long | 266 ;; MD5 digest is 32 chars long |
498 ;; mddriver adds a newline to make neaten output for tty | 267 ;; mddriver adds a newline to make neaten output for tty |
499 ;; viewing, make sure we leave it behind. | 268 ;; viewing, make sure we leave it behind. |
500 (vm-buffer-substring-no-properties (point-min) (+ (point-min) 32))) | 269 (vm-buffer-substring-no-properties (point-min) (+ (point-min) 32))) |
501 (and buffer (kill-buffer buffer))))) | 270 (and buffer (kill-buffer buffer))))) |